@@ -93,6 +93,30 @@ def __init__(self):
93
93
self .tolerance = 0.0001 # user specified tolerance
94
94
self .tags = {}
95
95
96
+ def popPendingEdges (self , errorOnEmpty : bool = True ) -> List [Edge ]:
97
+ """
98
+ Get and clear pending edges.
99
+
100
+ :raises ValueError: if errorOnEmpty is True and no edges are present.
101
+ """
102
+ if errorOnEmpty and not self .pendingEdges :
103
+ raise ValueError ("No pending edges present" )
104
+ out = self .pendingEdges
105
+ self .pendingEdges = []
106
+ return out
107
+
108
+ def popPendingWires (self , errorOnEmpty : bool = True ) -> List [Wire ]:
109
+ """
110
+ Get and clear pending wires.
111
+
112
+ :raises ValueError: if errorOnEmpty is True and no wires are present.
113
+ """
114
+ if errorOnEmpty and not self .pendingWires :
115
+ raise ValueError ("No pending wires present" )
116
+ out = self .pendingWires
117
+ self .pendingWires = []
118
+ return out
119
+
96
120
97
121
class Workplane (object ):
98
122
"""
@@ -2099,6 +2123,8 @@ def _addPendingWire(self, wire: Wire) -> None:
2099
2123
2100
2124
def _consolidateWires (self ) -> List [Wire ]:
2101
2125
2126
+ # note: do not use CQContext.popPendingEdges or Wires here, this method does not
2127
+ # clear pending edges or wires.
2102
2128
wires = cast (
2103
2129
List [Union [Edge , Wire ]],
2104
2130
[el for el in chain (self .ctx .pendingEdges , self .ctx .pendingWires )],
@@ -2136,39 +2162,33 @@ def wire(self, forConstruction: bool = False) -> "Workplane":
2136
2162
Returns a CQ object with all pending edges connected into a wire.
2137
2163
2138
2164
All edges on the stack that can be combined will be combined into a single wire object,
2139
- and other objects will remain on the stack unmodified
2165
+ and other objects will remain on the stack unmodified. If there are no pending edges,
2166
+ this method will just return self.
2140
2167
2141
2168
:param forConstruction: whether the wire should be used to make a solid, or if it is just
2142
2169
for reference
2143
- :type forConstruction: boolean. true if the object is only for reference
2144
2170
2145
2171
This method is primarily of use to plugin developers making utilities for 2-d construction.
2146
2172
This method should be called when a user operation implies that 2-d construction is
2147
- finished, and we are ready to begin working in 3d
2173
+ finished, and we are ready to begin working in 3d.
2148
2174
2149
2175
SEE '2-d construction concepts' for a more detailed explanation of how CadQuery handles
2150
- edges, wires, etc
2176
+ edges, wires, etc.
2151
2177
2152
2178
Any non edges will still remain.
2153
2179
"""
2154
2180
2155
- edges = self .ctx .pendingEdges
2156
-
2157
2181
# do not consolidate if there are no free edges
2158
- if len (edges ) == 0 :
2182
+ if len (self . ctx . pendingEdges ) == 0 :
2159
2183
return self
2160
2184
2161
- self .ctx .pendingEdges = []
2162
-
2163
- others = []
2164
- for e in self .objects :
2165
- if type (e ) != Edge :
2166
- others .append (e )
2167
-
2185
+ edges = self .ctx .popPendingEdges ()
2168
2186
w = Wire .assembleEdges (edges )
2169
2187
if not forConstruction :
2170
2188
self ._addPendingWire (w )
2171
2189
2190
+ others = [e for e in self .objects if not isinstance (e , Edge )]
2191
+
2172
2192
return self .newObject (others + [w ])
2173
2193
2174
2194
def each (
@@ -2734,10 +2754,7 @@ def twistExtrude(
2734
2754
"""
2735
2755
# group wires together into faces based on which ones are inside the others
2736
2756
# result is a list of lists
2737
- wireSets = sortWiresByBuildOrder (list (self .ctx .pendingWires ))
2738
-
2739
- # now all of the wires have been used to create an extrusion
2740
- self .ctx .pendingWires = []
2757
+ wireSets = sortWiresByBuildOrder (self .ctx .popPendingWires ())
2741
2758
2742
2759
# compute extrusion vector and extrude
2743
2760
eDir = self .plane .zDir .multiply (distance )
@@ -3187,13 +3204,12 @@ def cutThruAll(self, clean: bool = True, taper: float = 0) -> "Workplane":
3187
3204
3188
3205
:param boolean clean: call :py:meth:`clean` afterwards to have a clean shape
3189
3206
:raises ValueError: if there is no solid to subtract from in the chain
3207
+ :raises ValueError: if there are no pending wires to cut with
3190
3208
:return: a CQ object with the resulting object selected
3191
3209
3192
3210
see :py:meth:`cutBlind` to cut material to a limited depth
3193
3211
"""
3194
- wires = self .ctx .pendingWires
3195
- self .ctx .pendingWires = []
3196
-
3212
+ wires = self .ctx .popPendingWires ()
3197
3213
solidRef = self .findSolid ()
3198
3214
3199
3215
rv = []
@@ -3214,8 +3230,7 @@ def loft(
3214
3230
Make a lofted solid, through the set of wires.
3215
3231
:return: a CQ object containing the created loft
3216
3232
"""
3217
- wiresToLoft = self .ctx .pendingWires
3218
- self .ctx .pendingWires = []
3233
+ wiresToLoft = self .ctx .popPendingWires ()
3219
3234
3220
3235
r : Shape = Solid .makeLoft (wiresToLoft , ruled )
3221
3236
@@ -3245,9 +3260,7 @@ def _extrude(
3245
3260
# group wires together into faces based on which ones are inside the others
3246
3261
# result is a list of lists
3247
3262
3248
- wireSets = sortWiresByBuildOrder (list (self .ctx .pendingWires ))
3249
- # now all of the wires have been used to create an extrusion
3250
- self .ctx .pendingWires = []
3263
+ wireSets = sortWiresByBuildOrder (self .ctx .popPendingWires ())
3251
3264
3252
3265
# compute extrusion vector and extrude
3253
3266
eDir = self .plane .zDir .multiply (distance )
@@ -3293,11 +3306,8 @@ def _revolve(
3293
3306
3294
3307
This method is a utility method, primarily for plugin and internal use.
3295
3308
"""
3296
- # We have to gather the wires to be revolved
3297
- wireSets = sortWiresByBuildOrder (list (self .ctx .pendingWires ))
3298
-
3299
- # Mark that all of the wires have been used to create a revolution
3300
- self .ctx .pendingWires = []
3309
+ # Get the wires to be revolved
3310
+ wireSets = sortWiresByBuildOrder (self .ctx .popPendingWires ())
3301
3311
3302
3312
# Revolve the wires, make a compound out of them and then fuse them
3303
3313
toFuse = []
@@ -3350,19 +3360,17 @@ def _sweep(
3350
3360
mode = wire
3351
3361
3352
3362
if not multisection :
3353
- wireSets = sortWiresByBuildOrder (list ( self .ctx .pendingWires ))
3363
+ wireSets = sortWiresByBuildOrder (self .ctx .popPendingWires ( ))
3354
3364
for ws in wireSets :
3355
3365
thisObj = Solid .sweep (
3356
3366
ws [0 ], ws [1 :], p , makeSolid , isFrenet , mode , transition
3357
3367
)
3358
3368
toFuse .append (thisObj )
3359
3369
else :
3360
- sections = self .ctx .pendingWires
3370
+ sections = self .ctx .popPendingWires ()
3361
3371
thisObj = Solid .sweep_multi (sections , p , makeSolid , isFrenet , mode )
3362
3372
toFuse .append (thisObj )
3363
3373
3364
- self .ctx .pendingWires = []
3365
-
3366
3374
return Compound .makeCompound (toFuse )
3367
3375
3368
3376
def interpPlate (
0 commit comments