diff --git a/src/Mod/Draft/CMakeLists.txt b/src/Mod/Draft/CMakeLists.txt index 5534384c65..cbbd07b302 100644 --- a/src/Mod/Draft/CMakeLists.txt +++ b/src/Mod/Draft/CMakeLists.txt @@ -41,6 +41,7 @@ SET (Draft_geoutils draftgeoutils/fillets.py draftgeoutils/offsets.py draftgeoutils/linear_algebra.py + draftgeoutils/cuboids.py ) SET(Draft_tests diff --git a/src/Mod/Draft/DraftGeomUtils.py b/src/Mod/Draft/DraftGeomUtils.py index 9a05027173..e0805ec34d 100644 --- a/src/Mod/Draft/DraftGeomUtils.py +++ b/src/Mod/Draft/DraftGeomUtils.py @@ -223,73 +223,10 @@ from draftgeoutils.faces import bind from draftgeoutils.faces import cleanFaces -def isCubic(shape): - """isCubic(shape): verifies if a shape is cubic, that is, has - 8 vertices, 6 faces, and all angles are 90 degrees.""" - # first we try fast methods - if len(shape.Vertexes) != 8: - return False - if len(shape.Faces) != 6: - return False - if len(shape.Edges) != 12: - return False - for e in shape.Edges: - if geomType(e) != "Line": - return False - # if ok until now, let's do more advanced testing - 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 not round(e1.getAngle(e2),precision()) in rpi: - return False - return True +from draftgeoutils.cuboids import isCubic -def getCubicDimensions(shape): - """getCubicDimensions(shape): returns a list containing the placement, - the length, the width and the height of a cubic shape. If not cubic, nothing - is returned. The placement point is the lowest corner of the shape.""" - if not isCubic(shape): return None - # determine lowest face, which will be our base - 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 - basenorm = base.normalAt(0.5,0.5) - # getting length and width - vx = vec(base.Edges[0]) - vy = vec(base.Edges[1]) - # getting rotations - rotZ = DraftVecUtils.angle(vx) - rotY = DraftVecUtils.angle(vx,FreeCAD.Vector(vx.x,vx.y,0)) - rotX = DraftVecUtils.angle(vy,FreeCAD.Vector(vy.x,vy.y,0)) - # getting height - 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) - # print(vtemp) - if round(vtemp.getAngle(vx),precision()) == rpi: - if round(vtemp.getAngle(vy),precision()) == rpi: - vz = vtemp - if not vz: return None - mat = FreeCAD.Matrix() - mat.move(plpoint) - mat.rotateX(rotX) - mat.rotateY(rotY) - mat.rotateZ(rotZ) - return [FreeCAD.Placement(mat),round(vx.Length,precision()),round(vy.Length,precision()),round(vz.Length,precision())] +from draftgeoutils.cuboids import getCubicDimensions from draftgeoutils.wires import removeInterVertices diff --git a/src/Mod/Draft/draftgeoutils/cuboids.py b/src/Mod/Draft/draftgeoutils/cuboids.py new file mode 100644 index 0000000000..4da70a84e5 --- /dev/null +++ b/src/Mod/Draft/draftgeoutils/cuboids.py @@ -0,0 +1,130 @@ +# *************************************************************************** +# * Copyright (c) 2009, 2010 Yorik van Havre * +# * Copyright (c) 2009, 2010 Ken Cline * +# * * +# * This file is part of the FreeCAD CAx development system. * +# * * +# * This program is free software; you can redistribute it and/or modify * +# * it under the terms of the GNU Lesser General Public License (LGPL) * +# * as published by the Free Software Foundation; either version 2 of * +# * the License, or (at your option) any later version. * +# * for detail see the LICENCE text file. * +# * * +# * FreeCAD is distributed in the hope that it will be useful, * +# * but WITHOUT ANY WARRANTY; without even the implied warranty of * +# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +# * GNU Library General Public License for more details. * +# * * +# * You should have received a copy of the GNU Library General Public * +# * License along with FreeCAD; if not, write to the Free Software * +# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +# * USA * +# * * +# *************************************************************************** +"""Provides various functions for cubic shapes (parallelepipeds).""" +## @package cuboids +# \ingroup DRAFTGEOUTILS +# \brief Provides various functions for 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. + """ + # first we try fast methods + 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 + + # if ok until now, let's do more advanced testing + 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 + + # determine lowest face, which will be our base + 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 + # basenorm = base.normalAt(0.5, 0.5) + + # getting length and width + vx = vec(base.Edges[0]) + vy = vec(base.Edges[1]) + + # getting rotations + 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)) + + # getting height + 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) + # print(vtemp) + 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())]