development of

Tieghaに関する備忘録とおまけ

【IJCAD】選択オブジェクトから情報を取得する

IJCAD 2018 以前では…

以前のバージョンの IJCAD では、SelectedObject オブジェクトを、 PickPointSelectedObject クラスや、CrossingOrWindowSelectedObject クラスにキャストできないという、なんとも言えない問題がありました。

as 演算子 を使用した型変換をすると null が返される、括弧を使用してキャストをすると System.InvalidCastException の例外がスローされてしまうといった具合です。

この問題のおかげで IJCAD 2018 以前では、Editor.GetSelection メソッドを使用したユーザ入力などで、オブジェクトがどのような状況で選択されたのかの詳細を知る術がありませんでした。

IJCAD 2019 にて

この仕様もない問題ですが、どうやら IJCAD 2019 にてやっと解決したようで、どのようにしてオブジェクトが選択されたのかの詳細が取得することができました。

サンプルコード

var db = Application.DocumentManager.MdiActiveDocument.Database;
var ed = Application.DocumentManager.MdiActiveDocument.Editor;

// ユーザ選択による選択セットを作成
var res = ed.GetSelection();
if (res.Status != PromptStatus.OK) return;

// 選択セットを取得
var ss = res.Value;

foreach(SelectedObject selobj in ss)
{
    var id = selobj.ObjectId;
    var dxfName = id.ObjectClass.DxfName;

    // どのように選択されたか確認
    switch(selobj.SelectionMethod)
    {
        // 非グラフィカルな方法で選択された場合
        case SelectionMethod.NonGraphical:

            ed.WriteMessage($"\n{dxfName}{id}は、非グラフィカルな方法(すべて(ALL)や最後(L)等)で選択されました。");
            break;

        // オブジェクトをクリックして選択された場合
        case SelectionMethod.PickPoint:

            // SelectedObjectをPickPointSelectedObjectにキャスト
            var pickSelObj = (PickPointSelectedObject)selobj;
            // 選択時の要約を取得
            var pickPoint = pickSelObj.PickPoint;

            ed.WriteMessage($"\n{dxfName}{id}は、座標{pickPoint.PointOnLine}をクリックして選択しました。");
            break;

        // 窓またはポリゴン窓で選択された場合
        case SelectionMethod.Window:

            // SelectedObjectをCrossingOrWindowSelectedObjectにキャスト
            var windowSelObj = (CrossingOrWindowSelectedObject)selobj;
            // 選択時の要約を取得
            var pickPointDescriptors = windowSelObj.GetPickPoints();

            ed.WriteMessage($"\n{dxfName}{id}を窓またはポリゴン窓で選択しました。");
            ed.WriteMessage("\n窓またはポリゴン窓は、次の座標点で構成されています。");
            for(var i = 0; i < pickPointDescriptors.Count(); i++)
            {
                if (i != 0) ed.WriteMessage(", ");
                ed.WriteMessage($"\n  点{i + 1}:{pickPointDescriptors[i].PointOnLine}");
            }
            break;

        // 交差またはポリゴン交差で選択された場合
        case SelectionMethod.Crossing:

            // SelectedObjectをCrossingOrWindowSelectedObjectにキャスト
            var crossingSelObj = (CrossingOrWindowSelectedObject)selobj;
            // 選択時の要約を取得
            pickPointDescriptors = crossingSelObj.GetPickPoints();

            ed.WriteMessage($"\n{dxfName}{id}を交差またはポリゴン交差で選択しました。");
            ed.WriteMessage("\n交差またはポリゴン交差は、次の座標点で構成されています。");
            for (var i = 0; i < pickPointDescriptors.Count(); i++)
            {
                if (i != 0) ed.WriteMessage(", ");
                ed.WriteMessage($"\n  点{i + 1}:{pickPointDescriptors[i].PointOnLine}");
            }
            break;

        // フェンスで選択された場合
        case SelectionMethod.Fence:

            // SelectedObjectをFenceSelectedObjectにキャスト
            var fanceSelObj = (FenceSelectedObject)selobj;
            // 選択時の要約を取得
            pickPointDescriptors = fanceSelObj.GetIntersectionPoints();

            ed.WriteMessage($"\n{dxfName}{id}をフェンスで選択しました。");
            ed.WriteMessage("\n入力したフェンスとは、次の座標点で交差しています。");
            for (var i = 0; i < pickPointDescriptors.Count(); i++)
            {
                if (i != 0) ed.WriteMessage(", ");
                ed.WriteMessage($"\n  点{i + 1}:{pickPointDescriptors[i].PointOnLine}");
            }
            break;

        // その他の方法で選択された場合
        default:
            ed.WriteMessage($"\n{dxfName}{id}は不明な方法で選択されました。");
            break;
    }
}

SelectedObject オブジェクトから、選択時のさまざまな情報を取得できるようになりましたので、例えばオブジェクトをクリックして選択されたときの座標や、窓や交差による選択範囲がどの座標を指定したかを、やっと確認できるようになりました。