bspy 4.1__py3-none-any.whl → 4.2__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 +3 -0
- bspy/_spline_domain.py +92 -9
- bspy/_spline_evaluation.py +79 -20
- bspy/_spline_fitting.py +201 -45
- bspy/_spline_intersection.py +284 -137
- bspy/_spline_operations.py +63 -48
- bspy/hyperplane.py +6 -6
- bspy/manifold.py +2 -2
- bspy/solid.py +15 -12
- bspy/spline.py +180 -50
- bspy/spline_block.py +343 -0
- bspy/viewer.py +7 -6
- {bspy-4.1.dist-info → bspy-4.2.dist-info}/METADATA +11 -5
- bspy-4.2.dist-info/RECORD +18 -0
- {bspy-4.1.dist-info → bspy-4.2.dist-info}/WHEEL +1 -1
- bspy-4.1.dist-info/RECORD +0 -17
- {bspy-4.1.dist-info → bspy-4.2.dist-info}/LICENSE +0 -0
- {bspy-4.1.dist-info → bspy-4.2.dist-info}/top_level.txt +0 -0
bspy/spline_block.py
ADDED
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import bspy.spline
|
|
3
|
+
import bspy._spline_domain
|
|
4
|
+
import bspy._spline_evaluation
|
|
5
|
+
import bspy._spline_intersection
|
|
6
|
+
import bspy._spline_fitting
|
|
7
|
+
import bspy._spline_operations
|
|
8
|
+
|
|
9
|
+
class SplineBlock:
|
|
10
|
+
"""
|
|
11
|
+
A class to represent and process an array-like collection of splines.
|
|
12
|
+
Spline blocks are useful for efficiently manipulating and solving systems of equations with splines.
|
|
13
|
+
|
|
14
|
+
Parameters
|
|
15
|
+
----------
|
|
16
|
+
block : an array-like collection of splines (may be a list of lists)
|
|
17
|
+
Splines in the same row are treated as if they are added together.
|
|
18
|
+
Each row need not have the same number of splines, but all splines in a row must have the same
|
|
19
|
+
number of dependent variables (same nDep). Corresponding independent variables must have the same domain.
|
|
20
|
+
|
|
21
|
+
For example, if F is a spline with nInd = 3 and nDep = 2, G is a spline with nInd = 1 and nDep = 2,
|
|
22
|
+
and h is a spline with nInd = 2 and nDep = 1, then [[F, G], [h]] is a valid block (total nDep is 3
|
|
23
|
+
and max nInd is 4).
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def _block_evaluation(self, returnShape, splineFunction, args):
|
|
27
|
+
value = np.zeros(returnShape, self.coefsDtype)
|
|
28
|
+
nDep = 0
|
|
29
|
+
for row in self.block:
|
|
30
|
+
nInd = 0
|
|
31
|
+
for spline in row:
|
|
32
|
+
value[nDep:nDep + spline.nDep] += splineFunction(spline, *[arg[nInd:nInd + spline.nInd] for arg in args])
|
|
33
|
+
nInd += spline.nInd
|
|
34
|
+
nDep += spline.nDep
|
|
35
|
+
return value
|
|
36
|
+
|
|
37
|
+
def _block_operation(self, splineFunction, args):
|
|
38
|
+
newBlock = []
|
|
39
|
+
for row in self.block:
|
|
40
|
+
newRow = []
|
|
41
|
+
nInd = 0
|
|
42
|
+
for spline in row:
|
|
43
|
+
newRow.append(splineFunction(spline, *[arg[nInd:nInd + spline.nInd] for arg in args]))
|
|
44
|
+
nInd += spline.nInd
|
|
45
|
+
newBlock.append(newRow)
|
|
46
|
+
return SplineBlock(newBlock)
|
|
47
|
+
|
|
48
|
+
def __init__(self, block):
|
|
49
|
+
if isinstance(block, bspy.spline.Spline):
|
|
50
|
+
self.block = [[block]]
|
|
51
|
+
elif isinstance(block[0], bspy.spline.Spline):
|
|
52
|
+
self.block = [block]
|
|
53
|
+
else:
|
|
54
|
+
self.block = block
|
|
55
|
+
self.nInd = 0
|
|
56
|
+
self.nDep = 0
|
|
57
|
+
self.knotsDtype = None
|
|
58
|
+
self.coefsDtype = None
|
|
59
|
+
self.size = 0
|
|
60
|
+
self._domain = []
|
|
61
|
+
for row in self.block:
|
|
62
|
+
rowInd = 0
|
|
63
|
+
rowDep = 0
|
|
64
|
+
for spline in row:
|
|
65
|
+
if rowDep == 0:
|
|
66
|
+
rowDep = spline.nDep
|
|
67
|
+
if self.nInd == 0:
|
|
68
|
+
self.knotsDtype = spline.knots[0].dtype
|
|
69
|
+
self.coefsDtype = spline.coefs.dtype
|
|
70
|
+
elif rowDep != spline.nDep:
|
|
71
|
+
raise ValueError("All splines in the same row must have the same nDep")
|
|
72
|
+
d = spline.domain()
|
|
73
|
+
for i in range(rowInd, rowInd + spline.nInd):
|
|
74
|
+
ind = i - rowInd
|
|
75
|
+
if i < self.nInd:
|
|
76
|
+
if self._domain[i][0] != d[ind, 0] or self._domain[i][1] != d[ind, 1]:
|
|
77
|
+
raise ValueError("Domains of independent variables must match")
|
|
78
|
+
else:
|
|
79
|
+
self._domain.append(d[ind])
|
|
80
|
+
rowInd += spline.nInd
|
|
81
|
+
self.nInd = max(self.nInd, rowInd)
|
|
82
|
+
self.nDep += rowDep
|
|
83
|
+
self.size += len(row)
|
|
84
|
+
self._domain = np.array(self._domain, self.knotsDtype)
|
|
85
|
+
|
|
86
|
+
def __call__(self, uvw):
|
|
87
|
+
return self.evaluate(uvw)
|
|
88
|
+
|
|
89
|
+
def __repr__(self):
|
|
90
|
+
return f"SplineBlock({self.block})"
|
|
91
|
+
|
|
92
|
+
def contours(self):
|
|
93
|
+
"""
|
|
94
|
+
Find all the contour curves of a block of splines whose `nInd` is one larger than its `nDep`.
|
|
95
|
+
|
|
96
|
+
Returns
|
|
97
|
+
-------
|
|
98
|
+
curves : `iterable`
|
|
99
|
+
A collection of `Spline` curves, `u(t)`, each of whose domain is [0, 1], whose range is
|
|
100
|
+
in the parameter space of the given spline, and which satisfy `self(u(t)) = 0`.
|
|
101
|
+
|
|
102
|
+
See Also
|
|
103
|
+
--------
|
|
104
|
+
`zeros` : Find the roots of a block of splines (nInd must match nDep).
|
|
105
|
+
|
|
106
|
+
Notes
|
|
107
|
+
-----
|
|
108
|
+
Uses `zeros` to find all intersection points and `Spline.contour` to find individual intersection curves.
|
|
109
|
+
The algorithm used to to find all intersection curves is from Grandine, Thomas A., and Frederick W. Klein IV.
|
|
110
|
+
"A new approach to the surface intersection problem." Computer Aided Geometric Design 14, no. 2 (1997): 111-134.
|
|
111
|
+
"""
|
|
112
|
+
return bspy._spline_intersection.contours(self)
|
|
113
|
+
|
|
114
|
+
def contract(self, uvw):
|
|
115
|
+
"""
|
|
116
|
+
Contract a spline block by assigning a fixed value to one or more of its independent variables.
|
|
117
|
+
|
|
118
|
+
Parameters
|
|
119
|
+
----------
|
|
120
|
+
uvw : `iterable`
|
|
121
|
+
An iterable of length `nInd` that specifies the values of each independent variable to contract.
|
|
122
|
+
A value of `None` for an independent variable indicates that variable should remain unchanged.
|
|
123
|
+
|
|
124
|
+
Returns
|
|
125
|
+
-------
|
|
126
|
+
block : `SplineBlock`
|
|
127
|
+
The contracted spline block.
|
|
128
|
+
"""
|
|
129
|
+
return self._block_operation(bspy._spline_operations.contract, (uvw,))
|
|
130
|
+
|
|
131
|
+
def derivative(self, with_respect_to, uvw):
|
|
132
|
+
"""
|
|
133
|
+
Compute the derivative of the spline block at given parameter values.
|
|
134
|
+
|
|
135
|
+
Parameters
|
|
136
|
+
----------
|
|
137
|
+
with_respect_to : `iterable`
|
|
138
|
+
An iterable of length `nInd` that specifies the integer order of derivative for each independent variable.
|
|
139
|
+
A zero-order derivative just evaluates the spline normally.
|
|
140
|
+
|
|
141
|
+
uvw : `iterable`
|
|
142
|
+
An iterable of length `nInd` that specifies the values of each independent variable (the parameter values).
|
|
143
|
+
|
|
144
|
+
Returns
|
|
145
|
+
-------
|
|
146
|
+
value : `numpy.array`
|
|
147
|
+
The value of the derivative of the spline block at the given parameter values (array of size nDep).
|
|
148
|
+
"""
|
|
149
|
+
return self._block_evaluation(self.nDep, bspy._spline_evaluation.derivative, (with_respect_to, uvw))
|
|
150
|
+
|
|
151
|
+
def domain(self):
|
|
152
|
+
"""
|
|
153
|
+
Return the domain of a spline block.
|
|
154
|
+
|
|
155
|
+
Returns
|
|
156
|
+
-------
|
|
157
|
+
bounds : `numpy.array`
|
|
158
|
+
nInd x 2 array of the lower and upper bounds on each of the independent variables.
|
|
159
|
+
"""
|
|
160
|
+
return self._domain
|
|
161
|
+
|
|
162
|
+
def evaluate(self, uvw):
|
|
163
|
+
"""
|
|
164
|
+
Compute the value of the spline block at given parameter values.
|
|
165
|
+
|
|
166
|
+
Parameters
|
|
167
|
+
----------
|
|
168
|
+
uvw : `iterable`
|
|
169
|
+
An iterable of length `nInd` that specifies the values of each independent variable (the parameter values).
|
|
170
|
+
|
|
171
|
+
Returns
|
|
172
|
+
-------
|
|
173
|
+
value : `numpy.array`
|
|
174
|
+
The value of the spline block at the given parameter values (array of size nDep).
|
|
175
|
+
"""
|
|
176
|
+
return self._block_evaluation(self.nDep, bspy._spline_evaluation.evaluate, (uvw,))
|
|
177
|
+
|
|
178
|
+
def jacobian(self, uvw):
|
|
179
|
+
"""
|
|
180
|
+
Compute the value of the spline block's Jacobian at given parameter values.
|
|
181
|
+
|
|
182
|
+
Parameters
|
|
183
|
+
----------
|
|
184
|
+
uvw : `iterable`
|
|
185
|
+
An iterable of length `nInd` that specifies the values of each independent variable (the parameter values).
|
|
186
|
+
|
|
187
|
+
Returns
|
|
188
|
+
-------
|
|
189
|
+
value : `numpy.array`
|
|
190
|
+
The value of the spline block's Jacobian at the given parameter values. The shape of the return value is (nDep, nInd).
|
|
191
|
+
"""
|
|
192
|
+
jacobian = np.zeros((self.nDep, self.nInd), self.coefsDtype)
|
|
193
|
+
nDep = 0
|
|
194
|
+
for row in self.block:
|
|
195
|
+
nInd = 0
|
|
196
|
+
for spline in row:
|
|
197
|
+
jacobian[nDep:nDep + spline.nDep, nInd:nInd + spline.nInd] += spline.jacobian(uvw[nInd:nInd + spline.nInd])
|
|
198
|
+
nInd += spline.nInd
|
|
199
|
+
nDep += spline.nDep
|
|
200
|
+
return jacobian
|
|
201
|
+
|
|
202
|
+
def normal(self, uvw, normalize=True, indices=None):
|
|
203
|
+
"""
|
|
204
|
+
Compute the normal of the spline block at given parameter values. The number of independent variables must be
|
|
205
|
+
one different than the number of dependent variables.
|
|
206
|
+
|
|
207
|
+
Parameters
|
|
208
|
+
----------
|
|
209
|
+
uvw : `iterable`
|
|
210
|
+
An iterable of length `nInd` that specifies the values of each independent variable (the parameter values).
|
|
211
|
+
|
|
212
|
+
normalize : `boolean`, optional
|
|
213
|
+
If True the returned normal will have unit length (the default). Otherwise, the normal's length will
|
|
214
|
+
be the area of the tangent space (for two independent variables, its the length of the cross product of tangent vectors).
|
|
215
|
+
|
|
216
|
+
indices : `iterable`, optional
|
|
217
|
+
An iterable of normal indices to calculate. For example, `indices=(0, 3)` will return a vector of length 2
|
|
218
|
+
with the first and fourth values of the normal. If `None`, all normal values are returned (the default).
|
|
219
|
+
|
|
220
|
+
Returns
|
|
221
|
+
-------
|
|
222
|
+
normal : `numpy.array`
|
|
223
|
+
The normal vector of the spline block at the given parameter values.
|
|
224
|
+
|
|
225
|
+
See Also
|
|
226
|
+
--------
|
|
227
|
+
`normal_spline` : Compute a spline that evaluates to the normal of the given spline block (not normalized).
|
|
228
|
+
|
|
229
|
+
Notes
|
|
230
|
+
-----
|
|
231
|
+
Attentive readers will notice that the number of independent variables could be one more than the number of
|
|
232
|
+
dependent variables (instead of one less, as is typical). In that case, the normal represents the null space of
|
|
233
|
+
the matrix formed by the tangents of the spline. If the null space is greater than one dimension, the normal will be zero.
|
|
234
|
+
"""
|
|
235
|
+
return bspy._spline_evaluation.normal(self, uvw, normalize, indices)
|
|
236
|
+
|
|
237
|
+
def normal_spline(self, indices=None):
|
|
238
|
+
"""
|
|
239
|
+
Compute a spline that evaluates to the normal of the given spline block. The length of the normal
|
|
240
|
+
is the area of the tangent space (for two independent variables, its the length of the cross product of tangent vectors).
|
|
241
|
+
The number of independent variables must be one different than the number of dependent variables.
|
|
242
|
+
Find all the contour curves of a block of splines whose `nInd` is one larger than its `nDep`.
|
|
243
|
+
|
|
244
|
+
Parameters
|
|
245
|
+
----------
|
|
246
|
+
indices : `iterable`, optional
|
|
247
|
+
An iterable of normal indices to calculate. For example, `indices=(0, 3)` will make the returned spline compute a vector of length 2
|
|
248
|
+
with the first and fourth values of the normal. If `None`, all normal values are returned (the default).
|
|
249
|
+
|
|
250
|
+
Returns
|
|
251
|
+
-------
|
|
252
|
+
spline : `Spline`
|
|
253
|
+
The spline that evaluates to the normal of the given spline block.
|
|
254
|
+
|
|
255
|
+
See Also
|
|
256
|
+
--------
|
|
257
|
+
`normal` : Compute the normal of the spline block at given parameter values.
|
|
258
|
+
|
|
259
|
+
Notes
|
|
260
|
+
-----
|
|
261
|
+
Attentive readers will notice that the number of independent variables could be one more than the number of
|
|
262
|
+
dependent variables (instead of one less, as is typical). In that case, the normal represents the null space of
|
|
263
|
+
the matrix formed by the tangents of the spline block. If the null space is greater than one dimension, the normal will be zero.
|
|
264
|
+
"""
|
|
265
|
+
return bspy._spline_operations.normal_spline(self, indices)
|
|
266
|
+
|
|
267
|
+
def range_bounds(self):
|
|
268
|
+
"""
|
|
269
|
+
Return the range of a spline block as lower and upper bounds on each of the
|
|
270
|
+
dependent variables.
|
|
271
|
+
"""
|
|
272
|
+
return self._block_evaluation((self.nDep, 2), bspy._spline_evaluation.range_bounds, [])
|
|
273
|
+
|
|
274
|
+
def reparametrize(self, newDomain):
|
|
275
|
+
"""
|
|
276
|
+
Reparametrize a spline block to match new domain bounds. The number of knots and coefficients remain unchanged.
|
|
277
|
+
|
|
278
|
+
Parameters
|
|
279
|
+
----------
|
|
280
|
+
newDomain : array-like
|
|
281
|
+
nInd x 2 array of the new lower and upper bounds on each of the independent variables (same form as
|
|
282
|
+
returned from `domain`). If a bound pair is `None` then the original bound (and knots) are left unchanged.
|
|
283
|
+
For example, `[[0.0, 1.0], None]` will reparametrize the first independent variable and leave the second unchanged)
|
|
284
|
+
|
|
285
|
+
Returns
|
|
286
|
+
-------
|
|
287
|
+
block : `SplineBlock`
|
|
288
|
+
Reparametrized spline block.
|
|
289
|
+
|
|
290
|
+
See Also
|
|
291
|
+
--------
|
|
292
|
+
`domain` : Return the domain of a spline block.
|
|
293
|
+
"""
|
|
294
|
+
return self._block_operation(bspy._spline_domain.reparametrize, (newDomain,))
|
|
295
|
+
|
|
296
|
+
def trim(self, newDomain):
|
|
297
|
+
"""
|
|
298
|
+
Trim the domain of a spline block.
|
|
299
|
+
|
|
300
|
+
Parameters
|
|
301
|
+
----------
|
|
302
|
+
newDomain : array-like
|
|
303
|
+
nInd x 2 array of the new lower and upper bounds on each of the independent variables (same form as
|
|
304
|
+
returned from `domain`). If a bound is None or nan then the original bound (and knots) are left unchanged.
|
|
305
|
+
|
|
306
|
+
Returns
|
|
307
|
+
-------
|
|
308
|
+
block : `SplineBlock`
|
|
309
|
+
Trimmed spline block.
|
|
310
|
+
"""
|
|
311
|
+
return self._block_operation(bspy._spline_domain.trim, (newDomain,))
|
|
312
|
+
|
|
313
|
+
def zeros(self, epsilon=None, initialScale=None):
|
|
314
|
+
"""
|
|
315
|
+
Find the roots of a block of splines (nInd must match nDep).
|
|
316
|
+
|
|
317
|
+
Parameters
|
|
318
|
+
----------
|
|
319
|
+
epsilon : `float`, optional
|
|
320
|
+
Tolerance for root precision. The root will be within epsilon of the actual root.
|
|
321
|
+
The default is the machine epsilon.
|
|
322
|
+
|
|
323
|
+
initialScale : array-like, optional
|
|
324
|
+
The initial scale of each dependent variable (as opposed to the current scale of
|
|
325
|
+
the spline block, which may have been normalized). The default is an array of ones (size nDep).
|
|
326
|
+
|
|
327
|
+
Returns
|
|
328
|
+
-------
|
|
329
|
+
roots : `iterable`
|
|
330
|
+
An iterable containing the roots of the block of splines. If the block is
|
|
331
|
+
zero over an interval, that root will appear as a tuple of the interval.
|
|
332
|
+
For curves (nInd == 1), the roots are ordered.
|
|
333
|
+
|
|
334
|
+
See Also
|
|
335
|
+
--------
|
|
336
|
+
`contours` : Find all the contour curves of a spline block whose `nInd` is one larger than its `nDep`.
|
|
337
|
+
|
|
338
|
+
Notes
|
|
339
|
+
-----
|
|
340
|
+
Implements a variation of the projected-polyhedron technique from Sherbrooke, Evan C., and Nicholas M. Patrikalakis.
|
|
341
|
+
"Computation of the solutions of nonlinear polynomial systems." Computer Aided Geometric Design 10, no. 5 (1993): 379-405.
|
|
342
|
+
"""
|
|
343
|
+
return bspy._spline_intersection.zeros_using_projected_polyhedron(self, epsilon, initialScale)
|
bspy/viewer.py
CHANGED
|
@@ -152,12 +152,14 @@ class Viewer(tk.Tk):
|
|
|
152
152
|
if draw:
|
|
153
153
|
self.treeview.selection_add(iid)
|
|
154
154
|
for i, boundary in enumerate(solid.boundaries):
|
|
155
|
-
self.list(boundary, f"
|
|
155
|
+
self.list(boundary, f"Boundary {i}", fillColor, lineColor, options, False, iid)
|
|
156
156
|
elif isinstance(spline, Boundary):
|
|
157
157
|
boundary = spline
|
|
158
158
|
if isinstance(boundary.manifold, Hyperplane):
|
|
159
159
|
uvMin = boundary.domain.bounds[:,0]
|
|
160
160
|
uvMax = boundary.domain.bounds[:,1]
|
|
161
|
+
if (uvMax - uvMin).min() < 1.0e-8:
|
|
162
|
+
return
|
|
161
163
|
xyzMinMin = boundary.manifold.evaluate(uvMin)
|
|
162
164
|
xyzMinMax = boundary.manifold.evaluate((uvMin[0], uvMax[1]))
|
|
163
165
|
xyzMaxMin = boundary.manifold.evaluate((uvMax[0], uvMin[1]))
|
|
@@ -210,7 +212,7 @@ class Viewer(tk.Tk):
|
|
|
210
212
|
if isinstance(spline, Spline):
|
|
211
213
|
self.list(spline)
|
|
212
214
|
else:
|
|
213
|
-
self.
|
|
215
|
+
self.list(spline)
|
|
214
216
|
|
|
215
217
|
def erase_all(self):
|
|
216
218
|
"""Stop drawing all splines. Splines remain in the treeview."""
|
|
@@ -223,8 +225,7 @@ class Viewer(tk.Tk):
|
|
|
223
225
|
"""Remove splines from the treeview."""
|
|
224
226
|
for item in self.treeview.selection():
|
|
225
227
|
spline = self.splineList.pop(item)
|
|
226
|
-
self.
|
|
227
|
-
self.treeview.delete(*self.treeview.selection())
|
|
228
|
+
self.treeview.delete(item)
|
|
228
229
|
self.update()
|
|
229
230
|
|
|
230
231
|
def empty(self):
|
|
@@ -426,7 +427,7 @@ class Viewer(tk.Tk):
|
|
|
426
427
|
fillColor : `numpy.array`
|
|
427
428
|
Array of four floats (r, g, b, a) in the range [0, 1].
|
|
428
429
|
"""
|
|
429
|
-
return spline.metadata["fillColor"]
|
|
430
|
+
return np.array(spline.metadata["fillColor"], np.float32)
|
|
430
431
|
|
|
431
432
|
@staticmethod
|
|
432
433
|
def set_fill_color(spline, r, g=None, b=None, a=None):
|
|
@@ -467,7 +468,7 @@ class Viewer(tk.Tk):
|
|
|
467
468
|
lineColor : `numpy.array`
|
|
468
469
|
Array of four floats (r, g, b, a) in the range [0, 1].
|
|
469
470
|
"""
|
|
470
|
-
return spline.metadata["lineColor"]
|
|
471
|
+
return np.array(spline.metadata["lineColor"], np.float32)
|
|
471
472
|
|
|
472
473
|
@staticmethod
|
|
473
474
|
def set_line_color(spline, r, g=None, b=None, a=None):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: bspy
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.2
|
|
4
4
|
Summary: Library for manipulating and rendering non-uniform B-splines
|
|
5
5
|
Home-page: http://github.com/ericbrec/BSpy
|
|
6
6
|
Author: Eric Brechner
|
|
@@ -34,14 +34,20 @@ Library for manipulating and rendering B-spline curves, surfaces, and multidimen
|
|
|
34
34
|
|
|
35
35
|
The [Manifold](https://ericbrec.github.io/BSpy/bspy/manifold.html) abstract base class for [Hyperplane](https://ericbrec.github.io/BSpy/bspy/hyperplane.html) and [Spline](https://ericbrec.github.io/BSpy/bspy/spline.html).
|
|
36
36
|
|
|
37
|
-
The [Spline](https://ericbrec.github.io/BSpy/bspy/spline.html) class has a method to fit multidimensional data for
|
|
38
|
-
|
|
37
|
+
The [Spline](https://ericbrec.github.io/BSpy/bspy/spline.html) class has a method to fit multidimensional data for scalar and vector functions of single and multiple variables. It also can fit splines to functions, to solutions for ordinary differential equations (ODEs), and to geodesics.
|
|
38
|
+
Spline has methods to create points, lines, circular arcs, spheres, cones, cylinders, tori, ruled surfaces, surfaces of revolution, and four-sided patches.
|
|
39
39
|
Other methods add, subtract, and multiply splines, as well as confine spline curves to a given range.
|
|
40
|
-
There are methods to evaluate spline values, derivatives, integrals,
|
|
40
|
+
There are methods to evaluate spline values, derivatives, normals, integrals, continuity, curvature, and the Jacobian, as well as methods that return spline representations of derivatives, normals, integrals, graphs, and convolutions.
|
|
41
|
+
In addition, there are methods to manipulate the domain of splines, including trim, join, split, reparametrize, transpose, reverse, add and remove knots, elevate and extrapolate, and fold and unfold.
|
|
42
|
+
There are methods to manipulate the range of splines, including dot product, cross product, translate, rotate, scale, and transform.
|
|
43
|
+
Finally, there are methods to compute the zeros and contours of a spline and to intersect two splines.
|
|
44
|
+
Splines can be saved and loaded in json format.
|
|
41
45
|
|
|
42
46
|
The [Hyperplane](https://ericbrec.github.io/BSpy/bspy/hyperplane.html) class has methods to create individual hyperplanes in any dimension, along with axis-aligned hyperplanes and hypercubes.
|
|
43
47
|
|
|
44
|
-
The [Solid](https://ericbrec.github.io/BSpy/bspy/solid.html) class has methods to construct n-dimensional solids from trimmed [Manifold](https://ericbrec.github.io/BSpy/bspy/manifold.html) boundaries. Each solid consists of a list of boundaries and a Boolean value that indicates if the solid contains infinity. Each [Boundary](https://ericbrec.github.io/BSpy/bspy/solid.html) consists of a manifold (currently a [Hyperplane](https://ericbrec.github.io/BSpy/bspy/hyperplane.html) or [Spline](https://ericbrec.github.io/BSpy/bspy/spline.html)) and a domain solid that trims the manifold. Solids have methods to form the intersection, union, difference, and complement of solids. There are methods to compute point containment, winding numbers, surface integrals, and volume integrals. There are also methods to translate, transform, and slice solids.
|
|
48
|
+
The [Solid](https://ericbrec.github.io/BSpy/bspy/solid.html) class has methods to construct n-dimensional solids from trimmed [Manifold](https://ericbrec.github.io/BSpy/bspy/manifold.html) boundaries. Each solid consists of a list of boundaries and a Boolean value that indicates if the solid contains infinity. Each [Boundary](https://ericbrec.github.io/BSpy/bspy/solid.html) consists of a manifold (currently a [Hyperplane](https://ericbrec.github.io/BSpy/bspy/hyperplane.html) or [Spline](https://ericbrec.github.io/BSpy/bspy/spline.html)) and a domain solid that trims the manifold. Solids have methods to form the intersection, union, difference, and complement of solids. There are methods to compute point containment, winding numbers, surface integrals, and volume integrals. There are also methods to translate, transform, and slice solids. Solids can be saved and loaded in json format.
|
|
49
|
+
|
|
50
|
+
The [SplineBlock](https://ericbrec.github.io/BSpy/bspy/spline_block.html) class has methods to represent and process an array-like collection of splines, including ones to compute the contours and zeros of a spline block, as well as a variety of methods to evaluate a spline block and its derivatives. Spline blocks are useful for efficiently manipulating and solving systems of equations with splines.
|
|
45
51
|
|
|
46
52
|
The [SplineOpenGLFrame](https://ericbrec.github.io/BSpy/bspy/splineOpenGLFrame.html) class is an
|
|
47
53
|
[OpenGLFrame](https://pypi.org/project/pyopengltk/) with custom shaders to render spline curves and surfaces. Spline surfaces with more
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
bspy/__init__.py,sha256=ruWkrHgrjGFeB2uATnCNY-J9hpgK5R6vsXrtshBIFDk,1476
|
|
2
|
+
bspy/_spline_domain.py,sha256=xbXOlRxFSwbM55dNiy6RpSOJsgHc1xD3hgACBxYiifk,33647
|
|
3
|
+
bspy/_spline_evaluation.py,sha256=MQmF6hhxHXBEOWCSTGZOTmecP5uOn7VrI9Aj8NUCSb8,9622
|
|
4
|
+
bspy/_spline_fitting.py,sha256=EbM_FI-QW5PjZKbpAF4r4dP8DZOLn8QX3dYvG9zzuFo,50753
|
|
5
|
+
bspy/_spline_intersection.py,sha256=cFciLdc1wTFZuKixfWoOlN8PJhQHWt_nN6N9Wt4EMhw,65438
|
|
6
|
+
bspy/_spline_operations.py,sha256=KNkWSg27jFjoewsaNqMfNLrMAD4MUQJvCkXOfQbEHmI,43088
|
|
7
|
+
bspy/hyperplane.py,sha256=wngJw_9x358gf_S1O3sPqodnUx7HHdJunAp4ceOq7Fw,24605
|
|
8
|
+
bspy/manifold.py,sha256=Ecrm7LjcfttOJ617mKMXdJSWqVxt2eToNvpq5skLliA,14255
|
|
9
|
+
bspy/solid.py,sha256=E8iAcIFV5r_SrzcY_5UB0hKitE-bcrI0-dPzXcvD6iw,36763
|
|
10
|
+
bspy/spline.py,sha256=Bt1WDF69ZYO--rz9Myclb26f0fDnr62q1NWYTxcwFvw,100398
|
|
11
|
+
bspy/splineOpenGLFrame.py,sha256=ezPUyDr9QKF0KU7H6XjHL-HhN23ffC8KbxGhGgGJhQ0,95843
|
|
12
|
+
bspy/spline_block.py,sha256=gfoK_-QVqQCrv9acDCkQf-deHZntjOw1VgyPWAxDWcU,14656
|
|
13
|
+
bspy/viewer.py,sha256=S0yij3LwHIll0ZA-bZevpkNFYSzs41a5xb8EgpHTW_M,33760
|
|
14
|
+
bspy-4.2.dist-info/LICENSE,sha256=nLfJULN68Jw6GfCJp4xeMksGuRdyWNdgEsZGjw2twig,1091
|
|
15
|
+
bspy-4.2.dist-info/METADATA,sha256=a7T__b4_Kyf9wKg7ba8_s_51FdKB-XgaQg0zLfLWGI8,6792
|
|
16
|
+
bspy-4.2.dist-info/WHEEL,sha256=cpQTJ5IWu9CdaPViMhC9YzF8gZuS5-vlfoFihTBC86A,91
|
|
17
|
+
bspy-4.2.dist-info/top_level.txt,sha256=fotZnJn6aCwgUbBEV3hslIko7Nw-eqtHLq2eyJLlFsY,5
|
|
18
|
+
bspy-4.2.dist-info/RECORD,,
|
bspy-4.1.dist-info/RECORD
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
bspy/__init__.py,sha256=q8XOJK3FsbHybfy2CSPufY5Z5SQJNxK_tH-d9zXR5vY,1308
|
|
2
|
-
bspy/_spline_domain.py,sha256=kklvRrSeEEUUQ48yXvCCDzHMRPd4_BHICxAsOhyxhjk,30178
|
|
3
|
-
bspy/_spline_evaluation.py,sha256=3cWD3sL4odnZ4w1DBQFmUnPg2PuPpSfaGfNcBl8ZrW0,7079
|
|
4
|
-
bspy/_spline_fitting.py,sha256=hFhPyL39d87IGZiAs8teFhYZHxPN1EvzQYxHcDTeBLw,45318
|
|
5
|
-
bspy/_spline_intersection.py,sha256=EV19Qt-kccr5K17aB1EETJXENdz-_UJlYTKWjK-ueJU,58324
|
|
6
|
-
bspy/_spline_operations.py,sha256=y98zl-r31xsZzD6X0VYbuEPUabg3UNC_ERCbkXZRZXU,42530
|
|
7
|
-
bspy/hyperplane.py,sha256=gRConjCEdMAjP8UXA7kaYU--NQHr1tYiVHtmZzLNnqY,24639
|
|
8
|
-
bspy/manifold.py,sha256=29KkZXvv759-aywGd7Ek4Egm-DCBNDTEfusW_Az1kC4,14244
|
|
9
|
-
bspy/solid.py,sha256=qbHofcdNbMTaoCCfKfxloYiEqZDsxfOIJD3MwZguEJ8,36444
|
|
10
|
-
bspy/spline.py,sha256=747e_kChnGnN2Y93EcP9XymDrf2T4NFFweFB_YghEvw,94776
|
|
11
|
-
bspy/splineOpenGLFrame.py,sha256=ezPUyDr9QKF0KU7H6XjHL-HhN23ffC8KbxGhGgGJhQ0,95843
|
|
12
|
-
bspy/viewer.py,sha256=HdtjAj5CZnv4VKcfS8MhT-ciPEPRVNUTp-02TW1NQSU,33717
|
|
13
|
-
bspy-4.1.dist-info/LICENSE,sha256=nLfJULN68Jw6GfCJp4xeMksGuRdyWNdgEsZGjw2twig,1091
|
|
14
|
-
bspy-4.1.dist-info/METADATA,sha256=Fe5wy39gSJOVk7Z3Ruz1Utm3oYZQlPyyJJMYGu6YvP4,6152
|
|
15
|
-
bspy-4.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
16
|
-
bspy-4.1.dist-info/top_level.txt,sha256=fotZnJn6aCwgUbBEV3hslIko7Nw-eqtHLq2eyJLlFsY,5
|
|
17
|
-
bspy-4.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|