.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Rotating UCS and Plan command

10 REPLIES 10
Reply
Message 1 of 11
Rob.O
2584 Views, 10 Replies

Rotating UCS and Plan command

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!

 

10 REPLIES 10
Message 2 of 11
Hallex
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
Message 3 of 11
Rob.O
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?

Message 4 of 11
Hallex
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
Message 5 of 11
Rob.O
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! Smiley Sad

Message 6 of 11
Rob.O
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!

Message 7 of 11
kdub_nz
in reply to: Rob.O

ed.SetCurrentView(view);

 

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

//

Everything will work just as you expect it to, unless your expectations are incorrect.

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

Message 8 of 11
Hallex
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
Message 9 of 11
Rob.O
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!

Message 10 of 11
Rob.O
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. Smiley Surprised

 

Thanks!

Message 11 of 11
bowdenj
in reply to: Rob.O

Did you try setting:

acVportTblRec.UcsFollowMode = True

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost