development of

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

【IJCAD】一時的なグラフィックを表示する

AutoCAD で一時的なグラフィックを表示するには

AutoCAD で一時的なグラフィックを表示させるには、Editor.DrawVector メソッドを使った方法と、TransientManager クラスを使った方法があります。

Editor.DrawVector メソッドは、指定したベクトルを描画します。
TransientManager クラスは一時的なものを管理するクラスで、TransientManager.AddTransient メソッドで一時的に表示したいオブジェクトを追加することで、ビューポート上に一時的なグラフィックが表示されます。

IJCAD で一時的なグラフィックを表示するには

IJCAD には、Editor.DrawVector メソッドは存在しますが、残念ながら TransientManager クラスは実装されていませんでした。

直線や矩形の一時的なグラフィックを表示するには、 Editor.DrawVector メソッドでも事足りますが、円や楕円の一時グラフィックを表示するとなると、曲線をベクトルで表現するのは手間がかかってしまいます。

そこで多少 IJCAD に負荷をかけることになりますが、PointMonitor イベント内で Geometry.Draw メソッド使用して、一時的なグラフィックを表示させてみます。 

サンプルコード

private static List<Entity> _entities = new List<Entity>();
private bool _pointMonitor = false;

[CommandMethod("TEMPOBJ")]
public void CreateTemporaryObject()
{
    PointMonitorON();

    var ed = Application.DocumentManager.MdiActiveDocument.Editor;
    while (true)
    {
        var res = ed.GetPoint("\n円の中心を指定");
        if (res.Status != PromptStatus.OK) break;
        _entities.Add(new Circle(res.Value, Vector3d.ZAxis, 10.0));
    }
}

[CommandMethod("TEMPOBJCLEAR")]
public void ClearTemporaryObject()
{
    _entities.ForEach(ent => ent.Dispose());
    _entities.Clear();

    PointMonitorOFF();
}

[CommandMethod("PMON")]
public void PointMonitorON()
{
    if(!_pointMonitor)
    {
        var ed = Application.DocumentManager.MdiActiveDocument.Editor;
        ed.PointMonitor += Ed_PointMonitor;
        _pointMonitor = true;
    }
}

[CommandMethod("PMOFF")]
public void PointMonitorOFF()
{
    if (_pointMonitor)
    {
        var ed = Application.DocumentManager.MdiActiveDocument.Editor;
        ed.PointMonitor -= Ed_PointMonitor;
        _pointMonitor = false;
    }
}

private static void Ed_PointMonitor(object sender, PointMonitorEventArgs e)
{
    if (_entities.Count == 0) return;
    var geo = e.Context.DrawContext.Geometry;
    _entities.ForEach(ent => geo.Draw(ent));
}

※サンプルコードについての補足

PointMonitorEventArgs.Context プロパティから順に、DrawContext プロパティ、Geometry プロパティと進み、ViewportGeometry オブジェクトを取得します。

後は、Geometry.Draw メソッドを使用して、一時的なグラフィックがビューポートに表示されます。

PointMonitor イベントを使用した方法では、ビューポートのリフレッシュが完了したタイミングでマウスカーソルの動きを止めると、一時的なグラフィックが表示されていない状態になったりするなど、完全な TransientManager クラスの代替とは言えません。

また、AutoCADTransientManager クラスを使用したグラフィックの表示でもいえますが、一時的に作成したオブジェクトが必要がなくなったときは、確実にオブジェクトを解放しておかないとメモリリークの原因になってしまうので注意してください。