10
10
Face ,
11
11
Edge ,
12
12
)
13
- from .occ_impl .assembly import _loc2vtk , toVTK
13
+ from .occ_impl .assembly import _loc2vtk , toVTKAssy
14
14
15
15
from typing import Union , Any , List , Tuple , Iterable , cast , Optional
16
16
26
26
vtkMapper ,
27
27
vtkRenderWindowInteractor ,
28
28
vtkActor ,
29
- vtkProp ,
29
+ vtkProp3D ,
30
30
vtkPolyDataMapper ,
31
31
vtkAssembly ,
32
32
vtkRenderWindow ,
33
33
vtkWindowToImageFilter ,
34
+ vtkRenderer ,
35
+ vtkPropCollection ,
34
36
)
35
37
from vtkmodules .vtkCommonCore import vtkPoints
36
38
from vtkmodules .vtkCommonDataModel import vtkCellArray , vtkPolyData
37
39
from vtkmodules .vtkCommonColor import vtkNamedColors
38
40
from vtkmodules .vtkIOImage import vtkPNGWriter
39
41
40
42
41
- DEFAULT_COLOR = [1 , 0.8 , 0 , 1 ]
43
+ DEFAULT_COLOR = (1 , 0.8 , 0 )
44
+ DEFAULT_EDGE_COLOR = (0 , 0 , 0 )
42
45
DEFAULT_PT_SIZE = 7.5
43
46
DEFAULT_PT_COLOR = "darkviolet"
44
47
DEFAULT_CTRL_PT_COLOR = "crimson"
50
53
51
54
ShapeLike = Union [Shape , Workplane , Assembly , Sketch , TopoDS_Shape ]
52
55
Showable = Union [
53
- ShapeLike , List [ShapeLike ], Vector , List [Vector ], vtkProp , List [vtkProp ]
56
+ ShapeLike , List [ShapeLike ], Vector , List [Vector ], vtkProp3D , List [vtkProp3D ]
54
57
]
55
58
56
59
57
- def _to_assy (* objs : ShapeLike , alpha : float = 1 ) -> Assembly :
60
+ def _to_assy (
61
+ * objs : ShapeLike ,
62
+ color : Tuple [float , float , float ] = DEFAULT_COLOR ,
63
+ alpha : float = 1 ,
64
+ ) -> Assembly :
65
+ """
66
+ Convert shapes to Assembly.
67
+ """
58
68
59
- assy = Assembly (
60
- color = Color (DEFAULT_COLOR [0 ], DEFAULT_COLOR [1 ], DEFAULT_COLOR [2 ], alpha )
61
- )
69
+ assy = Assembly (color = Color (* color , alpha ))
62
70
63
71
for obj in objs :
64
72
if isinstance (obj , (Shape , Workplane , Assembly )):
@@ -75,15 +83,15 @@ def _to_assy(*objs: ShapeLike, alpha: float = 1) -> Assembly:
75
83
76
84
def _split_showables (
77
85
objs ,
78
- ) -> Tuple [List [ShapeLike ], List [Vector ], List [Location ], List [vtkProp ]]:
86
+ ) -> Tuple [List [ShapeLike ], List [Vector ], List [Location ], List [vtkProp3D ]]:
79
87
"""
80
88
Split into showables and others.
81
89
"""
82
90
83
91
rv_s : List [ShapeLike ] = []
84
92
rv_v : List [Vector ] = []
85
93
rv_l : List [Location ] = []
86
- rv_a : List [vtkProp ] = []
94
+ rv_a : List [vtkProp3D ] = []
87
95
88
96
for el in objs :
89
97
if instance_of (el , ShapeLike ):
@@ -92,7 +100,7 @@ def _split_showables(
92
100
rv_v .append (el )
93
101
elif isinstance (el , Location ):
94
102
rv_l .append (el )
95
- elif isinstance (el , vtkProp ):
103
+ elif isinstance (el , vtkProp3D ):
96
104
rv_a .append (el )
97
105
elif isinstance (el , list ):
98
106
tmp1 , tmp2 , tmp3 , tmp4 = _split_showables (el ) # split recursively
@@ -158,6 +166,28 @@ def _to_vtk_axs(locs: List[Location], scale: float = 0.1) -> vtkAssembly:
158
166
return rv
159
167
160
168
169
+ def _to_vtk_shapes (
170
+ obj : List [ShapeLike ],
171
+ color : Tuple [float , float , float ] = DEFAULT_COLOR ,
172
+ edgecolor : Tuple [float , float , float ] = DEFAULT_EDGE_COLOR ,
173
+ edges : bool = True ,
174
+ linewidth : float = 2 ,
175
+ alpha : float = 1 ,
176
+ tolerance : float = 1e-3 ,
177
+ ) -> vtkAssembly :
178
+ """
179
+ Convert Shapes to vtkAssembly.
180
+ """
181
+
182
+ return toVTKAssy (
183
+ _to_assy (* obj , color = color , alpha = alpha ),
184
+ edgecolor = (* edgecolor , 1 ),
185
+ edges = edges ,
186
+ linewidth = linewidth ,
187
+ tolerance = tolerance ,
188
+ )
189
+
190
+
161
191
def ctrlPts (
162
192
s : Union [Face , Edge ],
163
193
size : float = DEFAULT_CTRL_PT_SIZE ,
@@ -249,6 +279,105 @@ def ctrlPts(
249
279
return rv
250
280
251
281
282
+ def _iterate_actors (obj : Union [vtkProp3D , vtkActor , vtkAssembly ]) -> Iterable [vtkActor ]:
283
+ """
284
+ Iterate over vtkActors, other props are ignored.
285
+ """
286
+ if isinstance (obj , vtkActor ):
287
+ yield obj
288
+ elif isinstance (obj , vtkAssembly ):
289
+ coll = vtkPropCollection ()
290
+ obj .GetActors (coll )
291
+
292
+ coll .InitTraversal ()
293
+ for i in range (0 , coll .GetNumberOfItems ()):
294
+ prop = coll .GetNextProp ()
295
+ if isinstance (prop , vtkActor ):
296
+ yield prop
297
+
298
+
299
+ def style (
300
+ obj : Showable ,
301
+ scale : float = 0.2 ,
302
+ alpha : float = 1 ,
303
+ tolerance : float = 1e-2 ,
304
+ edges : bool = True ,
305
+ mesh : bool = False ,
306
+ specular : bool = True ,
307
+ markersize : float = 5 ,
308
+ linewidth : float = 2 ,
309
+ spheres : bool = False ,
310
+ tubes : bool = False ,
311
+ color : str = "gold" ,
312
+ edgecolor : str = "black" ,
313
+ meshcolor : str = "lightgrey" ,
314
+ vertexcolor : str = "cyan" ,
315
+ ** kwargs ,
316
+ ) -> Union [vtkActor , vtkAssembly ]:
317
+ """
318
+ Apply styling to CQ objects. To be used in conjunction with show.
319
+ """
320
+
321
+ # styling functions
322
+ def _apply_style (actor ):
323
+ props = actor .GetProperty ()
324
+ props .SetEdgeColor (vtkNamedColors ().GetColor3d (meshcolor ))
325
+ props .SetVertexColor (vtkNamedColors ().GetColor3d (vertexcolor ))
326
+ props .SetPointSize (markersize )
327
+ props .SetLineWidth (linewidth )
328
+ props .SetRenderPointsAsSpheres (spheres )
329
+ props .SetRenderLinesAsTubes (tubes )
330
+ props .SetEdgeVisibility (mesh )
331
+
332
+ if specular :
333
+ props .SetSpecular (SPECULAR )
334
+ props .SetSpecularPower (SPECULAR_POWER )
335
+ props .SetSpecularColor (SPECULAR_COLOR )
336
+
337
+ def _apply_color (actor ):
338
+ props = actor .GetProperty ()
339
+ props .SetColor (vtkNamedColors ().GetColor3d (color ))
340
+ props .SetOpacity (alpha )
341
+
342
+ # split showables
343
+ shapes , vecs , locs , actors = _split_showables ([obj ,])
344
+
345
+ # convert to a prop
346
+ rv : Union [vtkActor , vtkAssembly ]
347
+
348
+ if shapes :
349
+ rv = _to_vtk_shapes (
350
+ shapes ,
351
+ color = vtkNamedColors ().GetColor3d (color ),
352
+ edgecolor = vtkNamedColors ().GetColor3d (edgecolor ),
353
+ edges = edges ,
354
+ linewidth = linewidth ,
355
+ alpha = alpha ,
356
+ tolerance = tolerance ,
357
+ )
358
+
359
+ # apply style to every actor
360
+ for a in _iterate_actors (rv ):
361
+ _apply_style (a )
362
+
363
+ elif vecs :
364
+ rv = _to_vtk_pts (vecs )
365
+ _apply_style (rv )
366
+ _apply_color (rv )
367
+ elif locs :
368
+ rv = _to_vtk_axs (locs , scale = scale )
369
+ else :
370
+ rv = vtkAssembly ()
371
+
372
+ for p in actors :
373
+ for a in _iterate_actors (p ):
374
+ _apply_style (a )
375
+ _apply_color (a )
376
+ rv .AddPart (a )
377
+
378
+ return rv
379
+
380
+
252
381
def show (
253
382
* objs : Showable ,
254
383
scale : float = 0.2 ,
@@ -262,14 +391,15 @@ def show(
262
391
zoom : float = 1.0 ,
263
392
roll : float = - 35 ,
264
393
elevation : float = - 45 ,
394
+ position : Optional [Tuple [float , float , float ]] = None ,
395
+ focus : Optional [Tuple [float , float , float ]] = None ,
265
396
width : Union [int , float ] = 0.5 ,
266
397
height : Union [int , float ] = 0.5 ,
267
398
trihedron : bool = True ,
268
399
bgcolor : tuple [float , float , float ] = (1 , 1 , 1 ),
269
400
gradient : bool = True ,
270
401
xpos : Union [int , float ] = 0 ,
271
402
ypos : Union [int , float ] = 0 ,
272
- ** kwrags : Any ,
273
403
):
274
404
"""
275
405
Show CQ objects using VTK. This functions optionally allows to make screenshots.
@@ -286,7 +416,8 @@ def show(
286
416
axs = _to_vtk_axs (locs , scale = scale )
287
417
288
418
# assy+renderer
289
- renderer = toVTK (assy , tolerance = tolerance )
419
+ renderer = vtkRenderer ()
420
+ renderer .AddActor (toVTKAssy (assy , tolerance = tolerance ))
290
421
291
422
# VTK window boilerplate
292
423
win = vtkRenderWindow ()
@@ -350,13 +481,6 @@ def show(
350
481
# use FXXAA
351
482
renderer .UseFXAAOn ()
352
483
353
- # set camera
354
- camera = renderer .GetActiveCamera ()
355
- camera .Roll (roll )
356
- camera .Elevation (elevation )
357
- renderer .ResetCamera ()
358
- camera .Zoom (zoom )
359
-
360
484
# add pts and locs
361
485
renderer .AddActor (pts )
362
486
renderer .AddActor (axs )
@@ -365,6 +489,20 @@ def show(
365
489
for p in props :
366
490
renderer .AddActor (p )
367
491
492
+ # set camera
493
+ camera = renderer .GetActiveCamera ()
494
+ camera .Roll (roll )
495
+ camera .Elevation (elevation )
496
+ camera .Zoom (zoom )
497
+
498
+ if position or focus :
499
+ if position :
500
+ camera .SetPosition (* position )
501
+ if focus :
502
+ camera .SetFocalPoint (* focus )
503
+ else :
504
+ renderer .ResetCamera ()
505
+
368
506
# initialize and set size
369
507
inter .Initialize ()
370
508
0 commit comments