C#ATIA

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

コピペの為の依存している要素を選択する

昔、unofficialのサイトでTipsとして紹介されていたのですが、
・・・忘れました。

思い出しながら試してみました。
ベースにするデータはこんな感じです。

XY平面にスケッチ書いて押し出し・フィレット・境界・スイープ
させました。形状に意味は無く "一連が関連している" と思って
頂けると助かります。
又、例として出しているものは比較的単純ですが、もっと色々な
要素がごちゃ混ぜ状態だと思って頂けると幸いです。


この状態で最後のスイープを他のCATPartに履歴付きでコピペ
する為には、関連しているもの全てをコピーする必要が有るの
ですが、絶対条件として
・関連している要素の先頭がデータム要素
・XY,YZ,ZX平面
のどちらかである必要があります。


確か、Tipsとして紹介されていたのはGSDの "ツール" - "不要な
エレメントの削除..." だったような気がするのですが。

一度全ての要素を削除に変更し、目的のスイープを保持に
切り替えると、保持する為に必要な要素が "保持、伝播" に
なります。これがコピーすべき要素です。

但し、これらを選択済みで終了させる方法が何かあったような
記憶なのですが、どうしても思い出せません・・・。


"親/子..." を表示させ、親要素をクリックし続けると行きつくとこまで
いけるので、選択済み状態にした上でOKを押すと選択済み状態が
維持出来ました。

これが一番早いかな?


又、一番先頭がスケッチ1だと判明した場合、以前に更新済みの状態にし
あまり利用される事のないアップグレードをコマンドを利用する方法です。

スケッチ1をアップグレードすると、関連する要素が更新待機になります。
"パラメータ化を解析..." を行い、"更新待機フィーチャー" にすると
更新待機している要素のみが表示されるため、ダイアログを表示させたまま
選択しコピーが可能でした。

・・・と思ったのですが、無関係なものも選択しちゃうので、今回の
お話と逆パターンの関連する子を探し出す方法ですね。

確か "アップグレード" は、マクロで関連要素を探し出す際にも利用出来た
記憶があります。


個人的には "不要なエレメントの削除..." で選択済み状態にする方法が
見つかるのが簡単だと思うのですが・・・。
(もしくは、パワーコピー可能であればそれが一番楽)

要素の依存関係5

こちらの続きです。
要素の依存関係4 - C#ATIA

色々と悩んでます。一番の悩みは・・・取り組む時間が無い事です。

取り組んでいたものを捨て去って、新たな考え方を元に作り直して
いたのですが、想定していない結果となり、元の方針に戻しました。

まず単純な例を。スケッチを描き押し出しただけです。

この場合は、こんな表示にさせる事にしました。

基本的に、タイムラインの要素のみにしようと思っていたのですが、
表示がだらしなくなるため、
・Treeトップはルートコンポーネント
・XY,YZ,XZ平面は入れる(スケッチが依存している場合が多い為)
・ボディは入れる

個人的には結構素直な表示だと思っています。
ここでフィレットを付けます。

フィレットは、"押し出しで作成されたエッジに依存している"
と言う情報を取得する事が出来ません。
"ボディ1のエッジに依存している" と言う情報は取得できます。
悩んだ末、ボディを入れることにしました。

ゴチャゴチャやるとこんな感じです。

見やすいのかな・・・。



一番悩んでいるのが、次のパターン。
スケッチを描き、押し出し。再度スケッチを描き、押し出し。
ラップするようにして作っていますが、2個目の押し出しは
新規ボディで作ります。

これを実行すると、こんな感じで問題ありません。

これをブーリアンでくっ付けます。

この状態で表示させると

押し出し2で作成したボディ2が消えます・・・。
これはFusion360クソ忌々しい仕様です。

GUIで編集に入ると、間違いなくターゲットボディと
ツールボディの情報を持っています。

しかし、APIでは取得出来ません。

('traceback'なんとかは、エラーを意味します)


実はこの2個の情報を取得する方法を知っています。
タイムラインのマーカーをブーリアンの直前に移動させ

実行させると、両方共取れます。

これがFusion360クソ忌々しい仕様です。

タイムラインマーカーの移動はAPIでも出来るのですが、
情報取得の為に長時間の再計算(Fusion360が)を必要とする
マーカーの移動をさせるべきかどうか?
に悩んでます。
相談して意見を聞けば良いのですが、これを英語で説明
出来るのか? 回答もらって理解出来るのか?
についても悩んでます。

時間が欲しい。暇になりたい。

アクティブシートの最初のビューをコピペし形状を削除

しろくろさんがかなりヒントを書いてくれたので、
自分なりに作ってみました。

”CATIA.HSOSynchronized使った方が早い” と書きていましたが、
試した所若干遅かったです。ごめんなさい。

'vba アクティブシートの最初のビューをコピペし形状を削除

' winAPI
#If VBA7 And Win64 Then
    Private Declare PtrSafe Function timeGetTime Lib "winmm.dll" () As Long
#Else
    Private Declare Function timeGetTime Lib "winmm.dll" () As Long
#End If

Option Explicit

Sub CATMain()
    
    Dim actdoc As DrawingDocument
    Set actdoc = CATIA.ActiveDocument
    
    Dim sel As Selection
    Set sel = actdoc.Selection
    
    Dim actSheet As DrawingSheet
    Set actSheet = actdoc.Sheets.ActiveSheet
    
    Dim vi As DrawingView
    Set vi = actSheet.Views.Item(3) '一個目のビュー
    sel.Clear

    If vi.GeometricElements.Count < 2 Then
        'GeometricElements.Countが1の場合は、
        '形状が無いみたい
        Exit Sub
    End If


    Dim t As Long
    t = timeGetTime  '時間の測定開始
    
    'CATIA.HSOSynchronized = False
    
    'ビューコピー
    sel.Add vi
    sel.Copy
    
    sel.Clear
    
    'ビューペースト
    sel.Add actSheet
    sel.Paste
    
    'クローンしたビューの選択
    sel.Clear
    sel.Add actSheet.Views.Item(actSheet.Views.Count)

    '現行選択の形状を検索
    sel.Search "CATDrwSearch.2DGeometry,sel"
    
    Dim removeCount As Long
    removeCount = sel.Count
    
    '削除
    '昔はDeleteよりCutの方が早いと言われていたのですが
    'Deleteの方が早いです
    sel.Delete
    'sel.Cut
    
    'CATIA.HSOSynchronized = True
    
    '削除数と処理時間
    MsgBox removeCount & " : " & (timeGetTime - t) * 0.001 & "s"
    
End Sub

検索-削除を複数回行うより1回の方がきっと早いだろうと
思われるため、こちらの設定をマクロの記録しました。

緑部分のオン/オフがCATIA.HSOSynchronizedなのかと思って
いたのですがどうなんでしょうかねぇ。
r1 Application (Object)


どうしても複数条件が必要な検索をマクロで使用する必要が
ある場合は、拡張で何とか条件を作った方が良いかな?とも
思っています。



又、何で手動で手間がかかるのか? が少し分かりました。
実際に検索した際、こんな表示になります。

テストした際のデータに形状が14015個有るのに対して、
検索後に選択されたのは1290個 と言う状態です。
この場合、選択し検索し削除し、再度選択し検索し削除・・・
と、10回以上行う必要がある為ではないかな?と感じてます。

僕の設定が偶々1290個になっているのですが、これは
オプションの設定で変更できます。

試した所、MAXでは5000でした。量が多いとやっぱり複数回
行う必要があるかな・・・。

要素の依存関係3

こちらの続きです。
要素の依存関係2 - C#ATIA

取りあえず履歴から情報を取得する事は後回しにして、
依存関係を表示させるものを探しました。

最初はVis Networkと言うものにしようかと調べていたら、
こちらを発見しました。
mxGraphで階層グラフを可視化する | フューチャー技術ブログ
確かにmxGraphの方が綺麗なグラフを描いてくれそうです。
GitHub - maxGraph/maxGraph: maxGraph is a fully client side JavaScript diagramming librarymxGraph 4.2.2

飛び切り高性能です。


昨日のスクリプトと合わせパレットで表示させると
こんな感じです。(分かりにくい)

押し出し1と2はスケッチ1に依存して・・・と言う感じ。
ん?矢印逆か?

実はこれ、表示するのにものすごく時間がかかるんです。
”これで大丈夫なはず!!” と思って実行させても何も表示されず、
コンソール見てもエラーは吐かれず・・・と思っているうちに
表示されました。位置の計算に時間がかかるのだろうけど
あまりに遅い。

この辺を理解したい。
がんばってmxGraphの初期表示パフォーマンスを改善する - Qiita
表示は本当にきれいです。

要素の依存関係2

こちらの続きです。
要素の依存関係1 - C#ATIA

ドキュメントでチラッと確認した際、"あぁ、あのプロパティチェック
すれば親子関係は取得出来るな" と思っていたものが違ったので
チマチマやるしかないと分かりました。しんどい。

ある程度ボリュームのあるサンプルデータとして、こちらを
使う事にします。

何から何まで取得するには無理があるので、とりあえず
プロファイルを利用しているものだけを出力します。

# Fusion360API Python script

import traceback
import adsk.fusion
import adsk.core


def run(context):
    ui = adsk.core.UserInterface.cast(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

        tl: adsk.fusion.Timeline = des.timeline
        lst = [t for t in tl]
        ents = [t.entity for t in tl]

        for e in ents:
            print(e.name)
            lst = getProfileReferences(e)
            [print(f' -- {p.name}') for p in lst]

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

def getProfileReferences(self):

    def getParentEntity(prof):
        if hasattr(prof, 'parentSketch'):
            return prof.parentSketch
        elif hasattr(prof, 'body'):
            return prof.body
        else:
            return

    try:
        prof = self.profile
        if hasattr(prof, '__iter__'):
            profs = [getParentEntity(p) for p in self.profile]
            profsDict = {}
            [profsDict.setdefault(p.entityToken, p) for p in profs]
            return list(profsDict.values())
        else:
            return [getParentEntity(prof)]
    except:
        return []

取りあえず、タイムラインの要素名を先頭から出力しつつ、
プロファイルを持っているものは、プロファイルの要素名を
"--"付きで出力します。 恐らく他人にはよくわからない事を
やっている事は自負しています。
サンプルデータだとこんな出力。

スケッチ1
Extrude1
 -- スケッチ1
スケッチ2
Extrude2
 -- スケッチ1
Draft1
スケッチ3
Extrude3
 -- スケッチ3
Fillet1
Hole1
スケッチ4
スケッチ5
Sweep1
 -- スケッチ4
スケッチ6
Extrude4
Draft2
平面1
スケッチ7
Extrude5
 -- スケッチ7
スケッチ8
Extrude6
 -- スケッチ8
Extrude7
 -- スケッチ8
スケッチ9
Extrude8
 -- スケッチ9
Mirror1
スケッチ10
Fillet2
Fillet3
Chamfer1
Web1
Mirror2

まぁスタートしたばかりなので。

要素の依存関係1

4年放置されているこちらのテーマに挑むことにしました。
List of Dependent Features - Autodesk Community

ちょっと始めましたが、とんでもなく大変だと分かりました。
甘かったかな・・・。