こちらの続きです。
円すい上の2点の最短距離をAPIで1 - C#ATIA
完成しました。
解決済み: Re: 円すい上の2点の最短距離 - Autodesk Community
#Fusion360API Python script #Author-kantoku #Description-円錐上の2点の最短距離 import adsk.core, adsk.fusion, traceback import math _app = adsk.core.Application.cast(None) _ui = adsk.core.UserInterface.cast(None) # 1ステップの角度(deg) STEP_ANG = 5 def run(context): try: global _app, _ui _app = adsk.core.Application.get() _ui = _app.userInterface des :adsk.fusion.Design = _app.activeProduct root :adsk.fusion.Component = des.rootComponent # 円錐 cone :adsk.fusion.BRepFace = root.bRepBodies.item(0).faces.item(1) # 展開図スケッチ sktDevelop :adsk.fusion.Sketch = root.sketches.itemByName('展開図') dims :adsk.fusion.SketchDimensions = sktDevelop.sketchDimensions dimAng :adsk.fusion.SketchDimension = getDimensionByName(dims, 'd13') dimTgt :adsk.fusion.SketchDimension = getDimensionByName(dims, 'd14') dimTmp :adsk.fusion.SketchDimension = getDimensionByName(dims, 'd11') # 作業スケッチ sktWork :adsk.fusion.Sketch = root.sketches.itemByName('作業') dims = sktWork.sketchDimensions dimPrt :adsk.fusion.SketchDimension = getDimensionByName(dims, 'd8') pntSkt :adsk.fusion.SketchPoint = sktWork.sketchPoints.item(4) # カメラ vp :adsk.core.Viewport = _app.activeViewport cam :adsk.core.Camera = vp.camera viewLng = cam.eye.vectorTo(cam.target).length # 結果スケッチ sktRes :adsk.fusion.Sketch = root.sketches.add(root.xYConstructionPlane) # 円錐上に点作成 pntRes = adsk.fusion.SketchPoint.cast(None) for v in range(0,120 + STEP_ANG,STEP_ANG): # 展開スケッチ更新 dimAng.parameter.value = math.radians(v) dimTmp.isDriving = False dimTgt.isDriving = True dimTgt.isDriving = False dimTmp.isDriving = True # 作業スケッチ更新 dimPrt.parameter.value = dimTgt.parameter.value # 結果スケッチに取り込み includes = sktRes.include(pntSkt) pntRes :adsk.fusion.SketchPoint = includes.item(0) pntRes.isReference = False # 画面更新 updateCam(cone, pntRes.geometry, viewLng) # 画面が固まるのを防ぐ adsk.doEvents() # 曲線作成 pnts = adsk.core.ObjectCollection.create() [pnts.add(p) for p in sktRes.sketchPoints] pnts.removeByIndex(0) sktRes.sketchCurves.sketchFittedSplines.add(pnts) # 邪魔な点非表示 sktRes.arePointsShown = False except: if _ui: _ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) # カメラの更新 def updateCam( brep :adsk.fusion.BRepFace, tgt :adsk.core.Point3D, viLng :float): vec :adsk.core.Vector3D = getViewVec(brep, tgt) vec.scaleBy(viLng) eye :adsk.core.Point3D = tgt.copy() eye.translateBy(vec) vp :adsk.core.Viewport = _app.activeViewport cam :adsk.core.Camera = vp.camera cam.eye = eye cam.target = tgt cam.upVector = adsk.core.Vector3D.create(0, 0, 1) vp.camera = cam _app.activeViewport.refresh() # サーフェス上の点位置の法線取得 def getViewVec( brep :adsk.fusion.BRepFace, pnt :adsk.core.Point3D) -> adsk.core.Vector3D: eva :adsk.core.SurfaceEvaluator = brep.evaluator vec = adsk.core.Vector3D.cast(None) _,vec = eva.getNormalAtPoint(pnt) vec.normalize() return vec # モデリングパラメータ名から寸法取得 def getDimensionByName( dims :adsk.fusion.SketchDimensions, name :str) -> adsk.fusion.SketchDimension: lst =[d for d in dims if d.parameter.name == name] if len(lst) < 1: return None return adsk.fusion.SketchDimension.cast(lst[0])
全く使いまわしのきかないものです・・・。
普段はループ内で複数の処理するの嫌なのですが、動画にしたかったので
あえて遅くなるようにしています。
画面も一緒に追いかけるようにしたのですが、
cam.upVector = adsk.core.Vector3D.create(0, 0, 1)
最初にこの処理を入れ忘れ、結構酔いそうになりました。