作成日:2021.08.12更新日:2021.08.12
IJCAD の .NET API を利用して、図面に図形を作図する方法を紹介します。
IJCAD で DWG または DXF 形式の図面ファイルを開くと、図面の情報がメモリ上に展開されます。
メモリ上に展開された図面情報は 図面データベース と呼ばれ、プラグインから図面のデータを操作するには、図面データベースを参照します。
ここでは図面データベースのデータ構造の概要と、図面に簡単な図形を作図する方法を説明します。
図面データベースにはテーブルが定義されており、図面の情報は、その種類に応じてテーブルごとに管理されています。
テーブルには、ブロックテーブル、画層テーブル、文字スタイルテーブル、線種テーブルなどがあります。
図面に対する操作に応じて、参照するテーブルを決め、テーブルのレコードを追加、変更、取得することで、図面からの情報取得や図面の編集ができます。
テーブル内の個々の要素は、レコードと呼ばれます。
ブロックテーブルの場合、モデル空間、レイアウト、ブロック定義などが、個別のレコードとして管理されており、各レコードには、作図されている図形の情報が結び付けられています。
図形を作図するには、ブロックテーブルからモデル空間のレコードを取得し、そのレコードに作図する図形の情報を追加します。
.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 プラグインの開発方法【開発の進め方の基本】の手順に従って、新しいプロジェクトを作成します。
NETLOAD ./IJCADPlugin.dll
と書いておきます。以上の要領で作成したプロジェクトのひな形は、こちらからダウンロードできます。
ひな形のプロジェクトを Visual Studio で開いたとき、参照エラーが起きている場合は、参照を設定し直してください。
手始めに、円と線分を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
クラスのオブジェクトにプロパティを設定した後で、以下の手順が必要です。
円の作図は、次のようにして実現できます。
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 が正しく動作していることになります。
DRAWTWOSHAPES コマンドの実装を応用して、目標の図形を作図するコマンドを作成しましょう。
作図の要領は次の通りです。
ここでは、目標の図形を作図するコマンドを 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 のドキュメントをダウンロードして、図形の種類とクラス定義を参照してください。