結構頑張っているつもりなのに、今月はブログの更新が少ない・・・。
こちらの動画のスクリプトを無くしそうなので、公開しておきます。
# Fusion360API Python script import traceback import adsk.core as core import adsk.fusion as fusion def run(context): ui: core.UserInterface = None try: app: core.Application = core.Application.get() ui = app.userInterface des: fusion.Design = app.activeProduct root: fusion.Component = des.rootComponent msg: str = 'Select' selFilter: str = 'Faces' while True: sel: core.Selection = selectEnt(msg, selFilter) if not sel: break create_simple_cylinder_face(sel.entity) except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) def create_simple_cylinder_face( face: fusion.BRepFace, ) -> None: tangens = [f for f in face.tangentiallyConnectedFaces] tangens.append(face) res = add_offset_faces(tangens, 0.001) if not res: return cylinder = create_cylinder(tangens) diff_body(face.body, cylinder) def create_cylinder( faces: list, ) -> fusion.BRepBody: face: fusion.BRepFace = faces[0] axisZ: core.Vector3D = get_axis_vector(face) axisZ.normalize() axisX: core.Vector3D = get_unique_vector(axisZ) axisY: core.Vector3D = axisX.crossProduct(axisZ) tmpMgr: fusion.TemporaryBRepManager = fusion.TemporaryBRepManager.get() clone: fusion.BRepBody = tmpMgr.copy(face) [tmpMgr.booleanOperation(clone, tmpMgr.copy(f), fusion.BooleanTypes.UnionBooleanType) for f in faces] bbox: core.OrientedBoundingBox3D = get_bbox( clone, axisX, axisY, ) ratio = bbox.height * 0.5 + 0.001 points = [] for length in (ratio, -ratio): v: core.Vector3D = axisZ.copy() v.scaleBy(length) p: core.Point3D = bbox.centerPoint.copy() p.translateBy(v) points.append(p) radius = get_radius(face) cylBody: fusion.BRepBody = tmpMgr.createCylinderOrCone( points[0], radius, points[1], radius, ) return draw_bodies([cylBody])[0] def add_offset_faces( faces: list, value: float, ) -> fusion.OffsetFacesFeature: try: app: core.Application = core.Application.get() face: fusion.BRepFace = faces[0] body: fusion.BRepBody = face.body comp: fusion.Component = body.parentComponent offsetFeats: fusion.OffsetFacesFeatures = comp.features.offsetFacesFeatures offsetCount = offsetFeats.count ui: core.UserInterface = app.userInterface sels: core.Selections = ui.activeSelections sels.clear() [sels.add(f) for f in faces] cmds = [ u'Commands.Start FusionPressPullCommand', u'Commands.SetString infoOffsetType {}'.format('addNewOffset'), u'Commands.SetDouble OffsetFacesDistanceInput {}'.format(value), u'NuCommands.CommitCmd', ] [app.executeTextCommand(cmd) for cmd in cmds] if offsetFeats.count > offsetCount: return offsetFeats[-1] else: return None except: return None def diff_body( targetBody: fusion.BRepBody, toolBody: fusion.BRepBody, ) -> fusion.CombineFeature: comp: fusion.Component = targetBody.parentComponent objs: core.ObjectCollection = lst2col([toolBody]) combineFeats: fusion.CombineFeatures = comp.features.combineFeatures combineIpt: fusion.CombineFeatureInput = combineFeats.createInput( targetBody, objs, ) combineIpt.isNewComponent = False combineIpt.isKeepToolBodies = False combineIpt.operation = fusion.FeatureOperations.CutFeatureOperation return combineFeats.add(combineIpt) def get_radius( face: fusion.BRepFace, ) -> float: facePnt: core.Point3D = face.pointOnFace eva: core.SurfaceEvaluator = face.evaluator _, prm = eva.getParameterAtPoint(facePnt) _, _, cr1, cr2 = eva.getCurvature(prm) return max([abs(1 / c) for c in (cr1, cr2) if c != 0]) def get_bbox( body: fusion.BRepBody, axisX: core.Vector3D, axisY: core.Vector3D, ) -> core.OrientedBoundingBox3D: app: core.Application = core.Application.get() measMgr: core.MeasureManager = app.measureManager return measMgr.getOrientedBoundingBox( body, axisY, axisX, ) def get_unique_vector( vec: core.Vector3D ) -> core.Vector3D: v: core.Vector3D = core.Vector3D.create(0,0,1) if vec.isParallelTo(v): v = core.Vector3D.create(1,0,0) return vec.crossProduct(v) def get_axis_vector( face: fusion.BRepFace, ) -> core.Vector3D: facePnt: core.Point3D = face.pointOnFace eva: core.SurfaceEvaluator = face.evaluator _, prm = eva.getParameterAtPoint(facePnt) lineType = core.Line3D.classType() # test # geoEva: core.SurfaceEvaluator = face.geometry.evaluator prmSets = ( (prm.x, False), (prm.x, True), (prm.y, False), (prm.y, True), ) for prm, isU in prmSets: resLst = eva.getIsoCurve(prm, isU) for res in resLst: # test # pp1 = geoEva.isClosedInU # pp2 = geoEva.isClosedInV if res.objectType == lineType: return res.asInfiniteLine().direction return None def col2lst( col: core.ObjectCollection, ) -> list: return [x for x in col] def lst2col( lst: list, ) -> core.ObjectCollection: objs: core.ObjectCollection = core.ObjectCollection.create() [objs.add(x) for x in lst] return objs def selectEnt( msg: str, filterStr: str ) -> core.Selection: try: app: core.Application = core.Application.get() ui: core.UserInterface = app.userInterface sel = ui.selectEntity(msg, filterStr) return sel except: return None def draw_bodies( bodyLst: list, targetOcc: fusion.Occurrence = None ) -> list: ''' bodyの出力 ''' app: core.Application = core.Application.get() des: fusion.Design = app.activeProduct if not targetOcc: comp: fusion.Component = des.rootComponent else: comp: fusion.Component = targetOcc.component baseFeat: fusion.BaseFeature = None if des.designType == fusion.DesignTypes.ParametricDesignType: baseFeat = comp.features.baseFeatures.add() bodies: fusion.BRepBodies = comp.bRepBodies resBodies = [] if baseFeat: baseFeat.startEdit() resBodies = [bodies.add(body, baseFeat) for body in bodyLst] baseFeat.finishEdit() return baseFeat.bodies else: return [bodies.add(body) for body in bodyLst]
念の為お伝えしておくと、このスクリプトは完成度が低いです。
場合によっては、Fusion360クラッシュするし、テストしたデータで
開けなくなるものが、2件出来ました。
使わない方が良いと思います。