def __group_coaxial_cylinders(cylinders, tol_ang=0.5, tol_lin=0.1, roundDigit=6): """According to cylinders' axis, categorize a list of cylinders into a dictionary by using its axis as a key. Arguments: cylinders {[TopoDS_Face,...]} -- list of TopoDS_Face tol_ang {float} -- [Unit - degree] the angle between these two axis below this value will be recognize as two parallel axis tol_lin Returns: {'string': [TopoDS_Face,...]} -- returns a dictionary, key is string of axis and location vector, value is list of TopoDS_Shape """ logging.debug('Entering group_coaxial') tol_rad = radians(tol_ang) skipList = [] cyl_ax_grp = {} for i in range(0, len(cylinders)): if i in skipList: continue cyl1 = BRepAdaptor_Surface(cylinders[i], True).Cylinder() axis1 = cyl1.Axis() location1 = cyl1.Location() axisDir1 = (round(axis1.Direction().X(), roundDigit), round(axis1.Direction().Y(), roundDigit), round(axis1.Direction().Z(), roundDigit)) cylLoc1 = (round(location1.X(), roundDigit), round(location1.Y(), roundDigit), round(location1.Z(), roundDigit)) key = (axisDir1, cylLoc1) if key not in cyl_ax_grp.keys(): cyl_ax_grp[key] = [cylinders[i]] else: logging.warning('Error !!! Please check the logic again !') for j in range(i + 1, len(cylinders)): # logging.debug('i = %d, j = %d' % (i, j)) if j in skipList: # logging.debug('skip !!') continue cyl2 = BRepAdaptor_Surface(cylinders[j]).Cylinder() axis2 = cyl2.Axis() if axis1.IsCoaxial(axis2, tol_rad, tol_lin) or axis1.IsCoaxial( axis2.Reversed(), tol_rad, tol_lin): # logging.debug('Coaxial !!') cyl_ax_grp[key].append(cylinders[j]) skipList.append(j) return cyl_ax_grp
def group_cyl_byPln(solid, distTol=0.5, angTolDeg=5.0): cylinders = RecognizeTopo(solid).cylinders() cyl_dirGrp = group_cylinders_byAxisDir(cylinders, anglTolDeg=angTolDeg, groupParallelAx=True) cyl_dirGrpKeys = list(cyl_dirGrp.keys()) # group cylinders by plane CylinderGrpsFromDiffPln = {} j = 0 for dirKey in cyl_dirGrpKeys: CylinderGrpsFromDiffPln[dirKey] = [] parallel_cyl_grps = cyl_dirGrp[dirKey].copy() grp_cylinderOnSamePln = {} while len(parallel_cyl_grps) >= 1: # take out the first element for creating plane, and search the other cylinders on the same plane firstCylinder = parallel_cyl_grps.pop(0) # fitting a geomety surface to TopoDS_Surface brepCylinder = BRepAdaptor_Surface(firstCylinder).Cylinder() dir1 = brepCylinder.Axis().Direction() # location of cylinder is usually the location of local coordinate system, which is on the axis of cylinder loc1 = brepCylinder.Location() # create gp_Pln pln = gp_Pln(loc1, dir1) grp_cylinderOnSamePln[pln] = [firstCylinder] # Search the cylinders on the same pln, if yes, extract from parallel_cyl_grps # loop all elements in parallel_cyl_grps while j < len(parallel_cyl_grps): brepCylinder2 = BRepAdaptor_Surface( parallel_cyl_grps[j]).Cylinder() loc2 = brepCylinder2.Location() if pln.Distance(gp_Pnt(loc2.X(), loc2.Y(), loc2.Z())) < distTol: grp_cylinderOnSamePln[pln].append(parallel_cyl_grps[j]) parallel_cyl_grps.pop(j) else: j += 1 j = 0 CylinderGrpsFromDiffPln[dirKey] = grp_cylinderOnSamePln return CylinderGrpsFromDiffPln