こちらの続きです。
NativeObjectとProxyの理解とモロモロ3 - C#ATIA
前回は、タイトルとしていたNativeObjectとProxyが登場し、大体解決しました。
あくまで大体なので、解決しない事例が出てきます。
早速ですが、前回のGUIのコンポーネント(正しくはオカレンス)内にコンポーネントを
さらに作ります。(コンポーネント2:1)
ルートコンポーネントから見ると、孫世代のコンポーネントとなります。
これを便利上、"孫コンポーネント" と呼ぶことにします。
この孫コンポーネント内に、孫コンポーネントのXY平面をサポートとしたスケッチ作成します。
スケッチ内では前回同等、原点を中心とした円を作成します。
続いて、"コンポーネント1:1" 内の孫コンポーネントを移動します。
"位置をキャプチャ" 忘れず行ってください。
これも移動量は X 10mm Y 20mm Z 30mm としておきましょう。
ルートコンポーネントから見た場合、 X 20mm Y 40mm Z 60mm となっています。
これを前回のコードを修正し、孫コンポーネントのスケッチ円の中心座標を取得出来るようにします。
# Fusion360API Python script # sample4 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 # 孫コンポーネント(正しくはオカレンス)取得 occs :adsk.fusion.Occurrences = root.allOccurrences occ :adsk.fusion.Occurrence = occs.itemByName('コンポーネント2:1') # オカレンスのコンポーネント # オカレンスにはスケッチが無く、参照元のコンポーネントに有り comp :adsk.fusion.Component = occ.component # コンポーネント内の1個目のスケッチ skt :adsk.fusion.Sketch = comp.sketches[0] # proxyとして取得 skt_proxy :adsk.fusion.Sketch = skt.createForAssemblyContext(occ) # スケッチ内の1個目の円 - 目的の円 curvrs :adsk.fusion.SketchCurves = skt_proxy.sketchCurves circle :adsk.fusion.SketchCircle = curvrs.sketchCircles[0] # SketchCircleには中心点情報が無いので、geometryを取得 geo :adsk.core.Circle3D = circle.worldGeometry # 単位を正しくしたい為、係数取得 unitsMgr :adsk.core.UnitsManager = des.unitsManager defLenUnit :str = unitsMgr.defaultLengthUnits covunit :float = unitsMgr.convert(1, unitsMgr.internalUnits, defLenUnit) # 中心座標表示 ctr :adsk.core.Point3D = geo.center ui.messageBox('X: {1}{0}\nY: {2}{0}\nZ: {3}{0}'.format( defLenUnit, ctr.x * covunit, ctr.y * covunit, ctr.z * covunit)) except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
結果はこちら
あぁ予定外。正しく取得出来ました。
ん~そうか、選択じゃないからか・・・。
孫コンポーネントを作りましたが、実はルートコンポーネント直下にはコピペした
GUIコンポーネント(便利上、子コンポーネントと呼びます)にも出来ています。
しかも運の悪い事に同一のオカレンス名と言う扱いの悪さ・・・。
座標値を測定すると X 20mm Y 30mm Z 40mm です。
確かに先程移動したのは "コンポーネント1:1" の孫コンポーネントだけだったためです。
個人的には、これちょっと納得出来ない仕様なんですけど仕様なので仕方ないです。
結局、"コンポーネント1:2" の孫コンポーネントの円の中心(青矢印)は取得出来て
いないです。
原因はこちらのオカレンスの取得方法です。
・・・ # 孫コンポーネント(正しくはオカレンス)取得 occs :adsk.fusion.Occurrences = root.allOccurrences occ :adsk.fusion.Occurrence = occs.itemByName('コンポーネント2:1') # <-これ ・・・
itemByNameメソッドで目的のオカレンス名を指定しましたが、複数ある場合は
恐らく上にある方を優先的に返すのだろうと思われます。
こうして考えるとitemByNameメソッドに頼るのは、若干危ないな。
ん~結局悩んだ末、上から順番に目的の子コンポーネント(オカレンス)を取得し、
childOccurrencesプロパティを利用しました。
Fusion 360 Help
・・・ # ルートコンポーネント root :adsk.fusion.Component = des.rootComponent # 全オカレンス取得 occs :adsk.fusion.Occurrences = root.allOccurrences # <-修正 # 子コンポーネント(コピペされたオカレンス)取得 child_occ :adsk.fusion.Occurrence = occs.itemByName('コンポーネント1:2') # <-修正 # 孫コンポーネント(正しくはオカレンス)取得 occ :adsk.fusion.Occurrence = child_occ.childOccurrences.itemByName('コンポーネント2:1') # <-修正 # オカレンスのコンポーネント # オカレンスにはスケッチが無く、参照元のコンポーネントに有り comp :adsk.fusion.Component = occ.component ・・・
実行結果はこちら
無事取得出来ました・・・出来たけどすっきりしませんね。
ルートコンポーネントから、目的のスケッチが入っているオカレンスまでの道のりを
知っているから出来ただけなので。
次回はもうちょっと実践的?な内容で続けます。