Skip to content

Commit 32cda0a

Browse files
Limit DXF BSpline Degree
Most DXF renderers and processing tools can't handle BSplines with degree >= 3 (order >= 4). For maximum compatibility, we should approximate such BSplines using degree-3 splines. This change uses the OpenCascade facilities to do so, though ezdxf.math also provides some spline approximation facilities that could be used. Using the OpenCascade approach allows us to match FreeCAD's parameters which are presumably tuned on a diversity of real-world designs. Fixes #1225
1 parent 2356028 commit 32cda0a

File tree

1 file changed

+12
-3
lines changed
  • cadquery/occ_impl/exporters

1 file changed

+12
-3
lines changed

cadquery/occ_impl/exporters/dxf.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
from .utils import toCompound
55

66
from OCP.gp import gp_Dir
7-
from OCP.GeomConvert import GeomConvert
7+
from OCP.GeomConvert import GeomConvert, GeomConvert_ApproxCurve
8+
from OCP.GeomAbs import GeomAbs_C0
89

910
import ezdxf
1011

@@ -72,12 +73,20 @@ def _dxf_spline(e: Edge, msp: ezdxf.layouts.Modelspace, plane: Plane):
7273
adaptor = e._geomAdaptor()
7374
curve = GeomConvert.CurveToBSplineCurve_s(adaptor.Curve().Curve())
7475

75-
spline = GeomConvert.SplitBSplineCurve_s(
76+
full_spline = GeomConvert.SplitBSplineCurve_s(
7677
curve, adaptor.FirstParameter(), adaptor.LastParameter(), CURVE_TOLERANCE
7778
)
7879

7980
# need to apply the transform on the geometry level
80-
spline.Transform(plane.fG.wrapped.Trsf())
81+
full_spline.Transform(plane.fG.wrapped.Trsf())
82+
83+
# approximate the transformed spline down to max degree 3 for
84+
# compatibilitly with more DXF processing tools.
85+
#
86+
# parameters choosen to match FreeCAD 0.20
87+
approx_spline = GeomConvert_ApproxCurve(full_spline, 0.001, GeomAbs_C0, 50, 3)
88+
89+
spline = approx_spline.Curve()
8190

8291
order = spline.Degree() + 1
8392
knots = list(spline.KnotSequence())

0 commit comments

Comments
 (0)