bspy 4.2__py3-none-any.whl → 4.3__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 +1 -1
- bspy/_spline_domain.py +72 -91
- bspy/_spline_evaluation.py +2 -2
- bspy/_spline_fitting.py +4 -4
- bspy/_spline_intersection.py +285 -273
- bspy/_spline_operations.py +45 -41
- bspy/hyperplane.py +7 -3
- bspy/manifold.py +8 -3
- bspy/solid.py +7 -3
- bspy/spline.py +17 -5
- bspy/splineOpenGLFrame.py +346 -303
- bspy/spline_block.py +155 -38
- bspy/viewer.py +20 -11
- {bspy-4.2.dist-info → bspy-4.3.dist-info}/METADATA +5 -3
- bspy-4.3.dist-info/RECORD +18 -0
- {bspy-4.2.dist-info → bspy-4.3.dist-info}/WHEEL +1 -1
- bspy-4.2.dist-info/RECORD +0 -18
- {bspy-4.2.dist-info → bspy-4.3.dist-info}/LICENSE +0 -0
- {bspy-4.2.dist-info → bspy-4.3.dist-info}/top_level.txt +0 -0
bspy/spline_block.py
CHANGED
|
@@ -8,29 +8,38 @@ import bspy._spline_operations
|
|
|
8
8
|
|
|
9
9
|
class SplineBlock:
|
|
10
10
|
"""
|
|
11
|
-
A class to
|
|
12
|
-
Spline blocks are useful for efficiently manipulating and solving systems of equations with splines.
|
|
11
|
+
A class to process an array-like collection of splines that represent a system of equations.
|
|
13
12
|
|
|
14
13
|
Parameters
|
|
15
14
|
----------
|
|
16
|
-
block : an array-like collection of splines (
|
|
17
|
-
Splines in the same row are treated as if they are added together.
|
|
15
|
+
block : an array-like collection of rows of splines (a list of lists)
|
|
16
|
+
The block of splines represents a system of equations. Splines in the same row are treated as if they are added together.
|
|
18
17
|
Each row need not have the same number of splines, but all splines in a row must have the same
|
|
19
18
|
number of dependent variables (same nDep). Corresponding independent variables must have the same domain.
|
|
20
19
|
|
|
21
|
-
For example,
|
|
22
|
-
|
|
23
|
-
and
|
|
20
|
+
For example, say you wanted to represent the system:
|
|
21
|
+
F(u, v, w) + G(u) = 0, h(u, v) = 0, where F and G are 2D vector functions and h is a scalar function.
|
|
22
|
+
After fitting F, G, and h with splines, you'd form the following spline block: [[F, G], [h]].
|
|
23
|
+
|
|
24
|
+
You may optionally supply maps for independent variables to represent complex systems of equations. For example,
|
|
25
|
+
say you wanted to represent a similar systems as before, but with a more complicated relationship between the
|
|
26
|
+
independent variables: F(u, v, w) + G(v, s) = 0, h(u, t, w, s) = 0.
|
|
27
|
+
First, you'd assign consecutive indices for each variable starting at zero. For example, (s, t, u, v, w) could be indexed as (0, 1, 2, 3, 4, 5).
|
|
28
|
+
Then, you'd provide maps for each spline's independent variables to form the following spline block:
|
|
29
|
+
[[([3, 4, 5], F), ([4, 0], G)], [([3, 1, 5, 0], h)]].
|
|
30
|
+
Notice how each spline from the first example is replaced by a (map, spline) tuple in the complex second example.
|
|
24
31
|
"""
|
|
25
32
|
|
|
33
|
+
@staticmethod
|
|
34
|
+
def _map_args(map, args):
|
|
35
|
+
return [arg[map] if isinstance(arg, np.ndarray) else [arg[index] for index in map] for arg in args]
|
|
36
|
+
|
|
26
37
|
def _block_evaluation(self, returnShape, splineFunction, args):
|
|
27
38
|
value = np.zeros(returnShape, self.coefsDtype)
|
|
28
39
|
nDep = 0
|
|
29
40
|
for row in self.block:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
value[nDep:nDep + spline.nDep] += splineFunction(spline, *[arg[nInd:nInd + spline.nInd] for arg in args])
|
|
33
|
-
nInd += spline.nInd
|
|
41
|
+
for map, spline in row:
|
|
42
|
+
value[nDep:nDep + spline.nDep] += splineFunction(spline, *SplineBlock._map_args(map, args))
|
|
34
43
|
nDep += spline.nDep
|
|
35
44
|
return value
|
|
36
45
|
|
|
@@ -38,49 +47,69 @@ class SplineBlock:
|
|
|
38
47
|
newBlock = []
|
|
39
48
|
for row in self.block:
|
|
40
49
|
newRow = []
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
newRow.append(splineFunction(spline, *[arg[nInd:nInd + spline.nInd] for arg in args]))
|
|
44
|
-
nInd += spline.nInd
|
|
50
|
+
for map, spline in row:
|
|
51
|
+
newRow.append((map, splineFunction(spline, *SplineBlock._map_args(map, args))))
|
|
45
52
|
newBlock.append(newRow)
|
|
46
53
|
return SplineBlock(newBlock)
|
|
47
54
|
|
|
48
55
|
def __init__(self, block):
|
|
49
56
|
if isinstance(block, bspy.spline.Spline):
|
|
50
|
-
|
|
51
|
-
elif isinstance(block[0], bspy.spline.Spline):
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
57
|
+
block = [[block]]
|
|
58
|
+
elif isinstance(block[0], bspy.spline.Spline) or (len(block) > 1 and isinstance(block[1], bspy.spline.Spline)):
|
|
59
|
+
block = [block]
|
|
60
|
+
|
|
61
|
+
self.block = []
|
|
55
62
|
self.nInd = 0
|
|
56
63
|
self.nDep = 0
|
|
57
64
|
self.knotsDtype = None
|
|
58
65
|
self.coefsDtype = None
|
|
59
66
|
self.size = 0
|
|
60
|
-
|
|
61
|
-
for row in
|
|
67
|
+
domain = {}
|
|
68
|
+
for row in block:
|
|
62
69
|
rowInd = 0
|
|
63
70
|
rowDep = 0
|
|
64
|
-
|
|
71
|
+
indSet = set()
|
|
72
|
+
newRow = []
|
|
73
|
+
for entry in row:
|
|
74
|
+
if isinstance(entry, bspy.spline.Spline):
|
|
75
|
+
spline = entry
|
|
76
|
+
map = list(range(rowInd, rowInd + spline.nInd))
|
|
77
|
+
else:
|
|
78
|
+
(map, spline) = entry
|
|
79
|
+
map = list(map) # Convert to list and make a copy
|
|
80
|
+
rowInd += spline.nInd
|
|
65
81
|
if rowDep == 0:
|
|
66
82
|
rowDep = spline.nDep
|
|
67
|
-
if self.
|
|
83
|
+
if self.nDep == 0:
|
|
68
84
|
self.knotsDtype = spline.knots[0].dtype
|
|
69
85
|
self.coefsDtype = spline.coefs.dtype
|
|
70
86
|
elif rowDep != spline.nDep:
|
|
71
87
|
raise ValueError("All splines in the same row must have the same nDep")
|
|
72
88
|
d = spline.domain()
|
|
73
|
-
for i in
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
89
|
+
for ind, i in enumerate(map):
|
|
90
|
+
if i in indSet:
|
|
91
|
+
raise ValueError(f"Multiple splines in the same row map to independent variable {i}")
|
|
92
|
+
else:
|
|
93
|
+
indSet.add(i)
|
|
94
|
+
if i in domain:
|
|
95
|
+
if domain[i][0] != d[ind, 0] or domain[i][1] != d[ind, 1]:
|
|
77
96
|
raise ValueError("Domains of independent variables must match")
|
|
78
97
|
else:
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
98
|
+
domain[i] = d[ind]
|
|
99
|
+
newRow.append((map, spline))
|
|
100
|
+
|
|
101
|
+
if rowDep > 0:
|
|
102
|
+
self.nDep += rowDep
|
|
103
|
+
self.size += len(row)
|
|
104
|
+
self.block.append(newRow)
|
|
105
|
+
|
|
106
|
+
self.nInd = len(domain)
|
|
107
|
+
self._domain = []
|
|
108
|
+
for i in range(self.nInd):
|
|
109
|
+
if i in domain:
|
|
110
|
+
self._domain.append(domain[i])
|
|
111
|
+
else:
|
|
112
|
+
raise ValueError(f"Block is missing independent variable {i}")
|
|
84
113
|
self._domain = np.array(self._domain, self.knotsDtype)
|
|
85
114
|
|
|
86
115
|
def __call__(self, uvw):
|
|
@@ -126,7 +155,26 @@ class SplineBlock:
|
|
|
126
155
|
block : `SplineBlock`
|
|
127
156
|
The contracted spline block.
|
|
128
157
|
"""
|
|
129
|
-
|
|
158
|
+
# First, remap the remaining independent variables (the ones not fixed by uvw).
|
|
159
|
+
remap = []
|
|
160
|
+
newIndex = 0
|
|
161
|
+
for value in uvw:
|
|
162
|
+
if value is None:
|
|
163
|
+
remap.append(newIndex)
|
|
164
|
+
newIndex += 1
|
|
165
|
+
else:
|
|
166
|
+
remap.append(None)
|
|
167
|
+
|
|
168
|
+
# Next, rebuild the block with contracted splines.
|
|
169
|
+
newBlock = []
|
|
170
|
+
for row in self.block:
|
|
171
|
+
newRow = []
|
|
172
|
+
for map, spline in row:
|
|
173
|
+
spline = spline.contract([uvw[index] for index in map])
|
|
174
|
+
map = [remap[ind] for ind in map if uvw[ind] is None]
|
|
175
|
+
newRow.append((map, spline))
|
|
176
|
+
newBlock.append(newRow)
|
|
177
|
+
return SplineBlock(newBlock)
|
|
130
178
|
|
|
131
179
|
def derivative(self, with_respect_to, uvw):
|
|
132
180
|
"""
|
|
@@ -190,12 +238,11 @@ class SplineBlock:
|
|
|
190
238
|
The value of the spline block's Jacobian at the given parameter values. The shape of the return value is (nDep, nInd).
|
|
191
239
|
"""
|
|
192
240
|
jacobian = np.zeros((self.nDep, self.nInd), self.coefsDtype)
|
|
241
|
+
uvw = np.atleast_1d(uvw)
|
|
193
242
|
nDep = 0
|
|
194
243
|
for row in self.block:
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
jacobian[nDep:nDep + spline.nDep, nInd:nInd + spline.nInd] += spline.jacobian(uvw[nInd:nInd + spline.nInd])
|
|
198
|
-
nInd += spline.nInd
|
|
244
|
+
for map, spline in row:
|
|
245
|
+
jacobian[nDep:nDep + spline.nDep, map] += spline.jacobian(uvw[map])
|
|
199
246
|
nDep += spline.nDep
|
|
200
247
|
return jacobian
|
|
201
248
|
|
|
@@ -293,6 +340,76 @@ class SplineBlock:
|
|
|
293
340
|
"""
|
|
294
341
|
return self._block_operation(bspy._spline_domain.reparametrize, (newDomain,))
|
|
295
342
|
|
|
343
|
+
def split(self, minContinuity = 0, breaks = None):
|
|
344
|
+
"""
|
|
345
|
+
Split a spline block into separate pieces.
|
|
346
|
+
|
|
347
|
+
Parameters
|
|
348
|
+
----------
|
|
349
|
+
minContinuity : `int`, optional
|
|
350
|
+
The minimum expected continuity of each spline block piece. The default is zero, for C0 continuity.
|
|
351
|
+
|
|
352
|
+
breaks : `iterable` of length `nInd` or `None`, optional
|
|
353
|
+
An iterable that specifies the breaks at which to separate the spline block.
|
|
354
|
+
len(breaks[ind]) == 0 if there the spline block isn't separated for the `ind` independent variable.
|
|
355
|
+
If breaks is `None` (the default), the spline block will only be separated at discontinuities.
|
|
356
|
+
|
|
357
|
+
Returns
|
|
358
|
+
-------
|
|
359
|
+
splineBlockArray : array of `SplineBlock`
|
|
360
|
+
A array of spline blocks with nInd dimensions containing the spline block pieces.
|
|
361
|
+
"""
|
|
362
|
+
if minContinuity < 0: raise ValueError("minContinuity must be >= 0")
|
|
363
|
+
if self.nInd < 1: return self
|
|
364
|
+
|
|
365
|
+
# Step 1: Determine all the breaks.
|
|
366
|
+
breakList = [set() for i in range(self.nInd)]
|
|
367
|
+
if breaks is not None:
|
|
368
|
+
if len(breaks) != self.nInd: raise ValueError("Invalid breaks")
|
|
369
|
+
for breakSet, knots, domain in zip(breakList, breaks, self.domain()):
|
|
370
|
+
for knot in knots:
|
|
371
|
+
if knot < domain[0] or knot > domain[1]: raise ValueError("Break outside of domain")
|
|
372
|
+
if domain[0] < knot < domain[1]:
|
|
373
|
+
breakSet.add(knot)
|
|
374
|
+
|
|
375
|
+
for row in self.block:
|
|
376
|
+
for map, spline in row:
|
|
377
|
+
for i, order, knots in zip(range(spline.nInd), spline.order, spline.knots):
|
|
378
|
+
unique, counts = np.unique(knots[order:], return_counts=True) # Skip left end
|
|
379
|
+
for knot, count in zip(unique, counts):
|
|
380
|
+
if count > order - 1 - minContinuity:
|
|
381
|
+
breakList[map[i]].add(knot)
|
|
382
|
+
|
|
383
|
+
# Step 2: Determine the size and shape of the splineBlockArray and allocate it.
|
|
384
|
+
size = 1
|
|
385
|
+
shape = []
|
|
386
|
+
for i, breakSet in enumerate(breakList):
|
|
387
|
+
count = len(breakSet)
|
|
388
|
+
shape.insert(0, count) # We build the transpose due to indexing arithmetic
|
|
389
|
+
size *= count
|
|
390
|
+
breakList[i] = sorted(breakSet)
|
|
391
|
+
splineBlockArray = np.empty(size, object)
|
|
392
|
+
|
|
393
|
+
# Step 3: Split up the spline block.
|
|
394
|
+
domain = self.domain().copy()
|
|
395
|
+
for i in range(size):
|
|
396
|
+
index = i
|
|
397
|
+
for j, knots in enumerate(breakList):
|
|
398
|
+
count = len(knots)
|
|
399
|
+
ix = index % count
|
|
400
|
+
index = index // count
|
|
401
|
+
if domain[j, 1] != knots[ix]:
|
|
402
|
+
if ix == 0:
|
|
403
|
+
domain[j, 0] = self._domain[j, 0]
|
|
404
|
+
else:
|
|
405
|
+
domain[j, 0] = domain[j, 1]
|
|
406
|
+
domain[j, 1] = knots[ix]
|
|
407
|
+
|
|
408
|
+
splineBlockArray[i] = self.trim(domain)
|
|
409
|
+
|
|
410
|
+
# Step 4: Reshape and transpose splineBlockArray
|
|
411
|
+
return splineBlockArray.reshape(shape).T
|
|
412
|
+
|
|
296
413
|
def trim(self, newDomain):
|
|
297
414
|
"""
|
|
298
415
|
Trim the domain of a spline block.
|
bspy/viewer.py
CHANGED
|
@@ -144,15 +144,19 @@ class Viewer(tk.Tk):
|
|
|
144
144
|
solid = spline
|
|
145
145
|
if solid.dimension != 3:
|
|
146
146
|
return
|
|
147
|
-
if name is None:
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
if name is not None:
|
|
148
|
+
solid.metadata["Name"] = name
|
|
149
|
+
elif "Name" not in solid.metadata:
|
|
150
|
+
solid.metadata["Name"] = f"Solid({solid.dimension}, {solid.containsInfinity})"
|
|
151
|
+
iid = self.treeview.insert('', 'end', text=solid.metadata["Name"], open=False)
|
|
150
152
|
self.splineList[iid] = solid
|
|
151
153
|
self.solidList.append(solid)
|
|
152
154
|
if draw:
|
|
153
155
|
self.treeview.selection_add(iid)
|
|
154
156
|
for i, boundary in enumerate(solid.boundaries):
|
|
155
|
-
|
|
157
|
+
if "Name" not in boundary.manifold.metadata:
|
|
158
|
+
boundary.manifold.metadata["Name"] = f"Boundary {i}"
|
|
159
|
+
self.list(boundary, None, fillColor, lineColor, options, False, iid)
|
|
156
160
|
elif isinstance(spline, Boundary):
|
|
157
161
|
boundary = spline
|
|
158
162
|
if isinstance(boundary.manifold, Hyperplane):
|
|
@@ -167,15 +171,20 @@ class Viewer(tk.Tk):
|
|
|
167
171
|
spline = Spline(2, 3, (2, 2), (2, 2),
|
|
168
172
|
np.array((uvMin, uvMin, uvMax, uvMax), np.float32).T,
|
|
169
173
|
np.array(((xyzMinMin, xyzMaxMin), (xyzMinMax, xyzMaxMax)), np.float32).T)
|
|
174
|
+
spline.metadata = boundary.manifold.metadata # Ensure the spline representing the hyperplane shares the same metadata
|
|
170
175
|
elif isinstance(boundary.manifold, Spline):
|
|
171
176
|
spline = boundary.manifold
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
177
|
+
tesselation = self.frame.tessellate2DSolid(boundary.domain)
|
|
178
|
+
if tesselation is not None:
|
|
179
|
+
if not hasattr(spline, "cache"):
|
|
180
|
+
spline.cache = {}
|
|
181
|
+
spline.cache["trim"] = tesselation
|
|
175
182
|
self.list(spline, name, fillColor, lineColor, options, draw, parentIID)
|
|
176
183
|
else:
|
|
177
|
-
if
|
|
178
|
-
spline.metadata["Name"] =
|
|
184
|
+
if name is not None:
|
|
185
|
+
spline.metadata["Name"] = name
|
|
186
|
+
elif "Name" not in spline.metadata:
|
|
187
|
+
spline.metadata["Name"] = f"Spline({spline.nInd}, {spline.nDep})"
|
|
179
188
|
if fillColor is not None:
|
|
180
189
|
spline.metadata["fillColor"] = fillColor
|
|
181
190
|
if lineColor is not None:
|
|
@@ -264,7 +273,7 @@ class Viewer(tk.Tk):
|
|
|
264
273
|
for item in self.treeview.selection():
|
|
265
274
|
spline = self.splineList[item]
|
|
266
275
|
if isinstance(spline, Spline):
|
|
267
|
-
coefs = spline.cache["
|
|
276
|
+
coefs = spline.cache["xyzCoefs32"].T
|
|
268
277
|
coefsAxis = tuple(range(1, spline.nInd + 1))
|
|
269
278
|
if gotOne:
|
|
270
279
|
splineMin = np.minimum(splineMin, coefs.min(axis=coefsAxis))
|
|
@@ -277,7 +286,7 @@ class Viewer(tk.Tk):
|
|
|
277
286
|
elif isinstance(spline, Solid):
|
|
278
287
|
for subitem in self.treeview.get_children(item):
|
|
279
288
|
spline = self.splineList[subitem]
|
|
280
|
-
coefs = spline.cache["
|
|
289
|
+
coefs = spline.cache["xyzCoefs32"].T
|
|
281
290
|
coefsAxis = tuple(range(1, spline.nInd + 1))
|
|
282
291
|
if gotOne:
|
|
283
292
|
splineMin = np.minimum(splineMin, coefs.min(axis=coefsAxis))
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: bspy
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.3
|
|
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
|
|
7
7
|
Author-email: ericbrec@msn.com
|
|
8
8
|
License: MIT
|
|
9
9
|
Project-URL: Bug Tracker, http://github.com/ericbrec/BSpy/issues
|
|
10
|
-
Keywords:
|
|
10
|
+
Keywords: bspline,B-spline,nub,solid,solid modeling,geometry,csg,opengl,tkinter
|
|
11
11
|
Classifier: License :: OSI Approved :: MIT License
|
|
12
12
|
Classifier: Environment :: Win32 (MS Windows)
|
|
13
13
|
Classifier: Environment :: Console
|
|
@@ -47,7 +47,9 @@ The [Hyperplane](https://ericbrec.github.io/BSpy/bspy/hyperplane.html) class has
|
|
|
47
47
|
|
|
48
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
49
|
|
|
50
|
-
The [SplineBlock](https://ericbrec.github.io/BSpy/bspy/spline_block.html) class has methods to
|
|
50
|
+
The [SplineBlock](https://ericbrec.github.io/BSpy/bspy/spline_block.html) class has methods to process an array-like collection of splines that represent a system of equations. There are highly-optimized methods to compute the contours and zeros of a spline block, as well as a variety of methods to manipulate and evaluate a spline block and its derivatives.
|
|
51
|
+
|
|
52
|
+
The [BSpyConvert](https://pypi.org/project/BSpyConvert/) package converts BSpy splines and solid models to and from [OpenCascade (OCCT)](https://dev.opencascade.org/) equivalents and a variety of geometry and CAD file formats, including STEP, IGES, and STL.
|
|
51
53
|
|
|
52
54
|
The [SplineOpenGLFrame](https://ericbrec.github.io/BSpy/bspy/splineOpenGLFrame.html) class is an
|
|
53
55
|
[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=LnJx7iHah7A4vud9y64LR61rBtYnuhV4Wno9O2IEK1I,1499
|
|
2
|
+
bspy/_spline_domain.py,sha256=bQQsJlKstIYdbEKIW7vr-7nTKat8y9thYc7jxzZHNFQ,33238
|
|
3
|
+
bspy/_spline_evaluation.py,sha256=WIv0tLZNLy0uHNj9YwR7vbputgT2Mn5QDXZzlD6ousk,9638
|
|
4
|
+
bspy/_spline_fitting.py,sha256=CEkmUQalXTT5N5ZOJpFF4Y2DI-ARlZap9IaCJ_Zg2Ws,50762
|
|
5
|
+
bspy/_spline_intersection.py,sha256=8FPTh4IDtzkRpieNtlnw8VhLabPzY4E_LWDaGxHIMTM,66973
|
|
6
|
+
bspy/_spline_operations.py,sha256=8yJGp4iVVvQ1zcUHAKgNq2TMIjDUhacf5XSoHp2jmVo,42799
|
|
7
|
+
bspy/hyperplane.py,sha256=gnVZ7rjisGpzHfm1moItyzq8mO7HguzzpY4dpFwyDiw,24840
|
|
8
|
+
bspy/manifold.py,sha256=vjgyz0M1mkgenUnTIbX7NFg1fUCgXtStr6ofF4oSLgg,14470
|
|
9
|
+
bspy/solid.py,sha256=ufNs5JV0jQ1A13pUY61N0pcW6Ep-DZmXUau7GHHcKk4,36992
|
|
10
|
+
bspy/spline.py,sha256=1USitAm1FIQg5JuWa1xLrVQQ2cWRGfP4VhQnS8XOKc8,101377
|
|
11
|
+
bspy/splineOpenGLFrame.py,sha256=N8elVJrt24_utOSoTaM5Ue5De2M4DxrquyB7o2lLLD4,96256
|
|
12
|
+
bspy/spline_block.py,sha256=O8MzfBEygVdAx57DoJMwzjkw349BQqht7_RVu8MO0Fg,20127
|
|
13
|
+
bspy/viewer.py,sha256=_iQCyEpsBFPBLLuHq7tc43IPVvlcqxdp0Hig0uvpQns,34349
|
|
14
|
+
bspy-4.3.dist-info/LICENSE,sha256=nLfJULN68Jw6GfCJp4xeMksGuRdyWNdgEsZGjw2twig,1091
|
|
15
|
+
bspy-4.3.dist-info/METADATA,sha256=lV6eciVqRf3FqWslbTD5OWb3gMD6-gv6WB-hkSRadPM,7044
|
|
16
|
+
bspy-4.3.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
|
|
17
|
+
bspy-4.3.dist-info/top_level.txt,sha256=fotZnJn6aCwgUbBEV3hslIko7Nw-eqtHLq2eyJLlFsY,5
|
|
18
|
+
bspy-4.3.dist-info/RECORD,,
|
bspy-4.2.dist-info/RECORD
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
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,,
|
|
File without changes
|
|
File without changes
|