こちらの続きです。
ポケットを探す1 - C#ATIA
前回の条件
・底面は水平
・側面は垂直
で凹形状となる面を見つけます。つまり、
ここから
これを探し出す って事です。(出来ました)
def find_pocket_faces( body: fusion.BRepBody, axis: core.Vector3D, ) -> list[fusion.BRepFace]: ''' ポケット面取得 ''' def is_pocket_edge( edge: fusion.BRepEdge, tolerance: float = 0.001, ) -> bool: if edge.faces.count == 2: face1: fusion.BRepFace = edge.faces[0] face2: fusion.BRepFace = edge.faces[1] edgeEva: core.CurveEvaluator3D = edge.evaluator _, minPrm, maxPrm = edgeEva.getParameterExtents() midPrm = (minPrm + maxPrm) * 0.5 _, midPnt = edgeEva.getPointAtParameter(midPrm) _, normal1 = face1.evaluator.getNormalAtPoint(midPnt) _, normal2 = face2.evaluator.getNormalAtPoint(midPnt) normalAngle = normal1.angleTo(normal2) if edge.coEdges[0].loop.face == face1: coEdge = edge.coEdges[0] elif edge.coEdges[1].loop.face == face1: coEdge = edge.coEdges[1] testPrm = midPrm + ((maxPrm - minPrm) * 0.001) _, testPnt = edgeEva.getPointAtParameter(testPrm) edgeDir: core.Vector3D = midPnt.vectorTo(testPnt) edgeDir.normalize() if not coEdge.isOpposedToEdge: edgeDir.scaleBy(-1) cross: core.Vector3D = normal1.crossProduct(normal2) if edgeDir.angleTo(cross) > math.pi * 0.5: return False return abs(normalAngle - math.pi * 0.5) < tolerance else: return False # ********** # Plane faces = [f for f in body.faces if f.geometry.objectType == core.Plane.classType()] # Normal faces = [f for f in faces if axis.isParallelTo(f.geometry.normal)] # Pocket faces = [f for f in faces if all([is_pocket_edge(e) for e in f.edges])] return faces
公開していなかったのですが、穴の検索はこんな感じです。
def find_hole_faces( body: fusion.BRepBody, axis: core.Vector3D, ) -> list[fusion.BRepFace]: ''' 穴面取得 ''' def is_hole( face: fusion.BRepFace, ) -> bool: ''' 穴か軸か ''' point: core.Point3D = face.pointOnFace eva: core.SurfaceEvaluator = face.evaluator normal: core.Vector3D = None _, normal = eva.getNormalAtPoint(point) normal.normalize() normal.scaleBy(0.001) checkPnt: core.Point3D = point.copy() checkPnt.translateBy(normal) cog: core.Point3D = face.centroid return cog.distanceTo(checkPnt) < cog.distanceTo(point) # Cylinder faces = [f for f in body.faces if f.geometry.objectType == core.Cylinder.classType()] # vextor faces = [f for f in faces if axis.isParallelTo(f.geometry.axis)] # hole faces = [f for f in faces if is_hole(f)] # remove overlap facesDict = {} [facesDict.setdefault(f.centroid.asArray(), f) for f in faces] return list(facesDict.values())
こんな感じの、底面平らな穴形状は、両方にHitしちゃうな。