Skip to content

Commit c0aaa48

Browse files
Implement Workplane.splineApprox
1 parent e82c7c3 commit c0aaa48

File tree

2 files changed

+67
-2
lines changed

2 files changed

+67
-2
lines changed

cadquery/cq.py

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1756,10 +1756,9 @@ def spline(
17561756
makeWire: bool = False,
17571757
) -> T:
17581758
"""
1759-
Create a spline interpolated through the provided points.
1759+
Create a spline interpolated through the provided points (2D or 3D).
17601760
17611761
:param listOfXYTuple: points to interpolate through
1762-
:type listOfXYTuple: list of 2-tuple
17631762
:param tangents: vectors specifying the direction of the tangent to the
17641763
curve at each of the specified interpolation points.
17651764
@@ -1852,6 +1851,52 @@ def spline(
18521851

18531852
return self.newObject([rv_w if makeWire else e])
18541853

1854+
def splineApprox(
1855+
self: T,
1856+
points: Iterable[VectorLike],
1857+
tol: Optional[float] = 1e-6,
1858+
minDeg: int = 1,
1859+
maxDeg: int = 6,
1860+
smoothing: Optional[Tuple[float, float, float]] = (1, 1, 1),
1861+
forConstruction: bool = False,
1862+
includeCurrent: bool = False,
1863+
makeWire: bool = False,
1864+
) -> T:
1865+
"""
1866+
Create a spline interpolated through the provided points (2D or 3D).
1867+
1868+
:param points: points to interpolate through
1869+
:param tol: tolerance of the algorithm (default: 1e-6)
1870+
:param minDeg: minimum spline degree (default: 1)
1871+
:param maxDeg: maximum spline degree (default: 6)
1872+
:param smoothing: optional parameters for the variational smoothing algorithm (default: (1,1,1))
1873+
:param includeCurrent: use current point as a starting point of the curve
1874+
:param makeWire: convert the resulting spline edge to a wire
1875+
:return: a Workplane object with the current point at the end of the spline
1876+
1877+
*WARNING* for advanced users.
1878+
"""
1879+
1880+
allPoints = self._toVectors(points, includeCurrent)
1881+
1882+
e = Edge.makeSplineApprox(
1883+
allPoints,
1884+
minDeg=minDeg,
1885+
maxDeg=maxDeg,
1886+
smoothing=smoothing,
1887+
**({"tol": tol} if tol else {}),
1888+
)
1889+
1890+
if makeWire:
1891+
rv_w = Wire.assembleEdges([e])
1892+
if not forConstruction:
1893+
self._addPendingWire(rv_w)
1894+
else:
1895+
if not forConstruction:
1896+
self._addPendingEdge(e)
1897+
1898+
return self.newObject([rv_w if makeWire else e])
1899+
18551900
def parametricCurve(
18561901
self: T,
18571902
func: Callable[[float], VectorLike],

tests/test_cadquery.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4400,6 +4400,8 @@ def testSplineApprox(self):
44004400

44014401
pts = [Vector(e[0], e[1], 0) for e in naca5305]
44024402

4403+
# spline
4404+
44034405
e1 = Edge.makeSplineApprox(pts, 1e-6, maxDeg=6, smoothing=(1, 1, 1))
44044406
e2 = Edge.makeSplineApprox(pts, 1e-6, minDeg=2, maxDeg=6)
44054407

@@ -4418,6 +4420,24 @@ def testSplineApprox(self):
44184420
self.assertTrue(e3.IsClosed())
44194421
self.assertTrue(w.IsClosed())
44204422

4423+
# Workplane method
4424+
4425+
w1 = Workplane().splineApprox(pts)
4426+
w2 = Workplane().splineApprox(pts, forConstruction=True)
4427+
w3 = Workplane().splineApprox(pts, makeWire=True,)
4428+
w4 = Workplane().splineApprox(pts, makeWire=True, forConstruction=True)
4429+
4430+
self.assertEqual(w1.edges().size(), 1)
4431+
self.assertEqual(len(w1.ctx.pendingEdges), 1)
4432+
self.assertEqual(w2.edges().size(), 1)
4433+
self.assertEqual(len(w2.ctx.pendingEdges), 0)
4434+
self.assertEqual(w3.wires().size(), 1)
4435+
self.assertEqual(len(w3.ctx.pendingWires), 1)
4436+
self.assertEqual(w4.wires().size(), 1)
4437+
self.assertEqual(len(w4.ctx.pendingWires), 0)
4438+
4439+
# spline surface
4440+
44214441
N = 40
44224442
T = 20
44234443
A = 5

0 commit comments

Comments
 (0)