そろそろ、こちらに取り掛かりたいです。
旋盤用の回転プロファイルをスケッチとして取得したい - Autodesk Community
え~思い付いた処理方法が上手く行くのかどうか不明です。
どんな風に・・・そのうち書きます。
取りあえず処理上、軸に対して目的のボディの最長(大?)位置
となる部分を探し出したいです。
画像で説明するとこんな状態です。
目的の軸は青いものです。ちょっと極端な例ですね。
CADの測定は、最短距離を求める測定機能はあるのですが、
その逆の最大距離を測定する機能ってあまり無いんですよね。
(CATIA V5にはあります)
それを最長位置を求め、スケッチの点を作るスクリプトです。
# Fusion360API Python script import traceback import adsk.fusion import adsk.core def run(context): ui = adsk.core.UserInterface.cast(None) try: app: adsk.core.Application = adsk.core.Application.get() ui = app.userInterface des: adsk.fusion.Design = app.activeProduct root: adsk.fusion.Component = des.rootComponent body: adsk.fusion.BRepBody = root.bRepBodies[0] axis: adsk.core.InfiniteLine3D = root.zConstructionAxis.geometry draw_max_point(body, axis) except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) def draw_max_point( body: adsk.fusion.BRepBody, axis: adsk.core.InfiniteLine3D): app: adsk.core.Application = adsk.core.Application.get() vec: adsk.core.Vector3D = axis.direction bBox: adsk.core.OrientedBoundingBox3D = get_boundingBox( body, vec, ) interPoint: adsk.core.Point3D = get_intersect_point_from_Infinite(bBox.centerPoint, axis) p1, p2 = get_length_range_points(bBox, interPoint) tmpRadius = 100000000 dmyCylinder: adsk.fusion.BRepFace = get_cylinder_face(p1, p2, tmpRadius) maxPoint: adsk.core.Point3D = get_max_point_from_cylinder(body, dmyCylinder) dumpPoints( [ maxPoint ] ) def get_max_point_from_cylinder( targetBody: adsk.fusion.BRepBody, cylinder: adsk.fusion.BRepFace) -> adsk.core.Point3D: app: adsk.core.Application = adsk.core.Application.get() measMgr: adsk.core.MeasureManager = app.measureManager res: adsk.core.MeasureResults = measMgr.measureMinimumDistance( targetBody, cylinder ) return res.positionOne def get_cylinder_face( startPoint: adsk.core.Point3D, endPoint: adsk.core.Point3D, radius:float) -> adsk.fusion.BRepFace: tmpMgr: adsk.fusion.TemporaryBRepManager = adsk.fusion.TemporaryBRepManager.get() cylinder: adsk.fusion.BRepBody = tmpMgr.createCylinderOrCone( startPoint, radius, endPoint, radius ) return cylinder.faces[0] def get_intersect_point_from_Infinite( point: adsk.core.Point3D, inf: adsk.core.InfiniteLine3D) -> adsk.core.Point3D: plane: adsk.core.Plane = adsk.core.Plane.create( point, inf.direction ) inters: adsk.core.ObjectCollection = inf.intersectWithSurface(plane) return inters[0] def get_length_range_points( bBox:adsk.core.OrientedBoundingBox3D, refPoint: adsk.core.Point3D) -> set: half_length = bBox.length * 0.5 vec: adsk.core.Vector3D = bBox.lengthDirection.copy() vec.normalize() vec.scaleBy(half_length) p1: adsk.core.Point3D = refPoint.copy() p1.translateBy(vec) vec.normalize() vec.scaleBy(-half_length) p2: adsk.core.Point3D = refPoint.copy() p2.translateBy(vec) return (p1, p2) def get_boundingBox( body: adsk.fusion.BRepBody, axis: adsk.core.Vector3D) -> adsk.core.OrientedBoundingBox3D: app: adsk.core.Application = adsk.core.Application.get() measMgr: adsk.core.MeasureManager = app.measureManager return measMgr.getOrientedBoundingBox( body, axis, get_orthogonal_vector(axis) ) def get_orthogonal_vector( vector: adsk.core.Vector3D) -> adsk.core.Vector3D: tmpVec: adsk.core.Vector3D = adsk.core.Vector3D.create(1,0,0) if vector.isParallelTo(tmpVec): tmpVec = adsk.core.Vector3D.create(0,1,0) return vector.crossProduct(tmpVec) def dumpPoints(points): app: adsk.core.Application = adsk.core.Application.get() des: adsk.fusion.Design = app.activeProduct root: adsk.fusion.Component = des.rootComponent skt: adsk.fusion.Sketch = root.sketches.add(root.xYConstructionPlane) sktPnts: adsk.fusion.SketchPoints = skt.sketchPoints for p in points: sktPnts.add(p)
なっ長くない? たったそれだけの事なのに・・・。
結果はこちらです。
そう、これだけ。もっと効率良いアルゴリズムあるのかな?