IJCAD プラグインの開発方法【図形の作図:基礎編】
作成日:2021.08.12
更新日:2021.08.12
IJCAD の .NET API を利用して、図面に図形を作図する方法を紹介します。
IJCAD で DWG または DXF 形式の図面ファイルを開くと、図面の情報がメモリ上に展開されます。
メモリ上に展開された図面情報は 図面データベース と呼ばれ、プラグインから図面のデータを操作するには、図面データベースを参照します。
ここでは図面データベースのデータ構造の概要と、図面に簡単な図形を作図する方法を説明します。
目次

図面データベース
データ構造
図面データベースにはテーブルが定義されており、図面の情報は、その種類に応じてテーブルごとに管理されています。
テーブルには、ブロックテーブル、画層テーブル、文字スタイルテーブル、線種テーブルなどがあります。
図面に対する操作に応じて、参照するテーブルを決め、テーブルのレコードを追加、変更、取得することで、図面からの情報取得や図面の編集ができます。
テーブル内の個々の要素は、レコードと呼ばれます。
ブロックテーブルの場合、モデル空間、レイアウト、ブロック定義などが、個別のレコードとして管理されており、各レコードには、作図されている図形の情報が結び付けられています。
図形を作図するには、ブロックテーブルからモデル空間のレコードを取得し、そのレコードに作図する図形の情報を追加します。
.NET API による図形の作図
.NET API では、プログラムから図面データベースを参照するために、GrxCAD.DatabaseServices
名前空間の Database
クラスを利用します。
IJCAD で現在開かれている図面に対して、C# のプログラムで Database
クラスのオブジェクトを参照するには、Application.DocumentManager.MdiActiveDocument.Database
とします。
図面に図形を作図する手順の概略は、次の通りです。
- 図面データベースから、ブロックテーブルを取得する。
- ブロックテーブルから、モデル空間のレコードを取得する。
- 作図する図形のオブジェクトを作成する。
- 作成した図形のオブジェクトを、モデル空間のレコードに追加する。
トランザクション
.NET API では、図面データベース内の情報を参照するためにトランザクションを使用します。
トランザクションは、一続きの処理のまとまりを表す単位で、
- 一続きの処理をすべて実行する(コミット)
- まったく実行しない、つまり、一続きの処理を実行する前の状態に戻す(ロールバック)
という制御が可能です。
トランザクションを使用する C# のプログラムは、次のようになります。
using (var tr = db.TransactionManager.StartTransaction()) { // 図面データベースの情報を読み書きする。 ... // 処理内容を図面データベースに反映する。 tr.Commit(); }
このプログラムで、db
は図面データベースを参照する変数です。
図面データベースからトランザクションマネージャを参照し、トランザクションマネージャにトランザクションを開始させます。
このとき取得したトランザクションオブジェクト(上のプログラムで、変数 tr
に代入されたオブジェクト) は、GrxCAD.DatabaseServices
名前空間の Transaction
クラスのインスタンスとなります。
図面に対する一連の処理を終了させるには、トランザクションのオブジェクトに対して Dispose
メソッドを呼び出します。
Dispose
メソッドが呼び出されると、コミットされていない変更はすべてロールバックされます。
このため、上のプログラムのように Commit
メソッドを呼び出さなければ、それまでの処理内容は図面データベースに反映されません。
上の例では using ステートメントを使っているので、{}
で囲まれた部分の処理を終えると、トランザクションオブジェクトに対して Dispose
メソッドが自動的に呼び出され、トランザクションを終了できるようになっています。
オブジェクトの取得
トランザクションオブジェクトは、図面データベースからオブジェクトを取得するときにも利用します。
.NET API では、図面データベースのテーブル、レコード、図形などはすべて、DbObject
クラスのサブクラスのインスタンスとなっています。
図面データベースのオブジェクトを取得するときは、まず対象のオブジェクトID (ObjectId
構造体のインスタンス) を取得し、Transaction
クラスの GetObject
メソッドを呼び出して、DbObject
クラスのインスタンスを取得します。
GetObject
メソッドにはオブジェクトIDの他にも引数があり、取得したオブジェクトに対して書き込みを行うかどうかを、第2引数として渡します。
オブジェクトから情報を取得するのみの場合は OpenMode.ForRead
とし、オブジェクトに何らかの変更を加える場合は OpenMode.ForWrite
とします。
IJCAD でアクティブになっている図面に図形を作図する C# のプログラムの概略は、次のようになります。
// IJCAD でアクティブになっている図面の図面データベースを参照する。 var db = Application.DocumentManager.MdiActiveDocument.Database; using (var tr = db.TransactionManager.StartTransaction()) { // ブロックテーブルのオブジェクトを取得する。 var bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; // (1) // ブロックテーブルから、モデル空間のレコードのオブジェクトを取得する。 var btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; // (2) // 図形のオブジェクトを作成して、図面データベースに追加する。 ... // 処理内容を図面データベースに反映させる。 tr.Commit(); }
図形を作図するには、図面データベースのブロックテーブルから、モデル空間のレコードを取得します。
上のプログラムでは、(1)でブロックテーブルのオブジェクトを取得し、(2)でモデル空間のレコードのオブジェクトを取得しています。
ブロックテーブルのオブジェクトIDは、Database
クラスの BlockTabkeId
プロパティで取得できます。
このオブジェクトIDを引数として GetObject
メソッドを呼び出し、得られた DbObject
クラスのオブジェクトを、ブロックテーブルのクラス(BlockTable
クラス)にキャストすると、ブロックテーブルのオブジェクトが取得できます。
ブロックテーブルには書き込みを行わない(レコードの追加、変更、削除はしない)ため、GetObject
メソッドの2番目の引数は OpenMode.ForRead
としています。
モデル空間のレコードのオブジェクトIDは、BlockTable
クラスのインスタンスに BlockTableRecord
クラスの ModelSpace
プロパティで定義された文字列を渡して取得できます。
上のプログラムでは、bt[BlockTableRecord.ModelSpace]
の部分がそれに相当します。
レイアウトやブロック定義についても、それぞれの名前を表す文字列を BlockTable
インスタンスのインデクサーに渡すことで、レコードのオブジェクトIDを取得できます。
ブロックテーブルのレコードのオブジェクトは、GetObject
メソッドで取得したオブジェクトを BlockTableRecord
クラスにキャストして取得できます。
モデル空間のレコードには書き込みを行う(モデル空間に図形を追加するため)ので、GetObject
メソッドの2番目の引数は OpenMode.ForWrite
としています。
図形を作図するコマンドの作成
図面データベースの構造と、それを操作するための .NET API の基本的な使い方を踏まえて、IJCAD で簡単な図形を作図するコマンドを作成してみましょう。
目標
IJCAD のアクティブ図面に対して、モデル空間に円と線分を作図します。
ここでは、下の図に示すような図形を一度に作図するコマンドを作成します。
準備
IJCAD プラグインの開発方法【開発の進め方の基本】の手順に従って、新しいプロジェクトを作成します。
- ソリューションとプロジェクトの名前はIJCADPluginとします。
- プロジェクトの参照設定で、IJCAD のインストールフォルダにあるgmap.dllとgmdb.dllを、参照に追加します。
- プロジェクトのプロパティでデバッグ設定を行います。
- 開始動作を外部プログラムの開始にし、IJCAD の実行ファイル(gcad.exe)の絶対パスを設定します。
- 開始オプションのコマンドライン引数に /b netload.scr と入力します。
- スクリプトファイル(netload.scr) を作成し、プロジェクトに追加します。
スクリプトファイルには、
NETLOAD ./IJCADPlugin.dll
と書いておきます。
以上の要領で作成したプロジェクトのひな形は、こちらからダウンロードできます。
ひな形のプロジェクトを Visual Studio で開いたとき、参照エラーが起きている場合は、参照を設定し直してください。
DRAWTWOSHAPES コマンド
円と線分を1つずつ作図する
手始めに、円と線分を1つずつ作図するコマンドを作成してみましょう。
コマンドの名前を DRAWTWOSHAPES として、Commands クラス(Commands.csで定義されています)に次のメソッドを作成します。
[CommandMethod("DRAWTWOSHAPES")] public void DrawTwoShapes() { // IJCAD でアクティブな図面の図面データベースを取得します。 var db = Application.DocumentManager.MdiActiveDocument.Database; // 図面データベースに対するトランザクションを開始します。 using (var tr = db.TransactionManager.StartTransaction()) { // ブロックテーブルのオブジェクトを取得します。 var bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; // モデル空間のレコードオブジェクトを取得します。 var btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; // (※) ここで図形を作図します。 // ここまでの処理の内容を図面データベースに反映させます。 tr.Commit(); } }
図面に図形を作図するプログラムの骨格は、上のようになります。
次に、上のプログラムの※の箇所に、線分と円を作図する処理を追加します。
線分を作図する
線分の作図は、次のようにして実現します。
using (var line = new Line()) { line.StartPoint = new Point3d(0, 0, 0); line.EndPoint = new Point3d(800, 0, 0); btr.AppendEntity(line); // ※1 tr.AddNewlyCreatedDBObject(line, true); // ※2 }
Line
は図面上の線分を表すクラスで、DbObject
クラスのサブクラスです。
作図のために作成したオブジェクトは Dispose
メソッドで破棄する必要があるため、上の例では using ステートメントを使い、作図完了後にオブジェクトを自動的に破棄するようにしています。
Line
クラスには、始点を表すプロパティ StartPoint
と 終点を表すプロパティ EndPoint
があり、それぞれ Point3d
クラスのインスタンスを設定します。
上の例では、線分の始点を (0, 0, 0), 終点を (800, 0, 0) としています。
線分を作図するには、Line
クラスのオブジェクトにプロパティを設定した後で、以下の手順が必要です。
- モデル空間に、線分のオブジェクトを追加する(※1の部分)。
- 図面データベースのトランザクションに、線分の追加を通知する(※2の部分)。
円を作図する
円の作図は、次のようにして実現できます。
using (var circle = new Circle()) { circle.Center = new Point3d(50, 50, 0); circle.Radius = 40; btr.AppendEntity(circle); tr.AddNewlyCreatedDBObject(circle, true); }
Circle
は図面上の円を表すクラスで、DbObject
クラスのサブクラスです。
Circle
クラスには、中心を表すプロパティ Center
と 半径を表すプロパティ Radius
があります。
上の例では、円の中心を (50, 50, 0), 半径を 40 としています。
動作を確認する
ここまでで作成したコマンドの動作を確認してみましょう。
プロジェクトをビルドしてデバッグ実行を開始すると、IJCAD が起動され、.NET アセンブリ (IJCADPlugin.dll) が自動でロードされます。
この状態で DRAWTWOSHAPES コマンドを実行すると、図形が作図されます。
作図された図形を確認するために、ZOOM コマンドを実行し、オプションに E(オブジェクト範囲)を指定します。
上の図のように、線分と円が1つずつ作図されていれば、DRAWTWOSHAPES が正しく動作していることになります。
DRAWSHAPES コマンド
DRAWTWOSHAPES コマンドの実装を応用して、目標の図形を作図するコマンドを作成しましょう。
作図の要領は次の通りです。
- 両端の x 座標が 0, 800 の線分(横線)を、y 座標を 0 から 800 まで 100 ずつ変えて作図する。
- 両端の y 座標が 0, 800 の線分(縦線)を、x 座標を 0 から 800 まで 100 ずつ変えて作図する。
- 以上の横線と縦線を作図すると、一辺の長さが 100 の 正方形の領域が64 個できる。 それぞれの正方形領域に、正方形の対角線の交点を中心とする半径 40 の円を作図する。
- 以上のすべての図形を、xy平面上に作図する。
プログラムを作成する
ここでは、目標の図形を作図するコマンドを DRAWSHAPES として、プログラムを作成します。
DRAWSHAPES コマンドを実行するためのメソッドを Commands
クラスに追加し、アクティブな図面に図形を作図する処理の骨格を作成します。
[CommandMethod("DRAWSHAPES")] public void DrawShapes() { // IJCAD でアクティブな図面の図面データベースを取得します。 var db = Application.DocumentManager.MdiActiveDocument.Database; // 図面データベースに対するトランザクションを開始します。 using (var tr = db.TransactionManager.StartTransaction()) { // ブロックテーブルのオブジェクトを取得します。 var bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; // モデル空間のレコードオブジェクトを取得します。 var btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord; // (※) ここで図形を作図します。 // ここまでの処理の内容を図面データベースに反映させます。 tr.Commit(); } }
次に、図形を作図する処理を、(※)の箇所に追加します。
先ほど示した要領に従って作図する処理の例を、以下に示します。
// 縦線と横線を、それぞれ9本ずつ作図します。 for (var p = 0; p < 900; p += 100) { using (var vLine = new Line()) // 縦線 using (var hLine = new Line()) // 横線 { // 縦線の始点と終点を設定します。 vLine.StartPoint = new Point3d(p, 0, 0); vLine.EndPoint = new Point3d(p, 800, 0); // 横線の始点と終点を設定します。 hLine.StartPoint = new Point3d(0, p, 0); hLine.EndPoint = new Point3d(800, p, 0); btr.AppendEntity(vLine); btr.AppendEntity(hLine); tr.AddNewlyCreatedDBObject(vLine, true); tr.AddNewlyCreatedDBObject(hLine, true); } } // 円を縦方向と横方向に8個ずつ、合計64個作図します。 for (var x = 0; x < 800; x += 100) { for (var y = 0; y < 800; y += 100) { using (var circle = new Circle()) { circle.Center = new Point3d(x + 50, y + 50, 0); circle.Radius = 40; btr.AppendEntity(circle); tr.AddNewlyCreatedDBObject(circle, true); } } }
動作を確認する
ここまでで作成したコマンドの動作を確認しましょう。
Visual Studio からプロジェクトをデバック実行し、IJCAD を起動して DRAWSHAPES コマンドを実行します。
作図内容を確認するため、ZOOM コマンドを実行し、E オプションを指定します。
上のように、最初の目標に示した図形が作図されれば、DRAWSHAPES コマンドが正しく実装されています。
まとめ
IJCAD の .NET API で、図形を作図する方法を紹介しました。
作図できる図形のクラスは、GrxCAD.DatabaseServices
名前空間で定義されています。
線分や円以外の図形の作図方法については、こちらから API のドキュメントをダウンロードして、図形の種類とクラス定義を参照してください。