Skip to content

Commit 7be6070

Browse files
committed
Use popPending methods
1 parent b316461 commit 7be6070

File tree

2 files changed

+50
-43
lines changed

2 files changed

+50
-43
lines changed

cadquery/cq.py

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2122,6 +2122,8 @@ def _addPendingWire(self, wire: Wire) -> None:
21222122

21232123
def _consolidateWires(self) -> List[Wire]:
21242124

2125+
# note: do not use CQContext.popPendingEdges or Wires here, this method does not
2126+
# clear pending edges or wires.
21252127
wires = cast(
21262128
List[Union[Edge, Wire]],
21272129
[el for el in chain(self.ctx.pendingEdges, self.ctx.pendingWires)],
@@ -2159,39 +2161,33 @@ def wire(self, forConstruction: bool = False) -> "Workplane":
21592161
Returns a CQ object with all pending edges connected into a wire.
21602162
21612163
All edges on the stack that can be combined will be combined into a single wire object,
2162-
and other objects will remain on the stack unmodified
2164+
and other objects will remain on the stack unmodified. If there are no pending edges,
2165+
this method will just return self.
21632166
21642167
:param forConstruction: whether the wire should be used to make a solid, or if it is just
21652168
for reference
2166-
:type forConstruction: boolean. true if the object is only for reference
21672169
21682170
This method is primarily of use to plugin developers making utilities for 2-d construction.
21692171
This method should be called when a user operation implies that 2-d construction is
2170-
finished, and we are ready to begin working in 3d
2172+
finished, and we are ready to begin working in 3d.
21712173
21722174
SEE '2-d construction concepts' for a more detailed explanation of how CadQuery handles
2173-
edges, wires, etc
2175+
edges, wires, etc.
21742176
21752177
Any non edges will still remain.
21762178
"""
21772179

2178-
edges = self.ctx.pendingEdges
2179-
21802180
# do not consolidate if there are no free edges
2181-
if len(edges) == 0:
2181+
if len(self.ctx.pendingEdges) == 0:
21822182
return self
21832183

2184-
self.ctx.pendingEdges = []
2185-
2186-
others = []
2187-
for e in self.objects:
2188-
if type(e) != Edge:
2189-
others.append(e)
2190-
2184+
edges = self.ctx.popPendingEdges()
21912185
w = Wire.assembleEdges(edges)
21922186
if not forConstruction:
21932187
self._addPendingWire(w)
21942188

2189+
others = [e for e in self.objects if not isinstance(e, Edge)]
2190+
21952191
return self.newObject(others + [w])
21962192

21972193
def each(
@@ -2757,10 +2753,7 @@ def twistExtrude(
27572753
"""
27582754
# group wires together into faces based on which ones are inside the others
27592755
# result is a list of lists
2760-
wireSets = sortWiresByBuildOrder(list(self.ctx.pendingWires))
2761-
2762-
# now all of the wires have been used to create an extrusion
2763-
self.ctx.pendingWires = []
2756+
wireSets = sortWiresByBuildOrder(self.ctx.popPendingWires())
27642757

27652758
# compute extrusion vector and extrude
27662759
eDir = self.plane.zDir.multiply(distance)
@@ -3210,13 +3203,12 @@ def cutThruAll(self, clean: bool = True, taper: float = 0) -> "Workplane":
32103203
32113204
:param boolean clean: call :py:meth:`clean` afterwards to have a clean shape
32123205
:raises ValueError: if there is no solid to subtract from in the chain
3206+
:raises ValueError: if there are no pending wires to cut with
32133207
:return: a CQ object with the resulting object selected
32143208
32153209
see :py:meth:`cutBlind` to cut material to a limited depth
32163210
"""
3217-
wires = self.ctx.pendingWires
3218-
self.ctx.pendingWires = []
3219-
3211+
wires = self.ctx.popPendingWires()
32203212
solidRef = self.findSolid()
32213213

32223214
rv = []
@@ -3237,8 +3229,7 @@ def loft(
32373229
Make a lofted solid, through the set of wires.
32383230
:return: a CQ object containing the created loft
32393231
"""
3240-
wiresToLoft = self.ctx.pendingWires
3241-
self.ctx.pendingWires = []
3232+
wiresToLoft = self.ctx.popPendingWires()
32423233

32433234
r: Shape = Solid.makeLoft(wiresToLoft, ruled)
32443235

@@ -3268,9 +3259,7 @@ def _extrude(
32683259
# group wires together into faces based on which ones are inside the others
32693260
# result is a list of lists
32703261

3271-
wireSets = sortWiresByBuildOrder(list(self.ctx.pendingWires))
3272-
# now all of the wires have been used to create an extrusion
3273-
self.ctx.pendingWires = []
3262+
wireSets = sortWiresByBuildOrder(self.ctx.popPendingWires())
32743263

32753264
# compute extrusion vector and extrude
32763265
eDir = self.plane.zDir.multiply(distance)
@@ -3316,11 +3305,8 @@ def _revolve(
33163305
33173306
This method is a utility method, primarily for plugin and internal use.
33183307
"""
3319-
# We have to gather the wires to be revolved
3320-
wireSets = sortWiresByBuildOrder(list(self.ctx.pendingWires))
3321-
3322-
# Mark that all of the wires have been used to create a revolution
3323-
self.ctx.pendingWires = []
3308+
# Get the wires to be revolved
3309+
wireSets = sortWiresByBuildOrder(self.ctx.popPendingWires())
33243310

33253311
# Revolve the wires, make a compound out of them and then fuse them
33263312
toFuse = []
@@ -3373,19 +3359,17 @@ def _sweep(
33733359
mode = wire
33743360

33753361
if not multisection:
3376-
wireSets = sortWiresByBuildOrder(list(self.ctx.pendingWires))
3362+
wireSets = sortWiresByBuildOrder(self.ctx.popPendingWires())
33773363
for ws in wireSets:
33783364
thisObj = Solid.sweep(
33793365
ws[0], ws[1:], p, makeSolid, isFrenet, mode, transition
33803366
)
33813367
toFuse.append(thisObj)
33823368
else:
3383-
sections = self.ctx.pendingWires
3369+
sections = self.ctx.popPendingWires()
33843370
thisObj = Solid.sweep_multi(sections, p, makeSolid, isFrenet, mode)
33853371
toFuse.append(thisObj)
33863372

3387-
self.ctx.pendingWires = []
3388-
33893373
return Compound.makeCompound(toFuse)
33903374

33913375
def interpPlate(

tests/test_cadquery.py

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -394,8 +394,7 @@ def testRect(self):
394394

395395
def testLoft(self):
396396
"""
397-
Test making a lofted solid
398-
:return:
397+
Test making a lofted solid
399398
"""
400399
s = Workplane("XY").circle(4.0).workplane(5.0).rect(2.0, 2.0).loft()
401400
self.saveModel(s)
@@ -405,10 +404,13 @@ def testLoft(self):
405404
# the resulting loft had a split on the side, not sure why really, i expected only 3 faces
406405
self.assertEqual(7, s.faces().size())
407406

408-
def testLoftWithOneWireRaisesValueError(self):
409-
s = Workplane("XY").circle(5)
407+
def testLoftRaisesValueError(self):
408+
s0 = Workplane().hLine(1) # no wires
409+
with raises(ValueError):
410+
s0.loft()
411+
s1 = Workplane("XY").circle(5) # one wire
410412
with self.assertRaises(ValueError) as cm:
411-
s.loft()
413+
s1.loft()
412414
err = cm.exception
413415
self.assertEqual(str(err), "More than one wire is required")
414416

@@ -551,6 +553,14 @@ def testRevolveCone(self):
551553
self.assertEqual(2, result.vertices().size())
552554
self.assertEqual(2, result.edges().size())
553555

556+
def testRevolveErrors(self):
557+
"""
558+
Test that revolve raises errors when used incorrectly.
559+
"""
560+
result = Workplane("XY").lineTo(0, 10).lineTo(5, 0)
561+
with raises(ValueError):
562+
result.revolve()
563+
554564
def testSpline(self):
555565
"""
556566
Tests construction of splines
@@ -1040,6 +1050,11 @@ def testSweep(self):
10401050

10411051
self.assertAlmostEqual(v1.getAngle(v2), math.pi / 4, 6)
10421052

1053+
# test for ValueError if pending wires is empty
1054+
w0 = Workplane().hLine(1).vLine(1)
1055+
with raises(ValueError):
1056+
w0.sweep(path)
1057+
10431058
# Test aux spine invalid input handling
10441059
with raises(ValueError):
10451060
result = (
@@ -1655,10 +1670,13 @@ def testCutThroughAll(self):
16551670
self.assertTrue(r.val().isValid())
16561671
self.assertEqual(r.faces().size(), 7)
16571672

1658-
# test ValueError when no solids found
1659-
w0 = Workplane().hLine(1).vLine(1).close()
1673+
# test errors
1674+
box0 = Workplane().box(1, 1, 1).faces(">Z").workplane().hLine(1)
16601675
with raises(ValueError):
1661-
w0.cutThruAll()
1676+
box0.cutThruAll()
1677+
no_box = Workplane().hLine(1).vLine(1).close()
1678+
with raises(ValueError):
1679+
no_box.cutThruAll()
16621680

16631681
def testCutToFaceOffsetNOTIMPLEMENTEDYET(self):
16641682
"""
@@ -4290,3 +4308,8 @@ def testPopPending(self):
42904308
w4 = Workplane().circle(1).extrude(1)
42914309
with self.assertRaises(ValueError):
42924310
w4.ctx.popPendingWires()
4311+
4312+
# test via cutBlind
4313+
w5 = Workplane().circle(1).extrude(1)
4314+
with self.assertRaises(ValueError):
4315+
w5.cutBlind(-1)

0 commit comments

Comments
 (0)