Skip to content

Commit fe81d33

Browse files
authored
Merge pull request #872 from CadQuery/ezdxf-spline-fix
DXF spline export fix
2 parents 6a94606 + 6f52d88 commit fe81d33

File tree

2 files changed

+51
-5
lines changed

2 files changed

+51
-5
lines changed

cadquery/occ_impl/exporters/dxf.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,16 +76,23 @@ def _dxf_spline(e: Edge, msp: ezdxf.layouts.Modelspace, plane: Plane):
7676
curve, adaptor.FirstParameter(), adaptor.LastParameter(), CURVE_TOLERANCE
7777
)
7878

79+
# need to apply the transform on the geometry level
80+
spline.Transform(plane.fG.wrapped.Trsf())
81+
7982
order = spline.Degree() + 1
8083
knots = list(spline.KnotSequence())
8184
poles = [(p.X(), p.Y(), p.Z()) for p in spline.Poles()]
85+
weights = (
86+
[spline.Weight(i) for i in range(1, spline.NbPoles() + 1)]
87+
if spline.IsRational()
88+
else None
89+
)
8290

83-
weights = list(spline.Weights()) if spline.IsRational() else None
91+
if spline.IsPeriodic():
92+
pad = spline.NbKnots() - spline.LastUKnotIndex()
93+
poles += poles[:pad]
8494

85-
if spline.IsClosed():
86-
dxf_spline = ezdxf.math.BSplineClosed(poles, order, knots, weights)
87-
else:
88-
dxf_spline = ezdxf.math.BSpline(poles, order, knots, weights)
95+
dxf_spline = ezdxf.math.BSpline(poles, order, knots, weights)
8996

9097
msp.add_spline().apply_construction_tool(dxf_spline)
9198

tests/test_exporters.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
from cadquery import *
1010
from cadquery import exporters, importers
1111
from tests import BaseTest
12+
from OCP.GeomConvert import GeomConvert
13+
from OCP.BRepBuilderAPI import BRepBuilderAPI_MakeEdge
1214

1315

1416
class TestExporters(BaseTest):
@@ -168,6 +170,43 @@ def testDXF(self):
168170
self.assertAlmostEqual(s4.val().Area(), s4_i.val().Area(), 6)
169171
self.assertAlmostEqual(s4.edges().size(), s4_i.edges().size())
170172

173+
# test periodic spline
174+
w = Workplane().spline([(1, 1), (2, 2), (3, 2), (3, 1)], periodic=True)
175+
exporters.dxf.exportDXF(w, "res5.dxf")
176+
177+
w_i = importers.importDXF("res5.dxf")
178+
179+
self.assertAlmostEqual(w.val().Length(), w_i.wires().val().Length(), 6)
180+
181+
# test rational spline
182+
c = Edge.makeCircle(1)
183+
adaptor = c._geomAdaptor()
184+
curve = GeomConvert.CurveToBSplineCurve_s(adaptor.Curve().Curve())
185+
186+
e = Workplane().add(Edge(BRepBuilderAPI_MakeEdge(curve).Shape()))
187+
exporters.dxf.exportDXF(e, "res6.dxf")
188+
189+
e_i = importers.importDXF("res6.dxf")
190+
191+
self.assertAlmostEqual(e.val().Length(), e_i.wires().val().Length(), 6)
192+
193+
# test non-planar section
194+
s5 = (
195+
Workplane()
196+
.spline([(0, 0), (1, 0), (1, 1), (0, 1)])
197+
.close()
198+
.extrude(1, both=True)
199+
.translate((-3, -4, 0))
200+
)
201+
202+
s5.plane = Plane(origin=(0, 0.1, 0.5), normal=(0.05, 0.05, 1))
203+
s5 = s5.section()
204+
exporters.dxf.exportDXF(s5, "res7.dxf")
205+
206+
s5_i = importers.importDXF("res7.dxf")
207+
208+
self.assertAlmostEqual(s5.val().Area(), s5_i.val().Area(), 4)
209+
171210
def testTypeHandling(self):
172211

173212
with self.assertRaises(ValueError):

0 commit comments

Comments
 (0)