| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | """Provides various functions to work with cubic shapes (parallelepipeds).""" |
| | |
| | |
| | |
| |
|
| | |
| | |
| | import math |
| |
|
| | import FreeCAD as App |
| | import DraftVecUtils |
| |
|
| | from draftgeoutils.general import geomType, vec, precision |
| |
|
| |
|
| | def isCubic(shape): |
| | """Return True if the shape is a parallelepiped (cuboid). |
| | |
| | A parallelepiped of cube-like shape has 8 vertices, 6 faces, 12 edges, |
| | and all angles are 90 degrees between its edges. |
| | """ |
| | |
| | if len(shape.Vertexes) != 8 or len(shape.Faces) != 6 or len(shape.Edges) != 12: |
| | return False |
| |
|
| | for e in shape.Edges: |
| | if geomType(e) != "Line": |
| | return False |
| |
|
| | |
| | for f in shape.Faces: |
| | if len(f.Edges) != 4: |
| | return False |
| |
|
| | for i in range(4): |
| | e1 = vec(f.Edges[i]) |
| | if i < 3: |
| | e2 = vec(f.Edges[i + 1]) |
| | else: |
| | e2 = vec(f.Edges[0]) |
| | rpi = [0.0, round(math.pi / 2, precision())] |
| | if round(e1.getAngle(e2), precision()) not in rpi: |
| | return False |
| |
|
| | return True |
| |
|
| |
|
| | def getCubicDimensions(shape): |
| | """Return a list containing the placement, and dimensions of the shape. |
| | |
| | The dimensios are length, width and height of a the parallelepiped, |
| | rounded to the value indicated by `precision`. |
| | The placement point is the lowest corner of the shape. |
| | |
| | If it is not a parallelepiped (cuboid), return None. |
| | """ |
| | if not isCubic(shape): |
| | return None |
| |
|
| | |
| | z = [10, 1000000000000] |
| | for i in range(len(shape.Faces)): |
| | if shape.Faces[i].CenterOfMass.z < z[1]: |
| | z = [i, shape.Faces[i].CenterOfMass.z] |
| |
|
| | if z[0] > 5: |
| | return None |
| |
|
| | base = shape.Faces[z[0]] |
| | basepoint = base.Edges[0].Vertexes[0].Point |
| | plpoint = base.CenterOfMass |
| | |
| |
|
| | |
| | vx = vec(base.Edges[0]) |
| | vy = vec(base.Edges[1]) |
| | if round(vx.Length) == round(vy.Length): |
| | vy = vec(base.Edges[2]) |
| |
|
| | |
| | rotZ = DraftVecUtils.angle(vx) |
| | rotY = DraftVecUtils.angle(vx, App.Vector(vx.x, vx.y, 0)) |
| | rotX = DraftVecUtils.angle(vy, App.Vector(vy.x, vy.y, 0)) |
| |
|
| | |
| | vz = None |
| | rpi = round(math.pi / 2, precision()) |
| | for i in range(1, 6): |
| | for e in shape.Faces[i].Edges: |
| | if basepoint in [e.Vertexes[0].Point, e.Vertexes[1].Point]: |
| | vtemp = vec(e) |
| | |
| | if round(vtemp.getAngle(vx), precision()) == rpi: |
| | if round(vtemp.getAngle(vy), precision()) == rpi: |
| | vz = vtemp |
| |
|
| | if not vz: |
| | return None |
| |
|
| | mat = App.Matrix() |
| | mat.move(plpoint) |
| | mat.rotateX(rotX) |
| | mat.rotateY(rotY) |
| | mat.rotateZ(rotZ) |
| |
|
| | return [ |
| | App.Placement(mat), |
| | round(vx.Length, precision()), |
| | round(vy.Length, precision()), |
| | round(vz.Length, precision()), |
| | ] |
| |
|
| |
|
| | |
| |
|