Skip to content

Commit 8c15d18

Browse files
Implement parametricSurface
1 parent 50bada4 commit 8c15d18

File tree

2 files changed

+54
-3
lines changed

2 files changed

+54
-3
lines changed

cadquery/cq.py

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1861,10 +1861,10 @@ def parametricCurve(
18611861
makeWire: bool = True,
18621862
) -> T:
18631863
"""
1864-
Create a spline interpolated through the provided points.
1864+
Create a spline curve approximating the provided function.
18651865
1866-
:param func: function f(t) that will generate (x,y) pairs
1867-
:type func: float --> (float,float)
1866+
:param func: function f(t) that will generate (x,y,z) pairs
1867+
:type func: float --> (float,float,float)
18681868
:param N: number of points for discretization
18691869
:param start: starting value of the parameter t
18701870
:param stop: final value of the parameter t
@@ -1888,6 +1888,47 @@ def parametricCurve(
18881888

18891889
return self.newObject([rv_w if makeWire else e])
18901890

1891+
def parametricSurface(
1892+
self: T,
1893+
func: Callable[[float, float], VectorLike],
1894+
N: int = 20,
1895+
start: float = 0,
1896+
stop: float = 1,
1897+
tol: float = 1e-2,
1898+
) -> T:
1899+
"""
1900+
Create a spline surface approximating the provided function.
1901+
1902+
:param func: function f(u,v) that will generate (x,y,z) pairs
1903+
:type func: (float,float) --> (float,float,float)
1904+
:param N: number of points for discretization in one direction
1905+
:param start: starting value of the parameters u,v
1906+
:param stop: final value of the parameters u,v
1907+
:param tol: tolerance used by the approximation algorithm
1908+
:return: a Workplane object with the current point unchanged
1909+
1910+
This method might be unstable and may require tuning of the tol parameter.
1911+
1912+
"""
1913+
1914+
diff = stop - start
1915+
allPoints = []
1916+
1917+
for i in range(N):
1918+
allPoints.append(
1919+
self._toVectors(
1920+
(
1921+
func(start + diff * i / N, start + diff * j / N)
1922+
for j in range(N + 1)
1923+
),
1924+
False,
1925+
)
1926+
)
1927+
1928+
f = Face.makeSplineApprox(allPoints, tol=tol)
1929+
1930+
return self.newObject([f])
1931+
18911932
def ellipseArc(
18921933
self: T,
18931934
x_radius: float,

tests/test_cadquery.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4425,3 +4425,13 @@ def testSplineApprox(self):
44254425

44264426
with raises(ValueError):
44274427
f3 = Face.makeSplineApprox(pts, smoothing=(1, 1, 1), maxDeg=3)
4428+
4429+
def testParametricSurface(self):
4430+
4431+
from math import pi, cos
4432+
4433+
r = Workplane().parametricSurface(
4434+
lambda u, v: (u, v, cos(2 * pi * i) * cos(2 * pi * j))
4435+
)
4436+
4437+
self.assertTrue(r.faces().val().isValid())

0 commit comments

Comments
 (0)