こちらの続きです。
軸に対して最大距離になるポイントを取得する - C#ATIA
色々あったり、悩んだり。
Z軸(青)からボディに対して最大距離方向に断面のサーフェスを作ります。
# 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) resBody: adsk.fusion.BRepBody = get_inter_section_temp_face(body, axis, maxPoint) dump_bodies([resBody]) def get_inter_section_temp_face( body: adsk.fusion.BRepBody, axis: adsk.core.InfiniteLine3D, point: adsk.core.Point3D) -> adsk.fusion.BRepBody: interPoint: adsk.core.Point3D = get_intersect_point_from_Infinite(point, axis) vec: adsk.core.Vector3D = interPoint.vectorTo(point) plane: adsk.core.Plane = adsk.core.Plane.create( interPoint, axis.direction.crossProduct(vec) ) tmpMgr: adsk.fusion.TemporaryBRepManager = adsk.fusion.TemporaryBRepManager.get() wireBody: adsk.fusion.BRepBody = tmpMgr.planeIntersection(body, plane) faceBody: adsk.fusion.BRepBody = tmpMgr.createFaceFromPlanarWires([wireBody]) largeBody: adsk.fusion.BRepBody = get_large_face(axis, point) tmpMgr.booleanOperation( faceBody, largeBody, adsk.fusion.BooleanTypes.IntersectionBooleanType ) return faceBody def get_large_face( axis: adsk.core.InfiniteLine3D, point: adsk.core.Point3D) -> adsk.fusion.BRepBody: largeValue = 10000000000 vec: adsk.core.Vector3D = axis.direction.copy() points = [] vec.scaleBy(largeValue) p: adsk.core.Point3D = point.copy() p.translateBy(vec) points.append(p) vec.scaleBy(-1) p: adsk.core.Point3D = point.copy() p.translateBy(vec) points.append(p) points.append(get_intersect_point_from_Infinite(points[1], axis)) points.append(get_intersect_point_from_Infinite(points[0], axis)) points.append(points[0]) lines = [adsk.core.Line3D.create(p1, p2) for p1, p2 in zip(points, points[1:])] print(f'Line Count:{len(lines)}') tmpMgr: adsk.fusion.TemporaryBRepManager = adsk.fusion.TemporaryBRepManager.get() wireBody: adsk.fusion.BRepBody = None wireBody, _ = tmpMgr.createWireFromCurves(lines) # create face return tmpMgr.createFaceFromPlanarWires([wireBody]) 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 dumpWire(wire: adsk.fusion.BRepWire): 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) sktFixs: adsk.fusion.SketchFixedSplines = skt.sketchCurves.sketchFixedSplines for e in wire.edges: geo = e.geometry adsk.core.Line3D.asNurbsCurve if hasattr(geo, 'asNurbsCurve'): geo = geo.asNurbsCurve sktFixs.addByNurbsCurve(geo) def dump_bodies(bodyLst: list): app: adsk.core.Application = adsk.core.Application.get() des: adsk.fusion.Design = app.activeProduct root: adsk.fusion.Component = des.rootComponent baseFeat: adsk.fusion.BaseFeature = None if des.designType == adsk.fusion.DesignTypes.ParametricDesignType: baseFeat = root.features.baseFeatures.add() bodies: adsk.fusion.BRepBodies = root.bRepBodies if baseFeat: baseFeat.startEdit() [bodies.add(body, baseFeat) for body in bodyLst] baseFeat.finishEdit() else: [bodies.add(body) for body in bodyLst] 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) def dumpPlane(plane: adsk.core.Plane) -> adsk.fusion.ConstructionPlanes: app: adsk.core.Application = adsk.core.Application.get() des: adsk.fusion.Design = app.activeProduct root: adsk.fusion.Component = des.rootComponent baseFeat: adsk.fusion.BaseFeature = None if des.designType == adsk.fusion.DesignTypes.ParametricDesignType: baseFeat = root.features.baseFeatures.add() if baseFeat: baseFeat.startEdit() constPlanes: adsk.fusion.ConstructionPlanes = root.constructionPlanes planeIpt: adsk.fusion.ConstructionPlaneInput = constPlanes.createInput() planeIpt.setByPlane(plane) constPlane: adsk.fusion.ConstructionPlane = constPlanes.add(planeIpt) if baseFeat: baseFeat.finishEdit() return constPlane def draw_cg_body(body: adsk.fusion.BRepBody): app: adsk.core.Application = adsk.core.Application.get() des: adsk.fusion.Design = app.activeProduct root: adsk.fusion.Component = des.rootComponent cgGroup: adsk.fusion.CustomGraphicsGroup = root.customGraphicsGroups.add() cgBody:adsk.fusion.CustomGraphicsBRepBody = cgGroup.addBRepBody(body)
単に断面を作るのでは無く、Z軸より最大距離方向だけです。
最大距離の反対方向には断面を作らないようにしています。
何故か? 軸で回転させたいからです・・・。(今、悩んでいる所)