IJCAD プラグインの開発方法【図形の編集】

作成日:2021.08.12更新日:2021.08.12

image

IJCAD の .NET API を利用して、図形を編集する方法を紹介します。

API で図形を編集するには、図面データベースから図形オブジェクトを取得し、編集内容に応じて、図形オブジェクトのプロパティを変更します。

図面データベース内のオブジェクトに変更を加えるときは、オブジェクトのオープンモードに注意する必要があります。

ここでは、図形オブジェクトを編集するコマンドの作成を交えて、オープンモードとその変更方法について説明します。

目次

image

オープンモード

オープンモードとは何か

IJCAD の API で、図形、画層、線種などの情報を取得するには、オブジェクトIDからオブジェクトを取得して、目的のクラスにキャストします。

オープンモードとは、取得したオブジェクトの利用目的に相当し、次のものがあります。

  • 読み取りモード: オブジェクトの情報を取得する。
  • 書き込みモード: オブジェクトの情報を変更する。
  • 通知モード: オブジェクトから通知を受け取る。

読み込みモードで取得したオブジェクトに変更を加えようとすると、コマンド実行時に例外が発生します。

また、オブジェクトを書き込みモードで取得すると、UNDO コマンドによる取り消しやトランザクションのロールバックを行う場合に備えて、オブジェクトへの変更内容を記録する処理が行われます。

このため、オブジェクトの情報を変更しない場合は、コマンドの実行時の処理のオーバーヘッドを避けるため、読み取りモードでオブジェクトを取得することが望ましいです。

.NET API では、オープンモードが OpenMode 列挙型として、次のように定義されています。

  • 読み取りモード: OpenMode.ForRead
  • 書き込みモード: OpenMode.ForWrite
  • 通知モード: OpenMode.ForNotify

オブジェクトを取得するときには、Transaction クラスのインスタンスにオブジェクトIDと OpenMode 列挙型の値を渡して、GetObject メソッドを呼び出します。

例として、モデル空間の図形の情報を読み取る処理の概略は、次のようになります。

using (var tr = db.TransactionManager.StartTransaction()) { // ブロックテーブルを取得します。 var bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; // モデル空間のレコードを取得します。 var btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord; // モデル空間の個々の図形に対して処理を行います。 foreach (ObjectId oid in btr) { // 図形オブジェクトを取得します。 var obj = tr.GetObject(oid, OpenMode.ForRead); // 図形オブジェクトに対して処理を行います。 ... } // トランザクションをコミットします。 tr.Commit(); }

上のプログラムでは、ブロックテーブルのオブジェクト、モデル空間のレコードのオブジェクト、図形オブジェクトを取得するときに GetObject メソッドを呼び出しており、オープンモードはすべて読み込みモード(OpenMode.ForRead)となっています。

モデル空間のレコードオブジェクトについて、図形の情報を取得するだけの場合はオープンモードを読み込みモードとしますが、図形を作図する場合には、モデル空間のレコードオブジェクトに変更が加わる(作図する図形のオブジェクトが追加されるため)ため、オープンモードを書き込みモードとします。

オープンモードの変更

図面データベースからオブジェクトを取得した後でも、オープンモードを変更できます。

DBObject クラスには、オープンモードを変更するために次のメソッドが定義されています。

  • UpgradeOpen メソッド: 読み取りモードを書き込みモードに返る。
  • DowngradeOpen メソッド: 書き込みモードを読み取りモードに変える。

図面を編集するコマンドを作成するとき、「図面にある図形のうち、特定の条件を満たすものだけを変更する」という処理を行いたい場合があります。

この場合、次の手順で目的の処理を実現できます。

  • 読み取りモードで図形オブジェクトを取得する。
  • 変更対象に当てはまるなら、書き込みモードに変更する。
  • 変更処理が終わったら、読み込みモードに戻す。

この手順を C# のプログラムとして書くと、次のようになります。

var obj = tr.GetObject(oid, OpenMode.ForRead); if ((変更対象の条件)) { obj.UpgradeOpen(); // 読み取りモード→書き込みモード (obj に対する変更) obj.DowngradeOpen(): // 書き込みモード→読み取りモード }

プログラムの作成

IJCAD でアクティブになっている図面に対して、図形を編集するプログラムを作成してみましょう。

目標

図面に作図されている図形のうち、線分のみを対象として、始点と終点どちらかのz座標が0でなければ、その線分の色を赤色に変えます。

作成するコマンドの名前は、CHECKLINES とします。

準備

こちらの手順に従って開発環境を用意するか、Visual Studio プロジェクトのひな形をダウンロードします。

ひな形のプロジェクトを Visual Studio で開いたとき、参照エラーが起きている場合は、参照を設定し直してください。

CHECKLINES コマンドの作成

図形オブジェクトの取得

Commands クラス(Commands.cs で定義されています)にコマンド実行用のメソッドを作成し、次のように処理の概略を作成します。

[CommandMethod("CHECKLINES")] public void CheckLines() { // 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.ForRead) as BlockTableRecord; // モデル空間の個々の図形に対して処理を行います。 foreach (ObjectId oid in btr) { // 図形オブジェクトを取得します。 var obj = tr.GetObject(oid, OpenMode.ForRead); // (※) 図形オブジェクトから情報を取得します。 } // トランザクションをコミットします。 tr.Commit(); } }

CHECKLINESコマンドでは図形を作図しないので、モデル空間のレコードのオブジェクトは、読み取りモードで取得します。

このため、GetObject メソッドの第2引数には OpenMode.ForRead を指定しています。

また、図形オブジェクトについても GetObject メソッドで第2引数を OpenMode.ForRead とし、読み込みモードでオブジェクトを取得しています。

線分の色の変更

上のプログラムの※部分に、線分に対する処理を追加します。

個々の図形オブジェクトは読み込みモードで取得しているので、条件を満たす線分に対してのみ UpgradeOpen メソッドを利用し、図形の色を変更できるようにします。

個々の図形に対する処理は次のようになります。

// 線分のみを対象にします。 if (obj is Line) { var line = obj as Line; // 始点か終点のz座標が、0でないかどうかを調べます。 if (line.StartPoint.Z != 0 || line.EndPoint.Z != 0) { // 線分のプロパティを変更できるようにします。 line.UpgradeOpen(); // 線分の色を変えます。 line.ColorIndex = 1; // 赤 // オープンモードを読み込みモードに戻します。 line.DowngradeOpen(); } }

この処理では、まず変数 obj の参照するオブジェクトが線分かどうかを、is 演算子を使って判定しています。

obj の参照する図形オブジェクトが線分ならば、as 演算子で Line クラスにキャストします。

これで、線分の始点と終点の座標が得られるので、それぞれの点のz座標を調べます。

どちらかのz座標が0でなければ、UpgradeOpen メソッドを呼び出して、線分の色を変えられるようにします。

上のコードでは、Line クラスの ColorIndex プロパティに、IJCAD のインデックスカラーの番号を設定することで、線分の色を変えています。

線分の色を変えたら DowngradeOpen メソッドを呼び出して、図形オブジェクトを読み込みモードに戻します。

これで、CHECKLINES コマンドを実行するプログラムが作成できました。

動作の確認

動作確認用のサンプル図面をダウンロードしておきます。

デバッグ実行を開始して、IJCAD を起動し、.NET アセンブリがロードされたら、ダウンロードした図面を開きます。

image

サンプル図面にはいくつかの図形が作図されており、線分については始点と終点の位置に、それぞれの座標を示す文字が作図されています。

この図面では、中央の縦線と右上の斜め線の2つの線分が、z座標が0でない端点を含んでいます。

確認用の図面を開いたら、CHECKLINES コマンドを実行します。

image

z座標が0でない端点を含む線分だけが赤色に変われば、コマンドが正しく作成できています。

まとめ

図面データベースの図形オブジェクトを編集する方法を紹介しました。

今回作成したコマンドのように、特定の条件を満たす図形だけを編集したい場合には、UpgradeOpen メソッドと DowngradeOpen メソッドを利用して、オブジェクトのオープンモードを切り替える方法が有効です。

プラグイン開発の際にはコマンド実行時のパフォーマンスを考慮することも重要ですので、今回紹介したオープンモードの扱い方を、実際の開発に役立ててください。

関連記事

image