@@ -307,6 +307,8 @@ def split(self: T, *args, **kwargs) -> T:
307
307
else [v for v in arg .vals () if isinstance (v , Shape )]
308
308
)
309
309
rv = [solid .split (* tools )]
310
+ if isinstance (arg , Workplane ):
311
+ self ._mergeTags (arg )
310
312
311
313
# split using the current workplane
312
314
else :
@@ -456,6 +458,7 @@ def add(self, obj):
456
458
self .objects .extend (obj )
457
459
elif isinstance (obj , Workplane ):
458
460
self .objects .extend (obj .objects )
461
+ self ._mergeTags (obj )
459
462
else :
460
463
self .objects .append (obj )
461
464
return self
@@ -471,20 +474,31 @@ def val(self) -> CQObject:
471
474
472
475
def _getTagged (self , name : str ) -> "Workplane" :
473
476
"""
474
- Search the parent chain for a an object with tag == name.
477
+ Search the parent chain for an object with tag == name.
475
478
476
479
:param name: the tag to search for
477
- :type name: string
478
- :returns: the CQ object with tag == name
480
+ :returns: the Workplane object with tag == name
479
481
:raises: ValueError if no object tagged name
480
482
"""
481
483
rv = self .ctx .tags .get (name )
482
484
483
485
if rv is None :
484
- raise ValueError (f"No CQ object named { name } in chain" )
486
+ raise ValueError (f"No Workplane object named { name } in chain" )
485
487
486
488
return rv
487
489
490
+ def _mergeTags (self : T , obj : "Workplane" ) -> T :
491
+ """
492
+ Merge tags
493
+
494
+ This is automatically called when performing boolean ops.
495
+ """
496
+
497
+ if self .ctx != obj .ctx :
498
+ self .ctx .tags = {** obj .ctx .tags , ** self .ctx .tags }
499
+
500
+ return self
501
+
488
502
def toOCC (self ) -> Any :
489
503
"""
490
504
Directly returns the wrapped OCCT object.
@@ -3250,22 +3264,23 @@ def union(
3250
3264
If there is no current solid, the items in toUnion are unioned together.
3251
3265
3252
3266
:param toUnion:
3253
- :type toUnion: a solid object, or a CQ object having a solid,
3254
- :param boolean clean: call :py:meth:`clean` afterwards to have a clean shape (default True)
3255
- :param boolean glue: use a faster gluing mode for non-overlapping shapes (default False)
3256
- :param float tol: tolerance value for fuzzy bool operation mode (default None)
3267
+ :type toUnion: a solid object, or a Workplane object having a solid,
3268
+ :param clean: call :py:meth:`clean` afterwards to have a clean shape (default True)
3269
+ :param glue: use a faster gluing mode for non-overlapping shapes (default False)
3270
+ :param tol: tolerance value for fuzzy bool operation mode (default None)
3257
3271
:raises: ValueError if there is no solid to add to in the chain
3258
- :return: a CQ object with the resulting object selected
3272
+ :return: a Workplane object with the resulting object selected
3259
3273
"""
3260
3274
3261
3275
# first collect all of the items together
3262
3276
newS : List [Shape ]
3263
- if isinstance (toUnion , CQ ):
3277
+ if isinstance (toUnion , Workplane ):
3264
3278
newS = cast (List [Shape ], toUnion .solids ().vals ())
3265
3279
if len (newS ) < 1 :
3266
3280
raise ValueError (
3267
- "CQ object must have at least one solid on the stack to union!"
3281
+ "Workplane object must have at least one solid on the stack to union!"
3268
3282
)
3283
+ self ._mergeTags (toUnion )
3269
3284
elif isinstance (toUnion , (Solid , Compound )):
3270
3285
newS = [toUnion ]
3271
3286
else :
@@ -3315,19 +3330,20 @@ def cut(
3315
3330
Cuts the provided solid from the current solid, IE, perform a solid subtraction.
3316
3331
3317
3332
:param toCut: object to cut
3318
- :type toCut: a solid object, or a CQ object having a solid,
3319
- :param boolean clean: call :py:meth:`clean` afterwards to have a clean shape
3333
+ :type toCut: a solid object, or a Workplane object having a solid,
3334
+ :param clean: call :py:meth:`clean` afterwards to have a clean shape
3320
3335
:raises ValueError: if there is no solid to subtract from in the chain
3321
- :return: a CQ object with the resulting object selected
3336
+ :return: a Workplane object with the resulting object selected
3322
3337
"""
3323
3338
3324
3339
# look for parents to cut from
3325
3340
solidRef = self .findSolid (searchStack = True , searchParents = True )
3326
3341
3327
3342
solidToCut : Sequence [Shape ]
3328
3343
3329
- if isinstance (toCut , CQ ):
3344
+ if isinstance (toCut , Workplane ):
3330
3345
solidToCut = _selectShapes (toCut .vals ())
3346
+ self ._mergeTags (toCut )
3331
3347
elif isinstance (toCut , (Solid , Compound )):
3332
3348
solidToCut = (toCut ,)
3333
3349
else :
@@ -3360,19 +3376,20 @@ def intersect(
3360
3376
Intersects the provided solid from the current solid.
3361
3377
3362
3378
:param toIntersect: object to intersect
3363
- :type toIntersect: a solid object, or a CQ object having a solid,
3364
- :param boolean clean: call :py:meth:`clean` afterwards to have a clean shape
3379
+ :type toIntersect: a solid object, or a Workplane object having a solid,
3380
+ :param clean: call :py:meth:`clean` afterwards to have a clean shape
3365
3381
:raises ValueError: if there is no solid to intersect with in the chain
3366
- :return: a CQ object with the resulting object selected
3382
+ :return: a Workplane object with the resulting object selected
3367
3383
"""
3368
3384
3369
3385
# look for parents to intersect with
3370
3386
solidRef = self .findSolid (searchStack = True , searchParents = True )
3371
3387
3372
3388
solidToIntersect : Sequence [Shape ]
3373
3389
3374
- if isinstance (toIntersect , CQ ):
3390
+ if isinstance (toIntersect , Workplane ):
3375
3391
solidToIntersect = _selectShapes (toIntersect .vals ())
3392
+ self ._mergeTags (toIntersect )
3376
3393
elif isinstance (toIntersect , (Solid , Compound )):
3377
3394
solidToIntersect = (toIntersect ,)
3378
3395
else :
0 commit comments