こちらの続きです。
マウスカーソルの座標値を取得する5 - C#ATIA
取り組んでいる時間が無さそうなので、現状のものを公開しておきます。
そこそこ機能するはずです。
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()))
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')
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
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° とし、アンダーカット部分ではマイナスで表示します。
角度基準:"角度" を表示させる際の基準となる向きを指定できます。
現状はスケッチの直線のみです。(ここが現在のお悩み)