Sunday, January 23, 2011

Creating A "Move" Command With .NET API - Take 2

In a previous post Creating A "Move" Command With .NET API, I demonstrated how to use Editor.Drag() to build a custom "MOVE" command. It was pretty easy. However, as Jeroen Verdonschot pointed out in his comment, "Ortho" mode does not work within Editor.Drag(). This would be a serious drawback if you want the custom "MOVE" command to be really useful.

As matter of fact, in one of my earliest post here I demonstrated a technique of using Transient Graphics with a video clip. One can see it was almost a nearly finished "MOVE" command. So, I figured, I could just take on the "MOVE" command again and handle the "Ortho on/off" situation.

Here is the class "MyMoveCmd" that does the moving work:

using System;
using System.Collections.Generic;

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;

namespace MoveWithTG
{
    public class MyMoveCmd
    {
        private Document _dwg;
        private Editor _editor;
        private ObjectIdCollection _selectedIds;
        private Point3d _basePoint;
        private Point3d _currentPoint;
        private Point3d _moveToPoint;
        private List  _tgDrawables;
        private bool _pointMonitored = false;

        public MyMoveCmd(Document dwg)
        {
            _dwg=dwg;
            _editor=_dwg.Editor;
        }

        public void DoMove()
        {
            //Select object and highlight selected
            ObjectIdCollection ids = new ObjectIdCollection();

            using (Transaction tran = _dwg.Database.
                TransactionManager.StartOpenCloseTransaction())
            {
                if (!GetSelectedEntities(tran, out ids))
                {
                    _editor.WriteMessage("\n*Cancel*");
                    ids = new ObjectIdCollection();
                }

            }

            if (ids.Count == 0) return;

            _selectedIds = ids;

            //Calculate base point (lower-left conner of 
            //bounding box that encloses all selected entities)
            _basePoint = GetDefaultBasePoint();

            //current dragging point
            _currentPoint = _basePoint;

            Transaction trans = _dwg.Database.
                TransactionManager.StartTransaction();

            CreateTransientGraphics(trans);

            try
            {
                _editor.PointMonitor +=
                    new PointMonitorEventHandler(Editor_PointMonitor);
                _pointMonitored = true;

                while (true)
                {
                    PromptPointOptions opt =
                        new PromptPointOptions("\nSelect point to move to: ");
                    opt.UseBasePoint = true;
                    opt.BasePoint = _basePoint;
                    opt.Keywords.Add("Base point");
                    opt.AppendKeywordsToMessage = true;
                    PromptPointResult res = _editor.GetPoint(opt);
                    if (res.Status == PromptStatus.OK)
                    {
                        //Get "Move To" point
                        if (IsOrthModeOn())
                        {
                            _moveToPoint = GetOrthoPoint(res.Value);
                        }
                        else
                        {
                            _moveToPoint = res.Value;
                        }

                        MoveEntities(trans);
                        _editor.WriteMessage("\n{0} moved", _selectedIds.Count);
                        break;
                    }
                    else if (res.Status == PromptStatus.Keyword)
                    {
                        //If user choose to pick BasePoint,
                        //Stop habdling PointMonitor
                        ClearTransientGraphics();

                        _editor.PointMonitor -=
                            new PointMonitorEventHandler(Editor_PointMonitor);
                        _pointMonitored = false;

                        Point3d p;
                        if (!PickBasePoint(out p))
                        {
                            _editor.WriteMessage("\n*Cancel*");
                            break;
                        }
                        else
                        {
                            //Reset base point and current dragging point
                            _basePoint = p;
                            _currentPoint = _basePoint;

                            //Re-create transient graphics
                            CreateTransientGraphics(trans);

                            _editor.PointMonitor +=
                                new PointMonitorEventHandler(Editor_PointMonitor);
                            _pointMonitored = true;
                        }
                    }
                    else
                    {
                        _editor.WriteMessage("\n*Cancel*");
                        break;
                    }
                }
            }
            catch
            {
                throw;
            }
            finally
            {
                ClearHighlight(trans);
                ClearTransientGraphics();

                if (_pointMonitored)
                {
                    _editor.PointMonitor -=
                        new PointMonitorEventHandler(Editor_PointMonitor);
                }

                trans.Commit();
                trans.Dispose();
            }

        }

        #region private metods

        private bool GetSelectedEntities(Transaction tran, out ObjectIdCollection ids)
        {
            ids = new ObjectIdCollection();

            PromptSelectionResult res = _editor.SelectImplied();
            if (res.Status == PromptStatus.OK)
            {
                foreach (ObjectId id in res.Value.GetObjectIds())
                {
                    ids.Add(id);
                    HighlightEntity(tran, id, true);
                }
            }
            else
            {
                while (true)
                {
                    string msg=ids.Count>0?ids.Count + " selected. Pick entity: ":"Pick entity: ";
                    PromptEntityOptions opt = new PromptEntityOptions("\n" + msg);
                    opt.AllowNone = true;
                    PromptEntityResult entRes = _editor.GetEntity(opt);
                    if (entRes.Status == PromptStatus.OK)
                    {
                        bool exists = false;
                        foreach (ObjectId id in ids)
                        {
                            if (id == entRes.ObjectId)
                            {
                                exists = true;
                                break;
                            }
                        }

                        if (!exists)
                        {
                            ids.Add(entRes.ObjectId);
                            HighlightEntity(tran, entRes.ObjectId,true);
                        }
                    }
                    else if (entRes.Status == PromptStatus.None)
                    {
                        break;
                    }
                    else
                    {
                        return false;
                    }
                }  
            }

            return true;
        }

        private void HighlightEntity(Transaction tran, ObjectId id, bool highlight)
        {
            Entity ent = (Entity)tran.GetObject(id, OpenMode.ForWrite);
            if (highlight)
                ent.Highlight();
            else
                ent.Unhighlight();
        }

        private Point3d GetDefaultBasePoint()
        {
            Extents3d exts = new Extents3d(
                new Point3d(0.0, 0.0, 0.0), new Point3d(0.0, 0.0, 0.0));

            using (Transaction tran =
                _dwg.Database.TransactionManager.StartTransaction())
            {
                for (int i = 0; i < _selectedIds.Count; i++)
                {
                    ObjectId id = _selectedIds[i];
                    Entity ent = (Entity)tran.GetObject(id, OpenMode.ForRead);

                    if (i == 0)
                    {
                        exts = ent.GeometricExtents;
                    }
                    else
                    {
                        Extents3d ext = ent.GeometricExtents;
                        exts.AddExtents(ext);
                    }
                }

                tran.Commit();
            }

            return exts.MinPoint;
        }

        private bool PickBasePoint(out Point3d pt)
        {
            pt = new Point3d();

            PromptPointOptions opt = new PromptPointOptions("Pick base point: ");
            PromptPointResult res = _editor.GetPoint(opt);
            if (res.Status == PromptStatus.OK)
            {
                pt = res.Value;
                return true;
            }
            else
            {
                return false;
            }
        }

        private bool IsOrthModeOn()
        {
            object orth = Autodesk.AutoCAD.ApplicationServices.
                Application.GetSystemVariable("ORTHOMODE");

            return Convert.ToInt32(orth) > 0;
        }

        private Point3d GetOrthoPoint(Point3d pt)
        {
            double x=pt.X;
            double y=pt.Y;

            Vector3d vec = _basePoint.GetVectorTo(pt);
            if (Math.Abs(vec.X)>=Math.Abs(vec.Y))
            {
                y = _basePoint.Y;
            }
            else
            {
                x = _basePoint.X;
            }

            return new Point3d(x, y, 0.0);
        }

        private void ClearHighlight(Transaction trans)
        {
            foreach (ObjectId id in _selectedIds)
            {
                HighlightEntity(trans, id, false);
            }
        }

        private void MoveEntities(Transaction tran)
        {
            Matrix3d mat = Matrix3d.Displacement(_basePoint.GetVectorTo(_moveToPoint));
            foreach (ObjectId id in _selectedIds)
            {
                Entity ent = (Entity)tran.GetObject(id, OpenMode.ForWrite);
                ent.TransformBy(mat);
            }
        }

        #endregion

        #region private method: handling PointMonitor and transient graphics

        private void Editor_PointMonitor(object sender, PointMonitorEventArgs e)
        {
            Point3d pt = e.Context.RawPoint;
            if (IsOrthModeOn())
            {
                pt = GetOrthoPoint(pt);
            }

            UpdateTransientGraphics(pt);

            _currentPoint = pt;
        }

        private void CreateTransientGraphics(Transaction tran)
        {
            _tgDrawables = new List();

            foreach (ObjectId id in _selectedIds)
            {
                Entity ent = (Entity)tran.GetObject(id, OpenMode.ForRead);

                Entity drawable = ent.Clone() as Entity;
                drawable.ColorIndex = 1;
                _tgDrawables.Add(drawable);
            }

            foreach (Drawable d in _tgDrawables)
            {
                TransientManager.CurrentTransientManager.
                    AddTransient(d, TransientDrawingMode.DirectShortTerm, 
                    128, new IntegerCollection());
            }
        }

        private void UpdateTransientGraphics(Point3d moveToPoint)
        {
            Matrix3d mat = Matrix3d.Displacement(_currentPoint.GetVectorTo(moveToPoint));
            foreach (Drawable d in _tgDrawables)
            {
                Entity e = d as Entity;
                e.TransformBy(mat);

                TransientManager.CurrentTransientManager.
                    UpdateTransient(d, new IntegerCollection());
            }
        }

        private void ClearTransientGraphics()
        {
            TransientManager.CurrentTransientManager.
                EraseTransients(TransientDrawingMode.DirectShortTerm, 
                128, new IntegerCollection());

            foreach (Drawable d in _tgDrawables)
            {
                d.Dispose();
            }

            _tgDrawables.Clear();
        }

        #endregion
    }
}

Then the simple command class:

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;

[assembly: CommandClass(typeof(MoveWithTG.MyCommands))]

namespace MoveWithTG
{
    public class MyCommands
    {
        [CommandMethod("MyMove",CommandFlags.UsePickSet)]
        public static void DoCommand()
        {
            Document dwg = Autodesk.AutoCAD.ApplicationServices.
                Application.DocumentManager.MdiActiveDocument;

            MyMoveCmd move = new MyMoveCmd(dwg);
            move.DoMove();
        }
    }
}

The behaviour of the custom "MOVE" command can be seen here.

If you want the selected objects not only move horizontally or vertically when "Ortho" mode is on, but also can be moved along a specific angle, one of my other posts here would be of help.

Note: due to the blog's format, The Generic type cannot be shown in the post correctly. The "List" shown in red should be List(Of Drawable) in VB.NET. It looks like I have to post code in VB.NET if my code uses Generic. Too bad.

Note again: due to the blog's format, the code using Generic in C# cannot be shown here correctly for its angled bracket, I now post the VB.NET code here. In my future post, if there is Generic involved, I'll try post code in VB.NET.

Here is the class "MyMoveCmd" in VB.NET:

Imports System.Collections.Generic

Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.GraphicsInterface


Public Class MyMoveCmd

    Private _dwg As Document
    Private _editor As Editor
    Private _selectedIds As ObjectIdCollection
    Private _basePoint As Point3d
    Private _currentPoint As Point3d
    Private _moveToPoint As Point3d
    Private _tgDrawables As List(Of Drawable)
    Private _pointMonitored As Boolean = False

    Public Sub New(ByVal dwg As Document)
        _dwg = dwg
        _editor = _dwg.Editor
    End Sub

    Public Sub DoMove()
        'Select object and highlight selected
        Dim ids As New ObjectIdCollection()

        Using tran As Transaction = _
            _dwg.Database.TransactionManager.StartOpenCloseTransaction()

            If Not GetSelectedEntities(tran, ids) Then
                _editor.WriteMessage(vbLf & "*Cancel*")
                ids = New ObjectIdCollection()

            End If
        End Using

        If ids.Count = 0 Then
            Return
        End If

        _selectedIds = ids

        'Calculate base point (lower-left conner of 
        'bounding box that encloses all selected entities)
        _basePoint = GetDefaultBasePoint()

        'current dragging point
        _currentPoint = _basePoint

        Dim trans As Transaction = _
            _dwg.Database.TransactionManager.StartTransaction()

        CreateTransientGraphics(trans)

        Try

            AddHandler _editor.PointMonitor, AddressOf Editor_PointMonitor
            _pointMonitored = True

            While True
                Dim opt As New PromptPointOptions(vbLf & "Select point to move to: ")
                opt.UseBasePoint = True
                opt.BasePoint = _basePoint
                opt.Keywords.Add("Base point")
                opt.AppendKeywordsToMessage = True
                Dim res As PromptPointResult = _editor.GetPoint(opt)
                If res.Status = PromptStatus.OK Then
                    'Get "Move To" point
                    If IsOrthModeOn() Then
                        _moveToPoint = GetOrthoPoint(res.Value)
                    Else
                        _moveToPoint = res.Value
                    End If

                    MoveEntities(trans)
                    _editor.WriteMessage(vbLf & "{0} moved", _selectedIds.Count)
                    Exit While
                ElseIf res.Status = PromptStatus.Keyword Then
                    'If user choose to pick BasePoint,
                    'Stop habdling PointMonitor
                    ClearTransientGraphics()

                    RemoveHandler _editor.PointMonitor, AddressOf Editor_PointMonitor
                    _pointMonitored = False

                    Dim p As Point3d
                    If Not PickBasePoint(p) Then
                        _editor.WriteMessage(vbLf & "*Cancel*")
                        Exit While
                    Else
                        'Reset base point and current dragging point
                        _basePoint = p
                        _currentPoint = _basePoint

                        'Re-create transient graphics
                        CreateTransientGraphics(trans)

                        AddHandler _editor.PointMonitor, AddressOf Editor_PointMonitor
                        _pointMonitored = True
                    End If
                Else
                    _editor.WriteMessage(vbLf & "*Cancel*")
                    Exit While
                End If
            End While
        Catch
            Throw
        Finally
            ClearHighlight(trans)
            ClearTransientGraphics()

            If _pointMonitored Then
                RemoveHandler _editor.PointMonitor, AddressOf Editor_PointMonitor
            End If

            trans.Commit()
            trans.Dispose()
        End Try

    End Sub

#Region "private metods"

    Private Function GetSelectedEntities(ByVal tran As Transaction, _
                                         ByRef ids As ObjectIdCollection) As Boolean

        ids = New ObjectIdCollection()

        Dim res As PromptSelectionResult = _editor.SelectImplied()
        If res.Status = PromptStatus.OK Then
            For Each id As ObjectId In res.Value.GetObjectIds()
                ids.Add(id)
                HighlightEntity(tran, id, True)
            Next
        Else
            While True
                Dim msg As String = If(ids.Count > 0, _
                                       Convert.ToString(ids.Count) & " selected. Pick entity: ", _
                                       "Pick entity: ")
                Dim opt As New PromptEntityOptions(vbLf & msg)
                opt.AllowNone = True
                Dim entRes As PromptEntityResult = _editor.GetEntity(opt)
                If entRes.Status = PromptStatus.OK Then
                    Dim exists As Boolean = False
                    For Each id As ObjectId In ids
                        If id = entRes.ObjectId Then
                            exists = True
                            Exit For
                        End If
                    Next

                    If Not exists Then
                        ids.Add(entRes.ObjectId)
                        HighlightEntity(tran, entRes.ObjectId, True)
                    End If
                ElseIf entRes.Status = PromptStatus.None Then
                    Exit While
                Else
                    Return False
                End If
            End While
        End If

        Return True
    End Function

    Private Sub HighlightEntity(ByVal tran As Transaction, _
                                ByVal id As ObjectId, ByVal highlight As Boolean)

        Dim ent As Entity = DirectCast(tran.GetObject(id, OpenMode.ForWrite), Entity)
        If highlight Then
            ent.Highlight()
        Else
            ent.Unhighlight()
        End If

    End Sub

    Private Function GetDefaultBasePoint() As Point3d

        Dim exts As New Extents3d(New Point3d(0.0, 0.0, 0.0), New Point3d(0.0, 0.0, 0.0))

        Using tran As Transaction = _dwg.Database.TransactionManager.StartTransaction()
            For i As Integer = 0 To _selectedIds.Count - 1
                Dim id As ObjectId = _selectedIds(i)
                Dim ent As Entity = DirectCast(tran.GetObject(id, OpenMode.ForRead), Entity)

                If i = 0 Then
                    exts = ent.GeometricExtents
                Else
                    Dim ext As Extents3d = ent.GeometricExtents
                    exts.AddExtents(ext)
                End If
            Next

            tran.Commit()
        End Using

        Return exts.MinPoint

    End Function

    Private Function PickBasePoint(ByRef pt As Point3d) As Boolean

        pt = New Point3d()

        Dim opt As New PromptPointOptions("Pick base point: ")
        Dim res As PromptPointResult = _editor.GetPoint(opt)
        If res.Status = PromptStatus.OK Then
            pt = res.Value
            Return True
        Else
            Return False
        End If

    End Function

    Private Function IsOrthModeOn() As Boolean

        Dim orth As Object = Autodesk.AutoCAD.ApplicationServices. _
            Application.GetSystemVariable("ORTHOMODE")

        Return Convert.ToInt32(orth) > 0

    End Function

    Private Function GetOrthoPoint(ByVal pt As Point3d) As Point3d

        Dim x As Double = pt.X
        Dim y As Double = pt.Y

        Dim vec As Vector3d = _basePoint.GetVectorTo(pt)
        If Math.Abs(vec.X) >= Math.Abs(vec.Y) Then
            y = _basePoint.Y
        Else
            x = _basePoint.X
        End If

        Return New Point3d(x, y, 0.0)

    End Function

    Private Sub ClearHighlight(ByVal trans As Transaction)
        For Each id As ObjectId In _selectedIds
            HighlightEntity(trans, id, False)
        Next
    End Sub

    Private Sub MoveEntities(ByVal tran As Transaction)

        Dim mat As Matrix3d = Matrix3d.Displacement(_basePoint.GetVectorTo(_moveToPoint))
        For Each id As ObjectId In _selectedIds
            Dim ent As Entity = DirectCast(tran.GetObject(id, OpenMode.ForWrite), Entity)
            ent.TransformBy(mat)
        Next

    End Sub

#End Region

#Region "private method: handling PointMonitor and transient graphics"

    Private Sub Editor_PointMonitor(ByVal sender As Object, ByVal e As PointMonitorEventArgs)
        Dim pt As Point3d = e.Context.RawPoint
        If IsOrthModeOn() Then
            pt = GetOrthoPoint(pt)
        End If

        UpdateTransientGraphics(pt)

        _currentPoint = pt
    End Sub

    Private Sub CreateTransientGraphics(ByVal tran As Transaction)

        _tgDrawables = New List(Of Drawable)()

        For Each id As ObjectId In _selectedIds
            Dim ent As Entity = DirectCast(tran.GetObject(id, OpenMode.ForRead), Entity)

            Dim drawable As Entity = TryCast(ent.Clone(), Entity)
            drawable.ColorIndex = 1
            _tgDrawables.Add(drawable)
        Next

        For Each d As Drawable In _tgDrawables
            TransientManager.CurrentTransientManager.AddTransient( _
                d, TransientDrawingMode.DirectShortTerm, _
                128, New IntegerCollection())
        Next
    End Sub

    Private Sub UpdateTransientGraphics(ByVal moveToPoint As Point3d)

        Dim mat As Matrix3d = Matrix3d.Displacement( _
            _currentPoint.GetVectorTo(moveToPoint))

        For Each d As Drawable In _tgDrawables
            Dim e As Entity = TryCast(d, Entity)
            e.TransformBy(mat)

            TransientManager.CurrentTransientManager.UpdateTransient( _
                d, New IntegerCollection())
        Next

    End Sub

    Private Sub ClearTransientGraphics()

        TransientManager.CurrentTransientManager.EraseTransients( _
            TransientDrawingMode.DirectShortTerm, _
            128, New IntegerCollection())

        For Each d As Drawable In _tgDrawables
            d.Dispose()
        Next

        _tgDrawables.Clear()

    End Sub

#End Region
End Class

Here is the command class:

Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.EditorInput
Imports Autodesk.AutoCAD.DatabaseServices

 

Public Class MyCommands

     _
    Public Shared Sub DoCommand()
        Dim dwg As Document = Autodesk.AutoCAD.ApplicationServices. _
            Application.DocumentManager.MdiActiveDocument

        Dim move As New MyMoveCmd(dwg)
        move.DoMove()
    End Sub

End Class

15 comments:

Jeroen Verdonschot said...
This comment has been removed by the author.
Jeroen Verdonschot said...

editor.pointmonitor thing work? I surfed some forums but I can't find a answer.

If I use your code I get a RaiseEvent error with editor.pointmonitor. I saw some answers on the web about a addhandler. Is this a class if have to load or some library I haven't loaded?

I have the feeling this a complete newbie question but maybe there are more newbies who use your code to learn .NET.

Thanks,

Jeroen

Norman Yuan said...

Jeroen,

Are you using VBH.NET? You can copy my code and use some on-line C#/VB.NET converting tool to get a VB.NET version of the code right away. Such as this one:

http://www.developerfusion.com/tools/convert/csharp-to-vb/

Jeroen Verdonschot said...

Norman,

I use VB.net (seemed the easiest of the .net family)
The translator gives some errors. So I try translate is it part by part and try to find why the translator won't translate.

I translated "Dragging a Line in Certain Angle"-code so I could understand pointmonitor. But this code also gives the RaiseEvent error.

Jeroen

Norman Yuan said...

Jeroen,

I have added VB.NET code to the article. Hope it would be of help for you.

Jeroen Verdonschot said...

Thanks!!!!

Jeroen Verdonschot said...

Norman,

Thanks to your examples I created 2 commands. I use the copy command daily. It based on the Sketchup move command. You can multiply or divide you last copy.

Is there a way to upload the code? (if you're interested at all of course :))

Jeroen

Norman Yuan said...

Hello Jeroen,

Yes, I am interested in seeing how you did that. If you have a blog to post your code, it would be beneficial to more people (but the www.blogger.com that we use seems not that good for posting programming code). Or you can zip it up and attach it to an email sent to norman.yuan.fsj@gmail.com.

Thanks.

Norman

Kean Walmsley said...

Hi gents,

I'd also be interested in seeing this code (and potentially sharing it with my readers, with your permission).

Let me know if you're interested (kean.walmsley@autodesk.com).

Regards,

Kean

Norman Yuan said...

Kean,

Feel free to quote the code shown in my article, if it is in your interest. I have learned a lot form your blog.

Regards,

Norman Yuna

Jeroen Verdonschot said...

Hi all,

Sorry for the delay. I have mailed a zip with my commands to you, Norman.
The move command is nothing special. The copy command is a copy of the original copy command only with divide and multiply. (something I use everyday now). Divide, divides the last copy action by an X number of copies. Multiply, works like a linear array.

I have a TO DO list for the commands. Renaming of some variables, adding some comments that explain and make ortho work in a UCS other than the World UCS.
And I'm very curious what you think because I'm working with VB.net for a month now so there is a lot to learn for me.

Regards,

Jeroen

Solidworks Support said...

ProgeCAD Smart is free but can't be used commercially (i.e. by a business or company).. . It offers the same basic functionality as AutoCAD and IntelliCAD.

Solidworks Support

Kevin Knowles said...

This is long but good code regarding Creating A "Move" Command With .NET API. And I think this work for all the .net developer.

Anonymous said...

[Johan Delvaux] I like your blog. This code is useful to me in order to create a copy increment command (copy a selection set and increment certain attributes in blocks). Just wanted to add that if you want to use ortho mode like the standard COPY and MOVE commands - where you can also snap to certain points which overrule ortho mode, you can use the ComputedPoint property of the IPointContext:

private void Editor_PointMonitor(object sender, PointMonitorEventArgs e)
{
if (!e.Context.PointComputed)
return;

//Point3d pt = e.Context.RawPoint;
Point3d pt = e.Context.ComputedPoint;
/*
if (IsOrthModeOn())
{
pt = GetOrthoPoint(pt);
}
*/

UpdateTransientGraphics(pt);

_currentPoint = pt;
}

And also then at the moment of doing the real move, you can just use _moveToPoint = res.Value;

instead of transforming it with
_moveToPoint = GetOrthoPoint(res.Value);

Gin said...

Hello yuan.
So sorry to bother you.

I'm a .net developer, engaged in CAD development work for one years. Recently i need a solution for resolving moving action of solid3d like the CAD "Move" command do(preview entity).
I have read the two blogs talking about Drag Move, they do really help. Thanks a lot.

But then i found an issus: when the code is running in editor.drag(...), i could not see the preview of selected entities if i wasn't in the specified visual style(2D wireframe).This issue happens in the previous drag move implementation.
And for Take 2 implementation, i could only see a red block in editor.
I don't know how to fix this issue, or it could not be fixed ? So i post this comment and hope you could give me some advice.

I know the two blogs were written six years ago, and it has been a long time. Sorry for bothering you again.

Regards,
Gin.

Followers

About Me

My photo
After graduating from university, I worked as civil engineer for more than 10 years. It was AutoCAD use that led me to the path of computer programming. Although I now do more generic business software development, such as enterprise system, timesheet, billing, web services..., AutoCAD related programming is always interesting me and I still get AutoCAD programming tasks assigned to me from time to time. So, AutoCAD goes, I go.