いつもありがとうございます。
タイトルの通り、フォルダのIDからコンポーネントをAPIで挿入したいです。
urn:adsk.wipprod:fs.folder:co.kuClebubTj-Rn8Q2LI******
というIDは取得できたんですが、そのIDで入れる時には、
rootFolderからループでフォルダの中に下りていって、
dataFolders.itemById(id)
にて、フォルダを探してファイルにたどり着いているんですが、フォルダのループを回してたどり着くのと時間が差が感じられず、itemByIdの使い方が間違ってるのかも???と思っています。
もしわかれば教えてください。どうぞよろしくお願い致します。
解決済! 解決策の投稿を見る。
回答者: kandennti. 解決策の投稿を見る。
@maeokaQ2NB3 さん こんにちは。
色々と試したところ、リンク付きでインポートが出来ました。
目的のフォルダのIDと目的のファイル名が分かっている事が前提です。
(目的のフォルダの名前でも出来そうです)
データパネルの状態は、こんな感じです。
API(プロジェクト)
L hoge(フォルダ)
L hoge(目的のファイル)
以下のスクリプトを実行すると、
・新規でファイルを作成
・プロジェクトのルートフォルダの位置に "piyo" の名前で保存
・"hoge" をリンク付きで挿入
恐らく、挿入する際は同一プロジェクトであることが条件だと思います。
#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: # 目的のフォルダのIDと目的のファイル名が分かっている事前提 target_folder_id = 'urn:adsk.wipprod:fs.folder:co.Mh12739LTn6Rp0pWqJgHmQ' target_filename = 'hoge' new_filename = 'piyo' # オマジナイ global _app, _ui _app = adsk.core.Application.get() _ui = _app.userInterface # アクティブプロジェクト取得 project = _app.data.activeProject # 目的のフォルダ取得 # 目的のフォルダ位置が分からない場合は検索しまくる fols = project.rootFolder.dataFolders children_folder = fols.itemById(target_folder_id) # 目的のファイル名取得 target_datafile = getDatafileByName(children_folder, target_filename) # 新規ファイル作成 # 恐らく目的のファイルと同一プロジェクトに保存されていることが前提の様 newDoc = _app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType) newDoc.saveAs(new_filename, project.rootFolder, 'これはAPIテスト用です', '') root :adsk.fusion.Component = _app.activeProduct.rootComponent # リンク付き取り込み occ = root.occurrences.addByInsert( target_datafile, adsk.core.Matrix3D.create(), True) except: if _ui: _ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) # dataFilesにItemByItemが無いんですね・・・ def getDatafileByName( dataFolder :adsk.core.DataFolder, fileName :str) ->adsk.core.DataFile: for file in dataFolder.dataFiles: if file.name == fileName: return file break return None
IDやファイル名の関係上、このままではエラーになると思いますので
修正してください。(例外処理してません・・・)
ありがとうございます。動きました!
もう一つお聞かせいただけますか?分割は可能といえば可能なんですが、ファイルが一つのフォルダに800個あり、ファイルを検索してAPIで挿入する時に完全にフリーズするので、フォルダを800個作り、IDをテキストに吐き出すプログラムを作りました。root - parts フォルダの中にそのフォルダ群はあるのですが、IDで降りていっても、ループでフォルダをたどるのも体感時間があまり変わりませんが、その理由はご存じですか?
なかなか重くてつらいです・・・
800個もモデル作った事が無いので、何とも・・・。
>IDで降りていっても、ループでフォルダをたどるのも体感時間があまり
>変わりませんが、その理由はご存じですか?
理由はわからないのですが、確かにDataHubを扱うと異常なほど
遅い印象はあります。
恐らく処理そのものが遅いのではなくて、アクセスすること自体が遅い
印象ですね。(Stepデータを開く際、「開く」で開けるのと、
データパネルでUpするのでは、かなりの時間差を感じます)
フリーズする件についてですが、可能性だけ探ってみるとですが、
こちらのコードのループ内に「adsk.doEvents()」を入れています。
http://kantoku.hatenablog.com/entry/2020/01/20/093016
Helpに記載が無いメソッドですが、恐らく一瞬だけアプリケーション側に
オペレーションを渡しているのだろうと思います。
大きなファイルを読み込む際、Fusion360のブラウザ(左側部分)が
黒くなったりしませんか? 恐らくFusion360が一定時間以上
オペレーションを失っていると、あの黒い状態が発生するのだろうと
思うのですが、「adsk.doEvents()」を入れるとあの現象が防げます。
(但し、処理は遅くなります。)
Fusion360自体はマルチタスクなソフトではないのですが、マルチ
スレッドは利用出来ます。こちらにマルチスレッドのサンプルが有ります。
https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-85edd118-c2a4-11e6-b401-3417ebc87622
"doEvents()"を1個取り込む毎に行うと遅すぎるのですが、こちらを
利用しイベントを発生させ、doEvents()や保存を組み込むと、
仮にフリーズしたとしても、ひょっとしたら行けるところまで状態の
保存は可能かもしれません。
Fusion360は基本的に外部からAPIでの操作は出来ないと思うのですが、
唯一出来ることのサンプルがこちらにあります。
https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-8A2C4ECD-7D82-4E56-AFE8-4FA72464AE66
htmlファイルからファイルを開くことが可能だそうです。
(サイトの一番下で試せます)
よく読むと「開く」だけではなく「挿入」も可能っぽいです。
ひょっとしたら何かの可能性があるかもしれません。
Autodesk社製品にForgeと言うものがあるのですが、恐らくFusion360の
クラウドデータを支えているのではないかな? と思っています。
https://forge.autodesk.com/
単にFusion360からのアクセスが遅いことが原因なのであれば、直接
Forgeで行ってしまえれば遅さは解消しそうな気もしてます。
但し、「リンク付きで取り込む」ような処理はFusion360でしか
行えない様な気はしてます・・・。
Fusion360のアドインを幾つか公開されている方が、forgeの
チュートリアルの一部を公開しています。
https://github.com/hanskellner/learn.forge.viewhubmodels
(興味無いのであまり見てません・・・)
もう一つのアイデアですが、オンラインが原因なのであれば
オフライン上で全て取り込んだ状態に作り上げ、のちにオンラインに
するとか・・・オフラインにした時点でDataHubにアクセス
出来ないのでムリっぽい気もしてます。
kantokuさま、
いつもありがとうございます!しかもすごくボリューム沢山!
doEvents()、試してみます。ありがとうございます。
マルチスレッドは今は頭がついていかないですが、解決策に近い可能性が高そうなので読み込んでみます!
htmlも見たことありました・・・この活用もありですね。これもまた研究してみます。
forgeは知り合いが確か一度勧めてくださったので、聞いてみます。
いやあ、調べてもなかなか出てこないのに色々教えてくださってありがとうございます!
めちゃ助かります。
またわからない事があったら質問させてください。本当にありがとうございます。
書いた量のの割には、中身は薄いです。
800個はさすがにつらいので、単純形状のデータ50個で試しました。
http://kantoku.hatenablog.com/entry/2020/01/31/180849
タスクトレイのCPUでFusion360確認してました。
仮に「反応なし」のようになっていても、数値が上がっていれば
処理は続けているハズです。
おおお~。続いてありがとうございます!
すごいですね。本当に目的通りのものです。
全IDを取得することはスンナリと出来たので、本当だったら組み合わせて作るファイル直IDとかフォルダ直IDでinsertできればいいんですが、おっしゃる通り、forgeとかブラウザ経由のやり方を頑張って会得するのが良さそうだと思いました。
ありがとうございます!
続けてありがとうございます!
いま僕が使っているのが、ルートフォルダの中を、csvファイルに、
フォルダID,ファイルの後ろ2桁の数字
を一行ずつ読み込んでaddbyinsertしてます。一つにつき平均7秒と30秒程度かかってたんですが、IDのおかげでほぼ全て7秒と、早くなりました!
マルチスレッドの説明はウェブで読んだのですが、これは、一つのcsvの行を読んでる間に次の一行のオカレンスを入れる準備や、次々とinsertを出来るようになるものでしょうか?
お探しの情報が見つからないときは、コミュニティで質問しましょう。困っている人がいたら、情報を教えてあげましょう。