C#ATIA

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

DMUスペースアナリシスのセッション3

こちらの続きです。
DMUスペースアナリシスのセッション2 - C#ATIA
CATIAのマクロです。

気が付くのが遅かったのですが、grabcadこちらで問い合わせを
頂いてました。(コメント欄です)
Free CAD Designs, Files & 3D Models | The GrabCAD Community Library
一か月程放置してました。スイマセン。

頑張って日本語のブログを読んでくれたようです。
断面数を”1”として入力しても3個断面を作ってしまうとの事です。

断面数1の場合、ガイドのラインの中心部分だけに断面を作るわけ
ではなく、ラインの両端にも断面を作るようにマクロがなってました。
ん~よく覚えていないのですが。

その為、両端の断面を作らないようにするためには、
InitRange関数を以下の様に修正すると大丈夫です。

Private Function InitRange(ByVal Count As Long) As Collection
 Dim Lst As Collection
 Set Lst = New Collection

 Dim stp As Double
 stp = 1# / (Count + 1)

 Dim i As Long
 For i = 1 To Count
  Lst.Add i * stp
 Next
 Set InitRange = Lst
End Function

ドイツ人かな?

曲線の長さと同期させる6

こちらの続きです。
曲線の長さと同期させる5 - C#ATIA

毎回動画だけです・・・汚すぎて公開しづらい。

最初はアドインを停止した状態で線を移動してます。
その後は、ドキュメントを開いた直後から同期させたり
出来るようになりました。

考え方を変えたおかげで以下が改善しました。
・ドキュメントオープン直後、即修正済みのアスタリスクが付かなくなった。
・ドキュメントオープン直後から同期。
・パラメーター名を修正しても監視を継続。
・監視している一部の線を削除しても、監視を継続
・監視している円弧を円にしても、監視を継続(これは謎)

基本的な機能は望んでいる状態にほぼなりました!

Fusion360のオブジェクト入りリストを比較

Fusion360のオブジェクトが入ったリスト同士を比較したいんです。
リスト内の順番には依存したく無く、純粋に中身で比較したいんです。

以下のサンプルのリストは順番違いで中身は同じなので、”True”
を期待していますが、リスト同士では "False"。
どうやらsetでの比較なら順番に依存しないと分かったのですが、
生憎、Fusion360のオブジェクト(Fusion360に限らないと思うけど)
ではsetが作れない・・・。
他にも方法あると思うのですが、entityToken(str)使うのが正攻法と
判断しました。

# Fusion360API Python script

import traceback
import adsk.fusion
import adsk.core

def run(context):
    ui: adsk.core.UserInterface = None
    try:
        app: adsk.core.Application = adsk.core.Application.get()
        ui = app.userInterface
        des: adsk.fusion.Design = app.activeProduct
        root: adsk.fusion.Component = des.rootComponent

        # listのまま比較
        lstA = [
            root.originConstructionPoint,
            root.xYConstructionPlane,
            root.yZConstructionPlane,
        ]

        lstB = [
            root.yZConstructionPlane,
            root.xYConstructionPlane,
            root.originConstructionPoint,
        ]

        app.log(f'{lstA == lstB}') # -> False


        # entityTokenで比較
        tokenA = set(e.entityToken for e in lstA)
        tokenB = set(e.entityToken for e in lstB)

        app.log(f'{tokenA == tokenB}') # -> True

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

下らない内容なんですが、忘れちゃうので・・・。
(恐らく書いていても忘れる)

全てのユーザーパラメータの属性を出力する関数

こちらの続きです。
ユーザーパラメータの属性 - C#ATIA

確認作業が面倒な為、あのアドインに突っ込む為に出力部のみを
関数化。

def run(context):
    ui: adsk.core.UserInterface = None
    try:
        app: adsk.core.Application = adsk.core.Application.get()
        ui = app.userInterface

        dumpUserPrmAttrs(app.activeDocument)

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

def dumpUserPrmAttrs(doc: adsk.fusion.FusionDocument) -> None:
    app: adsk.core.Application = adsk.core.Application.get()
    prms: adsk.fusion.UserParameters = doc.design.userParameters

    attr: adsk.core.Attribute
    prm: adsk.fusion.UserParameter
    for prm in prms:
        for groupName in prm.attributes.groupNames:
            group = prm.attributes.itemsByGroup(groupName)
            app.log(f'GroupName:{groupName}')
            for attr in group:
                app.log(f'  Name:{attr.name}  ValueSize:{len(attr.value.encode())}')

                dict = json.loads(attr.value)
                for key in dict.keys():
                    app.log(f'    {key}:{dict[key]}')

本題より、ツール的なものばっかり作っていて進まない・・・。

ユーザーパラメータの属性

中々納得出来る状態になりません。
よくよく考えたら、監視している曲線とユーザーパラメータとの
関係がはっきりすれば良いので、ドキュメントの属性に書き込むより、
ユーザーパラメータの属性に監視している曲線のentityTokenを
関連付ければ良い事に気が付きました・・・今更。

今までは、1曲線につき1属性を作っていたのですが、試した所
1属性に結構な量の曲線のentityTokenを突っ込んでも大丈夫だと
分かってきましたよ。

# Fusion360API Python script

import traceback
import adsk.fusion
import adsk.core
import json

GROUPNAME = 'kantoku'

def run(context):
    ui: adsk.core.UserInterface = None
    try:
        app: adsk.core.Application = adsk.core.Application.get()
        ui = app.userInterface

        # new doc
        doc: adsk.fusion.FusionDocument = app.documents.add(
            adsk.core.DocumentTypes.FusionDesignDocumentType
        )

        # init UserParameter
        des: adsk.fusion.Design = app.activeProduct
        root: adsk.fusion.Component = des.rootComponent
        prm: adsk.fusion.UserParameter = des.userParameters.add(
            'test',
            adsk.core.ValueInput.createByReal(0),
            des.unitsManager.defaultLengthUnits,
            'hoge'
        )

        # get data
        lst = [
            root.entityToken,
            root.originConstructionPoint.entityToken,
            root.xYConstructionPlane.entityToken
        ]
        tokens = {str(idx): v for idx, v in enumerate(lst)}

        # UserParameter attribute
        prm.attributes.add(
            GROUPNAME,
            'test',
            json.dumps(tokens)
        )

        # dump
        attr: adsk.core.Attribute
        for groupName in prm.attributes.groupNames:
            group = prm.attributes.itemsByGroup(groupName)
            app.log(f'GroupName:{groupName}')
            for attr in group:
                app.log(f'  Name:{attr.name}  ValueSize:{len(attr.value.encode())}')

                dict = json.loads(attr.value)
                for key in dict.keys():
                    app.log(f'    {key}:{dict[key]}')

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

valueのサイズが2MBまでとなっていますが、全然余裕あります。
Fusion 360 Help

ほぼ作り直しになりますが、後から悩むより、今のタイミングで
大幅修正した方が正解のような気がしてます。

曲線の長さと同期させる5

こちらの続きです。
曲線の長さと同期させる4 - C#ATIA

実はダメだったパターンがある事に気が付きました。
・ドキュメントを切り替えると、監視対象を見失う。
・パラメータ名を変更すると、監視対象を見失う。
この2点を改善に取り組みました。

スケッチ作業中にパラメータを同期させると、どうしても
クラッシュしてしまう為、諦めてスケッチを抜けてから
同期させることにしました。
又、”デザイン” 以外では同期させない事にしました。
危険な匂いもしたので・・・。

ん~出口が見えなくてつらいな・・・。

曲線の長さと同期させる4

こちらの続きです。
曲線の長さと同期させる3 - C#ATIA

幾つかの困難?を乗り越え、何とか同期パラメータの情報を
ドキュメントに保存する事が出来るようになりました。

保存出来るようになった為、アドインさえ起動していれば
既存の機能の様にスケッチのラインを変更するだけで、
勝手にパラメータを修正します。長かった・・・。


現在は、1ドキュメントで1パラメータのみな上、パラメータ名も
固定なので、この辺を自由にしたいです。
その為の管理用のダイアログが必要なのですが、
ダイアログを表示させている最中に、もう一個ダイアログを
表示させることがFusion360では出来ないのでどうしようかな?