C#ATIA

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

ドロップダウンリストを変更する

APIで提供されていない処理をスクリプト/アドインで行う為の唯一の方法が
テキストコマンドを利用する方法です。
APIフォーラムでは、テキストコマンドを利用する方法については、
Autodesk社員&元社員には "沈黙" 又は "否定的" ですが、僕同様のユーザーには
ある程度浸透してくれたようで、他の方がテキストコマンドを利用した方法で
解決されているトピも幾つか見られます。


個人的には、取り組み始めた当初から長い間方法が不明で、非常に不便に
感じていたものが有ります。それは "ドロップダウンリスト" の値の
切り替えです。 ですが、ひょんな事から操作する方法が分かりました。


文字でグズグズ書いても分かりにくいため、もう少し具体的な説明をしましょう。
f:id:kandennti:20210426153047p:plain
ブロックのボディにかかるように円のスケッチが描かれています。
この状態で押し出しコマンドを呼び出し、距離を設定すると "操作" 部分が
"切り取り" の状態になります。この "操作" 部分がドロップダウンリストに
なっており、例えば新規ボディで実行したくても切り替える方法を見つけることが
出来ませんでした。
悪いことに、このドロップダウンリストは多くのコマンドに実装されている為、
テキストコマンドでのコマンドの実行の利用価値を大きく下げている原因と
なっていました。


では、実際にやってみましょう。
以前、こちらを取り組んだパイプコマンドを修正し、以前出来なかった処理を
行ってみます。
テキストコマンド1 - C#ATIA


〇Toolkit.cmdDialog
まず、コマンドのダイアログに表示されるImputsの "target label" を見つける
必要があります。これは以前も記載した内容ですが、一連の流れとして記載しておきます。

ダイアログが表示された状態で、テキストコマンドのこちらを実行します。

Toolkit.cmdDialog 

f:id:kandennti:20210426153310p:plain
この様に、ダイアログ上の情報の取得が出来ます。パイプコマンドの場合は
この様な結果です。

Toolkit.cmdDialog 
====>  CommandDialog:PrimitivePipePanel-4
Path, eSelectionButton, Label=パス, 選択
SWEEP_CHAINING_OPTION, eCheckBox, チェーン選択
infoSectionType, eDropDownButton, Label=断面, 円形
  MenuItems:
  infoCircular, eDropDownItem, 円形
  infoRectangular, eDropDownItem, 正方形
  infoTriangular, eDropDownItem, 三角
PIPE_HOLLOW_OPTION, eCheckBox, 空洞
infoBooleanType, eDropDownButton, Label=操作, 新規ボディ
  MenuItems:
  infoJoinType, eDropDownItem, 結合
  infoCutType, eDropDownItem, 切り取り
  infoIntersectType, eDropDownItem, 交差
  infoNewBodyType, eDropDownItem, 新規ボディ
  infoNewBodyInNewCompType, eDropDownItem, 新規コンポーネント

"Toolkit.cmdDialog" は非表示となっている要素も出力されますが、標示されてる
ダイアログと比べると何となく感じ取る事は出来るはずです。

"====>" が存在している行以降で、先頭にスペースの無い行を見てみると
おおよそこのようなフォーマットになっています。

"target label" , タイプ , ラベル , 値

タイプが "eDropDownButton" となっているものが、ドロップダウンリストとなっており
"MenuItems:" 以降の行が、選択肢となるリストで、この様なフォーマットなっています。

"target label" , タイプ , ラベル

ラベルから、"target label" はこの様になっていますね。
f:id:kandennti:20210426153341p:plain


〇Commands.SetString
今回のお話のメインディッシュはこれです。これこそがドロップダウンリストの値を
変更する為のコマンドです。使い方はこんな感じです。

Commands.SetString <target label> <listItemのtarget label>

例えば "断面" を正方形としたいのであれば、
f:id:kandennti:20210426153431p:plain

Commands.SetString infoSectionType infoRectangular

です。

最初の "操作" 部分が "切り取り" になってしまう事を避ける為、
必ず、 "新規ボディ" としたいのであれば

Commands.SetString infoBooleanType infoNewBodyType

です。


〇よりコントロールされたパイプコマンド
以前のスクリプトを数値を少し変更し、断面を正方形と三角形になる様にし、
それぞれ新規ボディで作成されるように修正しました。

#Fusion360API python script
#Author-kantoku
#Description-create PipeFeature sample

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

        # new doc
        _app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)
        des  :adsk.fusion.Design = _app.activeProduct
        des.designType = adsk.fusion.DesignTypes.ParametricDesignType
        root :adsk.fusion.Component = des.rootComponent

        # create sketch
        crv = initSktCircle(root)

        # create pipe
        initPipe(crv, 'infoRectangular', 'infoNewBodyType')

        # create sketch
        crv = initSktSpline(root)

        # create pipe
        initPipe(crv, 'infoTriangular', 'infoNewBodyType')

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

def initSktSpline(comp :adsk.fusion.Component):
    skt :adsk.fusion.Sketch = comp.sketches.add(comp.xYConstructionPlane)

    poss = [[-1,2,0], [2,1,0], [-3,-4,0]]

    pnt3D = adsk.core.Point3D
    objs = adsk.core.ObjectCollection.create()
    [objs.add(pnt3D.create(x,y,z)) for (x,y,z) in poss]
        
    crvs :adsk.fusion.SketchCurves = skt.sketchCurves
    crv = crvs.sketchFittedSplines.add(objs)

    return crv

def initSktCircle(comp :adsk.fusion.Component):
    skt :adsk.fusion.Sketch = comp.sketches.add(comp.xYConstructionPlane)

    pnt3D = adsk.core.Point3D
    crvs :adsk.fusion.SketchCurves = skt.sketchCurves
    crv = crvs.sketchCircles.addByCenterRadius(pnt3D.create(-5.0,-5,0), 4.0)

    return crv

def initPipe(
    path,
    infoSectionType = 'infoCircular',
    infoBooleanType = 'infoNewBodyType'):

    sels :adsk.core.Selections = _ui.activeSelections
    sels.clear()
    sels.add(path)

    txtCmds = [
        u'Commands.Start PrimitivePipe', # show dialog
        u'Commands.SetDouble SWEEP_POP_ALONG 1.0', # input distance
        u'Commands.SetDouble SectionRadius 0.5', # input radius
        u'Commands.SetString infoSectionType {}'.format(infoSectionType),
        u'Commands.SetString infoBooleanType {}'.format(infoBooleanType),
        u'NuCommands.CommitCmd' # execute command
    ]
    
    for cmd in txtCmds:
        _app.executeTextCommand(cmd)

    sels.clear()

結果はこの様になります。
f:id:kandennti:20210426153534p:plain


長い間の悩みが解消されたようです。これが利用出来るようになれば以前以上に
APIからのテキストコマンドの呼び出しが有効な手段となるはずです。