Autodesk Community Tips- ADNオープン
Autodesk Community Tipsではちょっとしたコツ、やり方、ショートカット、アドバイスやヒントを共有しています。

AutoCAD .NET API:オーバールールによるオブジェクトの連動

Issue

グループやブロック化していない状態の特定オブジェクトを移動や回転する際に、 イベント処理を使用せずに、アプリ内で関係のあるオブジェクトを同じように移動や回転する方法はありますか?

 

Solution

特定のオブジェクト タイプ(クラス)の移動や回転、縮尺変更など編集は、TransformOverrule オーバールール(Overrule)プロトコルを使用して、既定の振る舞いを変更することが可能です。ただし、イベント ハンドラーでのオブジェクト編集で同一イベントが発生してしまい、無限ループに陥らないような配慮が必要です。

 

次の C# コードは、MOVE コマンドや ROTATE コマンド、SCALE コマンドで円弧オブジェクト(Arc)を選択すると、青色(インデックスカラー色:)の線分オブジェクト(Line)に同じマトリックス変換を実施するものです。

 

public class TransformByOverrule : TransformOverrule
{
    public override void TransformBy(Entity ent, Matrix3d mat)
    {
        Database db = HostApplicationServices.WorkingDatabase;
        Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
        ed.WriteMessage("\nTransformBy.TransformBy Overrule - matrix {0}", mat.ToString());
        base.TransformBy(ent, mat);

        TypedValue[] typeval = new TypedValue[2];
        typeval.SetValue(new TypedValue(62, 5), 0);
        typeval.SetValue(new TypedValue(0, "LINE"), 1);
        SelectionFilter filter = new SelectionFilter(typeval);
        PromptSelectionResult psr = ed.SelectAll(filter);
        ed.WriteMessage("\nGetSelection = {0}", psr.Status.ToString());
        if (psr.Status == PromptStatus.OK)
        {
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                SelectionSet sset = psr.Value;
                foreach (ObjectId objId in sset.GetObjectIds())
                {
                    ed.WriteMessage("\nObjectTd:" + objId.ToString());
                    Entity slave = (Entity)tr.GetObject(objId, OpenMode.ForWrite);
                    slave.TransformBy(mat);
                }
                tr.Commit();
            }
        }
    }
}

static TransformByOverrule _toverrule = null;

[CommandMethod("MyCommand")]
static public void MyCommand()
{
    Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;
    if (_toverrule == null)
    {
        _toverrule = new TransformByOverrule();
        ObjectOverrule.AddOverrule(RXObject.GetClass(typeof(Arc)), _toverrule, true);
        ObjectOverrule.Overruling = true;
        ed.WriteMessage("\nBegin modifying ARC overrule");
    }
    else
    {
        ObjectOverrule.RemoveOverrule(RXObject.GetClass(typeof(Arc)), _toverrule);
        _toverrule.Dispose();
        _toverrule = null;
        ed.WriteMessage("\nEnd modifying ARC overrule");
    }
}

 

 TransformOverrule.gif