def get_closest_parallel_planePair(solid_add, solid_base=None, init_min_dist=1000.0, xyplane_z_inMM=1215.0): """ Arguments: solid_add {TopoDS_Solid} -- The solid going to be added Keyword Arguments: solid_base {TopoDS_Solid} -- By default, solid_base will be xy-plane (default: {None}) init_min_dist {float} -- [description] (default: {10.0}) Returns: {dict} -- keyValues: miniDist, topoPair, geomPair, mvVec """ min_dist = init_min_dist ang_list = find_closest_normal_pair(solid_add, solid_base) if solid_base is None: solid_base = gen_boxSolidAsTable(height=xyplane_z_inMM) axisGrp1 = group_planes_by_axis(solid_base) axisGrp2 = group_planes_by_axis(solid_add) axisPair = ang_list['minAxisKeyPair'] for axKeyPair in axisPair: for topoPln1 in axisGrp1[axKeyPair[0]]: surf1 = BRepAdaptor_Surface(topoPln1, True) pln1 = surf1.Plane() # [ToDo] A better distance evaluation, how to select a correct point which is inside the wire or centerofmass of plane plnpnt1 = pln1.Location() for topoPln2 in axisGrp2[axKeyPair[1]]: surf2 = BRepAdaptor_Surface(topoPln2, True) pln2 = surf2.Plane() # rospy.logdebug('Distance:', pln2.Distance(plnpnt1)) dist = pln2.Distance(plnpnt1) if dist < min_dist: min_dist = dist minDistTopoPair = [topoPln1, topoPln2] minDistGeomPair = [pln1, pln2] p = gp_Pnt(0, 0, 0) p1 = ais_ProjectPointOnPlane(p, minDistGeomPair[0]) p2 = ais_ProjectPointOnPlane(p, minDistGeomPair[1]) # in order to remove small digits projPln = minDistGeomPair[0] mvVec = gp_Vec(p2, p1) projPlnNormal = gp_Vec(projPln.Axis().Direction()) mag = np.sign(mvVec.Dot(projPlnNormal)) * mvVec.Magnitude() mvVec = projPlnNormal.Normalized().Multiplied(mag) return { 'minDist': dist, 'topoPair': minDistTopoPair, 'geomPair': minDistGeomPair, 'mvVec': mvVec }
def recognize_face(a_face): """ Takes a TopoDS shape and tries to identify its nature whether it is a plane a cylinder a torus etc. if a plane, returns the normal if a cylinder, returns the radius """ surf = BRepAdaptor_Surface(a_face, True) surf_type = surf.GetType() if surf_type == GeomAbs_Plane: print("--> plane") # look for the properties of the plane # first get the related gp_Pln gp_pln = surf.Plane() location = gp_pln.Location() # a point of the plane normal = gp_pln.Axis().Direction() # the plane normal # then export location and normal to the console output print("--> Location (global coordinates)", location.X(), location.Y(), location.Z()) print("--> Normal (global coordinates)", normal.X(), normal.Y(), normal.Z()) return surf.Plane() elif surf_type == GeomAbs_Cylinder: print("--> cylinder") # look for the properties of the cylinder # first get the related gp_Cyl gp_cyl = surf.Cylinder() location = gp_cyl.Location() # a point of the axis axis = gp_cyl.Axis().Direction() # the cylinder axis # then export location and normal to the console output print("--> Location (global coordinates)", location.X(), location.Y(), location.Z()) print("--> Axis (global coordinates)", axis.X(), axis.Y(), axis.Z()) elif surf_type == GeomAbs_Circle: print("--> circle") # look for the properties of the cylinder # first get the related gp_Cyl # gp_cyl = surf.() # location = gp_cyl.Location() # a point of the axis # axis = gp_cyl.Axis().Direction() # the cylinder axis # then export location and normal to the console output # print("--> Location (global coordinates)", location.X(), location.Y(), location.Z()) # print("--> Axis (global coordinates)", axis.X(), axis.Y(), axis.Z()) else: # TODO there are plenty other type that can be checked # see documentation for the BRepAdaptor class # https://www.opencascade.com/doc/occt-6.9.1/refman/html/class_b_rep_adaptor___surface.html print("not implemented")
def pipe_segment_to_edge(compound, uid=None): """ if it is two circles with linear face segments, the end sections will have N - 2 edges""" the_topo = Topo(compound) faces = [Face(f) for f in the_topo.faces()] faces.sort(reverse=True, key=lambda x: len(x.edges())) areas = [] verts = [] for f1 in faces[:2]: surf = BRepAdaptor_Surface(f1, True) surf_type = surf.GetType() areas.append(f1.area) uv, pnt = f1.mid_point() if surf_type == GeomAbs_Plane: gp_pln = surf.Plane() normal = f1.normal gppln2 = gp_Pln(pnt, normal) v = MEPConnector(gppln2) verts.append(v) radius = math.sqrt(sum(areas)) / (2 * math.pi) edge = MEPCurve(*verts) return MEPSegment(edge, radius, uid=uid)