Skip to content

Commit 0dab2be

Browse files
committed
added combine cut for all 3D ops
added combine cut for twistextrude sweep. Didn't added it for extrude as it already as cutBlind and the option to extrude until a given face is combine by default and would need a little bit more change to handle combine=cut (but its still possible)
1 parent 5fb8823 commit 0dab2be

File tree

2 files changed

+35
-7
lines changed

2 files changed

+35
-7
lines changed

cadquery/cq.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2951,7 +2951,7 @@ def twistExtrude(
29512951
self: T,
29522952
distance: float,
29532953
angleDegrees: float,
2954-
combine: bool = True,
2954+
combine: Union[bool, str] = True,
29552955
clean: bool = True,
29562956
) -> T:
29572957
"""
@@ -2968,7 +2968,7 @@ def twistExtrude(
29682968
29692969
:param distance: the distance to extrude normal to the workplane
29702970
:param angle: angle (in degrees) to rotate through the extrusion
2971-
:param boolean combine: True to combine the resulting solid with parent solids if found.
2971+
:param boolean or string combine: True to combine the resulting solid with parent solids if found, "cut" to remove the resulting solid with the parent solids if found.
29722972
:param boolean clean: call :py:meth:`clean` afterwards to have a clean shape
29732973
:return: a CQ object with the resulting solid selected.
29742974
"""
@@ -2993,7 +2993,9 @@ def twistExtrude(
29932993

29942994
r = Compound.makeCompound(shapes).fuse()
29952995

2996-
if combine:
2996+
if isinstance(combine, str) and combine == "cut":
2997+
newS = self._cutFromBase(r)
2998+
elif isinstance(combine, bool) and combine:
29972999
newS = self._combineWithBase(r)
29983000
else:
29993001
newS = self.newObject([r])
@@ -3072,7 +3074,7 @@ def revolve(
30723074
angleDegrees: float = 360.0,
30733075
axisStart: Optional[VectorLike] = None,
30743076
axisEnd: Optional[VectorLike] = None,
3075-
combine: bool = True,
3077+
combine: Union[bool, str] = True,
30763078
clean: bool = True,
30773079
) -> T:
30783080
"""
@@ -3146,7 +3148,7 @@ def sweep(
31463148
sweepAlongWires: Optional[bool] = None,
31473149
makeSolid: bool = True,
31483150
isFrenet: bool = False,
3149-
combine: bool = True,
3151+
combine: Union[bool, str] = True,
31503152
clean: bool = True,
31513153
transition: Literal["right", "round", "transformed"] = "right",
31523154
normal: Optional[VectorLike] = None,
@@ -3157,7 +3159,7 @@ def sweep(
31573159
31583160
:param path: A wire along which the pending wires will be swept
31593161
:param boolean multiSection: False to create multiple swept from wires on the chain along path. True to create only one solid swept along path with shape following the list of wires on the chain
3160-
:param boolean combine: True to combine the resulting solid with parent solids if found.
3162+
:param boolean or string combine: True to combine the resulting solid with parent solids if found, "cut" to remove the resulting solid with the parent solids if found.
31613163
:param boolean clean: call :py:meth:`clean` afterwards to have a clean shape
31623164
:param transition: handling of profile orientation at C1 path discontinuities. Possible values are {'transformed','round', 'right'} (default: 'right').
31633165
:param normal: optional fixed normal for extrusion
@@ -3187,7 +3189,9 @@ def sweep(
31873189
) # returns a Solid (or a compound if there were multiple)
31883190

31893191
newS: T
3190-
if combine:
3192+
if isinstance(combine, str) and combine == "cut":
3193+
newS = self._cutFromBase(r)
3194+
elif isinstance(combine, bool) and combine:
31913195
newS = self._combineWithBase(r)
31923196
else:
31933197
newS = self.newObject([r])

tests/test_cadquery.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,6 +1155,17 @@ def testSweep(self):
11551155
.sweep(path, auxSpine=Workplane().box(1, 1, 1))
11561156
)
11571157

1158+
# test sweep with combine="cut"
1159+
box = Workplane().box(10, 10, 10, centered=False)
1160+
path = Workplane("YZ").lineTo(10, 10)
1161+
cut = (
1162+
box.vertices(">Z and >X and >Y")
1163+
.workplane(centerOption="CenterOfMass")
1164+
.circle(1.5)
1165+
.sweep(path, combine="cut")
1166+
)
1167+
self.assertGreater(box.val().Volume(), cut.val().Volume())
1168+
11581169
def testMultisectionSweep(self):
11591170
"""
11601171
Tests the operation of sweeping along a list of wire(s) along a path
@@ -1279,6 +1290,19 @@ def testTwistExtrude(self):
12791290

12801291
self.assertEqual(6, r.faces().size())
12811292

1293+
def testTwistExtrudeCombineCut(self):
1294+
"""
1295+
Tests extrusion while twisting through an angle, removing the solid from the base solid
1296+
"""
1297+
box = Workplane().box(10, 10, 10)
1298+
cut = (
1299+
box.faces(">Z")
1300+
.workplane(invert=True)
1301+
.rect(1.5, 5)
1302+
.twistExtrude(10, 90, combine="cut")
1303+
)
1304+
self.assertGreater(box.val().Volume(), cut.val().Volume())
1305+
12821306
def testTwistExtrudeCombine(self):
12831307
"""
12841308
Tests extrusion while twisting through an angle, combining with other solids.

0 commit comments

Comments
 (0)