こちらの続きです。
マウスカーソルの座標値を取得する5 - C#ATIA
取り組んでいる時間が無さそうなので、現状のものを公開しておきます。
そこそこ機能するはずです。
#FusionAPI_python #Author-kantoku #Description-MouseMoveTest ver0.0.3 import adsk.core, adsk.fusion, traceback import math _ui = None _handlers = [] _faces = [] _covunit = 0 _defLenUnit = '' _draftVec = None #選択面変更 class MyCommandInputChangedHandler(adsk.core.InputChangedEventHandler): def __init__(self): super().__init__() def notify(self, args): try: eventArgs = adsk.core.InputChangedEventArgs.cast(args) if eventArgs.input.id != 'DraftVec': return selectionInput = adsk.core.SelectionCommandInput.cast(eventArgs.input) print(selectionInput.selectionCount) global _draftVec if selectionInput.selectionCount == 0 : app = adsk.core.Application.get() des = adsk.fusion.Design.cast(app.activeProduct) comp = des.rootComponent vecZ = comp.zConstructionAxis.geometry.direction _draftVec = vecZ return ent = selectionInput.selection(0).entity vec = None if ent.classType() == 'adsk::fusion::SketchLine': vec = ent.worldGeometry.asInfiniteLine().direction _draftVec = vec except: global _ui _ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) #このコマンドのイベント・ダイアログ作成 class MyCommandCreatedHandler(adsk.core.CommandCreatedEventHandler): def __init__(self): super().__init__() def notify(self, args): try: global _handlers cmd = adsk.core.Command.cast(args.command) #破棄 onDestroy = MyCommandDestroyHandler() cmd.destroy.add(onDestroy) _handlers.append(onDestroy) #勾配向き onInputChanged = MyCommandInputChangedHandler() cmd.inputChanged.add(onInputChanged) _handlers.append(onInputChanged) #マウス onMouseMove = MyMouseMoveHandler() cmd.mouseMove.add(onMouseMove) _handlers.append(onMouseMove) inputs = cmd.commandInputs inputs.addTextBoxCommandInput('Pos', 'マウス3D座標値 :', 'Non!', 1, True) inputs.addTextBoxCommandInput('MinR', '最小R :', '-', 1, True) inputs.addTextBoxCommandInput('Ang', '角度 :', '-', 1, True) selInput = inputs.addSelectionInput('DraftVec', '角度基準', 'DraftVec') selInput.setSelectionLimits(0,1) selInput.selectionfilters = ['SketchLines'] except: _ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) #このコマンドの破棄 class MyCommandDestroyHandler(adsk.core.CommandEventHandler): def __init__(self): super().__init__() def notify(self, args): try: adsk.terminate() except: _ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) #MouseMoveイベント class MyMouseMoveHandler(adsk.core.MouseEventHandler): def __init__(self): super().__init__() def notify(self, args): eventArgs = adsk.core.MouseEventArgs.cast(args) cmd = eventArgs.firingEvent.sender inputs = cmd.commandInputs #ビューポイント vp = eventArgs.viewport pos_ui = inputs.itemById('Pos') minr_ui = inputs.itemById('MinR') ang_ui = inputs.itemById('Ang') #マウス3D座標値 onface = OnFace(vp, eventArgs.viewportPosition) if onface == None: pos_ui.text = 'Non!' minr_ui.text = '-' ang_ui.text = '-' return else: pos_ui.text = 'x:{:.3f} y:{:.3f} z:{:.3f}'.format( onface[1].x * _covunit, onface[1].y * _covunit, onface[1].z * _covunit) #法線 ang_ui.text = '{:.3f} deg'.format(math.degrees(GetNomal(onface[0], onface[1]))) #曲率 cture = GetCurvature(onface[0], onface[1]) if cture == None: minr_ui.text = '-' else: if round(cture,4) != 0 : crv_info = '{:.3f}{}'.format( 1 / cture * _covunit * -1, _defLenUnit) minr_ui.text = crv_info else: minr_ui.text = '-' #法線 def GetNomal(face, pnt): eva = face.evaluator res, pram = eva.getParameterAtPoint(pnt) returnValue, normal = eva.getNormalAtPoint(pnt) ang = _draftVec.angleTo(normal) if ang > math.pi * 0.5 : ang = (math.pi * -1) + ang return ang #曲率 def GetCurvature(face, pnt): if face.geometry.classType() == 'adsk::core::Plane': return None eva = face.evaluator res, pram = eva.getParameterAtPoint(pnt) returnValue, maxTangent, maxCurvature, minCurvature = eva.getCurvature(pram) if returnValue: return maxCurvature return None #マウスカーソルの3D取得 def OnFace(vp, vp_pos): d3pos = vp.viewToModelSpace(vp_pos) cam = vp.camera vec = cam.eye.vectorTo(cam.target) pnt = adsk.core.Point3D.create( d3pos.x + vec.x, d3pos.y + vec.y, d3pos.z + vec.z) mouse3d = adsk.core.Line3D.create(d3pos, pnt).asInfiniteLine() ints = [(face, mouse3d.intersectWithSurface(geo)) for (face, geo) in _faces if mouse3d.intersectWithSurface(geo).count > 0] ints = [(face, p) for (face, pnts) in ints for p in pnts] ints = [(face, p, face.evaluator.getParameterAtPoint(p)) for (face, p) in ints] ints = [(face, p, prm) for (face, p, (res, prm)) in ints if res] ints = [(face, p, prm) for (face, p, prm) in ints] ints = [(face, p, cam.eye.distanceTo(p)) for (face, p, prm) in ints if face.evaluator.isParameterOnFace(prm)] if len(ints) < 1: return None return min(ints, key = (lambda x: x[2])) def run(context): try: global _ui app = adsk.core.Application.get() _ui = app.userInterface cmdDef = _ui.commandDefinitions.itemById('Mouse_Move_Test') if not cmdDef: cmdDef = _ui.commandDefinitions.addButtonDefinition( 'Mouse_Move_Test', 'Mouse_Move_Test', 'Mouse_Move_Test') onCommandCreated = MyCommandCreatedHandler() cmdDef.commandCreated.add(onCommandCreated) _handlers.append(onCommandCreated) des = adsk.fusion.Design.cast(app.activeProduct) #全サーフェス取得 global _faces _faces = [(face, face.geometry) for comp in des.allComponents if comp.isBodiesFolderLightBulbOn for bBody in comp.bRepBodies if bBody.isLightBulbOn & bBody.isVisible for face in bBody.faces] #単位準備 global _covunit, _defLenUnit unitsMgr = des.unitsManager _defLenUnit = unitsMgr.defaultLengthUnits _covunit = unitsMgr.convert(1, unitsMgr.internalUnits, _defLenUnit) #角度基準 global _draftVec comp = des.rootComponent _draftVec = comp.zConstructionAxis.geometry.direction cmdDef.execute() adsk.autoTerminate(False) except: if _ui: _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
スプリクト実行した際、こんなダイアログが出現します。
マウス3D座標値:マウスカーソル位置の3D座標です。面の上になっていない場合は表示されません。
又、未テストですがコンポーネントを移動・回転させている場合は、正しい位置を表示しません。
最小R:凸をプラス 凹をマイナスでRサイズを表示します。
角度:"角度基準" 未指定の場合、ルートコンポーネントのZ軸を元に角度を表示します。
水平を0° 垂直を90° とし、アンダーカット部分ではマイナスで表示します。
角度基準:"角度" を表示させる際の基準となる向きを指定できます。
現状はスケッチの直線のみです。(ここが現在のお悩み)