Autodesk Community Tips- ADNオープン
Autodesk Community Tipsではちょっとしたコツ、やり方、ショートカット、アドバイスやヒントを共有しています。
ソート順:
Question InventorのAPIで2D図面上の任意の2点の座標を指定して寸法を追加する方法はありますか。 Answer 入力となる座標に2D図面上で図形が存在しない場合、Inventorの図面寸法を作成することができません。   このため、任意の2点の座標から長さ寸法を挿入したい場合、スケッチ上に入力座標でポイントを作成し、ポイント間の拘束寸法を作成、作成した寸法を図面に取り込むことで寸法を発生させる必要があります。   なお、この方法で作成した寸法はスケッチでの入力点に拘束されているため、図面上の図形や、ビューの元データのモデルの更新に追随して更新されません。   また、拘束寸法をシートに取り込んだ場合、寸法値はドキュメントの規格設定によりinchまたはmmとなります。寸法値をcm等の別の単位で表示したい場合は、シートに取得したスケッチの拘束寸法に対して値の上書きを行う必要があります。なお、寸法値の上書きを行っている場合スケッチ上で拘束寸法の変更を行った場合においても、値の更新が自動で行われない(上書き値が表示される)点に注意が必要です。   以下は2点の座標を元にスケッチに点を追加、拘束寸法を作成後にシートに取り込みを行うVBAのサンプルコードです。 Dim oDoc As DrawingDocument Set oDoc = ThisApplication.ActiveDocument Dim oSheet As sheet Set oSheet = oDoc.ActiveSheet Dim oSketch As sketch Dim oDimensionConstraint As DimensionConstraint Set oDimensionConstraint = addDimensionBySketchPoint(oSheet, "スケッチ1", 10, 10, 12, 10) Dim oConsraintDimensionCollection As ObjectCollection Set oConsraintDimensionCollection = ThisApplication.TransientObjects.CreateObjectCollection oConsraintDimensionCollection.Add oDimensionConstraint 'retrieve model dimension Call oSheet.DrawingDimensions.GeneralDimensions.Retrieve(oDimensionConstraint.Parent, oConsraintDimensionCollection) End Sub Public Function addDimensionBySketchPoint(oSheet As sheet, sketchName As String, x1 As Double, y1 As Double, x2 As Double, y2 As Double) As DimensionConstraint Dim oTg As TransientGeometry Set oTg = ThisApplication.TransientGeometry Dim oSketch As DrawingSketch On Error Resume Next Set oSketch = oSheet.Sketches(sketchName) On Error GoTo 0 If oSketch Is Nothing Then Set oSketch = oSheet.Sketches.Add() End If oSketch.Edit Dim p1 As Point2d Set p1 = oTg.CreatePoint2d(x1, y1) Dim p2 As Point2d Set p2 = oTg.CreatePoint2d(x2, y2) Dim skP1 As SketchPoint Set skP1 = oSketch.SketchPoints.Add(p1, False) Dim skP2 As SketchPoint Set skP2 = oSketch.SketchPoints.Add(p2, False) Dim tp As Point2d Set tp = oTg.CreatePoint2d((x2 + x1) / 2, (y2 + y1) / 2) Dim oTwoPointDistanceDimConstraint As TwoPointDistanceDimConstraint Set oTwoPointDistanceDimConstraint = oSketch.DimensionConstraints.AddTwoPointDistance(skP1, skP2, kHorizontalDim, tp) Set addDimensionBySketchPoint = oTwoPointDistanceDimConstraint oSketch.ExitEdit  
記事全体を表示
質問 Inventor APIでiPropertyの質量を取得すると値がグラムで取得されます。 Inventor APIで取得する値の単位は何でしょうか。 回答 Inventorでは各ドキュメントの表示単位を設定可能ですが、内部データべースの単位は、常に同じ単位を利用しております。 InventorのAPIはこのデータベース単位を利用いたしますので(表示単位の設定にかかわらず)、データベース単位での値が取得されます。   Inventorの表示単位や内部データベースの単位の詳細については、APIリファレンスの「Inventor APIのユーザマニュアル」-「一般的なコンセプト」-「計測単位」にまとめられています。 以下は、APIリファレンスに記載のデータベース単位の表となります。   ただし、以下のコードでiPropertyの質量を取得すると、値がデータベース単位のキログラムではなく、グラムで取得されるため注意が必要です。 ThisApplication.ActiveDocument.PropertySets.Item("Design Tracking Properties").Item("Mass").Value   質量をデータベース単位のキログラムで取得する場合は、以下のようにMassPropertesのmassプロパティから取得が可能です。 ThisApplication.ActiveDocument.ComponentDefinition.MassProperties.mass  
記事全体を表示
質問 APIでInventorを起動する際にバージョン指定する方法はありますか。 回答 AutoCAD等でGetTypeFromProgID()の引数に、"AutoCAD.Application.xx” (xxはバーンジョンを表す数値)等を渡すことでバージョンを指定して起動することが出来るため、Inventorも同様の方法で起動する方法を探している状況かと思います。   残念ながら、InventorではAutoCADとはCOMのレジストリ登録の仕組みが異なっており、CreateInstance()でバージョンを指定して起動することが出来ません。   プログラムから指定のバージョンのInventorを起動する場合、以下の2通り方法があります。 1.カスタムプログラムからexeを起動する 2.カスタムプログラムから、CreateInstance()関数の実行時に、CreateInstance()関数が参照するInventorのExeのパスが記述されている、レジストリ情報を対象バージョンのInventor.exeのパスで上書きしたのちに、GetTypeFromProgID()⇒CreateInstance()を行う。 ただし、2の方法はCLASSES_ROOT配下のレジストリ情報の書き換えを行うため、adminまたはCLASSES_ROOTの書き換えに必要なユーザ権限が必要となりるため、通常は1の方法をとることになるかと思いますので、ここでは1の方法を記載します。   以下は、1の方法でInventorを起動するヘルパークラスです。 class AdnInventorLoader { public enum Version { Inventor_2020, Inventor_2021, Inventor_2022, Inventor_2023, }; public static Inventor.Application CreateInstanceFromProcess(Version version) { try { string exePath = GetExePath(version); if (exePath != string.Empty) { CleanUpRegistry(); System.Diagnostics.Process process = System.Diagnostics.Process.Start(exePath); if (process != null) { //Wait for 5 Mins if (process.WaitForInputIdle(300000)) { while (true) { try { Inventor.Application app = Marshal.GetActiveObject("Inventor.Application") as Inventor.Application; return app; } catch (Exception ex) { if (!ex.Message.Contains("MK_E_UNAVAILABLE")) break; System.Threading.Thread.Sleep(1000); } } } } } return null; } catch { return null; } } // Clean up registry to prevent // "Re-registration" dialog // http://tinyurl.com/dx4tsnu private static bool CleanUpRegistry() { try { using (RegistryKey inventorKey =Registry.CurrentUser.OpenSubKey("Software").OpenSubKey("Autodesk").OpenSubKey("Inventor").OpenSubKey("Current Version",true)) { if (inventorKey == null) return false; inventorKey.DeleteValue("Executable"); inventorKey.DeleteValue("LastVersionRun"); inventorKey.DeleteValue("Registered"); inventorKey.DeleteValue("RegistryVersion"); inventorKey.DeleteValue("SilentMode"); inventorKey.DeleteValue("UBI"); inventorKey.Close(); return true; } } catch { return false; } } // Retrieve Inventor.exe fullpath based on version private static string GetExePath(Version version) { try { string key = string.Empty; switch (version) { case Version.Inventor_2020: key = "RegistryVersion24.0"; break; case Version.Inventor_2021: key = "RegistryVersion25.0"; break; case Version.Inventor_2022: key = "RegistryVersion26.0"; break; case Version.Inventor_2023: key = "RegistryVersion27.0"; break; default: return string.Empty; } using (RegistryKey inventorKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64). OpenSubKey("SOFTWARE"). OpenSubKey("Autodesk"). OpenSubKey("Inventor"). OpenSubKey(key)) { if (inventorKey == null) return string.Empty; string path = inventorKey.GetValue("InventorLocation") as string; inventorKey.Close(); path += "Inventor.exe"; return (System.IO.File.Exists(path) ?path : string.Empty); } } catch { return string.Empty; } } } }    利用側からは以下のように、起動するInventorのバージョンを指定する列挙値を指定して起動します。 Inventor.Application app = AdnInventorLoader.CreateInstanceFromProcess(AdnInventorLoader.Version.Inventor_2023); if (app != null) app.Visible = true;   ※この記事はブログ記事「Running programmatically a specific version of Inventor」を元に、必要な部分を抽出し、加筆修正と日本語化を行ったものとなります。
記事全体を表示
質問 Vaultのカスタムプログラムの開発のために、Vault Exploror(Vaultクライアント)のコマンドが利用しているVault APIを知りたい。 回答 Vaultのカスタムプログラムを開発する際に、Vault Exploror(Vaultクライアント)のコマンド(またはその一部)と同様の処理を実現したい場合に、どのようなAPIを利用すればよいかを知りたい場合が多くあります。   Vault Exploror(Vaultクライアント)はコマンドの実行時に、Vault サーバのWebサービスAPIを実行してその機能を実現しているため、その通信内容をパケットキャプチャツール等で確認することで、どのWebサービスAPIが実行されているかを確認することが出来ます。   ここでは、パケットキャプチャツールのFiddler ClassicとVaultの通信内容をFiddler Classicで見やすくするエクステンションツールのvapiTraceを利用した方法を紹介します。   なお、以下手順の環境としてはVaultサーバとVaultクライアントが同一のマシン上にインストールされているテスト環境を前提としています。原理的には、別端末にインストールされている場合でも、Vaultクライアントがインストールされている環境で実行することで通信内容を確認できるはずですが、追加のFiddlerの設定が必要となる可能性があります。   手順   1.以下URLからFiddler Classicをダウンロードしてインストールします。 https://www.telerik.com/fiddler/fiddler-classic   2.以下GitHubリポジトリのリリースから、vapiTraceFiddlerExtension.zipをダウンロードし、zpiファイル解凍して、C:\Users\<ログインユーザ名>\AppData\Local\Programs\Fiddler\Inspectors 配下に配置します。 https://github.com/coolOrangeLabs/vapiTrace   3.Fiddlerを起動し[Tool]-[Option]メニューからCapture HTTPS Connections設定を有効にする。    4.Fiddlerを再起動して、Vaultクライアントを起動します。  Fiddlerの画面の左側には、キャプチャされた通信内容が時系列にリストで表示されます。URLが/AutodeskDMで始まる通信がVaultサーバとの通信となります。   リストからアイテムを選択し、右側の上下のペインでvapiTraceタブを選択すると、以下のスクリーンショットのように、上側のペインに呼び出したVault API(とその引数)、下側のペインにはAPIのレスポンスが表示され、実行されたAPIを確認することが出来ます。     リストの内容は、リストアイテムを選択して、右クリックメニュー[Remove]-[All Sessions]からクリアできるので、調査したいVaultエクスプローラのコマンドを実行前にリストをクリアし、Vaultのコマンドを実行後に[File]-[Capture Traffic]のチェックを外してキャプチャを停止することで、コマンドが実行しているAPIを効率的に調査することが出来るかと思います。   また、Vaultクライアントはコマンドの実行後にGUIを最新の情報に更新するために、情報を取得するAPIの呼び出しを行っています。カスタムプログラムの開発時には、要件に合わせてどのAPIが必要なのかの判断が必要となりますので、各APIの詳細をVault SDKのAPIリファレンスを参照して確認ください。   なお、Vaultクライアントからサーバにログインする際にVaultサーバにlocalhostを指定するとFiddlerで通信をキャプチャすることが出来ません。Vaultサーバにはマシン名を指定してください。
記事全体を表示
質問 AutoCADの.net APIで雲マーク(REVCLOUD)を取得する方法はありますか。   回答 AutoCADの雲マーク(RevCloudコマンドで作成される図形)は、拡張データ領域にアプリケーション名”RevcloudProps”のデータを持つLWPolylineとなっております。   このため、net APIで図形を選択する際のフィルタ条件に、図形がLWPolylineでかつアプリケーション名が”RevcloudProps”の拡張データを持つ図形指定することで雲マーク図形を取得することが可能です。   Dim dc As Document = Application.DocumentManager.MdiActiveDocument Dim db As Database = dc.Database Dim ed As Editor = dc.Editor Dim tvs(1) As TypedValue tvs.SetValue(New TypedValue(DxfCode.Start, "LWPOLYLINE"), 0) tvs.SetValue(New TypedValue(DxfCode.ExtendedDataRegAppName, "RevcloudProps"), 1) Dim sf As SelectionFilter = New SelectionFilter(tvs) Dim psr As PromptSelectionResult psr = ed.SelectAll(sf) If psr.Status<> PromptStatus.OK Then Exit Sub End If Using tx As Transaction = db.TransactionManager.StartTransaction() Try For Each id As ObjectId In psr.Value.GetObjectIds() Dim lwp As Polyline = tx.GetObject(id, OpenMode.ForWrite) Next tx.Commit() Catch e As System.Exception tx.Abort() ed.WriteMessage(e.Message) End Try End Using    
記事全体を表示
質問 AutoCADのVBAで、以下のサンプルコードの様にコレクションの要素を取得し存在しない場合は要素を追加する処理がありますが、同様の処理をAutoLispで行う場合はどのように記述したらよいでしょうか。 Dim sset As AcadSelectionSet On Error Resume Next Set sset = ThisDrawing.SelectionSets.Item("Test") On Error GoTo 0 If sset Is Nothing Then Set sset = ThisDrawing.SelectionSets.Add("Test") End If 回答 AutoLispのvl-catch-all-applyを使用することで、コレクションに存在しないアイテムを取得する際に発生するエラーをハンドルすることが可能です。 vl-catch-all-applyには引数のリストを指定された関数に渡し、すべての例外をトラップします。   上述のVBAと同様の処理を実現する場合は以下のサンプルコードのようにlambda式を作成して処理を実行、結果の値を確認する形となります。 (setq acadObject (vlax-get-acad-object)) (setq activeDocument (vla-get-activedocument acadObject)) (setq selectionSets (vla-get-selectionsets activeDocument)) (vl-catch-all-apply '(lambda() (setq sset (vla-Item selectionSets "test")) ) ) (if (= nil sset) (progn (setq sset (vla-add selectionSets "test")) ) )    
記事全体を表示
現象 Windows 11環境では、AutoCAD(AutoCAD 2022、2023、2024)のWindowにGDIを使用したカスタムグラフィック描画がされない。Windows 10環境では、同じプログラムでカスタムグラフィックが描画される。   診断 AutoCAD 2022以降のバージョンでは、DirextX12をサポートしております。このためWindows 11環境ではGDIを用いたカスタムグラフィックの描画が行われません。 解決策 この問題の解決のためには、カスタムグラフィックの描画にGDIではなくDirectX 12を使用するよう、プログラムの修正を行うことを推奨します。   プログラムの修正が困難な場合、ハードウェアアクセラレーションをオフに設定する、またはシステム変数GFXDX12の設定値を0に設定することで、この現象を回避することが可能です。  
記事全体を表示