I use GetPoint to get a start and end point from the user. Then I create an MLeader, and use the AddFirstVertex/AddLastVertex functions to tell it where to start and end.
GetPoint is giving me a Point3d that has a non-zero Z coordinate. I know this because I write the Z coordinate to the editor so the user can see the coordinates of the point they chose. But when I use the start/end points for the MLeader, the MLeader start/end points always have Z = 0. So the leader looks like it is pointing to the correct place until you rotate the view and see that the arrow head is actually way down at Z = 0.
Any ideas as to why the Z coordinate is being ignored by the MLeader?
' Draw leader line that shows the X/Y/Z of the start point chosen as the leader's text. <CommandMethod("Coord")> _ Public Sub Coord() ' Get the current document and database, and start a transaction. Dim doc As Document = Application.DocumentManager.MdiActiveDocument Dim db As Database = doc.Database Using trans As Transaction = db.TransactionManager.StartTransaction() ' Open the block table record for read. Dim blockTable As BlockTable = trans.GetObject(db.BlockTableId, OpenMode.ForRead) ' Open the block table record Model space for write. Dim blockTableRecord As BlockTableRecord = trans.GetObject(blockTable(blockTableRecord.ModelSpace), _ OpenMode.ForWrite) ' Get start/end points ' ==================== Dim ed As EditorInput.Editor = doc.Editor Dim userPoint As EditorInput.PromptPointResult = ed.GetPoint("Start point") Dim startPoint As Geometry.Point3d = userPoint.Value ed.WriteMessage(Environment.NewLine + "Start @ " + feetAndInches(startPoint)) Dim opts As EditorInput.PromptPointOptions = New EditorInput.PromptPointOptions("End point") opts.BasePoint = startPoint opts.UseBasePoint = True userPoint = ed.GetPoint(opts) Dim endPoint As Geometry.Point3d = userPoint.Value ed.WriteMessage(Environment.NewLine + "End @ " + feetAndInches(endPoint)) ' Convert startPoint using UCS ' ============================ ' TODO ' Create leader line ' ================== Dim leader As MLeader = New MLeader() leader.SetDatabaseDefaults() leader.LeaderLineType = LeaderType.StraightLeader Dim leaderNumber As Integer = leader.AddLeader() Dim lineNumber As Integer = leader.AddLeaderLine(leaderNumber) leader.AddFirstVertex(lineNumber, startPoint) leader.AddLastVertex(lineNumber, endPoint) ' Create the MText ' ---------------- Dim text As MText = New MText() text.SetDatabaseDefaults() Dim x As String = Runtime.Converter.DistanceToString(startPoint.X, DistanceUnitFormat.Architectural, 1) Dim y As String = Runtime.Converter.DistanceToString(startPoint.Y, DistanceUnitFormat.Architectural, 1) Dim z As String = Runtime.Converter.DistanceToString(startPoint.Z, DistanceUnitFormat.Architectural, 1) Dim msg As String = x + Environment.NewLine + y + Environment.NewLine + z text.Contents = msg text.Location = endPoint ' Get text style ' -------------- Dim styleTable As TextStyleTable = trans.GetObject(db.TextStyleTableId, OpenMode.ForWrite) Try Dim style As DatabaseServices.ObjectId = styleTable.Item("Romand") text.TextStyleId = style Catch e As Exception ed.WriteMessage("No Romand style found") End Try ' Assigne the MText to the leader line ' ------------------------------------ leader.ContentType = ContentType.MTextContent leader.TextAlignmentType = TextAlignmentType.LeftAlignment leader.MText = text ' Add to drawing. blockTableRecord.AppendEntity(leader) trans.AddNewlyCreatedDBObject(leader, True) ' Save the changes to the database and close the transaction. trans.Commit() End Using End Sub
Best to convert your points to world as they could be reading -ve when they are zero in world.
(Do it after getting the second point as the base point wants to stay in it's ucs form)
Matrix3d ucs = ed.CurrentUserCoordinateSystem;
Point3d Pt = pr.Value.TransformBy(ucs);
Next you may have to mess with the plane
I tried converting to UCS with this code:
Dim ucs As Geometry.Matrix3d = ed.CurrentUserCoordinateSystem startPoint = startPoint.TransformBy(ucs) endPoint = endPoint.TransformBy(ucs) ed.WriteMessage(Environment.NewLine + "Drawing start point @ " + feetAndInches(startPoint))
But the same behavior exists, MLeader lines always have a Z = 0. The coordinates before and after conversion to UCS are the same, so it doesn't seem that conversion to UCS is my problem. The coordinates do contain a Z value, so I am properly getting the Z value from the user.
The problem seems to be in the code that creates the MLeader. When build an MLeader with a Point3d that *does* contain a Z value, the Z is being ignored. Why would that be?
You can transform the leader after adding it to the database with something like:
leader.TransformBy(Matrix3d.Displacement(startPoint - leader.GetFirstVertex(lineNumber)))
Dim ucs As CoordinateSystem3d = ed.CurrentUserCoordinateSystem.CoordinateSystem3d
Dim transMat As Matrix3d = Matrix3d.AlignCoordinateSystem(Point3d.Origin, Vector3d.XAxis, Vector3d.YAxis, Vector3d.ZAxis, ucs.Origin, ucs.Xaxis, ucs.Yaxis, ucs.Zaxis)
leader.TransformBy(transMat)
Just keep in mind that the calls to 'GetPoint()' are in terms of the current user coordinate system (UCS) so if the user picks an endpoint without specifying the same Z coordinate as the startpoint you may not get what you expect for the endpoint when the leader shows up on screen. The user may have to enter the coordinate instead of picking the point or you may have to set the UCS to be on the same plane as the startPoint, possibly.
When you draw an MLeader using AutoCAD it has a jig helping it along and I think the internals of it work differently with picking it's leader points.