''' Collection of helper function to extract geometry properties from OCC elements Most of the functions are borrowed directly from assembly2lib.py or lib3D.py in assembly2 ''' import FreeCAD, FreeCADGui, Part import numpy import asm3.FCADLogger logger = asm3.FCADLogger.FCADLogger('assembly3') def objName(obj): if obj.Label == obj.Name: return obj.Name return '{}({})'.format(obj.Name,obj.Label) def isLine(param): if hasattr(Part,"LineSegment"): return isinstance(param,(Part.Line,Part.LineSegment)) else: return isinstance(param,Part.Line) def getElement(obj,tp): if isinstance(obj,tuple): obj = obj[0].getSubObject(obj[1]) if not isinstance(obj,Part.Shape): return if obj.isNull() or not tp: return if tp == 'Vertex': vertexes = obj.Vertexes if len(vertexes)==1 and not obj.Edges: return vertexes[0] elif tp == 'Edge': edges = obj.Edges if len(edges)==1 and not obj.Faces: return edges[0] elif tp == 'Face': faces = obj.Faces if len(faces)==1: return faces[0] def isPlane(obj): face = getElement(obj,'Face') if not face: return False elif str(face.Surface) == '': return True elif hasattr(face.Surface,'Radius'): return False elif str(face.Surface).startswith('': return False else: _axis,_center,error=fit_rotation_axis_to_surface1(face.Surface) error_normalized = error / face.BoundBox.DiagonalLength return error_normalized < 10**-6 def isAxisOfPlane(obj): face = getElement(obj,'Face') if not face: return False if str(face.Surface) == '': return True else: _axis,_center,error=fit_rotation_axis_to_surface1(face.Surface) error_normalized = error / face.BoundBox.DiagonalLength return error_normalized < 10**-6 def isCircularEdge(obj): edge = getElement(obj,'Edge') if not edge: return False elif not hasattr(edge, 'Curve'): #issue 39 return False if hasattr( edge.Curve, 'Radius' ): return True elif isLine(edge.Curve): return False else: BSpline = edge.Curve.toBSpline() try: arcs = BSpline.toBiArcs(10**-6) except Exception: #FreeCAD exception thrown () return False if all( hasattr(a,'Center') for a in arcs ): centers = numpy.array([a.Center for a in arcs]) sigma = numpy.std( centers, axis=0 ) return max(sigma) < 10**-6 return False def isLinearEdge(obj): edge = getElement(obj,'Edge') if not edge: return False elif not hasattr(edge, 'Curve'): #issue 39 return False if isLine(edge.Curve): return True elif hasattr( edge.Curve, 'Radius' ): return False else: BSpline = edge.Curve.toBSpline() try: arcs = BSpline.toBiArcs(10**-6) except Exception: #FreeCAD exception thrown () return False if all(isLine(a) for a in arcs): lines = arcs D = numpy.array([L.tangent(0)[0] for L in lines]) #D(irections) return numpy.std( D, axis=0 ).max() < 10**-9 return False def isVertex(obj): return getElement(obj,'Vertex') is not None def hasCenter(obj): return isVertex(obj) or isCircularEdge(obj) or \ isAxisOfPlane(obj) or isSphericalSurface(obj) def isSphericalSurface(obj): face = getElement(obj,'Face') if not face: return False return str( face.Surface ).startswith('Sphere ') def getElementPos(obj): pos = None vertex = getElement(obj,'Vertex') if vertex: return vertex.Point face = getElement(obj,'Face') if face: surface = face.Surface if str(surface) == '': # pos = face.BoundBox.Center pos = surface.Position elif all( hasattr(surface,a) for a in ['Axis','Center','Radius'] ): pos = surface.Center elif str(surface).startswith('