Skip to content

Commit 5d6e8c0

Browse files
committed
fix bezier approximation
1 parent 0a2a8e3 commit 5d6e8c0

File tree

3 files changed

+48
-3
lines changed

3 files changed

+48
-3
lines changed

ocpsvg/ocp.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from OCP.BRepFeat import BRepFeat
1212
from OCP.BRepLib import BRepLib_FindSurface
1313
from OCP.BRepTools import BRepTools
14+
from OCP.Convert import Convert_ParameterisationType
1415
from OCP.GC import (
1516
GC_MakeArcOfCircle,
1617
GC_MakeArcOfEllipse,
@@ -357,7 +358,7 @@ def ellipse_curve(
357358

358359

359360
def curve_to_bspline(curve: Geom_Curve) -> Geom_BSplineCurve:
360-
return GeomConvert.CurveToBSplineCurve_s(curve) # type: ignore
361+
return GeomConvert.CurveToBSplineCurve_s(curve, Convert_ParameterisationType.Convert_RationalC1) # type: ignore
361362

362363

363364
def curve_to_beziers(
@@ -399,8 +400,10 @@ def curve_to_beziers(
399400
)
400401

401402
else:
403+
bspline = curve_to_bspline(curve)
404+
bspline.Segment(adaptor.FirstParameter(), adaptor.LastParameter())
402405
yield from bspline_to_beziers(
403-
curve_to_bspline(curve),
406+
bspline,
404407
max_degree=max_degree,
405408
max_segments=max_segments,
406409
tolerance=tolerance,

ocpsvg/svg.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,8 @@ def curve_to_svg_path(
573573
beziers = curve_to_beziers(
574574
adaptor, tolerance=tolerance, max_degree=3 if use_cubics else 2
575575
)
576+
if reverse:
577+
beziers = reversed(list(beziers))
576578
for i, bezier in enumerate(beziers):
577579
yield from bezier_to_svg_path(
578580
bezier,

tests/test_svg.py

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99

1010
import pytest
1111
import svgelements
12+
from OCP.GC import GC_MakeArcOfCircle
1213
from OCP.Geom import Geom_Circle, Geom_Curve, Geom_Ellipse, Geom_TrimmedCurve
1314
from OCP.GeomAbs import GeomAbs_CurveType
14-
from OCP.gp import gp_Pnt, gp_Vec
15+
from OCP.gp import gp_Ax2, gp_Circ, gp_Pnt, gp_Vec
1516
from OCP.TopoDS import TopoDS, TopoDS_Edge, TopoDS_Face, TopoDS_Shape, TopoDS_Wire
1617
from pytest import approx, raises
1718

@@ -33,6 +34,7 @@
3334
SvgPathCommand,
3435
_SegmentInPath, # type: ignore private usage
3536
bezier_to_svg_path,
37+
curve_to_svg_path,
3638
edge_to_svg_path,
3739
edges_from_svg_path,
3840
face_to_svg_path,
@@ -159,6 +161,44 @@ def test_polyline_apprx(curve: Geom_Curve):
159161
assert set(seg[0] for seg in path).issubset(set("MLZ"))
160162

161163

164+
def test_trimmed_arc_to_cubics():
165+
radius = 10
166+
circ = gp_Circ(gp_Ax2(), radius)
167+
trimmed_arc = GC_MakeArcOfCircle(
168+
circ, gp_Pnt(-radius, 0, 0), gp_Pnt(0, +radius, 0), True
169+
).Value()
170+
171+
svg_with_arcs = list(curve_to_svg_path(trimmed_arc, tolerance=1e-6))
172+
svg_with_cubics_only = list(
173+
curve_to_svg_path(
174+
trimmed_arc, use_arcs=False, use_quadratics=False, tolerance=1e-6
175+
)
176+
)
177+
assert svg_with_arcs[0][-2:] == approx(svg_with_cubics_only[0][-2:])
178+
assert svg_with_arcs[-1][-2:] == approx(svg_with_cubics_only[-1][-2:])
179+
180+
181+
def test_trimmed_arc_to_cubics_reversed():
182+
radius = 10
183+
circ = gp_Circ(gp_Ax2(), radius)
184+
trimmed_arc = GC_MakeArcOfCircle(
185+
circ, gp_Pnt(-radius, 0, 0), gp_Pnt(0, +radius, 0), True
186+
).Value()
187+
188+
svg_with_arcs = list(curve_to_svg_path(trimmed_arc, reverse=True, tolerance=1e-6))
189+
svg_with_cubics_only = list(
190+
curve_to_svg_path(
191+
trimmed_arc,
192+
reverse=True,
193+
use_arcs=False,
194+
use_quadratics=False,
195+
tolerance=1e-6,
196+
)
197+
)
198+
assert svg_with_arcs[0][-2:] == approx(svg_with_cubics_only[0][-2:])
199+
assert svg_with_arcs[-1][-2:] == approx(svg_with_cubics_only[-1][-2:])
200+
201+
162202
@pytest.mark.parametrize(
163203
"wire, svg_d, opts",
164204
[

0 commit comments

Comments
 (0)