.NET

Reply
Mentor
Rob.O
Posts: 258
Registered: ‎06-25-2007
Message 1 of 11 (1,370 Views)

Rotating UCS and Plan command

1370 Views, 10 Replies
12-23-2011 11:11 AM

Hi All,

 

I have two questions about UCS creation/rotation and the AutoCAD PLAN command:

 

Question 1) I am creating a new UCS, rotating it based on user picks and saving it.  The problem is that it saves the new UCS origin location, but it will not save the rotation.  The code I am using was pieced together from a couple of different sources (.NET developers guide and code from Tony T from an old thread)  How can I make the new UCS "save" the rotation as well?

 

Question 2) Once I have the new UCS created, I want to esentially use the AutoCAD PLAN command and rotate to the name of the new UCS that was just created.  I cannot find ANY info anywhere on the internet on how to replicate the PLAN command using .NET.  Any advice?

 

Here is the code I am using to create, rotate and save the UCS:

 

Dim acDoc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
        Dim acCurDb As Database = acDoc.Database
        Dim acEd As Editor = acDoc.Editor
        Dim acEnt As Entity = Nothing

        Dim Zaxis As Vector3d

        Using acTrans As Transaction = acCurDb.TransactionManager.StartTransaction()
            Try

                ' Check for the exisitence of required blocks ***************************************************************************
                ' Declare block variables
                Dim strBlockName As String = "UCS-View"
                Dim strLayerName As String = "DEFPOINTS"
                Dim strSource As String = "W:\EnConDesignContent\Templates\ECDT_NW_11x17_ShopBorder_Template.dwg"
                Functions.CheckBlockInsert(strBlockName, strSource)

                Dim strtPnt As Point3d = Nothing
                Dim endPnt As Point3d = Nothing

                Dim myPromptPointFirst As New PromptPointOptions("")
                Dim myPromptPointFirst_Res As PromptPointResult

                Dim myPromptPointSecond As New PromptPointOptions("")
                Dim myPromptPointSecond_Res As PromptPointResult

                myPromptPointFirst.Message = vbCr & "Select first UCS point"

                myPromptPointFirst.AllowArbitraryInput = False
                myPromptPointFirst.AllowNone = False
RePick1:
                myPromptPointFirst_Res = acEd.GetPoint(myPromptPointFirst)

                '' If pick is ok, then continue
                If myPromptPointFirst_Res.Status = PromptStatus.OK Then
                    myPromptPointSecond.BasePoint = myPromptPointFirst_Res.Value
                    myPromptPointSecond.UseBasePoint = True '' Applies rubberband effect after first pick

                    myPromptPointSecond.Message = vbCr & "Select second UCS point"
RePick2:
                    myPromptPointSecond_Res = acEd.GetPoint(myPromptPointSecond)

                    '' If pick is ok, then continue
                    If myPromptPointSecond_Res.Status = PromptStatus.OK Then
                        strtPnt = myPromptPointFirst_Res.Value
                        endPnt = myPromptPointSecond_Res.Value

                        Dim acLine As Line = New Line(strtPnt, endPnt)
                        Functions.AddToModelSpace(HostApplicationServices.WorkingDatabase, acLine)

                        acEnt = acLine
                        Dim dblAngle As Double = acLine.Angle
                        Zaxis = acEnt.Ecs.CoordinateSystem3d.Zaxis

                        '' Open the UCS table for read
                        Dim acUCSTbl As UcsTable
                        acUCSTbl = acTrans.GetObject(acCurDb.UcsTableId, OpenMode.ForRead)

                        Dim acUCSTblRec As UcsTableRecord

                        '' Check to see if the "New_UCS" UCS table record exists (if not, create it)
                        If acUCSTbl.Has("New_UCS") = False Then
                            acUCSTblRec = New UcsTableRecord()
                            acUCSTblRec.Name = "New_UCS"

                            '' Open the UCSTable for write
                            acUCSTbl.UpgradeOpen()

                            '' Add the new UCS table record
                            acUCSTbl.Add(acUCSTblRec)
                            acTrans.AddNewlyCreatedDBObject(acUCSTblRec, True)
                        Else
                            acUCSTblRec = acTrans.GetObject(acUCSTbl("New_UCS"), OpenMode.ForWrite)
                        End If

			'' Set origin of UCS icon
                        acUCSTblRec.Origin = New Point3d(strtPnt.X, strtPnt.Y, strtPnt.Z)
                        
                        '' Open the active viewport
                        Dim acVportTblRec As ViewportTableRecord
                        acVportTblRec = acTrans.GetObject(acDoc.Editor.ActiveViewportId, OpenMode.ForWrite)

                        '' Display the UCS Icon at the origin of the current viewport
                        acVportTblRec.IconAtOrigin = True
                        acVportTblRec.IconEnabled = True

                        '' Set the UCS current
                        acVportTblRec.SetUcs(acUCSTblRec.ObjectId)
                        'acDoc.Editor.UpdateTiledViewportsFromDatabase()

			'' Rotate the UCS
                        Dim mat As Matrix3d = acEd.CurrentUserCoordinateSystem
                        mat *= Matrix3d.Rotation(dblAngle, Zaxis, strtPnt)
                        acEd.CurrentUserCoordinateSystem = mat

                        '' Display the name of the current UCS
                        Dim acUCSTblRecActive As UcsTableRecord
                        acUCSTblRecActive = acTrans.GetObject(acVportTblRec.UcsName, OpenMode.ForRead)

                        Application.ShowAlertDialog("The current UCS is: " & acUCSTblRecActive.Name)

                        '' Insert view block and rotate it to angle based on UCS selection
                        Dim acBT As BlockTable = acCurDb.BlockTableId.GetObject(OpenMode.ForRead)
                        Dim acBtr As BlockTableRecord = acBT(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForWrite)

                        Dim blkref As New BlockReference(strtPnt, acBT(strBlockName))
                        blkref.Layer = strLayerName
                        blkref.Rotation = dblAngle
                        Functions.AddToModelSpace(HostApplicationServices.WorkingDatabase, blkref)

			'' Zoom to the extents of the blockref
                        Dim chkId As ObjectId = blkref.ObjectId
                        Functions.ZoomObjects(New ObjectIdCollection() From {chkId})

                    ElseIf myPromptPointSecond_Res.Status = PromptStatus.Cancel Then
                        Exit Sub
                    ElseIf myPromptPointSecond_Res.Status = PromptStatus.Error Then
                        MsgBox("Not a vaild point. Please try again!", , "Invalid Point")
                        GoTo RePick1
                    ElseIf myPromptPointSecond_Res.Status = Nothing Then
                        '' Missed pick... retry
                        GoTo RePick1
                    End If
                ElseIf myPromptPointFirst_Res.Status = PromptStatus.Cancel Then
                    Exit Sub
                ElseIf myPromptPointFirst_Res.Status = PromptStatus.Error Then
                    MsgBox("Not a vaild point. Please try again!", , "Invalid Point")
                    GoTo RePick2
                ElseIf myPromptPointFirst_Res.Status = Nothing Then
                    '' Missed pick... retry
                    GoTo RePick2
                End If

            Catch acErrTB As Autodesk.AutoCAD.Runtime.Exception
                MsgBox("An error has occured. Contact your system adminstrator." & vbLf & vbLf & acErrTB.Message & vbLf & acErrTB.StackTrace)
            Finally
            End Try

            acTrans.Commit()
        End Using

 

Thanks!

 

*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 2 of 11 (1,364 Views)

Re: Rotating UCS and Plan command

12-23-2011 11:45 AM in reply to: Rob.O
Spoiler
 

On the quick glance I could not found where you put the axis vectors:

 

acUCSTblRec.Origin= ...

 

acUCSTblRec.XAxis=NewVector3d(...)

 

acUCSTblRec.YAxis=NewVector3d(...)

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Mentor
Rob.O
Posts: 258
Registered: ‎06-25-2007
Message 3 of 11 (1,359 Views)

Re: Rotating UCS and Plan command

12-23-2011 12:47 PM in reply to: Hallex

I originally tried putting the axis vectors in for X and Y, but I kept getting a malformed UCS when I would run the code.  It still rotates the UCS properly when I run the code without the axis vectors, but it just does not save the rotation.

 

I guess my issue was that I could not figure out how to code the axis vectors on a rotated UCS.

 

Any suggestions?

*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 4 of 11 (1,355 Views)

Re: Rotating UCS and Plan command

12-23-2011 01:12 PM in reply to: Rob.O

Not sure if this helps, I used it with success on 2005 earlier:

        Public Sub UcsByLine(ByVal ed As Editor, ByVal p1 As Point3d, ByVal p2 As Point3d)

            Dim zAxis As Vector3d = ed.CurrentUserCoordinateSystem.CoordinateSystem3d.Zaxis
            Dim xAxis As Vector3d = p1.GetVectorTo(p2)
            Dim yAxis As Vector3d = xAxis.GetPerpendicularVector 'zAxis.CrossProduct(xAxis)
            Dim mat As Matrix3d = Matrix3d.AlignCoordinateSystem(Point3d.Origin, Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis, p1, xAxis, yAxis, zAxis)
            ed.CurrentUserCoordinateSystem = mat
        End Sub

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Mentor
Rob.O
Posts: 258
Registered: ‎06-25-2007
Message 5 of 11 (1,352 Views)

Re: Rotating UCS and Plan command

12-23-2011 02:29 PM in reply to: Hallex

Hmmm... I am getting the same results even with your code.  The UCS rotates, but does not save the rotation to the new UCS name.  I must be doing something wrong! :smileysad:

Mentor
Rob.O
Posts: 258
Registered: ‎06-25-2007
Message 6 of 11 (1,344 Views)

Re: Rotating UCS and Plan command

12-23-2011 03:42 PM in reply to: Rob.O

Ok... think I got it!  I had to pass the Xaxis and Yaxis parmeters to the UCSTableRecord in order for it to save!!!  You were right on both counts Hallex, but it took me some time to catch on!!

 

 acUCSTblRec.XAxis = New Vector3d(Xaxis.X, Xaxis.Y, Xaxis.Z)
 acUCSTblRec.YAxis = New Vector3d(yAxis.X, yAxis.Y, yAxis.Z)

 

Any ideas on the PLAN command and I how I can replicate that in .NET?

 

Thanks again!

Valued Mentor
KerryBrown
Posts: 263
Registered: ‎11-29-2008
Message 7 of 11 (1,336 Views)

Re: Rotating UCS and Plan command

12-23-2011 06:12 PM in reply to: Rob.O

ed.SetCurrentView(view);

 

http://www.theswamp.org/index.php?topic=40077.msg453446#msg453446

//-------------------------------------------------------

class keyThumper<T> : Lazy<T>;      another  Swamper

*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 8 of 11 (1,321 Views)

Re: Rotating UCS and Plan command

12-24-2011 09:12 AM in reply to: Rob.O

Sorry for the belating

I was just quickly rewrote the online primer

See if this work for you

        <CommandMethod("NewUCS")> _
        Public Sub NewUCS()
            '' Get the current document and database, and start a transaction
            Dim doc As Document = Application.DocumentManager.MdiActiveDocument
            Dim db As Database = doc.Database
            Dim ed As Editor = doc.Editor
            Dim pso As New PromptEntityOptions(vbCr & "Select a line : ")
            pso.SetRejectMessage(vbLf & " Select a line only!")
            pso.AddAllowedClass(GetType(Line), False)
            Dim psr As PromptEntityResult = ed.GetEntity(pso)
            If psr.Status <> PromptStatus.OK Then
                Return
            End If
            Dim id As ObjectId = psr.ObjectId


            Using tr As Transaction = db.TransactionManager.StartTransaction()
                Dim ent As Entity = tr.GetObject(id, OpenMode.ForRead)
                Dim ln As Line = DirectCast(ent, Line)
                '' Open the UCS table for read
                Dim acUCSTbl As UcsTable
                acUCSTbl = tr.GetObject(db.UcsTableId, _
                                             OpenMode.ForRead)

                Dim acUCSTblRec As UcsTableRecord

                '' Check to see if the "New_UCS" UCS table record exists
                If acUCSTbl.Has("New_UCS") = False Then
                    acUCSTblRec = New UcsTableRecord()
                    acUCSTblRec.Name = "New_UCS"

                    '' Open the UCSTable for write
                    acUCSTbl.UpgradeOpen()

                    '' Add the new UCS table record
                    acUCSTbl.Add(acUCSTblRec)
                    tr.AddNewlyCreatedDBObject(acUCSTblRec, True)
                Else
                    acUCSTblRec = tr.GetObject(acUCSTbl("New_UCS"), _
                                                    OpenMode.ForWrite)
                End If

                acUCSTblRec.Origin = ln.StartPoint
                acUCSTblRec.XAxis = ln.StartPoint.GetVectorTo(ln.EndPoint)
                acUCSTblRec.YAxis = acUCSTblRec.XAxis.GetPerpendicularVector

                '' Open the active viewport
                Dim acVportTblRec As ViewportTableRecord
                acVportTblRec = tr.GetObject(doc.Editor.ActiveViewportId, _
                                                  OpenMode.ForWrite)

                '' Display the UCS Icon at the origin of the current viewport
                acVportTblRec.IconAtOrigin = True
                acVportTblRec.IconEnabled = True

                '' Set the UCS current
                acVportTblRec.SetUcs(acUCSTblRec.ObjectId)
                doc.Editor.UpdateTiledViewportsFromDatabase()
                Dim view As ViewTableRecord = ed.GetCurrentView()
                ed.SetCurrentView(view)
                '' Display the name of the current UCS
                Dim acUCSTblRecActive As UcsTableRecord
                acUCSTblRecActive = tr.GetObject(acVportTblRec.UcsName, _
                                                      OpenMode.ForRead)

                Application.ShowAlertDialog("The current UCS is: " & _
                                            acUCSTblRecActive.Name)

                Dim pPtRes As PromptPointResult
                Dim pPtOpts As PromptPointOptions = New PromptPointOptions("")

                '' Prompt for a point
                pPtOpts.Message = vbLf & "Enter a point: "
                pPtRes = doc.Editor.GetPoint(pPtOpts)

                Dim pPt3dWCS As Point3d
                Dim pPt3dUCS As Point3d

                '' If a point was entered, then translate it to the current UCS
                If pPtRes.Status = PromptStatus.OK Then
                    pPt3dWCS = pPtRes.Value
                    pPt3dUCS = pPtRes.Value

                    '' Translate the point from the current UCS to the WCS
                    Dim newMatrix As Matrix3d = New Matrix3d()
                    newMatrix = Matrix3d.AlignCoordinateSystem(Point3d.Origin, _
                                                               Vector3d.XAxis, _
                                                               Vector3d.YAxis, _
                                                               Vector3d.ZAxis, _
                                                               acVportTblRec.Ucs.Origin, _
                                                               acVportTblRec.Ucs.Xaxis, _
                                                               acVportTblRec.Ucs.Yaxis, _
                                                               acVportTblRec.Ucs.Zaxis)

                    pPt3dWCS = pPt3dWCS.TransformBy(newMatrix)

                    Application.ShowAlertDialog("The WCS coordinates are: " & vbLf & _
                                                pPt3dWCS.ToString() & vbLf & _
                                                "The UCS coordinates are: " & vbLf & _
                                                pPt3dUCS.ToString())
                End If

                '' Save the new objects to the database
                tr.Commit()
            End Using
        End Sub

 Merry Christmas and Happy Holiday to all

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Mentor
Rob.O
Posts: 258
Registered: ‎06-25-2007
Message 9 of 11 (1,274 Views)

Re: Rotating UCS and Plan command

01-04-2012 07:45 AM in reply to: Hallex

Hi folks!  Sorry it took so long for me to get back to you.  I was on vacation all of last week.

 

Kerry, when you have a moment, can you posibly give me some examples of how to use the .SetCurrentView method to set the current view to a plan view of the current UCS?  I read the thread you linked, but am still struggling with getting it to work and cannot find any other examples.

 

Maybe it is all in the Matrix3d transformation?

 

Thanks!

Mentor
Rob.O
Posts: 258
Registered: ‎06-25-2007
Message 10 of 11 (1,244 Views)

Re: Rotating UCS and Plan command

01-05-2012 03:39 PM in reply to: Rob.O

Just an update for those that may be following along...

 

I have this working by using a workaround (enabling the UCSFOLLOW system variable), but would eventually like to get it working properly.

 

On a side note... adding Editor.UpdateTiledViewportsFromDatabase() to update the new UCS names in the UCSII toolbar properly "breaks" the UCSFOLLOW functionality.  Unfortuantely, if Editor.UpdateTiledViewportsFromDatabase() is not used, then the current UCS name is not shown in the UCSII toolbar dropdown.  Probably just doing something wrong. :smileysurprised:

 

Thanks!

You are not logged in.

Log into access your profile, ask and answer questions, share ideas and more. Haven't signed up yet? Register

Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.

Need installation help?

Start with some of our most frequented solutions to get help installing your software.

Ask the Community