• Industries
  • Products
  • Buy
  • Services & Support
  • Communities
  • Discussion Groups

    .NET

    Reply
    Mentor
    Dull_Blades
    Posts: 231
    Registered: ‎06-25-2007

    Rotating UCS and Plan command

    916 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!

     

    Please use plain text.
    *Expert Elite*
    Hallex
    Posts: 1,334
    Registered: ‎10-08-2008

    Re: Rotating UCS and Plan command

    12-23-2011 11:45 AM in reply to: Dull_Blades
    Spoiler
     

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

     

    acUCSTblRec.Origin= ...

     

    acUCSTblRec.XAxis=NewVector3d(...)

     

    acUCSTblRec.YAxis=NewVector3d(...)

    _____________________________________
    C6309D9E0751D165D0934D0621DFF27919
    Please use plain text.
    Mentor
    Dull_Blades
    Posts: 231
    Registered: ‎06-25-2007

    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?

    Please use plain text.
    *Expert Elite*
    Hallex
    Posts: 1,334
    Registered: ‎10-08-2008

    Re: Rotating UCS and Plan command

    12-23-2011 01:12 PM in reply to: Dull_Blades

    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
    Please use plain text.
    Mentor
    Dull_Blades
    Posts: 231
    Registered: ‎06-25-2007

    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:

    Please use plain text.
    Mentor
    Dull_Blades
    Posts: 231
    Registered: ‎06-25-2007

    Re: Rotating UCS and Plan command

    12-23-2011 03:42 PM in reply to: Dull_Blades

    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!

    Please use plain text.
    Valued Mentor
    KerryBrown
    Posts: 259
    Registered: ‎11-29-2008

    Re: Rotating UCS and Plan command

    12-23-2011 06:12 PM in reply to: Dull_Blades

    ed.SetCurrentView(view);

     

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

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

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


    I do not endorse the social media app links below:smileyembarrassed:

    Please use plain text.
    *Expert Elite*
    Hallex
    Posts: 1,334
    Registered: ‎10-08-2008

    Re: Rotating UCS and Plan command

    12-24-2011 09:12 AM in reply to: Dull_Blades

    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
    Please use plain text.
    Mentor
    Dull_Blades
    Posts: 231
    Registered: ‎06-25-2007

    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!

    Please use plain text.
    Mentor
    Dull_Blades
    Posts: 231
    Registered: ‎06-25-2007

    Re: Rotating UCS and Plan command

    01-05-2012 03:39 PM in reply to: Dull_Blades

    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!

    Please use plain text.