こちらの続きです。
NativeObjectとProxyの理解とモロモロ1 - C#ATIA
ババっと答えのコードを示してしまうのはあまりに不親切と感じるので、真面目にやります。
今までサラっと進めましたが、Fusion360APIに取り組む上で避ける事が出来ない
コンポーネントとオカレンスについて理解を深めます。
実はここは、オカレンスなんです。
"コンポーネント1:1 って書いてあるんだからコンポーネントでしょ? 頭おかしいの?"
と思われるでしょうが、オカレンスなんです。
もうちょっと説明すると
赤印はコンポーネント名で
Fusion 360 Help
青印はオカレンス名です。
Fusion 360 Help
試しに、"コンポーネント1:1” をコピーし、ルートコンポーネントにペーストします。
"コンポーネント1:2” とイカにもと言う名称でペーストされます。
"コンポーネント1:1” をリネームするためにダブルクリックすると ":1" の部分は
既存の名称としては入っていません。
そのまま適当な名称に変更すると、ペーストされたコンポーネントまでリネームされます。
イメージとしてはこんな感じです。
画面上には表示されていない ”コンポーネント1” が存在しており、”コンポーネント1”を
参照した状態の ”コンポーネント1:1” と ”コンポーネント1:2” と言う名称のオカレンスが
画面上で表示されている事になります。
解釈を追加すれば、”コンポーネント1:1” をアクティブな状態に作業している状態は
”コンポーネント1” と言うコンポーネントで作業している事になるでしょう。
"オカレンス" と言う言葉がGUI上では一切表示されないため、劇的にややこしいです。
極端な話、
コンポーネント:形状情報 オカレンス:配置情報
を管理していると思っておいても良いかな?とは思っています。
ボルト等、同一のものを複数配置しなければならない場合は、この様な方法を採用するのは
データの圧縮になりますし、直観的な気がします。
これだけ説明しているにも関わらす、ルートコンポーネントだけはオカレンスがありません。
絶対的なもの(移動もジョイントで可動する側にも出来ない)で特別な存在です。
※このファイルをリンク付きのコンポーネントとして他ドキュメントに取り込んだ場合は、
当然オカレンスが存在することになります。
逆にその他のコンポーネントは、仮に1個しか配置されていなくてもオカレンスが必ず存在
しています。(と言いますか、オカレンスにコンポーネントが存在してます)
さて、ここから前回期待を裏切った理由を探ります。
が、その前に折角コピペしたコンポーネント(正しくはオカレンス)が有るので
これを念の為、X 10mm Y 20mm Z 30mm 移動しておきます。("位置をキャプチャ" 忘れずに)
これの期待はルートコンポーネント上で X 20mm Y 30mm Z 40mm の位置です。
でも、これを測定するつもりではなく ”コンポーネント1:1” と同一では混乱するので
ずらしただけです・・・。
問題のきっかけとなった部分はこの辺りです。
・・・ # オカレンスのコンポーネント # オカレンスにはスケッチが無く、参照元のコンポーネントに有り comp :adsk.fusion.Component = occ.component # コンポーネント内の1個目のスケッチ skt :adsk.fusion.Sketch = comp.sketches[0] ・・・
コメントに記載した通り、オカレンスには該当するスケッチ(sketchesプロパティ)が
無いため、コンポーネントからスケッチを取得しています。
先程示した通り、"occ.component" は "コンポーネント1" を参照しています。
これは2個のオカレンスから参照されている状態となっている為、コンポーネントだけ
から見た場合、どちらのオカレンスのスケッチを示しているのか? が、わかりません。
"辿って取得しているのだから、察しろよ" と言う気持ちもわかるのですがダメなんです。
それを確認するためのプロパティがあります。
今回のタイトルに含まれている、こちらのnativeObjectプロパティです。
Fusion 360 Help
簡単な解釈を行うと、nativeObjectプロパティで値を取得出来る場合はNativeObjectはではなく、
pythonの “None” を返してくる場合(空の場合)は、既にNativeObjectと言う事です。
これを確認する為、こんな感じで修正しました。
# Fusion360API Python script # sample3 import adsk.core, adsk.fusion, traceback def run(context): ui = None try: # おまじない app :adsk.core.Application = adsk.core.Application.get() ui :adsk.core.UserInterface = app.userInterface des :adsk.fusion.Design = app.activeDocument.design # ルートコンポーネント root :adsk.fusion.Component = des.rootComponent # ルートコンポーネント内のオカレンスの1個目 occs :adsk.fusion.Occurrences = root.allOccurrences occ :adsk.fusion.Occurrence = occs[0] # オカレンスのコンポーネント # オカレンスにはスケッチが無く、参照元のコンポーネントに有り comp :adsk.fusion.Component = occ.component # コンポーネント内の1個目のスケッチ skt :adsk.fusion.Sketch = comp.sketches[0] msg = 'ではありません!' if skt.nativeObject else 'です!' ui.messageBox(skt.name + 'は、nativeObject' + msg) except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
実行すると
です。・・・で、"NativeObject は何奴?" と言う事になります。
内容が重複しますが、上記のコードのスケッチ(skt)は、コンポーネントから取得しており
どちらのオカレンスの物かわかってません。
この共有したコンポーネントの状態のスケッチは参照元となっているスケッチで、
GUI上で表示されているスケッチではありません。これをFusion360APIでは "NativeObject"
と呼ぶようです。
今回はスケッチで説明していますが、他にも色々なオブジェクトにもnativeObjectプロパティが
存在しています。
では、オカレンスに存在している状態でのスケッチはどの様にして取得すれば良いのでしょうか?
と言ったところで、お時間が参りましたので次回に・・・。