MultiCAD .NETテクノロジーにより、マネージコードを超えることなくカスタムプリミティブを作成できます。 C ++での中間オブジェクトの欠如に加えて、MultiCAD .NETは.NETの標準メカニズムを最大限に活用します。その結果、CADプログラマーに馴染みのある多くの操作が不要になります。 。
MultiCAD .NETのデモとして、SDKに含まれているCustomObjectsサンプルアプリケーションを見ていきます。 この例では、テキストが内部にある長方形のフレームであるカスタムプリミティブを作成します。
テストプリミティブを含む図面は、.dwg互換のCADシステムで開くことができます。 プリミティブを変更するには、プリミティブのコードを含むアセンブリをダウンロードする必要があります。同じアセンブリが、再コンパイルせずに、サポートされているすべてのCADシステムにロードされます。 このテクノロジーはnanoCADにネイティブであり、モジュールをAutoCADにロードするには、Object Enablerが必要です。 カットの下での仕組みをご覧ください。
ユーザープリミティブクラス
新しいプリミティブ型を作成するには、すべてのユーザープリミティブの基本クラスであるMcCustomBaseから継承したクラスを作成する必要があります。 さらに、宣言されたクラスには2つの属性を使用する必要があります。
- [CustomEntity]属性は、クラスのタイプ、そのGUID、図面データベース内のすべてのオブジェクトに使用される名前、およびローカル名を示します。
- [Serializable]属性。.NETFrameworkで標準のシリアル化メカニズムを使用するため。
[CustomEntity(typeof(TextInBox), "1C925FA1-842B-49CD-924F-4ABF9717DB62", "TextInBox", "TextInBox Sample Entity")] [Serializable] public class TextInBox : McCustomBase { // First and second vertices of the box private Point3d _pnt1 = new Point3d(50, 50, 0); private Point3d _pnt2 = new Point3d(150, 100, 0); // Text inside the box private String _text = "Text field"; }
ここで、ジオメトリの表示、オブジェクトの図面への挿入、オブジェクトの選択と変換に使用されるMcCustomBase基本クラスメソッドを再定義します。
ジオメトリ表示
オブジェクトを表示するには、OnDraw()メソッドを使用します。 GeometryBuilderクラスのオブジェクトは、このメソッドのパラメーターとして機能し、実際にユーザープリミティブのレンダリングに使用されます。
public override void OnDraw(GeometryBuilder dc) { dc.Clear(); // Set the color to ByObject value dc.Color = McDbEntity.ByObject; // Draw box with choosen coordinates dc.DrawPolyline(new Point3d[] { _pnt1, new Point3d(_pnt1.X, _pnt2.Y, 0), _pnt2, new Point3d(_pnt2.X, _pnt1.Y, 0), _pnt1}); // Set text height dc.TextHeight = 2.5 * DbEntity.Scale; // Set text color dc.Color = Color.Blue; // Draw text at the box center dc.DrawMText(new Point3d((_pnt2.X + _pnt1.X) / 2.0, (_pnt2.Y + _pnt1.Y) / 2.0, 0), Vector3d.XAxis, Text, HorizTextAlign.Center, VertTextAlign.Center); }
図面へのオブジェクトの追加、インタラクティブな座標入力
図面にカスタムオブジェクトを追加するには、PlaceObject()メソッドを使用します。このメソッドは、データベースにオブジェクトを追加する実際の操作に加えて、オブジェクトの座標をインタラクティブに入力するために使用されます。 MultiCAD .NETのインタラクティブな入力の場合、必要な機能はInputJigクラスが担当します。
-
public InputResult GetPoint(string promt)
-プロンプトを表示する機能を備えた、ユーザーが選択した図面内のポイントを取得します。 -
public void ExcludeObject(McObjectId ObjectId)
-図面内のポイントを指定するときに、指定されたオブジェクトをバインディングから除外します。 この場合、自分自身へのバインドを回避するために、オブジェクトをバインドから除外します。 -
public EventHandler MouseMove
マウスモーションイベントのハンドラー。 これを使用して、マウスを動かしながらオブジェクトをインタラクティブに再描画します。
PlaceObject()
メソッドの実装は次のようになります。
public override hresult PlaceObject(PlaceFlags lInsertType) { InputJig jig = new InputJig(); // Get the first box point from the jig InputResult res = jig.GetPoint("Select first point:"); if (res.Result != InputResult.ResultCode.Normal) return hresult.e_Fail; _pnt1 = res.Point; // Add the object to the database DbEntity.AddToCurrentDocument(); // Exclude the object from snap points jig.ExcludeObject(ID); // Monitoring mouse moving and interactive entity redrawing jig.MouseMove = (s, a) => {TryModify(); _pnt2 = a.Point; DbEntity.Update(); }; // Get the second box point from the jig res = jig.GetPoint("Select second point:"); if (res.Result != InputResult.ResultCode.Normal) { DbEntity.Erase(); return hresult.e_Fail; } _pnt2 = res.Point; return hresult.s_Ok; }
オブジェクトの編集と変換
オブジェクトを変更し、テキスト文字列を編集する機能を追加します。 これを行うには、McCustomBase基本クラスに含まれる次のメソッドをオーバーライドする必要があります。
-
public virtual List OnGetGripPoints()
-オブジェクトのハンドルのリストを取得します。 -
public virtual void OnMoveGripPoints(List indexes, Vector3d offset, bool isStretch)
-ハンドル移動ハンドル。 -
public virtual void OnTransform(Matrix3d tfm)
-オブジェクトの変換方法を定義します。 -
public virtual hresult OnEdit(Point3d pnt, EditFlags lInsertType)
-オブジェクトを編集する手順を定義します。
ハンドルは、オブジェクトを変換するために使用されるマーカーでマークされた特別なポイントです。 ユーザーが指定したフレームのコーナーポイントにハンドルを表示します。
public override List OnGetGripPoints() { List arr = new List(); arr.Add(_pnt1); arr.Add(_pnt2); return arr; }
これで、図面内のオブジェクトを選択すると、ペンが指定のポイントに表示されます。
OnMoveGripPoints()ハンドラーメソッドを定義して、ドラッグアンドドロップハンドルを使用してコーナーポイントを定義して移動する機能を追加します。
public override void OnMoveGripPoints(List indexes, Vector3d offset, bool isStretch) { if (!TryModify()) return; if (indexes.Count == 2) { _pnt1 += offset; _pnt2 += offset; } else if (indexes.Count == 1) { if (indexes[0] == 0) _pnt1 += offset; else _pnt2 += offset; } }
ここのインデックスパラメータにはハンドル番号のリストが含まれ、オフセットはハンドル移動ベクトルです。
次に、OnTransform()メソッドを定義して、オブジェクトを変換するときに、両方の定義コーナーポイントの新しい座標が計算されるようにします。
public override void OnTransform(Matrix3d tfm) { //Save Undo state and set the object status to "Changed" if (!TryModify()) return; _pnt1 = _pnt1.TransformBy(tfm); _pnt2 = _pnt2.TransformBy(tfm); }
最後に、フレーム内のテキスト行を編集する機能を追加します。 編集するには、オブジェクトをダブルクリックするか、コンテキストメニューで適切な項目を選択します。 編集コマンドが呼び出されると、テキストフィールドのあるフォームが呼び出され、その行に新しい値を入力できます。
public override hresult OnEdit(Point3d pnt, EditFlags lInsertType) { TextInBox_Form frm = new TextInBox_Form(); frm.textBox1.Text = Text; frm.ShowDialog(); Text = frm.textBox1.Text; return hresult.s_Ok; }
オブジェクトプロパティをプロパティインスペクターに追加する
MultiCAD .NET APIは、.dwgファイルが開かれるプラットフォームに関係なく、AutoCADかnanoCADかに関係なく、オブジェクトプロパティインスペクターにカスタムオブジェクトプロパティを追加する機能を提供します。 これは、オブジェクトの対応するパブリックプロパティに次の属性を追加することで実行されます。
-
DisplayNameAttribute
インスペクターに表示されるプロパティの名前を定義します。 -
DescriptionAttribute
プロパティの説明を設定します。 -
CategoryAttribute
このプロパティが表示されるカテゴリの名前を定義します。
この機会を利用して、Textプロパティをオブジェクトプロパティパレットに追加します。
[DisplayName(" ")] [Description(" ")] [Category(" ")] public String Text { get { return _text; } set { //Save Undo state and set the object status to "Changed" if (!TryModify()) return; // Set new text value _text = value; } }
その後、オブジェクトのテキスト文字列の値がオブジェクトインスペクターに表示されます。
そこで、最初のバージョンのプリミティブを作成しました。これは、.dwg形式の図面に挿入し、CADユーザーに馴染みのあるいくつかの方法で編集できます。 しかし、人生はまだ止まっておらず、プリミティブの機能を向上させる必要があります。 次の記事のいずれかで、新しいフィールドを追加するプリミティブの2番目のバージョンを検討し、MultiCAD.NET APIによって提供されるプリミティブのバージョンを操作するためのオプションについて説明します。
記事のディスカッションは、フォーラム( forum.nanocad.ru/index.php?showtopic=6504)でも利用できます。
記事の英語への翻訳: MultiCAD .NET APIを使用したCADでのカスタムエンティティの作成 。