bspy 3.0.1__py3-none-any.whl → 4.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bspy/__init__.py +16 -9
- bspy/_spline_domain.py +83 -47
- bspy/_spline_evaluation.py +44 -62
- bspy/_spline_fitting.py +353 -75
- bspy/_spline_intersection.py +332 -59
- bspy/_spline_operations.py +33 -38
- bspy/hyperplane.py +540 -0
- bspy/manifold.py +391 -0
- bspy/solid.py +839 -0
- bspy/spline.py +310 -77
- bspy/splineOpenGLFrame.py +683 -19
- bspy/viewer.py +795 -0
- {bspy-3.0.1.dist-info → bspy-4.1.dist-info}/METADATA +25 -13
- bspy-4.1.dist-info/RECORD +17 -0
- {bspy-3.0.1.dist-info → bspy-4.1.dist-info}/WHEEL +1 -1
- bspy/bspyApp.py +0 -426
- bspy/drawableSpline.py +0 -585
- bspy-3.0.1.dist-info/RECORD +0 -15
- {bspy-3.0.1.dist-info → bspy-4.1.dist-info}/LICENSE +0 -0
- {bspy-3.0.1.dist-info → bspy-4.1.dist-info}/top_level.txt +0 -0
bspy/_spline_operations.py
CHANGED
|
@@ -35,9 +35,9 @@ def add(self, other, indMap = None):
|
|
|
35
35
|
permutation.append(i + 1) # Add 1 to account for dependent variables.
|
|
36
36
|
for i in range(other.nInd - 1, -1, -1):
|
|
37
37
|
if i not in otherMapped:
|
|
38
|
-
order.append(other.order[i])
|
|
39
|
-
nCoef.append(other.nCoef[i])
|
|
40
|
-
knots.append(other.knots[i])
|
|
38
|
+
order.append(other.order[other.nInd - 1 - i])
|
|
39
|
+
nCoef.append(other.nCoef[other.nInd - 1 - i])
|
|
40
|
+
knots.append(other.knots[other.nInd - 1 - i])
|
|
41
41
|
permutation.append(self.nInd + i + 1) # Add 1 to account for dependent variables.
|
|
42
42
|
nInd += 1
|
|
43
43
|
else:
|
|
@@ -67,19 +67,19 @@ def confine(self, range_bounds):
|
|
|
67
67
|
degree = order - 1
|
|
68
68
|
domain = spline.domain()
|
|
69
69
|
unique, counts = np.unique(spline.knots[0], return_counts=True)
|
|
70
|
-
machineEpsilon =
|
|
70
|
+
machineEpsilon = np.finfo(self.coefs.dtype).eps
|
|
71
71
|
epsilon = np.sqrt(machineEpsilon)
|
|
72
72
|
intersections = [] # List of tuples (u, boundaryPoint, headingOutside)
|
|
73
73
|
|
|
74
74
|
def addIntersection(u, headedOutside = False):
|
|
75
75
|
boundaryPoint = spline(np.atleast_1d(u))
|
|
76
76
|
for i in range(spline.nDep):
|
|
77
|
-
if boundaryPoint[i] < range_bounds[i][0]
|
|
77
|
+
if boundaryPoint[i] < range_bounds[i][0]:
|
|
78
78
|
headedOutside = True if boundaryPoint[i] < range_bounds[i][0] - epsilon else headedOutside
|
|
79
|
-
boundaryPoint[i] = range_bounds[i][0]
|
|
80
|
-
if boundaryPoint[i] > range_bounds[i][1]
|
|
79
|
+
boundaryPoint[i] = range_bounds[i][0]
|
|
80
|
+
if boundaryPoint[i] > range_bounds[i][1]:
|
|
81
81
|
headedOutside = True if boundaryPoint[i] > range_bounds[i][1] + epsilon else headedOutside
|
|
82
|
-
boundaryPoint[i] = range_bounds[i][1]
|
|
82
|
+
boundaryPoint[i] = range_bounds[i][1]
|
|
83
83
|
intersections.append((u, boundaryPoint, headedOutside))
|
|
84
84
|
|
|
85
85
|
def intersectBoundary(i, j):
|
|
@@ -163,7 +163,7 @@ def confine(self, range_bounds):
|
|
|
163
163
|
def contract(self, uvw):
|
|
164
164
|
domain = self.domain()
|
|
165
165
|
section = [slice(None)]
|
|
166
|
-
|
|
166
|
+
bValues = []
|
|
167
167
|
contracting = False
|
|
168
168
|
for iv in range(self.nInd):
|
|
169
169
|
if uvw[iv] is not None:
|
|
@@ -171,12 +171,12 @@ def contract(self, uvw):
|
|
|
171
171
|
raise ValueError(f"Spline evaluation outside domain: {uvw}")
|
|
172
172
|
|
|
173
173
|
# Grab all of the appropriate coefficients
|
|
174
|
-
ix =
|
|
175
|
-
|
|
176
|
-
indices.append(ix)
|
|
174
|
+
ix, indValues = bspy.Spline.bspline_values(None, self.knots[iv], self.order[iv], uvw[iv])
|
|
175
|
+
bValues.append(indValues)
|
|
177
176
|
section.append(slice(ix - self.order[iv], ix))
|
|
178
177
|
contracting = True
|
|
179
178
|
else:
|
|
179
|
+
bValues.append([])
|
|
180
180
|
section.append(slice(None))
|
|
181
181
|
|
|
182
182
|
if not contracting:
|
|
@@ -194,9 +194,8 @@ def contract(self, uvw):
|
|
|
194
194
|
del order[ix]
|
|
195
195
|
del nCoef[ix]
|
|
196
196
|
del knots[ix]
|
|
197
|
-
bValues = bspy.Spline.bspline_values(indices.pop(0), self.knots[iv], self.order[iv], uvw[iv])
|
|
198
197
|
coefs = np.moveaxis(coefs, ix + 1, -1)
|
|
199
|
-
coefs = coefs @ bValues
|
|
198
|
+
coefs = coefs @ bValues[iv]
|
|
200
199
|
else:
|
|
201
200
|
ix += 1
|
|
202
201
|
|
|
@@ -267,14 +266,6 @@ def graph(self):
|
|
|
267
266
|
dep[i] = knotAverage
|
|
268
267
|
return type(self)(self.nInd, self.nInd + self.nDep, self.order, self.nCoef, self.knots, coefs, self.metadata)
|
|
269
268
|
|
|
270
|
-
def greville(self, ind = 0):
|
|
271
|
-
if ind < 0 or ind >= self.nInd: raise ValueError("Invalid independent variable")
|
|
272
|
-
myKnots = self.knots[ind]
|
|
273
|
-
knotAverages = 0
|
|
274
|
-
for ix in range(1, self.order[ind]):
|
|
275
|
-
knotAverages = knotAverages + myKnots[ix : ix + self.nCoef[ind]]
|
|
276
|
-
return knotAverages / (self.order[ind] - 1)
|
|
277
|
-
|
|
278
269
|
def integrate(self, with_respect_to = 0):
|
|
279
270
|
if not(0 <= with_respect_to < self.nInd): raise ValueError("Invalid with_respect_to")
|
|
280
271
|
|
|
@@ -317,6 +308,8 @@ def multiplyAndConvolve(self, other, indMap = None, productType = 'S'):
|
|
|
317
308
|
# Construct new spline parameters.
|
|
318
309
|
nInd = self.nInd + other.nInd
|
|
319
310
|
nDep = other.nDep
|
|
311
|
+
if productType == 'C' and nDep == 2:
|
|
312
|
+
nDep = 1
|
|
320
313
|
order = [*self.order, *other.order]
|
|
321
314
|
nCoef = [*self.nCoef, *other.nCoef]
|
|
322
315
|
knots = [*self.knots, *other.knots]
|
|
@@ -521,12 +514,12 @@ def multiplyAndConvolve(self, other, indMap = None, productType = 'S'):
|
|
|
521
514
|
taylorCoefs = (coefs[ix1 - order1:ix1, ix2 - order2:ix2]).T # Transpose so we multiply on the left (due to matmul rules)
|
|
522
515
|
bValues = np.empty((order1, order1), knots1.dtype)
|
|
523
516
|
for derivativeOrder in range(order1):
|
|
524
|
-
bValues[:,derivativeOrder] = bspy.Spline.bspline_values(ix1, self.knots[ind1], order1, knot, derivativeOrder, True)
|
|
517
|
+
ix1, bValues[:,derivativeOrder] = bspy.Spline.bspline_values(ix1, self.knots[ind1], order1, knot, derivativeOrder, True)
|
|
525
518
|
taylorCoefs = taylorCoefs @ bValues
|
|
526
519
|
taylorCoefs = np.moveaxis(taylorCoefs, -1, 0) # Move ind1's taylor coefficients to the left side so we can compute ind2's
|
|
527
520
|
bValues = np.empty((order2, order2), knots2.dtype)
|
|
528
521
|
for derivativeOrder in range(order2):
|
|
529
|
-
bValues[:,derivativeOrder] = bspy.Spline.bspline_values(ix2, other.knots[ind2], order2, yLeft, derivativeOrder, True)
|
|
522
|
+
ix2, bValues[:,derivativeOrder] = bspy.Spline.bspline_values(ix2, other.knots[ind2], order2, yLeft, derivativeOrder, True)
|
|
530
523
|
taylorCoefs = taylorCoefs @ bValues
|
|
531
524
|
taylorCoefs = (np.moveaxis(taylorCoefs, 0, -1)).T # Move ind1's taylor coefficients back to the right side, and re-transpose
|
|
532
525
|
|
|
@@ -597,22 +590,20 @@ def multiplyAndConvolve(self, other, indMap = None, productType = 'S'):
|
|
|
597
590
|
# Next step in multiply:
|
|
598
591
|
# 2) Convert each spline segment into a polynomial (Taylor series).
|
|
599
592
|
# Isolate the appropriate segment coefficients
|
|
600
|
-
ix1 =
|
|
601
|
-
|
|
602
|
-
ix2 = np.searchsorted(other.knots[ind2], knot, 'right')
|
|
603
|
-
ix2 = min(ix2, other.nCoef[ind2])
|
|
593
|
+
ix1 = None
|
|
594
|
+
ix2 = None
|
|
604
595
|
|
|
605
596
|
# Compute taylor coefficients for the segment
|
|
606
|
-
|
|
607
|
-
bValues = np.empty((order1, order1), knots1.dtype)
|
|
597
|
+
bValues1 = np.empty((order1, order1), knots1.dtype)
|
|
608
598
|
for derivativeOrder in range(order1):
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
taylorCoefs = np.moveaxis(taylorCoefs, -1, 0) # Move ind1's taylor coefficients to the left side so we can compute ind2's
|
|
612
|
-
bValues = np.empty((order2, order2), knots2.dtype)
|
|
599
|
+
ix1, bValues1[:,derivativeOrder] = bspy.Spline.bspline_values(ix1, self.knots[ind1], order1, knot, derivativeOrder, True)
|
|
600
|
+
bValues2 = np.empty((order2, order2), knots2.dtype)
|
|
613
601
|
for derivativeOrder in range(order2):
|
|
614
|
-
|
|
615
|
-
taylorCoefs =
|
|
602
|
+
ix2, bValues2[:,derivativeOrder] = bspy.Spline.bspline_values(ix2, other.knots[ind2], order2, knot, derivativeOrder, True)
|
|
603
|
+
taylorCoefs = (coefs[ix1 - order1:ix1, ix2 - order2:ix2]).T # Transpose so we multiply on the left (due to matmul rules)
|
|
604
|
+
taylorCoefs = taylorCoefs @ bValues1
|
|
605
|
+
taylorCoefs = np.moveaxis(taylorCoefs, -1, 0) # Move ind1's taylor coefficients to the left side so we can compute ind2's
|
|
606
|
+
taylorCoefs = taylorCoefs @ bValues2
|
|
616
607
|
taylorCoefs = (np.moveaxis(taylorCoefs, 0, -1)).T # Move ind1's taylor coefficients back to the right side, and re-transpose
|
|
617
608
|
|
|
618
609
|
# 3) Sum coefficients of matching polynomial degree (the coefficients have already been multiplied together by the outer product).
|
|
@@ -703,7 +694,12 @@ def normal_spline(self, indices=None):
|
|
|
703
694
|
# using that calculation to span uvw from the starting knot to the end for each variable.
|
|
704
695
|
nCoef = len(newKnots[-1]) - newOrder[-1]
|
|
705
696
|
totalCoefs.append(totalCoefs[-1] * nCoef)
|
|
706
|
-
|
|
697
|
+
knotAverages = bspy.Spline(1, 0, [newOrd], [nCoef], [newKnots[-1]], []).greville()
|
|
698
|
+
for iKnot in range(1, len(knotAverages) - 1):
|
|
699
|
+
if knotAverages[iKnot] == knotAverages[iKnot + 1]:
|
|
700
|
+
knotAverages[iKnot] = 0.5 * (knotAverages[iKnot - 1] + knotAverages[iKnot])
|
|
701
|
+
knotAverages[iKnot + 1] = 0.5 * (knotAverages[iKnot + 1] + knotAverages[iKnot + 2])
|
|
702
|
+
uvwValues.append(knotAverages)
|
|
707
703
|
nCoefs.append(nCoef)
|
|
708
704
|
points = []
|
|
709
705
|
ijk = [0 for order in self.order]
|
|
@@ -721,7 +717,6 @@ def normal_spline(self, indices=None):
|
|
|
721
717
|
points = np.reshape(points, [nDep] + nCoefs)
|
|
722
718
|
points = np.transpose(points, [0] + list(range(self.nInd, 0, -1)))
|
|
723
719
|
return bspy.Spline.least_squares(uvwValues, points, order = newOrder, knots = newKnots, metadata = self.metadata)
|
|
724
|
-
# return bspy.Spline.least_squares(self.nInd, nDep, newOrder, points, newKnots, 0, self.metadata)
|
|
725
720
|
|
|
726
721
|
def rotate(self, vector, angle):
|
|
727
722
|
vector = np.atleast_1d(vector)
|