Autodesk Inventor API Hacking (APIのbug)

# 0. はじめに
[Freeradical](https://www.freeradical.jp)の中の人、[yamarah](https://qiita.com/yamarah)です。
私が知っているだけでも、片手以上のAPIのbugがあるのですが、明らかに気付くbugは除外して、気づきにくいbug、つまりは__はまりやすいbug__について記載します。

# 1. ReferenceKeyManager.BindKeyToObjectの第3引数がnullでないと落ちる

```C#
object dummy;
byte[] byteArray1, byteArray2;

// (中略)

// ↓ これは通る(場合がある)
someObject.ReferenceKeyManager.BindKeyToObject(ref byteArray1, 0, out dummy);
// ↓ ここで落ちる
anotherObject.ReferenceKeyManager.BindKeyToObject(ref byteArray2, 0, out dummy);
```

結論を言うと、都度dummyにnullをセットすると良い。

```C#
object dummy;
byte[] byteArray1, byteArray2;

// (中略)

// ↓ OK
dummy = null;
someObject.ReferenceKeyManager.BindKeyToObject(ref byteArray1, 0, out dummy);
// ↓ OK
dummy = null;
anotherObject.ReferenceKeyManager.BindKeyToObject(ref byteArray2, 0, out dummy);
```

これはVBAにおけるValiant型のハンドリングについて、inventor.interop.dll内にbugがあるんだろうけど、とにかく事前にnullを入れておけば大丈夫。

実際に私がはまった時の形はこれ。

```C#
someObject.ReferenceKeyManager.BindKeyToObject(ref byteArray1, 0, out _);
anotherObject.ReferenceKeyManager.BindKeyToObject(ref byteArray2, 0, out _);
```

これの2行目で落ちられたら、byteArrayの方を疑ってしまって、時間がかかったよ。

# 2. ApplicationEvents_OnNewEditObjectと3DスケッチとActiveEditDocument.ActivatedObjectの関係
下のコメントにある通り、特定の条件においてActivatedObjectの値が信用できない。

```C#
private void ApplicationEvents_OnNewEditObject(object EditObject,
                                               EventTimingEnum BeforeOrAfter,
                                               NameValueMap Context,
                                               out HandlingCodeEnum HandlingCode)
{
    HandlingCode = HandlingCodeEnum.kEventNotHandled;

    if (BeforeOrAfter == EventTimingEnum.kAfter)
    {
        if (EditObject is PartDocument) {
            object obj = m_Application.ActiveEditDocument.ActivatedObject;

            // ここで、objは常にnullのはずだが、3Dスケッチから抜けたときだけは、nullではない。
            // フィーチャーもしくはスケッチが編集中かどうかを、
            // ActiveEditDocument.ActivatedObject == nullで判断すると、バグる。
            // 代わりに、EditObjectがDocumentかどうかで判断することで、回避する。
        }
    }
}
```

# 3. SelectEventsへの参照が必要
`SelectEvents`に限らないのかもしれませんが、EventHandlerを持っているobjectへの参照を保持していないと、追加した関数は実行されません。
例えば、

```c#
//  private SelectEvents selectEvents;

public void Command_OnExecute(NameValueMap Context)
{
    interactionEvents = m_inventorApplication.CommandManager.CreateInteractionEvents();
    interactionEvents.SelectEvents.OnPreSelect += SelectEvents_OnPreSelect;
    interactionEvents.SelectEvents.OnSelect += SelectEvents_OnSelect;

//  selectEvents = interactionEvents.SelectEvents;
    interactionEvents.Start();
}
```
このcodeでは、「原則的に」`SelectEvents_OnPreSelect`と`SelectEvents_onSelect`が実行されません。
実行させるには、コメントアウトしてある2行を有効にする必要があります。
さて、「原則的に」と括弧書きにした理由は、`InteractionEvents.Start()`した直後の数百ミリ秒だけは反応するからです。

# 4. SketchBlockDefinition内に拘束付与できない
例えば、

```vb
' VBAですいません
Sub test()
    Dim line As SketchLine
    Set line = ThisApplication.ActiveDocument.SelectSet(1)
    
    Dim constraints As GeometricConstraints
    Set constraints = line.Parent.GeometricConstraints

    constraints.AddVertical line
End Sub
```
通常の`PlanarSketch`編集中に直線を選択して実行すれば、その直線に垂直拘束が付与されます。
しかし、`SketchBlockDefinition`を編集中に(一般的にはスケッチブロック編集中に)、直線を選択して実行すると、エラーが発生します。
どうやら、`SketchBlockDefinition.GeometricConstarints.AddXXX()`は全滅のようです。

# 5．モデル状態が有効なドキュメントのiPropertyをApprenticeServerから変更できない
Inventor2022で"モデル状態"なるものが導入されました。これの詳細については本稿から外れるので各自ググってもらうとして、問題として2021年5月現在では、Model状態が有効なドキュメントのiProertyをApprenticeServerから変更できません。例えば部品番号を変更できないので、該当ドキュメントをデザインアシスタントで操作できないという事態になっています。
Autodeskはこの問題を認識しているので、厳密にはバグではないのかもしれませんが、当然この問題は解消されるべきだし、そうなると信じてここに記しておきます。

# 98. Invenorのbugを見つけたら、どうすれば良いの?
APIに限らず、Inventorに関するbugを見つけた場合に、ユーザーはどうすれば良いのでしょう?
信じがたいことに、Autodeskには**公のbug報告の窓口がありません**。

* サブスクリプション契約に含まれるQA窓口から報告する。
* 商社経由で問題報告をしてもらう。
* 何らかのコネクションで、日本のAutodesk社員に訴える。

これらの方法は、どうも効果がないように見えます。

今、一番効果があるのは、[Autodesk Feedback Community](https://feedback.autodesk.com/)に登録して、Inventorのベータ登録をし、そこでbugレポートを上げることです。
当然、英語での報告になるのでハードルは高いのですが、Autodeskとして不具合を認識し(Defect Accepted)、開発チームのデータベースに載ったかまでは、確実に分かります。
Defect Acceptedが、必ずしもbug修正と同義ではない(放置されることも多々ある)のですが、現時点では一番有効な方法だと思います。

# 99. 親の記事に戻る
[Autodesk Inventor API Hacking (概略)](https://qiita.com/yamarah/items/cee08eb8f2b7aecbda83)