C#ATIA

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

リンク付きAssyの作成

忘れちゃいそうなので覚書です。

こちらに取り組みました。
Solved: Betreff: API: change Parameter and save in current folder - Autodesk CommunitySolved: Betreff: API: change Parameter and save in current folder - Autodesk Community
取り組みたかったわけではないのですが、最初にレスしたので責任感じて。

上記リンク先の最初のレスは、特定のパラメータをAPIで編集しつつ異なる
ファイル名で保存したい と言うもので、これは別に問題無いです。

苦しんだのは2個目のレス。
個別に保存したファイルをコンポーネントとして取り込んだ状態にしたい
と解釈し挑戦しました。

データパネルのファイルの保存や読み込み自体は簡単なのですが、タイミングが
非常に面倒なんです。

こちらにファイルを開く処理は "こうじゃないのかな?" と書いたことがあります。
解決済み: Re: ファイルの修復ができるときとできない時がある - Autodesk Community解決済み: Re: ファイルの修復ができるときとできない時がある - Autodesk Community
今回は保存なのですが、こちらの逆の手順です。

ファイル保存されたイベントが、こちらに用意されているのですが
ほぼ役に立ちません。
Fusion 360 Help
恐らくこちらのイベントは "ファイル保存コマンド" が終了した際に発生するだけで
ファイル自体が保存された訳ではないんです。・・・困っちゃうんです。

そこで最初はDocumentのdataFileプロパティが取得出来れば、保存が完了している
事に気が付き、こんな感じの関数を作りました。

        def waitFinishedSaving(
            doc :adsk.core.Document):

                while True:
                    adsk.doEvents()
                    try:
                        doc.dataFile
                        break
                    except:
                        time.sleep(0.1)

dataFileプロパティが取得出来ない(保存が終わっていない)場合は、
例外で拾い出し、0.1秒後に再チャレンジしています。
でも、これ駄目なんです。 SaveAsは、既に古いdataFileが残った状態の為
保存が完了していなくても例外が出ないんです。

結果的に開いているドキュメントからdataFileの取得を諦め、クラウド側から
引っ張り込んでくることにしました。

        def getDataFileFromDataPanel(
            docNames :list,
            folder) -> list:

            wait = 3.0
            while True:
                try:
                    folder.dataFiles.asArray()
                    break
                except:
                    time.sleep(wait)
                    adsk.doEvents()

            names = []
            
            while True:
                for name in docNames:
                    if not name in names:
                        time.sleep(wait)
                        break
                else:
                    app.executeTextCommand('DataPanel.reload')                    
                    names = [f.name for f in folder.dataFiles.asArray()]
                    adsk.doEvents()
                    continue
                break

            dataFiles = folder.dataFiles.asArray()
            files = []
            for name in docNames:
                for df in dataFiles:
                    if name == df.name:
                        files.append(df)
                        break
                else:
                    continue

            return files

2回の無限ループと1回の多重ループと言うキモイ形になっちゃいました。

最初の "while True" では、DataFileオブジェクトにアクセスするだけです。
後からわかったのですが、どうもFusion360が保存している最中にクラウド側に
アクセスすると例外になるようです。
その為、例外を避ける為アクセスしているだけです。

2回目の "while True" では、欲しいDataFileが全て保存されているかどうかだけ
チェックしています。

最後の多重ループで目的のDataFileを取得しています。
・・・もうちょっと素直なコードに書き換えられそうな気がしているのですが


実はこれ実用的じゃない事例が2種類ある事に気が付いています。
・目的のフォルダ内に、目的のファイルと同一名のファイルがあると、目的では
 ない方のファイルを取得してしまう可能性が有る。
・個人ライセンスの場合、編集可能数10個に達した時点で保存が出来なくなるため
 あっさり無限ループ餌食になる。


まぁあのスクリプト自体が役立つような気がするので、まぁ良いかな。
リンクを切った状態のAssyであれば、ローカルキャッシュかエクスポートで
出来そうなので、もっと短時間で処理出来そうな気がする。