C#ATIA

↑タイトル詐欺 主にFusion360API 偶にCATIA V5 VBA(絶賛ネタ切れ中)

円すい上の2点の最短距離をAPIで1

こちらの問題、他人にやらせてばかりで申し訳ないので、
僕っぽさを出すためにスクリプトで挑戦したいと考えてます。
解決済み: 円すい上の2点の最短距離 - Autodesk Community

スピードだけ求めたら、座標値を計算して曲線を求めた方が間違いなく
早いのですが、もうちょっとGUIの考え方に近い方法にしたい気がしてます。

作戦的にはこんな感じです。
こちらの展開図なのですが
f:id:kandennti:20200619094905p:plain
緑部分の角度を0~120°まで変化させ、赤部分の長さを取得します。
この長さは、三次元の状態の頂点から距離です。
f:id:kandennti:20200619094918p:plain
最終的にはこの方法で取得した大量の点からスプラインを作成すればOKな
ハズです。


展開図の赤部分は非駆動寸法なのです。これFusion360は式とかで
利用する事が出来ないんですよね。かなり不便です。
f:id:kandennti:20200619094932p:plain
でもAPIでは数値を取得出来ると言う事を僕は知っていました。
その為、こんな感じのものを作成しました。

#Fusion360API Python script
import adsk.core, adsk.fusion, traceback

_app = adsk.core.Application.cast(None)
_ui = adsk.core.UserInterface.cast(None)

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

        skt :adsk.fusion.Sketch = root.sketches.item(0)

        dims :adsk.fusion.SketchDimensions = skt.sketchDimensions
        dimAng :adsk.fusion.SketchDimension = dims.item(6)
        dimTgt :adsk.fusion.SketchDimension = dims.item(5)
        
        for v in range(10):
            dimAng.parameter.value = math.radians(v)
            print('{} : {}'.format(
                dimAng.parameter.expression, 
                dimTgt.parameter.expression))

    except:
        if _ui:
            _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

各".item(XX)"のインデックス値は事前に調べているため、あまり利用価値のない
ものとなってます。すいません。

内容的には最初の作戦通り、10回ほど角度を変化させて長さを取得しプリントで
垂れ流しているだけです。
結果はこんな感じです。

0.000 ° : 19.6577201 mm
1.000 ° : 19.6577201 mm
2.000 ° : 19.6577201 mm
3.000 ° : 19.6577201 mm
4.000 ° : 19.6577201 mm
5.000 ° : 19.6577201 mm
6.000 ° : 19.6577201 mm
7.000 ° : 19.6577201 mm
8.000 ° : 19.6577201 mm
9.000 ° : 19.6577201 mm

ん! 角度変えても長さが変わってない。
GUIの操作(手動)では非駆動寸法は反応しているので、画面上をUpdate
してくれそうな

_app.activeViewport.refresh()

adsk.doEvents()

とか入れるのですが、どうしても長さが変化してくれない。
かなり悩みましたが、非駆動寸法はGUIの扱いと異なるようです。


仕方が無いので、GUIで偶に行う方法を取り込むことに。
f:id:kandennti:20200619094951p:plain
赤部分を駆動に切り替えればOKなのですが、過拘束となるためNGです。
その為、過拘束を避ける方法を作ります。
・角度(緑)を変更
・過拘束回避用に一か所(オレンジ)を非駆動に変更
・長さ(赤)を駆動に変更
・長さを非駆動に変更
・回避用を駆動に変更
と言う泥臭い方法を1サイクルとしました。

#Fusion360API Python script
import adsk.core, adsk.fusion, traceback
import math

_app = adsk.core.Application.cast(None)
_ui = adsk.core.UserInterface.cast(None)

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

        skt :adsk.fusion.Sketch = root.sketches.item(0)

        dims :adsk.fusion.SketchDimensions = skt.sketchDimensions
        dimAng :adsk.fusion.SketchDimension = dims.item(6)
        dimTgt :adsk.fusion.SketchDimension = dims.item(5)
        dimTmp :adsk.fusion.SketchDimension = dims.item(2)

        _app.activeViewport.refresh()        
        for v in range(10):
            dimAng.parameter.value = math.radians(v)
            dimTmp.isDriving = False
            dimTgt.isDriving = True
            dimTgt.isDriving = False
            dimTmp.isDriving = True

            print('{} : {}'.format(
                dimAng.parameter.expression, 
                dimTgt.parameter.expression))

    except:
        if _ui:
            _ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

実行した結果は

0.000 ° : 30.000 mm
1.000 ° : 29.4117648 mm
2.000 ° : 28.8547744 mm
3.000 ° : 28.3269564 mm
4.000 ° : 27.8264254 mm
5.000 ° : 27.3514627 mm
6.000 ° : 26.9004985 mm
7.000 ° : 26.4720968 mm
8.000 ° : 26.0649413 mm
9.000 ° : 25.6778239 mm

無事、長さも変わりました。
まだ始まったばかり・・・。