1
2 from empro.geometry import *
3 import math
4 import string
5 import base64
6 import tempfile
7
8
15
17 __translate(iObject, iVector)
18 return iObject
19
31
37
44
50
53
54 -def scale(iObject,iFactor):
55 if isinstance(iObject, Assembly):
56 for i in range(len(iObject)):
57 scale(iObject[i], iFactor)
58 else:
59 return iObject.scale(iFactor)
60
61
63 """
64 Wire(iFrom, iTo)
65 Returns a straight wire object.
66 @type iFrom: L{Vector3d}
67 @param iFrom: start point of the wire
68 @type iTo: L{Vector3d}
69 @param iTo: end point of the wire
70 @rtype: L{Part}
71 @return: the wire object as L{Part}
72 """
73 s = Sketch()
74 s.add(Line(iFrom,iTo))
75 return s
76
78 s = Sketch()
79 lines = []
80 corners = [Vector3d(iFrom.x,iFrom.y,0),Vector3d(iTo.x,iFrom.y,0),
81 Vector3d(iTo.x,iTo.y,0),Vector3d(iFrom.x,iTo.y,0)]
82 for i in range(len(corners)):
83 s.addEdge(Line(corners[i-1],corners[i]))
84 extrude = Extrude(s,iTo.z-iFrom.z)
85 m = Model()
86 m.recipe = Recipe()
87 m.recipe.append(extrude)
88 m.coordinateSystem.translate(Vector3d(0,0,iFrom.z))
89 return m
90
91
93 """
94 Block(iFrom, iTo)
95 Returns a rectangular block defined by the two opposing points iFrom and iTo.
96 @type iFrom: L{Vector3d}
97 @param iFrom: first corner of the rectangular block
98 @type iTo: L{Vector3d}
99 @param iTo: opposing point of the rectangular block
100 @rtype: L{Model}
101 @return: the rectangular block
102 """
103 return __zBlock(iFrom,iTo)
104
105 -def xCylinder(iInnerRadius, iOuterRadius, iBottomCenter, iHeight):
106 """
107 xCylinder(iInnerRadius, iOuterRadius, iBottomCenter, iHeight)
108 Returns a cylinder whose axis is X-directed.
109 @type iInnerRadius: float
110 @param iInnerRadius: inner radius of the cylinder
111 @type iOuterRadius: float
112 @param iOuterRadius: outer radius of the cylinder
113 @type iBottomCenter: L{Vector3d}
114 @param iBottomCenter: center of the bottom of the cylinder
115 @type iHeight: float
116 @param iHeight: height of the cylinder
117 @rtype: L{Part}
118 @return: the cylinder as L{Part}
119 """
120 m = zCylinder(iInnerRadius, iOuterRadius, iBottomCenter, iHeight)
121 m.coordinateSystem.rotate(0.0,math.pi/2.0,0.0)
122 return m
123
124 -def yCylinder(iInnerRadius, iOuterRadius, iBottomCenter, iHeight):
125 """
126 yCylinder(iInnerRadius, iOuterRadius, iBottomCenter, iHeight)
127 Returns a cylinder whose axis is Y-directed.
128 @type iInnerRadius: float
129 @param iInnerRadius: inner radius of the cylinder
130 @type iOuterRadius: float
131 @param iOuterRadius: outer radius of the cylinder
132 @type iBottomCenter: L{Vector3d}
133 @param iBottomCenter: center of the bottom of the cylinder
134 @type iHeight: float
135 @param iHeight: height of the cylinder
136 @rtype: L{Part}
137 @return: the cylinder as L{Part}
138 """
139 m = zCylinder(iInnerRadius, iOuterRadius, iBottomCenter, iHeight)
140 m.coordinateSystem.rotate(math.pi/2.0,0.0,0.0)
141 return m
142
143 -def zCylinder(iInnerRadius, iOuterRadius, iBottomCenter, iHeight):
144 """
145 zCylinder(iInnerRadius, iOuterRadius, iBottomCenter, iHeight)
146 Returns a cylinder whose axis is Z-directed.
147 @type iInnerRadius: float
148 @param iInnerRadius: inner radius of the cylinder
149 @type iOuterRadius: float
150 @param iOuterRadius: outer radius of the cylinder
151 @type iBottomCenter: L{Vector3d}
152 @param iBottomCenter: center of the bottom of the cylinder
153 @type iHeight: float
154 @param iHeight: height of the cylinder
155 @rtype: L{Part}
156 @return: the cylinder as L{Part}
157 """
158 import empro
159 m = Model()
160 m.recipe = Recipe()
161 irValue = float(empro.core.Expression(iInnerRadius))
162 if irValue > 0.0 :
163 s = Sketch()
164 bottomCenter = Vector3d(0.0,0.0,0.0)
165 s.addEdge( zCircle(bottomCenter, iInnerRadius) )
166 s.addEdge( zCircle(bottomCenter, iOuterRadius) )
167 sweep = Extrude( s, iHeight )
168 m.recipe.append( sweep )
169 else :
170 libcmpnt = empro.geometry.Cylinder(iHeight, iOuterRadius, iOuterRadius)
171 m.recipe.append(libcmpnt)
172 m.coordinateSystem.translate(Vector3d(iBottomCenter.x,iBottomCenter.y,iBottomCenter.z))
173 return m
174
175
176
177
178 -def xCylinderFaceted(iInnerRadius, iOuterRadius, iBottomCenter, iHeight,iDivisions = 32):
179 """
180 yCylinderFaceted(iInnerRadius, iOuterRadius, iBottomCenter, iHeight, iDivisions)
181 Creates a regular polygonal prism with primary axis along the x-axis.
182 @type iInnerRadius: float
183 @param iInnerRadius: inner radius of the cylinder
184 @type iOuterRadius: float
185 @param iOuterRadius: outer radius of the cylinder
186 @type iBottomCenter: L{Vector3d}
187 @param iBottomCenter: center of the bottom of the cylinder
188 @type iHeight: float
189 @param iHeight: height of the cylinder
190 @param iDivisions: the number of divisions to use for the cylinder
191 @type iDivisions: int
192 @rtype: L{Part}
193 @return: the prism as L{Part}
194 """
195 m = zCylinderFaceted(iInnerRadius, iOuterRadius, iBottomCenter, iHeight)
196 m.coordinateSystem.rotate(0.0,math.pi/2.0,0.0)
197 return m
198
199
200 -def yCylinderFaceted(iInnerRadius, iOuterRadius, iBottomCenter, iHeight,iDivisions = 32):
201 """
202 yCylinderFaceted(iInnerRadius, iOuterRadius, iBottomCenter, iHeight, iDivisions)
203 Creates a regular polygonal prism with primary axis along the y-axis.
204 @type iInnerRadius: float
205 @param iInnerRadius: inner radius of the cylinder
206 @type iOuterRadius: float
207 @param iOuterRadius: outer radius of the cylinder
208 @type iBottomCenter: L{Vector3d}
209 @param iBottomCenter: center of the bottom of the cylinder
210 @type iHeight: float
211 @param iHeight: height of the cylinder
212 @param iDivisions: the number of divisions to use for the cylinder
213 @type iDivisions: int
214 @rtype: L{Part}
215 @return: the prism as L{Part}
216 """
217 m = zCylinderFaceted(iInnerRadius, iOuterRadius, iBottomCenter, iHeight)
218 m.coordinateSystem.rotate(math.pi/2.0,0.0,0.0)
219 return m
220
221
223 divisions = max(3,iDivisions)
224 iRadius = max(0.00000001,iRadius)
225 thetas = [i * 2 * math.pi / float(divisions) for i in range(iDivisions)]
226 return [Vector3d(iRadius * math.cos(theta), iRadius * math.sin(theta), 0) for theta in thetas]
227
228
230 tails = iPoints
231 heads = iPoints[1:] + [iPoints[0]]
232 for tail, head in zip(tails, heads):
233 iSketch.add(Line(tail, head))
234
235
236 -def zCylinderFaceted(iInnerRadius, iOuterRadius, iBottomCenter, iHeight, iDivisions = 32):
237 """
238 zCylinderFaceted(iInnerRadius, iOuterRadius, iBottomCenter, iHeight, iDivisions)
239 Creates a regular polygonal prism with primary axis along the z-axis.
240 @type iInnerRadius: float
241 @param iInnerRadius: inner radius of the cylinder
242 @type iOuterRadius: float
243 @param iOuterRadius: outer radius of the cylinder
244 @type iBottomCenter: L{Vector3d}
245 @param iBottomCenter: center of the bottom of the cylinder
246 @type iHeight: float
247 @param iHeight: height of the cylinder
248 @param iDivisions: the number of divisions to use for the cylinder
249 @type iDivisions: int
250 @rtype: L{Part}
251 @return: the prism as L{Part}
252 """
253 import empro
254 m = Model()
255 m.recipe = Recipe()
256 orValue = float(empro.core.Expression(iOuterRadius))
257 irValue = float(empro.core.Expression(iInnerRadius))
258 idivValue = int(empro.core.Expression(iDivisions))
259 if irValue > 0.0 :
260 s = Sketch()
261 bottomCenter = Vector3d(0.0,0.0,0.0)
262 __addPolyToSketch(s, __regularPoly( bottomCenter, orValue, idivValue))
263 __addPolyToSketch(s, __regularPoly( bottomCenter, irValue, idivValue))
264 iHeight = max(0.00000001,iHeight)
265 prism = Extrude(s,iHeight)
266 m.recipe.append( prism )
267 else :
268 libcmpnt = empro.geometry.Prism( iHeight, iOuterRadius, iOuterRadius, iDivisions)
269 m.recipe.append(libcmpnt)
270 angle = math.pi/idivValue
271 m.coordinateSystem.rotate(0.0,0.0,angle)
272 m.coordinateSystem.translate(Vector3d(iBottomCenter.x,iBottomCenter.y,iBottomCenter.z))
273 return m
274
275
277 """
278 xRegularPolygonalPrism(iBottomCenter, iRadius, iHeight, iDivisions)
279 Creates a regular polygonal prism with primary axis along the X-axis.
280 @type iBottomCenter: L{Vector3d}
281 @param iBottomCenter: the center of the bottom of the prism
282 @type iRadius: float
283 @param iRadius: the radius where the vertices of the regular polygon are placed
284 @type iHeight: float
285 @param iHeight: the height of the prism
286 @param iDivisions: the number of divisions to use for the prism
287 @type iDivisions: int
288 @rtype: L{Part}
289 @return: the prism as L{Part}
290 """
291 m = zRegularPolygonalPrism(iBottomCenter, iRadius, iHeight, iDivisions)
292 m.coordinateSystem.rotate(0.0,math.pi/2.0,0.0)
293 return m
294
296 """
297 yRegularPolygonalPrism(iBottomCenter, iRadius, iHeight, iDivisions)
298 Creates a regular polygonal prism with primary axis along the Y-axis.
299 @type iBottomCenter: L{Vector3d}
300 @param iBottomCenter: the center of the bottom of the prism
301 @type iRadius: float
302 @param iRadius: the radius where the vertices of the regular polygon are placed
303 @type iHeight: float
304 @param iHeight: the height of the prism
305 @param iDivisions: the number of divisions to use for the prism
306 @type iDivisions: int
307 @rtype: L{Part}
308 @return: the prism as L{Part}
309 """
310 m = zRegularPolygonalPrism(iBottomCenter, iRadius, iHeight, iDivisions)
311 m.coordinateSystem.rotate(math.pi/2.0,0.0,0.0)
312 return m
313
315 """
316 zRegularPolygonalPrism(iBottomCenter, iRadius, iHeight, iDivisions)
317 Creates a regular polygonal prism with primary axis along the z-axis.
318 @type iBottomCenter: L{Vector3d}
319 @param iBottomCenter: the center of the bottom of the prism
320 @type iRadius: float
321 @param iRadius: the radius where the vertices of the regular polygon are placed
322 @type iHeight: float
323 @param iHeight: the height of the prism
324 @param iDivisions: the number of divisions to use for the prism
325 @type iDivisions: int
326 @rtype: L{Part}
327 @return: the prism as L{Part}
328 """
329 import empro
330 libcmpnt = empro.geometry.Prism( iHeight, iRadius, iRadius, iDivisions)
331 m = Model()
332 m.recipe = Recipe()
333 m.recipe.append(libcmpnt)
334 idivValue = int(empro.core.Expression(iDivisions))
335 angle = math.pi/idivValue
336 m.coordinateSystem.rotate(0.0,0.0,angle)
337 m.coordinateSystem.translate(Vector3d(iBottomCenter.x,iBottomCenter.y,iBottomCenter.z))
338 return m
339
340
341 -def plateXY(iCenter, iDeltaX, iDeltaY, iName = "PlateXY"):
342 """
343 plateXY(iCenter, iDeltaX, iDeltaY)
344 plateXY(iCenter, iDeltaX, iDeltaY, iName)
345 Returns a rectangular plate parallel to the XY-plane.
346 @type iCenter: L{Vector3d}
347 @param iCenter: the center of the plate
348 @type iDeltaX: float
349 @param iDeltaX: the width of the plate along the X-axis
350 @type iDeltaY: float
351 @param iDeltaY: the width of the plate along the Y-axis
352 @type iName: string
353 @param iName: the name of the plate (Default = "PlateXY")
354 @rtype: L{Part}
355 @return: the plate as L{Part}
356 """
357 V = Vector3d
358 p1 = iCenter + V(-iDeltaX/2.0,-iDeltaY/2,0.0)
359 p2 = iCenter + V(-iDeltaX/2.0,iDeltaY/2,0.0)
360 p3 = iCenter + V(iDeltaX/2.0,iDeltaY/2,0.0)
361 p4 = iCenter + V(iDeltaX/2.0,-iDeltaY/2,0.0)
362 return PolyPlate([p1, p2, p3, p4], iName)
363
364
365 -def plateZX(iCenter, iDeltaZ, iDeltaX, iName = "PlateZX"):
366 """
367 plateZX(iCenter, iDeltaZ, iDeltaX)
368 plateZX(iCenter, iDeltaZ, iDeltaX, iName)
369 Returns a rectangular plate parallel to the ZX-plane.
370 @type iCenter: L{Vector3d}
371 @param iCenter: the center of the plate
372 @type iDeltaZ: float
373 @param iDeltaZ: the width of the plate along the Z-axis
374 @type iDeltaX: float
375 @param iDeltaX: the width of the plate along the X-axis
376 @type iName: string
377 @param iName: the name of the plate (Default = "PlateZX")
378 @rtype: L{Part}
379 @return: the plate as L{Part}
380 """
381
382 V = Vector3d
383 p1 = iCenter + V(-iDeltaX/2.0,0.0,-iDeltaZ/2)
384 p2 = iCenter + V(-iDeltaX/2.0,0.0,iDeltaZ/2)
385 p3 = iCenter + V(iDeltaX/2.0,0.0,iDeltaZ/2)
386 p4 = iCenter + V(iDeltaX/2.0,0.0,-iDeltaZ/2)
387 return PolyPlate([p1, p2, p3, p4], iName)
388
389 -def plateYZ(iCenter, iDeltaY, iDeltaZ, iName = "PlateYZ"):
390 """
391 plateYZ(iCenter, iDeltaY, iDeltaZ)
392 plateYZ(iCenter, iDeltaY, iDeltaZ, iName)
393 Returns a rectangular plate parallel to the YZ-plane.
394 @type iCenter: L{Vector3d}
395 @param iCenter: the center of the plate
396 @type iDeltaY: float
397 @param iDeltaY: the width of the plate along the Y-axis
398 @type iDeltaZ: float
399 @param iDeltaZ: the width of the plate along the Z-axis
400 @type iName: string
401 @param iName: the name of the plate (Default = "PlateYZ")
402 @rtype: L{Part}
403 @return: the plate as L{Part}
404 """
405
406 V = Vector3d
407 p1 = iCenter + V(0.0,-iDeltaY/2.0,-iDeltaZ/2)
408 p2 = iCenter + V(0.0,-iDeltaY/2.0,iDeltaZ/2)
409 p3 = iCenter + V(0.0,iDeltaY/2.0,iDeltaZ/2)
410 p4 = iCenter + V(0.0,iDeltaY/2.0,-iDeltaZ/2)
411 return PolyPlate([p1, p2, p3, p4], iName)
412
413
415 """
416 zCircle(iCenter,iRadius)
417 Returns a circle parallel to the XY-plane.
418 @type iCenter: L{Vector3d}
419 @param iCenter: the center of the circle
420 @type iRadius: float
421 @param iRadius: the radius of the circle
422 @rtype: L{Part}
423 @return: the circle as L{Part}
424 """
425 return Ellipse( iCenter, Vector3d(iRadius,0,iCenter.z), 1.0, 0.0, 2.0*math.pi )
426
427 -def QuadPlate(iPoint1, iPoint2, iPoint3, iPoint4, iName="QuadPlate"):
428 """
429 QuadPlate(iPoint1,iPoint2,iPoint3,iPoint4)
430 QuadPlate(iPoint1,iPoint2,iPoint3,iPoint4,iName)
431 Returns a plate defined by four points.
432 @type iPoint1: L{Vector3d}
433 @param iPoint1: the first point of the plate
434 @type iPoint2: L{Vector3d}
435 @param iPoint2: the second point of the plate
436 @type iPoint3: L{Vector3d}
437 @param iPoint3: the third point of the plate
438 @type iPoint4: L{Vector3d}
439 @param iPoint4: the fourth point of the plate
440 @type iName: string
441 @param iName: the name of the plate (Default = "QuadPlate")
442 @rtype: L{Part}
443 @return: the plate as L{Part}
444 """
445 return PolyPlate([iPoint1, iPoint2, iPoint3, iPoint4], iName)
446
448 """
449 PolyPlate([iPoint1, iPoint2, ...])
450 PolyPlate([iPoint1, iPoint2, ...], iName)
451 Returns a plate defined by a polygon
452 @type iPoints: list<L{Vector3d}>
453 @param iPoints: a sequence of polygon vertices.
454 @type iName: string
455 @param iName: the name of the plate (Default = "PolyPlate")
456 @rtype: L{Part}
457 @return: the plate as L{Part}
458 """
459 import empro
460 tails = iPoints
461 heads = iPoints[1:] + [iPoints[0]]
462 edges = []
463 for tail, head in zip(tails, heads):
464 edges.append( empro.acis.EDGE.curveLine( _toTuple(tail), _toTuple(head) ))
465 body, wires = empro.acis._coverPlanarEdges(edges,0)
466 m = empro.geometry.Model()
467 m.recipe.append( empro.geometry.ImportedCadEntity( body ) )
468 m.name = iName
469 return m
470
475
477 """
478 PolySketch([iPoint1, iPoint2, ...])
479 PolySketch([iPoint1, iPoint2, ...], iName)
480 Returns a sketch defined by a polygon
481 @type iPoints: list<L{Vector3d}>
482 @param iPoints: a sequence of polygon vertices.
483 @type iName: string
484 @param iName: the name of the sketch (Default = "PolySketch")
485 @rtype: L{Sketch}
486 @return: polygonal sketch
487 """
488 sketch = Sketch()
489 sketch.name = iName
490 __addPolyToSketch(sketch, iPoints)
491 return sketch
492
493
494 -def sheetBody(iSketch, iName = None):
495 iName = iName or iSketch.name
496 m = Model()
497 m.name = iName
498 m.recipe = Recipe()
499 m.recipe.name = iName
500 c = Cover(iSketch)
501 c.name = iName
502 m.recipe.append(c)
503 return m
504
505
512
513
515 import empro
516 desc3d = ""
517 (tf,tfn) = tempfile.mkstemp()
518 prevUnit = iDObject.unit
519 iObject = iDObject.clone()
520 __matchCoordinateSystems(iDObject,iObject)
521 canonicalUnit(iObject)
522 iObject.unit = empro.units.unitByAbbreviation("m")
523 iObject.exportToSAT(tfn)
524 iObject.unit = prevUnit
525
526 f = open(tfn,"r")
527 text = "".join(f.readlines())
528 f.close()
529 return base64.b64encode(text)
530
532 import empro
533 desc3d = ""
534 (tf,tfn) = tempfile.mkstemp()
535 prevUnit = iDObject.unit
536 iObject = iDObject.clone()
537 __matchCoordinateSystems(iDObject,iObject)
538 canonicalUnit(iObject)
539 iObject.unit = empro.units.unitByAbbreviation("m")
540 iObject.exportFaceToSAT(iFace,tfn)
541 iObject.unit = prevUnit
542
543 f = open(tfn,"r")
544 text = "".join(f.readlines())
545 f.close()
546 return base64.b64encode(text)
547
548
550 temp = []
551 if isinstance(iObject,Assembly):
552 for i in range(len(iObject)):
553 if iFilter:
554 if iFilter(iObject[i]):
555 temp += materialsUsedBy(iObject[i])
556 else:
557 temp += materialsUsedBy(iObject[i])
558 else:
559 temp.append(iObject.material)
560 return temp
561
562
564 temp = __materialsUsedBy(iObject,iFilter)
565 r = []
566 tempSet = set()
567 for m in temp:
568 if m!=None:
569 if not m.hash() in tempSet:
570 r.append(m)
571 tempSet.add(m.hash())
572 return r
573
574
587
589 """
590 sliceXY(iObject, zHeight)
591 Computes a slice of iObject at height zHeight.
592 @type iObject: L{Part}
593 @param iObject: a part that can be an L{Assembly} that needs to be sliced
594 @type zHeight: float
595 @param zHeight: the height at which the slice is to be taken
596 @rtype: L{Part}
597 @return: the slice as L{Part}
598 """
599 slices = []
600 if isinstance(iObject,Assembly):
601 for i in range(len(iObject)):
602 __sliceXY(iObject[i],zHeight,slices)
603 else:
604 __sliceXY(iObject,zHeight,slices)
605 if len(slices)==0:
606 return None
607 if len(slices)==1:
608 return slices[0]
609 assemb = Assembly()
610 for s in slices:
611 assemb.append(s)
612 return assemb
613
623 newFacet = [iPart.coordinateSystem.transformPosition(vec(facet[t]),"LocalToGlobal") for t in [0,1,2]]
624 newFacets.append(newFacet)
625 newAbsFacets.append( (facetName, newFacets) )
626 return newAbsFacets
627
629 """
630 absoluteFacets. Only for internal usage.
631 """
632 totalSetOfFacets = []
633 if isinstance(iObject,Assembly):
634 for i in range(len(iObject)):
635 totalSetOfFacets += __absoluteFacets(iObject[i])
636 else:
637 totalSetOfFacets = __absoluteFacets(iObject)
638 return totalSetOfFacets
639
640
642 """
643 assemblyFlatListInOrder(iAssembly)
644 Returns a flat list of all parts (excluding assemblies) in order as they appear in the project tree.
645 @type iObject: L{Part}
646 @param iObject: a part that can be an L{Assembly} that needs to be flat listed
647 @rtype: list<L{Part}>
648 @return: the ordered list of L{Part}'s
649 """
650 ret = []
651 if issubclass(type(iAss),Assembly):
652 for i in range(len(iAss)):
653 ret += assemblyFlatListInOrder(iAss[i])
654 elif issubclass(type(iAss), OaLayout):
655 ret += assemblyFlatListInOrder(iAss._assembly)
656 else:
657 ret = [iAss]
658 return ret
659
685
686
709