@@ -103,32 +103,58 @@ def testFaceTypesFilter(self):
103
103
def testPerpendicularDirFilter (self ):
104
104
c = CQ (makeUnitCube ())
105
105
106
- self .assertEqual (8 , c .edges ("#Z" ).size ()) # 8 edges are perp. to z
107
- self .assertEqual (4 , c .faces ("#Z" ).size ()) # 4 faces are perp to z too!
106
+ perp_edges = c .edges ("#Z" )
107
+ self .assertEqual (8 , perp_edges .size ()) # 8 edges are perp. to z
108
+ # dot product of perpendicular vectors is zero
109
+ for e in perp_edges .vals ():
110
+ self .assertAlmostEqual (e .tangentAt (0 ).dot (Vector (0 , 0 , 1 )), 0.0 )
111
+ perp_faces = c .faces ("#Z" )
112
+ self .assertEqual (4 , perp_faces .size ()) # 4 faces are perp to z too!
113
+ for f in perp_faces .vals ():
114
+ self .assertAlmostEqual (f .normalAt (None ).dot (Vector (0 , 0 , 1 )), 0.0 )
108
115
109
116
def testFaceDirFilter (self ):
110
117
c = CQ (makeUnitCube ())
111
118
# a cube has one face in each direction
112
119
self .assertEqual (1 , c .faces ("+Z" ).size ())
120
+ self .assertTupleAlmostEquals (
121
+ (0 , 0 , 1 ), c .faces ("+Z" ).val ().Center ().toTuple (), 3
122
+ )
113
123
self .assertEqual (1 , c .faces ("-Z" ).size ())
124
+ self .assertTupleAlmostEquals (
125
+ (0 , 0 , 0 ), c .faces ("-Z" ).val ().Center ().toTuple (), 3
126
+ )
114
127
self .assertEqual (1 , c .faces ("+X" ).size ())
115
- self .assertEqual (1 , c .faces ("X" ).size ()) # should be same as +X
128
+ self .assertTupleAlmostEquals (
129
+ (0.5 , 0 , 0.5 ), c .faces ("+X" ).val ().Center ().toTuple (), 3
130
+ )
116
131
self .assertEqual (1 , c .faces ("-X" ).size ())
132
+ self .assertTupleAlmostEquals (
133
+ (- 0.5 , 0 , 0.5 ), c .faces ("-X" ).val ().Center ().toTuple (), 3
134
+ )
117
135
self .assertEqual (1 , c .faces ("+Y" ).size ())
136
+ self .assertTupleAlmostEquals (
137
+ (0 , 0.5 , 0.5 ), c .faces ("+Y" ).val ().Center ().toTuple (), 3
138
+ )
118
139
self .assertEqual (1 , c .faces ("-Y" ).size ())
140
+ self .assertTupleAlmostEquals (
141
+ (0 , - 0.5 , 0.5 ), c .faces ("-Y" ).val ().Center ().toTuple (), 3
142
+ )
119
143
self .assertEqual (0 , c .faces ("XY" ).size ())
144
+ self .assertEqual (1 , c .faces ("X" ).size ()) # should be same as +X
120
145
self .assertEqual (c .faces ("+X" ).val ().Center (), c .faces ("X" ).val ().Center ())
121
146
self .assertNotEqual (c .faces ("+X" ).val ().Center (), c .faces ("-X" ).val ().Center ())
122
147
123
148
def testParallelPlaneFaceFilter (self ):
124
149
c = CQ (makeUnitCube ())
125
150
126
151
# faces parallel to Z axis
127
- self .assertEqual (2 , c .faces ("|Z" ).size ())
128
- # TODO: provide short names for ParallelDirSelector
129
- self .assertEqual (
130
- 2 , c .faces (selectors .ParallelDirSelector (Vector ((0 , 0 , 1 )))).size ()
131
- ) # same thing as above
152
+ # these two should produce the same behaviour:
153
+ for s in ["|Z" , selectors .ParallelDirSelector (Vector (0 , 0 , 1 ))]:
154
+ parallel_faces = c .faces (s )
155
+ self .assertEqual (2 , parallel_faces .size ())
156
+ for f in parallel_faces .vals ():
157
+ self .assertAlmostEqual (abs (f .normalAt (None ).dot (Vector (0 , 0 , 1 ))), 1 )
132
158
self .assertEqual (
133
159
2 , c .faces (selectors .ParallelDirSelector (Vector ((0 , 0 , - 1 )))).size ()
134
160
) # same thing as above
@@ -138,9 +164,15 @@ def testParallelPlaneFaceFilter(self):
138
164
139
165
def testParallelEdgeFilter (self ):
140
166
c = CQ (makeUnitCube ())
141
- self .assertEqual (4 , c .edges ("|Z" ).size ())
142
- self .assertEqual (4 , c .edges ("|X" ).size ())
143
- self .assertEqual (4 , c .edges ("|Y" ).size ())
167
+ for sel , vec in zip (
168
+ ["|X" , "|Y" , "|Z" ], [Vector (1 , 0 , 0 ), Vector (0 , 1 , 0 ), Vector (0 , 0 , 1 )]
169
+ ):
170
+ edges = c .edges (sel )
171
+ # each direction should have 4 edges
172
+ self .assertEqual (4 , edges .size ())
173
+ # each edge should be parallel with vec and have a cross product with a length of 0
174
+ for e in edges .vals ():
175
+ self .assertAlmostEqual (e .tangentAt (0 ).cross (vec ).Length , 0.0 )
144
176
145
177
def testMaxDistance (self ):
146
178
c = CQ (makeUnitCube ())
@@ -155,24 +187,28 @@ def testMaxDistance(self):
155
187
self .assertAlmostEqual (1.0 , v .Z , 3 )
156
188
157
189
# test the case of multiple objects at the same distance
158
- el = c .edges ("< Z" ).vals ()
190
+ el = c .edges ("> Z" ).vals ()
159
191
self .assertEqual (4 , len (el ))
192
+ for e in el :
193
+ self .assertAlmostEqual (e .Center ().z , 1 )
160
194
161
195
def testMinDistance (self ):
162
196
c = CQ (makeUnitCube ())
163
197
164
- # should select the topmost face
198
+ # should select the bottom face
165
199
self .assertEqual (1 , c .faces ("<Z" ).size ())
166
200
self .assertEqual (4 , c .faces ("<Z" ).vertices ().size ())
167
201
168
- # vertices should all be at z=1 , if this is the top face
202
+ # vertices should all be at z=0 , if this is the bottom face
169
203
self .assertEqual (4 , len (c .faces ("<Z" ).vertices ().vals ()))
170
204
for v in c .faces ("<Z" ).vertices ().vals ():
171
205
self .assertAlmostEqual (0.0 , v .Z , 3 )
172
206
173
207
# test the case of multiple objects at the same distance
174
208
el = c .edges ("<Z" ).vals ()
175
209
self .assertEqual (4 , len (el ))
210
+ for e in el :
211
+ self .assertAlmostEqual (e .Center ().z , 0 )
176
212
177
213
def testNthDistance (self ):
178
214
c = Workplane ("XY" ).pushPoints ([(- 2 , 0 ), (2 , 0 )]).box (1 , 1 , 1 )
@@ -252,20 +288,42 @@ def testNthDistance(self):
252
288
val = c .faces ("<Z[-2]" ).val ()
253
289
self .assertAlmostEqual (val .Center ().z , 1 )
254
290
291
+ # note that .val() will return the workplane center if the objects list
292
+ # is empty, so to make sure this test fails with a selector that
293
+ # selects nothing, use .vals()[0]
255
294
# verify that <Z[-1] is equivalent to <Z
256
- val1 = c .faces ("<Z[-1]" ).val ()
257
- val2 = c .faces ("<Z" ).val ()
295
+ val1 = c .faces ("<Z[-1]" ).vals ()[ 0 ]
296
+ val2 = c .faces ("<Z" ).vals ()[ 0 ]
258
297
self .assertTupleAlmostEquals (
259
298
val1 .Center ().toTuple (), val2 .Center ().toTuple (), 3
260
299
)
261
300
262
301
# verify that >Z[-1] is equivalent to >Z
263
- val1 = c .faces (">Z[-1]" ).val ()
264
- val2 = c .faces (">Z" ).val ()
302
+ val1 = c .faces (">Z[-1]" ).vals ()[ 0 ]
303
+ val2 = c .faces (">Z" ).vals ()[ 0 ]
265
304
self .assertTupleAlmostEquals (
266
305
val1 .Center ().toTuple (), val2 .Center ().toTuple (), 3
267
306
)
268
307
308
+ # DirectionNthSelector should not select faces that are not perpendicular
309
+ twisted_boxes = (
310
+ Workplane ()
311
+ .box (1 , 1 , 1 , centered = (True , True , False ))
312
+ .transformed (rotate = (45 , 0 , 0 ), offset = (0 , 0 , 3 ))
313
+ .box (1 , 1 , 1 )
314
+ )
315
+ self .assertTupleAlmostEquals (
316
+ twisted_boxes .faces (">Z[-1]" ).val ().Center ().toTuple (), (0 , 0 , 1 ), 3
317
+ )
318
+ # this should select a face on the upper/rotated cube, not the lower/unrotated cube
319
+ self .assertGreater (twisted_boxes .faces ("<(0, 1, 1)[-1]" ).val ().Center ().z , 1 )
320
+ # verify that >Z[-1] is equivalent to >Z
321
+ self .assertTupleAlmostEquals (
322
+ twisted_boxes .faces (">(0, 1, 1)[0]" ).vals ()[0 ].Center ().toTuple (),
323
+ twisted_boxes .faces ("<(0, 1, 1)[-1]" ).vals ()[0 ].Center ().toTuple (),
324
+ 3 ,
325
+ )
326
+
269
327
def testNearestTo (self ):
270
328
c = CQ (makeUnitCube (centered = False ))
271
329
@@ -453,22 +511,6 @@ def testRadiusNthSelector(self):
453
511
wire_circles .wires (selectors .RadiusNthSelector (1 )).val ().radius (), 4
454
512
)
455
513
456
- # a polygon with rounded corners has a radius, according to OCCT
457
- loop_wire = Wire .makePolygon (
458
- [Vector (- 10 , 0 , 0 ), Vector (0 , 10 , 0 ), Vector (10 , 0 , 0 ),]
459
- )
460
- loop_workplane = (
461
- Workplane ().add (loop_wire .offset2D (1 )).add (loop_wire .offset2D (2 ))
462
- )
463
- self .assertAlmostEqual (
464
- loop_workplane .wires (selectors .RadiusNthSelector (0 )).val ().radius (), 1.0
465
- )
466
- self .assertAlmostEqual (
467
- loop_workplane .wires (selectors .RadiusNthSelector (1 )).val ().radius (), 2.0
468
- )
469
- with self .assertRaises (IndexError ):
470
- loop_workplane .wires (selectors .RadiusNthSelector (2 ))
471
-
472
514
def testAndSelector (self ):
473
515
c = CQ (makeUnitCube ())
474
516
0 commit comments