bspy 4.0__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 +16 -3
- bspy/_spline_domain.py +101 -9
- bspy/_spline_evaluation.py +82 -17
- bspy/_spline_fitting.py +244 -114
- bspy/_spline_intersection.py +467 -156
- bspy/_spline_operations.py +70 -49
- bspy/hyperplane.py +540 -0
- bspy/manifold.py +334 -31
- bspy/solid.py +842 -0
- bspy/spline.py +350 -71
- bspy/splineOpenGLFrame.py +262 -14
- bspy/spline_block.py +343 -0
- bspy/viewer.py +134 -90
- {bspy-4.0.dist-info → bspy-4.2.dist-info}/METADATA +17 -6
- bspy-4.2.dist-info/RECORD +18 -0
- {bspy-4.0.dist-info → bspy-4.2.dist-info}/WHEEL +1 -1
- bspy-4.0.dist-info/RECORD +0 -15
- {bspy-4.0.dist-info → bspy-4.2.dist-info}/LICENSE +0 -0
- {bspy-4.0.dist-info → bspy-4.2.dist-info}/top_level.txt +0 -0
bspy/viewer.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
import tkinter as tk
|
|
3
|
+
from tkinter.ttk import Treeview
|
|
3
4
|
from tkinter.colorchooser import askcolor
|
|
4
5
|
from tkinter import filedialog
|
|
5
6
|
import queue, threading
|
|
6
|
-
from bspy import SplineOpenGLFrame
|
|
7
|
-
from bspy import Spline
|
|
7
|
+
from bspy import SplineOpenGLFrame, Solid, Boundary, Hyperplane, Spline
|
|
8
8
|
|
|
9
9
|
class _BitCheckbutton(tk.Checkbutton):
|
|
10
10
|
"""A tkinter `CheckButton` that gets/sets its variable based on a given `bitmask`."""
|
|
@@ -37,7 +37,7 @@ class _BitCheckbutton(tk.Checkbutton):
|
|
|
37
37
|
|
|
38
38
|
class Viewer(tk.Tk):
|
|
39
39
|
"""
|
|
40
|
-
A tkinter viewer (`tkinter.Tk`) that hosts a `SplineOpenGLFrame`, a
|
|
40
|
+
A tkinter viewer (`tkinter.Tk`) that hosts a `SplineOpenGLFrame`, a treeview full of
|
|
41
41
|
splines, and a set of controls to adjust and view the selected splines.
|
|
42
42
|
|
|
43
43
|
See Also
|
|
@@ -46,11 +46,11 @@ class Viewer(tk.Tk):
|
|
|
46
46
|
|
|
47
47
|
Examples
|
|
48
48
|
--------
|
|
49
|
-
Creates a Viewer,
|
|
49
|
+
Creates a Viewer, lists three splines, drawing (selecting) the third, and launches the viewer (blocks on the main loop).
|
|
50
50
|
>>> viewer = Viewer()
|
|
51
|
-
>>> viewer.
|
|
52
|
-
>>> viewer.
|
|
53
|
-
>>> viewer.
|
|
51
|
+
>>> viewer.list(spline1)
|
|
52
|
+
>>> viewer.list(spline2)
|
|
53
|
+
>>> viewer.draw(spline3)
|
|
54
54
|
>>> viewer.mainloop()
|
|
55
55
|
"""
|
|
56
56
|
|
|
@@ -76,17 +76,20 @@ class Viewer(tk.Tk):
|
|
|
76
76
|
horizontalScroll = tk.Scrollbar(controls, orient=tk.HORIZONTAL)
|
|
77
77
|
horizontalScroll.pack(side=tk.BOTTOM, fill=tk.X)
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
treeFrame = tk.Frame(controls, width=120)
|
|
80
|
+
treeFrame.pack(side=tk.LEFT, fill=tk.Y)
|
|
81
|
+
treeFrame.pack_propagate(0)
|
|
82
|
+
self.treeview = Treeview(treeFrame, show='tree')
|
|
83
|
+
self.treeview.pack(side=tk.LEFT, fill=tk.Y)
|
|
84
|
+
self.treeview.bind('<<TreeviewSelect>>', self._ListSelectionChanged)
|
|
85
|
+
self.bind('<Control-a>', lambda *args: self.treeview.selection_add(self.treeview.get_children()))
|
|
83
86
|
verticalScroll = tk.Scrollbar(controls, orient=tk.VERTICAL)
|
|
84
87
|
verticalScroll.pack(side=tk.LEFT, fill=tk.Y)
|
|
85
88
|
|
|
86
|
-
horizontalScroll.config(command=self.
|
|
87
|
-
self.
|
|
88
|
-
verticalScroll.config(command=self.
|
|
89
|
-
self.
|
|
89
|
+
horizontalScroll.config(command=self.treeview.xview)
|
|
90
|
+
self.treeview.configure(xscrollcommand=horizontalScroll.set)
|
|
91
|
+
verticalScroll.config(command=self.treeview.yview)
|
|
92
|
+
self.treeview.configure(yscrollcommand=verticalScroll.set)
|
|
90
93
|
|
|
91
94
|
# Controls on the right
|
|
92
95
|
controls = tk.Frame(self)
|
|
@@ -107,15 +110,15 @@ class Viewer(tk.Tk):
|
|
|
107
110
|
self.scale.pack(side=tk.LEFT)
|
|
108
111
|
self.scale.set(0.5)
|
|
109
112
|
|
|
110
|
-
self.splineList =
|
|
113
|
+
self.splineList = {}
|
|
114
|
+
self.solidList = []
|
|
111
115
|
self.splineDrawList = []
|
|
112
116
|
self.splineRadius = 0.0
|
|
113
117
|
self.adjust = None
|
|
114
118
|
self.workQueue = workQueue
|
|
115
119
|
if self.workQueue is not None:
|
|
116
120
|
self.work = {
|
|
117
|
-
"
|
|
118
|
-
"draw" : self.draw,
|
|
121
|
+
"list" : self.list,
|
|
119
122
|
"erase_all" : self.erase_all,
|
|
120
123
|
"empty" : self.empty,
|
|
121
124
|
"set_background_color" : self.set_background_color,
|
|
@@ -135,61 +138,100 @@ class Viewer(tk.Tk):
|
|
|
135
138
|
self.work[work[0]](*work[1])
|
|
136
139
|
self.after(200, self._check_for_work)
|
|
137
140
|
|
|
138
|
-
def list(self, spline, name = None):
|
|
139
|
-
"""List a `Spline` in the
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
141
|
+
def list(self, spline, name = None, fillColor=None, lineColor=None, options=None, draw=False, parentIID = ''):
|
|
142
|
+
"""List a `Spline`, `Boundary`, or `Solid` in the treeview. Can be called before viewer is running."""
|
|
143
|
+
if isinstance(spline, Solid):
|
|
144
|
+
solid = spline
|
|
145
|
+
if solid.dimension != 3:
|
|
146
|
+
return
|
|
147
|
+
if name is None:
|
|
148
|
+
name = "Solid"
|
|
149
|
+
iid = self.treeview.insert('', 'end', text=name, open=False)
|
|
150
|
+
self.splineList[iid] = solid
|
|
151
|
+
self.solidList.append(solid)
|
|
152
|
+
if draw:
|
|
153
|
+
self.treeview.selection_add(iid)
|
|
154
|
+
for i, boundary in enumerate(solid.boundaries):
|
|
155
|
+
self.list(boundary, f"Boundary {i}", fillColor, lineColor, options, False, iid)
|
|
156
|
+
elif isinstance(spline, Boundary):
|
|
157
|
+
boundary = spline
|
|
158
|
+
if isinstance(boundary.manifold, Hyperplane):
|
|
159
|
+
uvMin = boundary.domain.bounds[:,0]
|
|
160
|
+
uvMax = boundary.domain.bounds[:,1]
|
|
161
|
+
if (uvMax - uvMin).min() < 1.0e-8:
|
|
162
|
+
return
|
|
163
|
+
xyzMinMin = boundary.manifold.evaluate(uvMin)
|
|
164
|
+
xyzMinMax = boundary.manifold.evaluate((uvMin[0], uvMax[1]))
|
|
165
|
+
xyzMaxMin = boundary.manifold.evaluate((uvMax[0], uvMin[1]))
|
|
166
|
+
xyzMaxMax = boundary.manifold.evaluate(uvMax)
|
|
167
|
+
spline = Spline(2, 3, (2, 2), (2, 2),
|
|
168
|
+
np.array((uvMin, uvMin, uvMax, uvMax), np.float32).T,
|
|
169
|
+
np.array(((xyzMinMin, xyzMaxMin), (xyzMinMax, xyzMaxMax)), np.float32).T)
|
|
170
|
+
elif isinstance(boundary.manifold, Spline):
|
|
171
|
+
spline = boundary.manifold
|
|
172
|
+
if not hasattr(spline, "cache"):
|
|
173
|
+
spline.cache = {}
|
|
174
|
+
spline.cache["trim"] = self.frame.tessellate2DSolid(boundary.domain)
|
|
175
|
+
self.list(spline, name, fillColor, lineColor, options, draw, parentIID)
|
|
176
|
+
else:
|
|
177
|
+
if "Name" not in spline.metadata:
|
|
178
|
+
spline.metadata["Name"] = f"Spline({spline.nInd}, {spline.nDep})" if name is None else name
|
|
179
|
+
if fillColor is not None:
|
|
180
|
+
spline.metadata["fillColor"] = fillColor
|
|
181
|
+
if lineColor is not None:
|
|
182
|
+
spline.metadata["lineColor"] = lineColor
|
|
183
|
+
if options is not None:
|
|
184
|
+
spline.metadata["options"] = options
|
|
185
|
+
self.frame.make_drawable(spline)
|
|
186
|
+
iid = self.treeview.insert(parentIID, 'end', text=spline.metadata["Name"])
|
|
187
|
+
self.splineList[iid] = spline
|
|
188
|
+
if draw:
|
|
189
|
+
self.treeview.selection_add(iid)
|
|
190
|
+
|
|
191
|
+
show = list
|
|
192
|
+
|
|
193
|
+
def draw(self, spline, name = None, fillColor=None, lineColor=None, options=None):
|
|
194
|
+
"""List a `Spline`, `Boundary`, or `Solid` in the treeview and draw it in the viewer. Can be called before viewer is running."""
|
|
195
|
+
self.list(spline, name, fillColor, lineColor, options, True)
|
|
155
196
|
|
|
156
197
|
def save_splines(self):
|
|
157
|
-
|
|
158
|
-
|
|
198
|
+
splines = [self.splineList[item] for item in self.treeview.selection()]
|
|
199
|
+
if splines:
|
|
200
|
+
initialName = self.treeview.item(self.treeview.selection()[0])["text"] + ".json"
|
|
159
201
|
fileName = filedialog.asksaveasfilename(title="Save splines", initialfile=initialName,
|
|
160
202
|
defaultextension=".json", filetypes=(('Json files', '*.json'),('All files', '*.*')))
|
|
161
203
|
if fileName:
|
|
162
|
-
|
|
204
|
+
Solid.save(fileName, *splines)
|
|
163
205
|
|
|
164
206
|
def load_splines(self):
|
|
165
207
|
fileName = filedialog.askopenfilename(title="Load splines",
|
|
166
208
|
defaultextension=".json", filetypes=(('Json files', '*.json'),('All files', '*.*')))
|
|
167
209
|
if fileName:
|
|
168
|
-
splines =
|
|
210
|
+
splines = Solid.load(fileName)
|
|
169
211
|
for spline in splines:
|
|
170
|
-
|
|
212
|
+
if isinstance(spline, Spline):
|
|
213
|
+
self.list(spline)
|
|
214
|
+
else:
|
|
215
|
+
self.list(spline)
|
|
171
216
|
|
|
172
217
|
def erase_all(self):
|
|
173
|
-
"""Stop drawing all splines. Splines remain in the
|
|
174
|
-
self.
|
|
218
|
+
"""Stop drawing all splines. Splines remain in the treeview."""
|
|
219
|
+
self.treeview.selection_set()
|
|
175
220
|
self.splineRadius = 0.0
|
|
176
221
|
self.frame.ResetView()
|
|
177
222
|
self.update()
|
|
178
223
|
|
|
179
224
|
def remove(self):
|
|
180
|
-
"""Remove splines from the
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
del self.splineList[item]
|
|
185
|
-
self.splineDrawList.remove(spline)
|
|
186
|
-
self.listBox.delete(item, item)
|
|
225
|
+
"""Remove splines from the treeview."""
|
|
226
|
+
for item in self.treeview.selection():
|
|
227
|
+
spline = self.splineList.pop(item)
|
|
228
|
+
self.treeview.delete(item)
|
|
187
229
|
self.update()
|
|
188
230
|
|
|
189
231
|
def empty(self):
|
|
190
|
-
"""Stop drawing all splines and remove them from the
|
|
191
|
-
self.splineList =
|
|
192
|
-
self.
|
|
232
|
+
"""Stop drawing all splines and remove them from the treeview."""
|
|
233
|
+
self.splineList = {}
|
|
234
|
+
self.treeview.delete(*self.treeview.get_children())
|
|
193
235
|
self.splineRadius = 0.0
|
|
194
236
|
self.frame.ResetView()
|
|
195
237
|
self.update()
|
|
@@ -219,18 +261,32 @@ class Viewer(tk.Tk):
|
|
|
219
261
|
"""Update the spline draw list, set the default view, reset the bounds, and refresh the frame."""
|
|
220
262
|
self.splineDrawList = []
|
|
221
263
|
gotOne = False
|
|
222
|
-
for item in self.
|
|
264
|
+
for item in self.treeview.selection():
|
|
223
265
|
spline = self.splineList[item]
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
266
|
+
if isinstance(spline, Spline):
|
|
267
|
+
coefs = spline.cache["coefs32"].T[:3]
|
|
268
|
+
coefsAxis = tuple(range(1, spline.nInd + 1))
|
|
269
|
+
if gotOne:
|
|
270
|
+
splineMin = np.minimum(splineMin, coefs.min(axis=coefsAxis))
|
|
271
|
+
splineMax = np.maximum(splineMax, coefs.max(axis=coefsAxis))
|
|
272
|
+
else:
|
|
273
|
+
splineMin = coefs.min(axis=coefsAxis)
|
|
274
|
+
splineMax = coefs.max(axis=coefsAxis)
|
|
275
|
+
gotOne = True
|
|
276
|
+
self.splineDrawList.append(spline)
|
|
277
|
+
elif isinstance(spline, Solid):
|
|
278
|
+
for subitem in self.treeview.get_children(item):
|
|
279
|
+
spline = self.splineList[subitem]
|
|
280
|
+
coefs = spline.cache["coefs32"].T[:3]
|
|
281
|
+
coefsAxis = tuple(range(1, spline.nInd + 1))
|
|
282
|
+
if gotOne:
|
|
283
|
+
splineMin = np.minimum(splineMin, coefs.min(axis=coefsAxis))
|
|
284
|
+
splineMax = np.maximum(splineMax, coefs.max(axis=coefsAxis))
|
|
285
|
+
else:
|
|
286
|
+
splineMin = coefs.min(axis=coefsAxis)
|
|
287
|
+
splineMax = coefs.max(axis=coefsAxis)
|
|
288
|
+
gotOne = True
|
|
289
|
+
self.splineDrawList.append(spline)
|
|
234
290
|
|
|
235
291
|
if gotOne:
|
|
236
292
|
newRadius = 0.5 * np.max(splineMax - splineMin)
|
|
@@ -263,7 +319,7 @@ class Viewer(tk.Tk):
|
|
|
263
319
|
frame.DrawSpline(spline, transform)
|
|
264
320
|
|
|
265
321
|
def _ListSelectionChanged(self, event):
|
|
266
|
-
"""Handle when the
|
|
322
|
+
"""Handle when the treeview selection has changed."""
|
|
267
323
|
self.update()
|
|
268
324
|
|
|
269
325
|
def _ChangeFrameMode(self):
|
|
@@ -371,7 +427,7 @@ class Viewer(tk.Tk):
|
|
|
371
427
|
fillColor : `numpy.array`
|
|
372
428
|
Array of four floats (r, g, b, a) in the range [0, 1].
|
|
373
429
|
"""
|
|
374
|
-
return spline.metadata["fillColor"]
|
|
430
|
+
return np.array(spline.metadata["fillColor"], np.float32)
|
|
375
431
|
|
|
376
432
|
@staticmethod
|
|
377
433
|
def set_fill_color(spline, r, g=None, b=None, a=None):
|
|
@@ -412,7 +468,7 @@ class Viewer(tk.Tk):
|
|
|
412
468
|
lineColor : `numpy.array`
|
|
413
469
|
Array of four floats (r, g, b, a) in the range [0, 1].
|
|
414
470
|
"""
|
|
415
|
-
return spline.metadata["lineColor"]
|
|
471
|
+
return np.array(spline.metadata["lineColor"], np.float32)
|
|
416
472
|
|
|
417
473
|
@staticmethod
|
|
418
474
|
def set_line_color(spline, r, g=None, b=None, a=None):
|
|
@@ -519,7 +575,7 @@ class Graphics:
|
|
|
519
575
|
|
|
520
576
|
See Also
|
|
521
577
|
--------
|
|
522
|
-
`Viewer` : A tkinter app (`tkinter.Tk`) that hosts a `SplineOpenGLFrame`, a
|
|
578
|
+
`Viewer` : A tkinter app (`tkinter.Tk`) that hosts a `SplineOpenGLFrame`, a treeview full of
|
|
523
579
|
splines, and a set of controls to adjust and view the selected splines.
|
|
524
580
|
|
|
525
581
|
Examples
|
|
@@ -541,38 +597,26 @@ class Graphics:
|
|
|
541
597
|
viewer = Viewer(workQueue=self.workQueue)
|
|
542
598
|
viewer.mainloop()
|
|
543
599
|
|
|
544
|
-
def list(self, spline, name = None):
|
|
545
|
-
"""List a `Spline` in the
|
|
546
|
-
if name is
|
|
547
|
-
spline.metadata["Name"] = name
|
|
548
|
-
elif "Name" not in spline.metadata:
|
|
600
|
+
def list(self, spline, name = None, fillColor=None, lineColor=None, options=None, draw=False):
|
|
601
|
+
"""List a `Spline`, `Boundary`, or `Solid` in the treeview. Can be called before viewer is running."""
|
|
602
|
+
if name is None:
|
|
549
603
|
for name, value in self.variableDictionary.items():
|
|
550
604
|
if value is spline:
|
|
551
|
-
spline.metadata["Name"] = name
|
|
552
605
|
break
|
|
553
|
-
self.workQueue.put(("
|
|
606
|
+
self.workQueue.put(("list", (spline, name, fillColor, lineColor, options, draw)))
|
|
554
607
|
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
"""Add a `Spline` to the listbox and draw it."""
|
|
561
|
-
if name is not None:
|
|
562
|
-
spline.metadata["Name"] = name
|
|
563
|
-
elif "Name" not in spline.metadata:
|
|
564
|
-
for name, value in self.variableDictionary.items():
|
|
565
|
-
if value is spline:
|
|
566
|
-
spline.metadata["Name"] = name
|
|
567
|
-
break
|
|
568
|
-
self.workQueue.put(("draw", (spline,)))
|
|
608
|
+
show = list
|
|
609
|
+
|
|
610
|
+
def draw(self, spline, name = None, fillColor=None, lineColor=None, options=None):
|
|
611
|
+
"""List a `Spline`, `Boundary`, or `Solid` in the treeview and draw it in the viewer. Can be called before viewer is running."""
|
|
612
|
+
self.list(spline, name, fillColor, lineColor, options, True)
|
|
569
613
|
|
|
570
614
|
def erase_all(self):
|
|
571
|
-
"""Stop drawing all splines. Splines remain in the
|
|
615
|
+
"""Stop drawing all splines. Splines remain in the treeview."""
|
|
572
616
|
self.workQueue.put(("erase_all", ()))
|
|
573
617
|
|
|
574
618
|
def empty(self):
|
|
575
|
-
"""Stop drawing all splines and remove them from the
|
|
619
|
+
"""Stop drawing all splines and remove them from the treeview."""
|
|
576
620
|
self.workQueue.put(("empty", ()))
|
|
577
621
|
|
|
578
622
|
def set_background_color(self, 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
|
|
@@ -32,20 +32,31 @@ Requires-Dist: pyopengltk
|
|
|
32
32
|
# BSpy
|
|
33
33
|
Library for manipulating and rendering B-spline curves, surfaces, and multidimensional manifolds with non-uniform knots in each dimension.
|
|
34
34
|
|
|
35
|
-
The [
|
|
36
|
-
|
|
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
|
+
|
|
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.
|
|
37
39
|
Other methods add, subtract, and multiply splines, as well as confine spline curves to a given range.
|
|
38
|
-
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.
|
|
45
|
+
|
|
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.
|
|
47
|
+
|
|
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.
|
|
39
51
|
|
|
40
52
|
The [SplineOpenGLFrame](https://ericbrec.github.io/BSpy/bspy/splineOpenGLFrame.html) class is an
|
|
41
53
|
[OpenGLFrame](https://pypi.org/project/pyopengltk/) with custom shaders to render spline curves and surfaces. Spline surfaces with more
|
|
42
54
|
than 3 dependent variables will have their added dimensions rendered as colors (up to 6 dependent variables are supported). Only tested on Windows systems.
|
|
43
55
|
|
|
44
|
-
|
|
45
56
|
The [Viewer](https://ericbrec.github.io/BSpy/bspy/viewer.html) class is a
|
|
46
57
|
[tkinter.Tk](https://docs.python.org/3/library/tkinter.html) app that hosts a
|
|
47
58
|
[SplineOpenGLFrame](https://ericbrec.github.io/BSpy/bspy/splineOpenGLFrame.html),
|
|
48
|
-
a
|
|
59
|
+
a tree view full of solids and splines, and a set of controls to adjust and view the selected solids and splines. Only tested on Windows systems.
|
|
49
60
|
|
|
50
61
|
The [Graphics](https://ericbrec.github.io/BSpy/bspy/viewer.html#Graphics) class is a graphics engine to display splines.
|
|
51
62
|
It launches a [Viewer](https://ericbrec.github.io/BSpy/bspy/viewer.html) and issues commands to the viewer for use
|
|
@@ -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.0.dist-info/RECORD
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
bspy/__init__.py,sha256=p2tWAqZDc7JQ6-9-N-RLjscETpU5UPxgPB03Yc6Divk,923
|
|
2
|
-
bspy/_spline_domain.py,sha256=-DWbiUdYkG9AX-_IILWIe6Alj-U3QJ9vcOi3jp7jCv0,29737
|
|
3
|
-
bspy/_spline_evaluation.py,sha256=DErClOQrvXlK6uBZTwsGxAd6GXxBwXF9FIVnt57dOWI,6904
|
|
4
|
-
bspy/_spline_fitting.py,sha256=H5yWhYHwrpoqb7dN2lF7eDNhSHH5XngG7TYVCYyydlQ,46778
|
|
5
|
-
bspy/_spline_intersection.py,sha256=0aoUB5vKKObOM5B6W2U6MjqB91o3xXBPJr8j5a-hZ8U,47777
|
|
6
|
-
bspy/_spline_operations.py,sha256=C3O-v8FlQbUc3szKZJIKS0RkjjbqV38aQL-IDSqMVL8,42222
|
|
7
|
-
bspy/manifold.py,sha256=l2mOKBe-ejvXIIi3S3VpZ1ONuVZI1DPbdpibRwR1fu8,4343
|
|
8
|
-
bspy/spline.py,sha256=RH-OSleMxFgTyv9nCyOSmzSZIKU1R3Esh_R1nKFrekI,89834
|
|
9
|
-
bspy/splineOpenGLFrame.py,sha256=1-xaw4LnAqpu4DbSDDquRiN7eQe1bu6A5QLrreLy35Y,82849
|
|
10
|
-
bspy/viewer.py,sha256=CrPLdhPmCSuUeScAjxbb19iSbfxb2Ft9KBWx-K4IjLs,30727
|
|
11
|
-
bspy-4.0.dist-info/LICENSE,sha256=nLfJULN68Jw6GfCJp4xeMksGuRdyWNdgEsZGjw2twig,1091
|
|
12
|
-
bspy-4.0.dist-info/METADATA,sha256=CKnqv9yg3KJayKnOrPu_eC-W5hWsgeBi89eYtQj50l0,4857
|
|
13
|
-
bspy-4.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
14
|
-
bspy-4.0.dist-info/top_level.txt,sha256=fotZnJn6aCwgUbBEV3hslIko7Nw-eqtHLq2eyJLlFsY,5
|
|
15
|
-
bspy-4.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|