dbroada Posted April 26, 2013 Share Posted April 26, 2013 (edited) I am drawing a polyline with VB.Net using a modification of fixo's routine (his first post in this thread http://www.cadtutor.net/forum/showthread.php?78728-3d-points-amp-2d-polylines ). It suits my needs nicely except I can only see an elastic line from the last point clicked to where my next point will be. Is there a way of leaving a line from all the previous points? The only thing I can think of doing is setting a "mark", drawing lines as I go along and then undo back to the mark. However, I haven't looked at coding that yet. Have you other ideas? Edited April 26, 2013 by dbroada "vb.net" added Quote Link to comment Share on other sites More sharing options...
ReMark Posted April 26, 2013 Share Posted April 26, 2013 Does it have to be a line that you leave? You just need a visual reminder of where you were previously right? And does this reminder have to be permanent? Quote Link to comment Share on other sites More sharing options...
dbroada Posted April 26, 2013 Author Share Posted April 26, 2013 I probably should have mentioned that this is being done in VB.Net. I want a visual clue left to show where the polyline will be until the polyline is drawn. Once the polyline shape has been determined the marker should be erased. Quote Link to comment Share on other sites More sharing options...
ReMark Posted April 26, 2013 Share Posted April 26, 2013 I know this is going to show my age but could -BLIPMODE somehow be used? Quote Link to comment Share on other sites More sharing options...
dbroada Posted April 26, 2013 Author Share Posted April 26, 2013 I have considered that (we must be the same age) and immediately forgot about it. Age again I think. I was going to keep that up my sleeve hoping something "nicer" comes along but now I test it in 2013, its not there. Quote Link to comment Share on other sites More sharing options...
ReMark Posted April 26, 2013 Share Posted April 26, 2013 I almost agreed with you Dave until I remembered another trick. Try using .BLIPMODE instead. See the ? Quote Link to comment Share on other sites More sharing options...
dbroada Posted April 26, 2013 Author Share Posted April 26, 2013 I didn't know that. Thanks. Quote Link to comment Share on other sites More sharing options...
ReMark Posted April 26, 2013 Share Posted April 26, 2013 Us "senior" forum members have to stick together. You're entirely welcomed Dave. Good luck. Quote Link to comment Share on other sites More sharing options...
dbroada Posted April 29, 2013 Author Share Posted April 29, 2013 BUMP! While BLIPMODE will give me a clue, does anyone know if there a programatic way of laying down a line or pline which is then erased when I add the final pline? Quote Link to comment Share on other sites More sharing options...
SEANT Posted April 29, 2013 Share Posted April 29, 2013 This blog post uses an interesting variation for ghosting via Overrules: http://drive-cad-with-code.blogspot.com/2011/01/mimicking-autocads-area-command-with_21.html I utilized the mechanics to create a similar process for a program shown in action here: http://screencast.com/t/SAqWNXpN3L See where I select the points for the “Variable Quad”. Quote Link to comment Share on other sites More sharing options...
dbroada Posted April 30, 2013 Author Share Posted April 30, 2013 Sean, yes that first one would be very nice - but I'm too new to VB.Net to translate it today. I'll look again when I have more time and see if I can get it to work. In the meantime, blipmode here I come. Quote Link to comment Share on other sites More sharing options...
Tyke Posted August 13, 2013 Share Posted August 13, 2013 Sean, yes that first one would be very nice - but I'm too new to VB.Net to translate it today. I'll look again when I have more time and see if I can get it to work. In the meantime, blipmode here I come. Dave, did you ever get time to do this in VB? It would appear to be just what I need too. B Quote Link to comment Share on other sites More sharing options...
BlackBox Posted August 13, 2013 Share Posted August 13, 2013 ... but I'm too new to VB.Net to translate it today. ... So new, in fact, that you could easily start learning C#, methinks. Another option (as you are using .NET [aka CLR]), is to compile the C# code into an assembly, which you load into your VB.NET projects as reference(s)... This gives you the ability to reference any Type (Class), Property, Method, or Event you'd need from the source, without converting, nor learning C# (which I do highly recommend). In any event, my friend(s)... Here's the C# code Sean was kind enough to link previously, converted from C# to VB.NET using DeveloperFusion (so you may need to fix some errors, etc.)... You can remove the length of some of those calls by removing the Namespace qualification (with an additional Imports statement, etc.) as well, if you like.... Class "MyNewAreaCmd": Imports System.Collections.Generic Imports Autodesk.AutoCAD.ApplicationServices Imports Autodesk.AutoCAD.EditorInput Imports Autodesk.AutoCAD.Geometry Imports Autodesk.AutoCAD.GraphicsInterface Imports Autodesk.AutoCAD.DatabaseServices Namespace AreaCommand Public Class MyNewAreaCmd Private _dwg As Document Private _editor As Editor Private _area As Double = 0.0 Private _perimeter As Double = 0.0 Private _pline As Autodesk.AutoCAD.DatabaseServices.Polyline = Nothing Private _points As List Private _pickDone As Boolean Private _color As Integer = 1 Public Sub New(dwg As Document) _dwg = dwg _editor = _dwg.Editor End Sub Public ReadOnly Property Area() As Double Get Return _area End Get End Property Public ReadOnly Property Perimeter() As Double Get Return _perimeter End Get End Property Public Function GetArea() As Boolean _pline = Nothing 'Pick first point Dim pt1 As Point3d If Not GetFirstPoint(pt1) Then Return False End If 'Pick second point Dim pt2 As Point3d If Not GetSecondPoint(pt1, pt2) Then Return False End If _pickDone = False _points = New List() _points.Add(New Point2d(pt1.X, pt1.Y)) _points.Add(New Point2d(pt2.X, pt2.Y)) Try 'Enable custom Overrule MyPolylineOverrule.Instance.StartOverrule(_points, _color) 'Handling mouse cursor moving during picking _editor.PointMonitor += New PointMonitorEventHandler(AddressOf _editor_PointMonitor) While True If Not PickNextPoint() Then Exit While End If End While If _pline IsNot Nothing AndAlso _pickDone Then Calculate() End If Catch Throw Finally ClearTransientGraphics() 'Remove PointMonitor handler _editor.PointMonitor -= New PointMonitorEventHandler(AddressOf _editor_PointMonitor) 'Disbale custom Overrule MyPolylineOverrule.Instance.EndOverrule() End Try Return _pickDone End Function #Region "private methods" Private Sub Calculate() Dim p As New Autodesk.AutoCAD.DatabaseServices.Polyline(_points.Count) For i As Integer = 0 To _points.Count - 1 p.AddVertexAt(i, _points(i), 0.0, 0.0, 0.0) Next p.Closed = True _area = p.Area _perimeter = p.Length p.Dispose() End Sub Private Function GetFirstPoint(ByRef pt As Point3d) As Boolean pt = New Point3d() While True Dim opt As New PromptPointOptions(vbLf & "Pick first corner: ") opt.Keywords.Add("Background") opt.AppendKeywordsToMessage = True Dim res As PromptPointResult = _editor.GetPoint(opt) If res.Status = PromptStatus.OK Then pt = res.Value Return True ElseIf res.Status = PromptStatus.Keyword Then Dim intOpt As New PromptIntegerOptions(vbLf & "Enter color number (1 to 7): ") intOpt.AllowNegative = False intOpt.AllowZero = False intOpt.AllowArbitraryInput = False intOpt.UseDefaultValue = True intOpt.DefaultValue = 1 Dim intRes As PromptIntegerResult = _editor.GetInteger(intOpt) If intRes.Status = PromptStatus.OK Then _color = intRes.Value End If Else Return False End If End While End Function Private Function GetSecondPoint(basePt As Point3d, ByRef pt As Point3d) As Boolean pt = New Point3d() Dim opt As New PromptPointOptions(vbLf & "Pick next corner: ") opt.UseBasePoint = True opt.BasePoint = basePt Dim res As PromptPointResult = _editor.GetPoint(opt) If res.Status = PromptStatus.OK Then pt = res.Value Return True Else Return False End If End Function Private Function PickNextPoint() As Boolean Dim opt As New PromptPointOptions(vbLf & "Pick next corner: ") If _points.Count > 2 Then opt.Keywords.Add("Undo") opt.Keywords.Add("Total") opt.Keywords.[Default] = "Total" opt.AppendKeywordsToMessage = True opt.AllowArbitraryInput = False End If Dim res As PromptPointResult = _editor.GetPoint(opt) If res.Status = PromptStatus.OK Then _points.Add(New Point2d(res.Value.X, res.Value.Y)) Return True ElseIf res.Status = PromptStatus.Keyword Then If res.StringResult = "Undo" Then If _points.Count > 2 Then _points.RemoveAt(_points.Count - 1) End If Return True Else _pickDone = True Return False End If Else _pickDone = False Return False End If End Function Private Sub ClearTransientGraphics() If _pline IsNot Nothing Then TransientManager.CurrentTransientManager.EraseTransients(TransientDrawingMode.DirectTopmost, 128, New IntegerCollection()) _pline.Dispose() _pline = Nothing End If End Sub Private Sub _editor_PointMonitor(sender As Object, e As PointMonitorEventArgs) ClearTransientGraphics() 'Get mouse cursor location Dim pt As New Point2d(e.Context.RawPoint.X, e.Context.RawPoint.Y) _pline = New Autodesk.AutoCAD.DatabaseServices.Polyline(_points.Count + 1) For i As Integer = 0 To _points.Count - 1 _pline.AddVertexAt(i, _points(i), 0.0, 0.0, 0.0) Next _pline.AddVertexAt(_points.Count, pt, 0.0, 0.0, 0.0) _pline.Closed = True TransientManager.CurrentTransientManager.AddTransient(_pline, TransientDrawingMode.DirectTopmost, 128, New IntegerCollection()) End Sub #End Region End Class End Namespace Class "MyPolylineOverrule": Imports System.Collections.Generic Imports Autodesk.AutoCAD.Geometry Imports Autodesk.AutoCAD.GraphicsInterface Imports Autodesk.AutoCAD.Runtime Namespace AreaCommand Public Class MyPolylineOverrule Inherits DrawableOverrule Private Shared _instance As MyPolylineOverrule = Nothing Private _existingOverrulling As Boolean Private _color As Integer = 1 Private _points As List = Nothing Public Shared ReadOnly Property Instance() As MyPolylineOverrule Get If _instance Is Nothing Then _instance = New MyPolylineOverrule() End If Return _instance End Get End Property Public Property Color() As Integer Get Return _color End Get Set _color = value End Set End Property Public Sub StartOverrule(points As List) _points = points _existingOverrulling = Overruling 'Add the custom overrule AddOverrule(RXObject.GetClass(GetType(Autodesk.AutoCAD.DatabaseServices.Polyline)), Me, False) 'Use custom filter, implemented in IsApplicable() method SetCustomFilter() 'Make sure Overrule is enabled Overruling = True End Sub Public Sub StartOverrule(points As List, color As Integer) _color = color _points = points _existingOverrulling = Overruling 'Add the custom overrule AddOverrule(RXObject.GetClass(GetType(Autodesk.AutoCAD.DatabaseServices.Polyline)), Me, False) 'Use custom filter, implemented in IsApplicable() method SetCustomFilter() 'Make sure Overrule is enabled Overruling = True End Sub Public Sub EndOverrule() 'Remove this custom Overrule RemoveOverrule(RXObject.GetClass(GetType(Autodesk.AutoCAD.DatabaseServices.Polyline)), Me) 'restore to previous Overrule status (enabled or disabled) Overruling = _existingOverrulling End Sub Public Overrides Function WorldDraw(drawable As Drawable, wd As WorldDraw) As Boolean Dim pts As New Point3dCollection() For i As Integer = 0 To _points.Count - 1 pts.Add(New Point3d(_points(i).X, _points(i).Y, 0.0)) Next wd.SubEntityTraits.FillType = FillType.FillAlways wd.SubEntityTraits.Color = Convert.ToInt16(_color) wd.Geometry.Polygon(pts) Return MyBase.WorldDraw(drawable, wd) End Function Public Overrides Function IsApplicable(overruledSubject As Autodesk.AutoCAD.Runtime.RXObject) As Boolean Dim pl As Autodesk.AutoCAD.DatabaseServices.Polyline = TryCast(overruledSubject, Autodesk.AutoCAD.DatabaseServices.Polyline) If pl IsNot Nothing Then 'Only apply this overrule to the polyline 'that has not been added to working database 'e.g. created for the Transient Graphics If pl.Database Is Nothing Then Return True Else Return False End If Else Return False End If End Function End Class End Namespace Command class "MyCommands": Imports Autodesk.AutoCAD.ApplicationServices Imports Autodesk.AutoCAD.Runtime Imports Autodesk.AutoCAD.EditorInput <Assembly: CommandClass(GetType(AreaCommand.MyCommands))> Namespace AreaCommand Public Class MyCommands <CommandMethod("MyNewArea")> _ Public Shared Sub GetNewArea() Dim dwg As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument Dim ed As Editor = dwg.Editor Dim cmd As New MyNewAreaCmd(dwg) If cmd.GetArea() Then ed.WriteMessage(vbLf & "Area = {0}", cmd.Area) ed.WriteMessage(vbLf & "Perimeter = {0}", cmd.Perimeter) Else ed.WriteMessage(vbLf & "*Cancelled*") End If End Sub End Class End Namespace Quote Link to comment Share on other sites More sharing options...
Tyke Posted August 13, 2013 Share Posted August 13, 2013 Thanks for that RM, but unlike Dave I'm an old dog who finds it difficult to change his ways. I'll stick with VB. Since I posted I found the following in the Civil 3D Help. I haven't tested it yet but it looks promising, I just need to modify the code to allow more than five Points to be selected. Perhaps I can test it tomorrow. Calculate a Defined AreaArea (.NET) If the area you want to calculate is based on user specified points, you might consider creating an in memory object such as a lightweight polyline, and then query of the area of the object before discarding it. The following steps explain how you might accomplish this: 1. Use the GetPoint method in a loop to obtain the pointsfrom the user. 2. Create a lightweight polyline from thepoints provided by the user. Create a new Polyline object. Specify the numberof vertices and the points they should be at. 3. Use the Area property to obtain the area of the newly created polyline. 4. Dispose of the polyline using its Dispose method. Calculate the area defined by points entered from the user This example prompts the user to enter five points. A polyline is then created out of the points entered. The polyline is closed, and the area of the polyline is displayed in a message box. Since the polyline is not added to a block, it needs to be disposed before the command ends. VB.NET [color=black][font=Courier New]Imports Autodesk.AutoCAD.ApplicationServices[/font][/color] [color=black][font=Courier New]Imports Autodesk.AutoCAD.DatabaseServices[/font][/color] [color=black][font=Courier New]Imports Autodesk.AutoCAD.Geometry[/font][/color] [color=black][font=Courier New]Imports Autodesk.AutoCAD.EditorInput[/font][/color] [color=black][font=Courier New]Imports Autodesk.AutoCAD.Runtime[/font][/color] [color=black][font=Courier New]<CommandMethod("CalculateDefinedArea")> _[/font][/color] [color=black][font=Courier New]Public Sub CalculateDefinedArea()[/font][/color] [color=black][font=Courier New] '' Prompt the user for 5points[/font][/color] [color=black][font=Courier New]Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument[/font][/color] [color=black][font=Courier New]DimpPtRes As PromptPointResult[/font][/color] [color=black][font=Courier New] Dim colPt AsPoint2dCollection = New Point2dCollection[/font][/color] [color=black][font=Courier New] Dim pPtOpts AsPromptPointOptions = New PromptPointOptions("")[/font][/color] [color=black][font=Courier New] '' Prompt for the firstpoint[/font][/color] [color=black][font=Courier New] pPtOpts.Message = vbLf& "Specify first point: "[/font][/color] [color=black][font=Courier New] pPtRes =acDoc.Editor.GetPoint(pPtOpts)[/font][/color] [color=black][font=Courier New] colPt.Add(NewPoint2d(pPtRes.Value.X, pPtRes.Value.Y))[/font][/color] [color=black][font=Courier New] '' Exit if the userpresses ESC or cancels the command[/font][/color] [color=black][font=Courier New] If pPtRes.Status =PromptStatus.Cancel Then Exit Sub[/font][/color] [color=black][font=Courier New] Dim nCounter As Integer =1[/font][/color] [color=black][font=Courier New] While (nCounter <= 4)[/font][/color] [color=black][font=Courier New] '' Prompt for the nextpoints[/font][/color] [color=black][font=Courier New] Select Case nCounter[/font][/color] [color=black][font=Courier New] Case 1[/font][/color] [color=black][font=Courier New] pPtOpts.Message= vbLf & "Specify second point: "[/font][/color] [color=black][font=Courier New] Case 2[/font][/color] [color=black][font=Courier New] pPtOpts.Message= vbLf & "Specify third point: "[/font][/color] [color=black][font=Courier New] Case 3[/font][/color] [color=black][font=Courier New] pPtOpts.Message= vbLf & "Specify fourth point: "[/font][/color] [color=black][font=Courier New]Case 4[/font][/color] [color=black][font=Courier New] pPtOpts.Message= vbLf & "Specify fifth point: "[/font][/color] [color=black][font=Courier New] End Select[/font][/color] [color=black][font=Courier New] '' Use the previouspoint as the base point[/font][/color] [color=black][font=Courier New] pPtOpts.UseBasePoint =True[/font][/color] [color=black][font=Courier New] pPtOpts.BasePoint =pPtRes.Value[/font][/color] [color=black][font=Courier New] pPtRes =acDoc.Editor.GetPoint(pPtOpts)[/font][/color] [color=black][font=Courier New] colPt.Add(NewPoint2d(pPtRes.Value.X, pPtRes.Value.Y))[/font][/color] [color=black][font=Courier New] If pPtRes.Status =PromptStatus.Cancel Then Exit Sub[/font][/color] [color=black][font=Courier New] '' Increment thecounter[/font][/color] [color=black][font=Courier New] nCounter = nCounter +1[/font][/color] [color=black][font=Courier New] End While[/font][/color] [color=black][font=Courier New] '' Create a polyline with5 points[/font][/color] [color=black][font=Courier New] Using acPoly As Polyline =New Polyline()[/font][/color] [color=black][font=Courier New] acPoly.AddVertexAt(0,colPt(0), 0, 0, 0)[/font][/color] [color=black][font=Courier New] acPoly.AddVertexAt(1, colPt(1), 0, 0, 0)[/font][/color] [color=black][font=Courier New] acPoly.AddVertexAt(2,colPt(2), 0, 0, 0)[/font][/color] [color=black][font=Courier New] acPoly.AddVertexAt(3,colPt(3), 0, 0, 0)[/font][/color] [color=black][font=Courier New] acPoly.AddVertexAt(4,colPt(4), 0, 0, 0)[/font][/color] [color=black][font=Courier New] '' Close the polyline[/font][/color] [color=black][font=Courier New] acPoly.Closed = True[/font][/color] [color=black][font=Courier New] '' Query the area ofthe polyline[/font][/color] [color=black][font=Courier New] Application.ShowAlertDialog("Area of polyline: " & _[/font][/color] [color=black][font=Courier New] acPoly.Area.ToString())[/font][/color] [color=black][font=Courier New] '' Dispose of thepolyline[/font][/color] [color=black][font=Courier New]End Using[/font][/color] [color=black][font=Courier New]End Sub[/font][/color] Quote Link to comment Share on other sites More sharing options...
BlackBox Posted August 13, 2013 Share Posted August 13, 2013 Thanks for that RM. Since I posted I found the following in the Civil 3D Help. I haven't tested it yet but it looks promising, I just need to modify the code to allow more than five Points to be selected. Perhaps I can test it tomorrow. You're welcome Civil 3D is a beast... It's hard enough just trying to keep track of all of the API changes in AutoCAD, let alone gigantic verticals such as Civil 3D. Since you mentioned it though, and you're working with .NET, you might find the "Snoop Civil 3D" plug-in Augusto released at DevBlog to be useful (it's akin to MgdDbg for AutoCAD [which I also have an Autoloader .bundle for here], just without Civil 3D-specific Event monitoring)... For whatever reason, they've not provided an Autoloader plug-in, so I did in this post. There's a few posts before the one I've linked here that will provide additional information. Let me know if you have any comment/questions about using it. Cheers Quote Link to comment Share on other sites More sharing options...
Tyke Posted August 13, 2013 Share Posted August 13, 2013 You're welcome Civil 3D is a beast... It's hard enough just trying to keep track of all of the API changes in AutoCAD, let alone gigantic verticals such as Civil 3D. Since you mentioned it though, and you're working with .NET, you might find the "Snoop Civil 3D" plug-in Augusto released at DevBlog to be useful (it's akin to MgdDbg for AutoCAD [which I also have an Autoloader .bundle for here], just without Civil 3D-specific Event monitoring)... For whatever reason, they've not provided an Autoloader plug-in, so I did in this post. There's a few posts before the one I've linked here that will provide additional information. Let me know if you have any comment/questions about using it. Cheers I edited my post since you replied. I'm done for today and I'm now sitting in the living room after a delicious evening meal and have a a bottle of very good red wine that I'm sharing with the Little Lady. Thanks for the advice, it will be looked at when the effects of the wine have worn off. Quote Link to comment Share on other sites More sharing options...
BlackBox Posted August 13, 2013 Share Posted August 13, 2013 ... unlike Dave I'm an old dog who finds it difficult to change his ways. I'll stick with VB. .... You wouldn't want to know when I graduated High School then. You and the little lady have a lovely evening. Quote Link to comment Share on other sites More sharing options...
Tyke Posted August 14, 2013 Share Posted August 14, 2013 .... You wouldn't want to know when I graduated High School then. I bet I was already in retirement by then! About 8 years ago? You and the little lady have a lovely evening. We did, thanks. Quote Link to comment Share on other sites More sharing options...
BlackBox Posted August 14, 2013 Share Posted August 14, 2013 (edited) I bet I was already in retirement by then! About 8 years ago? [stuartVoice] I don't wanna say! [/stuartVoice] Hooray SNL (Saturday Night Live) Mad TV skits! Edited August 14, 2013 by BlackBox Ehhhehehehehe Quote Link to comment Share on other sites More sharing options...
tzframpton Posted August 14, 2013 Share Posted August 14, 2013 .......Mad TV Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.