4
4
from uuid import uuid1 as uuid
5
5
6
6
from .cq import Workplane
7
- from .occ_impl .shapes import Shape , Face , Edge
8
- from .occ_impl .geom import Location , Vector
7
+ from .occ_impl .shapes import Shape , Face , Edge , Wire
8
+ from .occ_impl .geom import Location , Vector , Plane
9
9
from .occ_impl .assembly import Color
10
10
from .occ_impl .solver import (
11
11
ConstraintSolver ,
18
18
19
19
# type definitions
20
20
AssemblyObjects = Union [Shape , Workplane , None ]
21
- ConstraintKinds = Literal ["Plane" , "Point" , "Axis" ]
21
+ ConstraintKinds = Literal ["Plane" , "Point" , "Axis" , "PointInPlane" ]
22
22
ExportLiterals = Literal ["STEP" , "XML" ]
23
23
24
24
PATH_DELIM = "/"
@@ -79,7 +79,7 @@ def __init__(
79
79
):
80
80
"""
81
81
Construct a constraint.
82
-
82
+
83
83
:param objects: object names refernced in the constraint
84
84
:param args: subshapes (e.g. faces or edges) of the objects
85
85
:param sublocs: locations of the objects (only relevant if the objects are nested in a sub-assembly)
@@ -106,14 +106,25 @@ def _getAxis(self, arg: Shape) -> Vector:
106
106
107
107
return rv
108
108
109
+ def _getPlane (self , arg : Shape ) -> Plane :
110
+
111
+ if isinstance (arg , Face ):
112
+ normal = arg .normalAt ()
113
+ elif isinstance (arg , (Edge , Wire )):
114
+ normal = arg .normal ()
115
+ else :
116
+ raise ValueError (f"Can not get normal from { arg } ." )
117
+ origin = arg .Center ()
118
+ return Plane (origin , normal = normal )
119
+
109
120
def toPOD (self ) -> ConstraintPOD :
110
121
"""
111
122
Convert the constraint to a representation used by the solver.
112
123
"""
113
124
114
125
rv : List [Tuple [ConstraintMarker , ...]] = []
115
126
116
- for arg , loc in zip (self .args , self .sublocs ):
127
+ for idx , ( arg , loc ) in enumerate ( zip (self .args , self .sublocs ) ):
117
128
118
129
arg = arg .located (loc * arg .location ())
119
130
@@ -123,6 +134,11 @@ def toPOD(self) -> ConstraintPOD:
123
134
rv .append ((arg .Center ().toPnt (),))
124
135
elif self .kind == "Plane" :
125
136
rv .append ((self ._getAxis (arg ).toDir (), arg .Center ().toPnt ()))
137
+ elif self .kind == "PointInPlane" :
138
+ if idx == 0 :
139
+ rv .append ((arg .Center ().toPnt (),))
140
+ else :
141
+ rv .append ((self ._getPlane (arg ).toPln (),))
126
142
else :
127
143
raise ValueError (f"Unknown constraint kind { self .kind } " )
128
144
@@ -157,22 +173,22 @@ def __init__(
157
173
"""
158
174
construct an assembly
159
175
160
- :param obj: root object of the assembly (deafault : None)
161
- :param loc: location of the root object (deafault : None, interpreted as identity transformation)
176
+ :param obj: root object of the assembly (default : None)
177
+ :param loc: location of the root object (default : None, interpreted as identity transformation)
162
178
:param name: unique name of the root object (default: None, reasulting in an UUID being generated)
163
179
:param color: color of the added object (default: None)
164
180
:return: An Assembly object.
165
-
166
-
181
+
182
+
167
183
To create an empty assembly use::
168
-
184
+
169
185
assy = Assembly(None)
170
-
186
+
171
187
To create one constraint a root object::
172
-
188
+
173
189
b = Workplane().box(1,1,1)
174
190
assy = Assembly(b, Location(Vector(0,0,1)), name="root")
175
-
191
+
176
192
"""
177
193
178
194
self .obj = obj
@@ -211,12 +227,15 @@ def add(
211
227
color : Optional [Color ] = None ,
212
228
) -> "Assembly" :
213
229
"""
214
- add a subassembly to the current assembly.
215
-
230
+ Add a subassembly to the current assembly.
231
+
216
232
:param obj: subassembly to be added
217
- :param loc: location of the root object (deafault: None, resulting in the location stored in the subassembly being used)
218
- :param name: unique name of the root object (default: None, resulting in the name stored in the subassembly being used)
219
- :param color: color of the added object (default: None, resulting in the color stored in the subassembly being used)
233
+ :param loc: location of the root object (default: None, resulting in the location stored in
234
+ the subassembly being used)
235
+ :param name: unique name of the root object (default: None, resulting in the name stored in
236
+ the subassembly being used)
237
+ :param color: color of the added object (default: None, resulting in the color stored in the
238
+ subassembly being used)
220
239
"""
221
240
...
222
241
@@ -229,18 +248,20 @@ def add(
229
248
color : Optional [Color ] = None ,
230
249
) -> "Assembly" :
231
250
"""
232
- add a subassembly to the current assembly with explicit location and name
233
-
251
+ Add a subassembly to the current assembly with explicit location and name.
252
+
234
253
:param obj: object to be added as a subassembly
235
- :param loc: location of the root object (deafault: None, interpreted as identity transformation)
236
- :param name: unique name of the root object (default: None, resulting in an UUID being generated)
254
+ :param loc: location of the root object (default: None, interpreted as identity
255
+ transformation)
256
+ :param name: unique name of the root object (default: None, resulting in an UUID being
257
+ generated)
237
258
:param color: color of the added object (default: None)
238
259
"""
239
260
...
240
261
241
262
def add (self , arg , ** kwargs ):
242
263
"""
243
- add a subassembly to the current assembly.
264
+ Add a subassembly to the current assembly.
244
265
"""
245
266
246
267
if isinstance (arg , Assembly ):
@@ -270,18 +291,18 @@ def add(self, arg, **kwargs):
270
291
271
292
def _query (self , q : str ) -> Tuple [str , Optional [Shape ]]:
272
293
"""
273
- Execute a selector query on the assembly.
294
+ Execute a selector query on the assembly.
274
295
The query is expected to be in the following format:
275
-
296
+
276
297
name[?tag][@kind@args]
277
-
298
+
278
299
valid example include:
279
-
300
+
280
301
obj_name @ faces @ >Z
281
- obj_name?tag1@faces@>Z
302
+ obj_name?tag1@faces@>Z
282
303
obj_name ? tag
283
304
obj_name
284
-
305
+
285
306
"""
286
307
287
308
tmp : Workplane
@@ -311,7 +332,7 @@ def _query(self, q: str) -> Tuple[str, Optional[Shape]]:
311
332
def _subloc (self , name : str ) -> Tuple [Location , str ]:
312
333
"""
313
334
Calculate relative location of an object in a subassembly.
314
-
335
+
315
336
Returns the relative posiitons as well as the name of the top assembly.
316
337
"""
317
338
@@ -422,9 +443,9 @@ def save(
422
443
) -> "Assembly" :
423
444
"""
424
445
save as STEP or OCCT native XML file
425
-
446
+
426
447
:param path: filepath
427
- :param exportType: export format (deafault : None, results in format being inferred form the path)
448
+ :param exportType: export format (default : None, results in format being inferred form the path)
428
449
"""
429
450
430
451
if exportType is None :
0 commit comments