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!
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?
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'~
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!
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!
ed.SetCurrentView(view);
http://www.theswamp.org/index.php?topic=40077.msg453446#msg453446
// Called Kerry in my other life.
Everything will work just as you expect it to, unless your expectations are incorrect.
class keyThumper<T> : Lazy<T>; another Swamper
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'~
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!
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.
Thanks!
Can't find what you're looking for? Ask the community or share your knowledge.