C#ATIA

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

documentイベント

こちらの取り組みです。
Drawing PDF Export: How to access the new export manager? - Autodesk Community
あぁ最初のレスは完全なる勘違いです。

開いている3Dデータから、開いていない図面データをAPIでPDFファイルとして
エクスポートしたい って事ですね。やっと理解しました。

Fusion360APIには結構なイベント処理が実装されているのですが
"Documentが完全に開かれた後に発生するイベントを利用したいが機能していない"
との事です。これです。
Fusion 360 Help

過去にAPIフォーラムでもDocumentナンチャラのイベントのタイミングがおかしい
事は何度か指摘されていたのは知っています。・・・あまり読んでいませんが。

あちらのレスに投げたコードの出力があまりに見にくいため、修正しつつ
イベントのタイミングを確認するコードにしました。

# Fusion360API Python script
# Dump the task of opening f2d files.
# ' << ' : Increased Tasks
# ' >> ' : IDecreased tasks
# '***' : Checked delimiters

import adsk.core, adsk.fusion, traceback
import adsk.drawing
import time

_app = adsk.core.Application.cast(None)
_ui = adsk.core.UserInterface.cast(None)
handlers = []

def run(context):
    try:
        global _app, _ui
        _app = adsk.core.Application.get()
        _ui = _app.userInterface

        # add event
        onDocumentOpened = MyDocumentOpenedHandler()
        _app.documentOpened.add(onDocumentOpened)
        handlers.append(onDocumentOpened)

        onDocumentOpening = MyDocumentOpeningHandler()
        _app.documentOpening.add(onDocumentOpening)
        handlers.append(onDocumentOpening)

        # msg
        dumpMsg(_app.executeTextCommand(u'Application.ListIdleTasks'))
        dumpMsg(' -- document open -- ')


        # get f2d datafile
        datafile = None
        for df in _app.data.activeProject.rootFolder.dataFiles:
            if df.fileExtension == 'f2d':
                datafile = df

        # check datafile
        if not datafile:
            _ui.messageBox('Abort because the "f2d" file cannot be found in the rootFolder of activeProject.')
            return

        # open doc
        docs = _app.documents
        docs.open(datafile)

        # show task
        state = []
        for _ in range(80):
            adsk.doEvents()

            tasks = _app.executeTextCommand(u'Application.ListIdleTasks').split('\n')
            now = [s.strip() for s in tasks[2:-1]]

            addTask = list(set(now) - set (state))
            [dumpMsg(' << {}'.format(s)) for s in addTask]

            delTask = list(set(state) - set (now))
            [dumpMsg(' >> {}'.format(s)) for s in delTask]

            dumpMsg('***')
            state = now
            time.sleep(0.1)

        # remove event
        _app.documentOpened.remove(onDocumentOpened)
        _app.documentOpening.remove(onDocumentOpening)

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

def dumpMsg(msg :str):
    _ui.palettes.itemById('TextCommands').writeText(str(msg))

class MyDocumentOpenedHandler(adsk.core.DocumentEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        dumpMsg('--- Document Opened Event ---')

class MyDocumentOpeningHandler(adsk.core.DocumentEventHandler):
    def __init__(self):
        super().__init__()
    def notify(self, args):
        dumpMsg('--- Document Opening Event ---')

申し訳ないのですが、あなたのPCではエラーになります。
(DataFile.idが僕の所の番号の為です)

データパネルのアクティブなプロジェクトのルートフォルダー内の最初の
F2Dファイルを開くように修正しています。
F2Dファイルが1個も無いと、中止します。

興味も無いと思いますが、結果はこんな感じ。

Size: 6
*Queue:
  Ns::LambdaTask
  Ns::DelayedEventsTask
  Nu::ExecuteActiveSessionTask
  QTCursorMonitor
  CheckMaterialEventTask
  CheckValidationTask
*Incomplete queue:
 -- document open -- 
--- Document Opening Event ---
--- Document Opened Event ---
 << Nu::ExecuteActiveSessionTask
 << Nu::Task
 << CheckKeysTask
 << InvalidateCommandByIdTask
 << InvalidateCommandsTask
 << CheckMaterialEventTask
 << AutoCam::PostDrawTask
 << DocumentFullyOpenedTask
 << CheckValidationTask
 << Ns::DelayedEventsTask
 << Ns::LambdaTask
 << MSFCmnUIManagerIdleUpdateTask
 << QTCursorMonitor
***
***
 << Nu::AnalyticsTask
***
***
***
 >> CheckValidationTask
***
 >> InvalidateCommandByIdTask
***
***
***
 >> AutoCam::PostDrawTask
***
***
 >> CheckKeysTask
***
***
***
***
 >> Nu::Task
***
***
 >> DocumentFullyOpenedTask
***
***
***
***
 >> InvalidateCommandsTask
***
 >> MSFCmnUIManagerIdleUpdateTask
***
***
***
 << CheckValidationTask
 >> Nu::AnalyticsTask
***
***
***
 << InvalidateCommandsTask
***
***
***
 >> CheckValidationTask
***
***
***
 >> InvalidateCommandsTask
***
***

最初は何もしていない状態のFusion360のタスクの状態です。
"-- document open -- " 以後にファイルを開き始めています。
0.1秒毎にタスクをチェックしていて
" << " は追加されたタスク
" >> " は削除されたタスク
です。
恐らく最後の方の "InvalidateCommandsTask" でFusion360が操作可能になるのだろう
と思うので、この時点で完全にファイルがオープンされた状態になっていると思われます。

びっくりするのが、イベント発生のタイミング。
f:id:kandennti:20201217152807p:plain
DocumentOpeningイベントのタイミングは納得できますが、
DocumentOpenedイベントはファイルが開かれるはるか前に発生してます。
Helpの説明と "ドキュメントが開かれると" て書いてありますが、
ファイルを開くコマンドが終了したタイミングで発生しているとしか思えない。
全く役に立たないですね。

"InvalidateCommandsTask" が、Documentを開いている間ずっと発生していてくれれば
簡単なんだけどなぁ。どうしよう?