0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Autodesk Inventor API Hacking (InteractionEventsは必須)

Last updated at Posted at 2019-06-13

#0. はじめに
内容的には、'だいたい一度はハマること'なんですが、重要かつ文章量が多いので別に分けました。
Documentに変更を加える前に、必ずInteractionEvents.Start()しなさい、という内容です。
2019.07.17 --- 5.に追記事項があります。併せて読んでください

#1. Command実行中に、Command実行すると、まずい
例えば、以下のような状況を考えます。
Extrude.PNG
まさに、押し出しCommandが実行中です。
この状態で、別のCommandを実行すると、どうなるでしょうか?
そのCommandがInteractionEventsを使っておらず、かつ、Documentに変更を加える場合は、問題が発生する(≒InventorがCrashする)ことがあります。
例えば上記画像の例でいうと、この状態でフィーチャー押し出し1を削除すると、押し出しCommandがパニックになるわけです。

#2. 実行中のCommandを終了させる
では、Documentを変更する前に、実行中のCommandがあれば終了させるのには、どうすれば良いでしょうか。
条件付きですが(後で述べます)、InteractionEvents.Start()すると、実行中のCommandを終了させることが出来ます。

具体的には、以下のようなCodeになるでしょう。

private InteractionEvents interactionEvents;

public void ControlEvents_OnExecute(NameValueMap options)
{
    if (なにか不都合)
    {
        return;
    }

    interactionEvents = m_Application.CommandManager.CreateInteractionEvents();
    interactionEvents.Name = "MyCommandName";
    interactionEvents.OnActivate += InteractionEvents_OnActivate;
    interactionEvents.OnTerminate += InteractionEvents_OnTerminate;
    interactionEvents.Start();
}

private void InteractionEvents_OnActivate()
{
    using (var transaction = new TinyTransaction(m_Application.ActiveEditDocument, "コマンド名"))
    {
        try
        {
            //
            // 実際の処理
            //
            transaction.End();
        }
        catch (System.Exception ex)
        {
            //
            // エラー処理
            //
        }
        finally
        {
            interactionEvents.Stop();
        }
    }
}

private void InteractionEvents_OnTerminate()
{
    if (interactionEvents != null) {
        //
        // 必要なら、後処理
        //
        interactionEvents = null;
    }
}

なお、Transaction処理は、別記事のTinyTransactionを使っています。

19.06.14 訂正
初出で上記ソース中に

// TransactionがAbortで終了する場合(デフォルト)は、ここでのStop()と、
// Inventorが自動発行するStop()で、InteractionEvents_OnTerminate()が2度呼ばれる。
// 神経質な人は、transaction.End()の直後でinteractionEvents.Stop()して、
// ここではしないようにすると良い。

と書きましたが、勘違いだったようです。何か複合条件があるのかもしれませんが、今のところ再現できないので、積極的にfinallyInteractionEvents.Stop()するのを良しとします。

#3. InteractionEventsはInteractionEventsを終了させる
分かってしまえば簡単な話しなのですが、InteractionEvents.Start()は、既に実行中のInteractionEventsを終了させます。
ですので、先ほど後述すると言った条件とは、先に実行しているCommandがInteractionEventsを実行していることになります。
そして、見逃しがちなのですが重要なことは、Documentを変更するCommandは、ユーザーによる操作が無くてもInteractionEventsを使うべきだということです。
既に述べた通り、そうすることで先に実行中のCommandがあれば、終了させることが出来ます。
(5.に追記あり)

#4. ユーザーのInteractionがあるのに、InteractionEventsを使わずに済む例 (危険)
例えば、自前のFormでユーザー操作を受け付ける場合は、InteractionEventsを使わなくても実装できます。
こういった場合でも、くどいようですがInteractionEventsを使用すべきです。
(5.に追記あり)

#5. 先行のCommandを終了させる方法 (19.07.17追記)
3.と4.で、InteractiveではないCommandでも、InteractionEventsを作ることで先行して実行中のCommandを終了させようと書きましたが、終了させる単純な方法が別にありました。

Inventor.CommandManager.StopActiveCommand();

DummyのInteractionEventsを作るより、こちらの方がスマートなので、用途によってはこのAPIを使うことをお勧めします。

#99. 親の記事に戻る
Autodesk Inventor API Hacking (概略)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?