Drawing multiple polylines

Drawing multiple polylines

Anonymous
Not applicable
2,452 Views
16 Replies
Message 1 of 17

Drawing multiple polylines

Anonymous
Not applicable

I am trying to draw multiple LWPOLYLINES and I can't seem to figure out how. I can draw one shape OK but when I try to draw another one it fails. I can do a similar thing with lines but can't make it work with polylines. The first little routine is lifted from Jerry Winters' book as is the 'AddToModelSpace' code.

 

Thanks for any help.

Mark

 

 

Public Class DrawPoly

 

 

    <CommandMethod("DrawPoly2")> _

    Public Sub DrawPoly()

 

        'This little routine draws several lines by changing the points and

        'calling the add routine. This works OK.

 

        Dim myStartPoint As Point3d = DocumentManager.MdiActiveDocument.Editor.GetPoint("pick point").Value

        For x As Double = myStartPoint.X - 4 To myStartPoint.X + 4

            Dim myline As New Line(myStartPoint, New Point3d(x, myStartPoint.Y + 2, 0))

            Util.AddToModelSpace(HostApplicationServices.WorkingDatabase, myline)

        Next x

       

 

        Dim PL As New Polyline

 

        PL.AddVertexAt(0, New Point2d(0, 0), 0, 0, 0)

        PL.AddVertexAt(1, New Point2d(1, 0), 0, 0, 0)

        PL.AddVertexAt(2, New Point2d(1, 1), 0, 0, 0)

        PL.AddVertexAt(3, New Point2d(0, 1), 0, 0, 0)

        PL.AddVertexAt(3, New Point2d(0, 0), 0, 0, 0)

        Util.AddToModelSpace(HostApplicationServices.WorkingDatabase, PL)

        'This works and draws a little box

      

        'Now change the vertices and draw another one.

        

        'Uncomment these lines and it fails

       

        'PL.AddVertexAt(0, New Point2d(5, 5), 0, 0, 0)

        'PL.AddVertexAt(1, New Point2d(5, 6), 0, 0, 0)

        'PL.AddVertexAt(2, New Point2d(6, 6), 0, 0, 0)

        'PL.AddVertexAt(3, New Point2d(5, 6), 0, 0, 0)

        'PL.AddVertexAt(4 New Point2d(5, 5), 0, 0, 0)

        'Util.AddToModelSpace(HostApplicationServices.WorkingDatabase, PL)

 

 

 

    End Sub

 

0 Likes
2,453 Views
16 Replies
Replies (16)
Message 2 of 17

Anonymous
Not applicable

I do not see all your code but your PL variable is pointing to the ployline you just added try

 

  Dim PL As New Polyline

 

        PL.AddVertexAt(0, New Point2d(0, 0), 0, 0, 0)

        PL.AddVertexAt(1, New Point2d(1, 0), 0, 0, 0)

        PL.AddVertexAt(2, New Point2d(1, 1), 0, 0, 0)

        PL.AddVertexAt(3, New Point2d(0, 1), 0, 0, 0)

        PL.AddVertexAt(3, New Point2d(0, 0), 0, 0, 0)

        Util.AddToModelSpace(HostApplicationServices.WorkingDatabase, PL)

        'This works and draws a little box

      

        'Now change the vertices and draw another one.

        

        'Uncomment these lines and it fails

       
 Dim PL2 As New Polyline
PL2.AddVertexAt(0, New Point2d(5, 5), 0, 0, 0) PL2.AddVertexAt(1, New Point2d(5, 6), 0, 0, 0) PL2.AddVertexAt(2, New Point2d(6, 6), 0, 0, 0) PL2.AddVertexAt(3, New Point2d(5, 6), 0, 0, 0) PL2.AddVertexAt(4 New Point2d(5, 5), 0, 0, 0) Util.AddToModelSpace(HostApplicationServices.WorkingDatabase, PL2) End Sub

 

0 Likes
Message 3 of 17

Anonymous
Not applicable

Yes, that will work. But what if I don't know how many of these shapes I wish to draw when I write the code? The number required will be based on user input. What I am trying to figure out is why I can draw multiple lines but not multiple polylines. What I want to do is place the code in a for-next loop like the line example and change the verticies for each group of four vertices thereby drawing a group of rectangles.

0 Likes
Message 4 of 17

Anonymous
Not applicable

What are you trying to accomplish?

0 Likes
Message 5 of 17

chiefbraincloud
Collaborator
Collaborator

You did not post the AddToModelSpace code (and I don't have Jerry's book), but I am sure it is Disposing of the object after adding it to the Model Space.

 

Notice, in your Line code, you declare the myline variable as a New Line inside the For loop.

 

That is what is missing from the Polyline code.  So, ...

 

Dim PL As New Polyline

 

        PL.AddVertexAt(0, New Point2d(0, 0), 0, 0, 0)

        PL.AddVertexAt(1, New Point2d(1, 0), 0, 0, 0)

        PL.AddVertexAt(2, New Point2d(1, 1), 0, 0, 0)

        PL.AddVertexAt(3, New Point2d(0, 1), 0, 0, 0)

        PL.AddVertexAt(3, New Point2d(0, 0), 0, 0, 0)

        Util.AddToModelSpace(HostApplicationServices.WorkingDatabase, PL)

        'This works and draws a little box

 

        'Re-initialize the PL variable     

        PL = New Polyline

 

        PL.AddVertexAt(0, New Point2d(5, 5), 0, 0, 0)

        PL.AddVertexAt(1, New Point2d(5, 6), 0, 0, 0)

        PL.AddVertexAt(2, New Point2d(6, 6), 0, 0, 0)

        PL.AddVertexAt(3, New Point2d(5, 6), 0, 0, 0)

        PL.AddVertexAt(4 New Point2d(5, 5), 0, 0, 0)

        Util.AddToModelSpace(HostApplicationServices.WorkingDatabase, PL)

 

 

Dave O.                                                                  Sig-Logos32.png
0 Likes
Message 6 of 17

kerry_w_brown
Advisor
Advisor

@chiefbraincloud wrote:

< .. > but I am sure it is Disposing of the object after adding it to the Model Space.

 

Why would you think that ??

.. and why would he want to ??

 

As a side note

This question is typical of a majority of questions I read on discussion groups and forums,

in that there is frequently insufficient information provided by the original poster to allow anything other than a wild assed guess at the problem let alone the solution.

 

... but perhaps that's just me. Smiley Indifferent

 


// Called Kerry or kdub in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect. ~ kdub
Sometimes the question is more important than the answer. ~ kdub

NZST UTC+12 : class keyThumper<T> : Lazy<T>;      another  Swamper
0 Likes
Message 7 of 17

chiefbraincloud
Collaborator
Collaborator

For one thing, it should be done, either explicitly or through a Using statement on the transaction, so if it is not being done in the AddToModelSpace routine, it should be being done in the OP's code.

 

Also, note that there is no Transaction in the OP's code, so there must be one in the AddToModelSpace routine.   Even if the object is not getting properly disposed, it must be added to the transaction, and then can not be accessed after the transaction has been committed, unless the variable is reassigned to a new reference, so the same fix would work, but leave the original object undisposed.  (should be a "Forgot to Call Dispose? message in the VS output window at runtime)

 

Personally, I prefer to keep the New Object creation and the transaction in the same function, returning the newly created ObjectID to the calling function, rather than passing Non-DB resident objects between functions.  It helps me to make sure I'm disposing of everything that needs disposed, and not disposing things that shouldn't be. But maybe that's just me.Smiley Wink

 

Edit:  I also just noticed that Jeffrey's post also suggested creating a New reference, but perhaps he did not quite correctly explain what was happenning behind the scene's, and from the OP's response to his message, I might add (for the benefit of the OP) that of course you could put the polyline stuff into a foreach/next or for/next loop just like the Line code, as long as the PL object is reset to a new reference inside the loop (and each original object properly disposed somewhere).

Dave O.                                                                  Sig-Logos32.png
0 Likes
Message 8 of 17

kerry_w_brown
Advisor
Advisor

 

Ahhh

You meant 'dispose the transaction'

You said 'Disposing of the object after adding it to the Model Space'

 

likely to lead to confusion ... in fact it did 🙂


// Called Kerry or kdub in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect. ~ kdub
Sometimes the question is more important than the answer. ~ kdub

NZST UTC+12 : class keyThumper<T> : Lazy<T>;      another  Swamper
0 Likes
Message 9 of 17

chiefbraincloud
Collaborator
Collaborator

To be clear, both the object and the transaction need to be disposed.  Under certain circumstances, disposing the transaction will automatically dispose the object that has been added to it.  Under other circumstances, such as an exception thrown prior to adding the object to the transaction, the object should be disposed of individually.

Dave O.                                                                  Sig-Logos32.png
0 Likes
Message 10 of 17

kerry_w_brown
Advisor
Advisor

 

Sorry, you lost me ..

What object needs to be disposed. ??

Are you discussing the polyline or the line. ?

A sample of what you mean may clarify your point.

 

And just a semantic point.

We don't add an object to the transaction.

We do use the transaction to wrap the adding (writing) of the object to the database ... simarly read access.

We commit the transaction if we want changes to appear in the database

 


// Called Kerry or kdub in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect. ~ kdub
Sometimes the question is more important than the answer. ~ kdub

NZST UTC+12 : class keyThumper<T> : Lazy<T>;      another  Swamper
0 Likes
Message 11 of 17

Anonymous
Not applicable

@Anonymous wrote:

Yes, that will work. But what if I don't know how many of these shapes I wish to draw when I write the code? The number required will be based on user input. What I am trying to figure out is why I can draw multiple lines but not multiple polylines. What I want to do is place the code in a for-next loop like the line example and change the verticies for each group of four vertices thereby drawing a group of rectangles.


The problem is he has not stated a problem. How can you have a solution if you do not know what you are trying to solve?

 

Normally I would tell him to put it in a for loop but I am trying to get out of the habit of solving the problem syntaxtically(if that is a real word) and solving it programatically.

If he would state it problem in pseuudocode

For Example

1. Let user select two points and draw rectangle

2. keep drawing rectangles for every two points until user presses escape

or

1. User selected point is the center of a predetermined size rectangle.

 

Then a for loop would probably not be the best solution.

 

If he would state the problem there are experienced and smart guys like Kerry and chiefbraincloud out there that will help him out.

 

 

0 Likes
Message 12 of 17

Anonymous
Not applicable

Here is the mystery code

 

 

 Function AddToModelSpace(ByVal DBIn As Database, ByVal EntityIn As Entity) As ObjectId
            Using myTrans As Transaction = DBIn.TransactionManager.StartTransaction
                Dim myBT As BlockTable = DBIn.BlockTableId.GetObject(OpenMode.ForRead)
                Dim myModelSpace As BlockTableRecord = _
               myBT(BlockTableRecord.ModelSpace).GetObject(OpenMode.ForWrite)
                myModelSpace.AppendEntity(EntityIn)
                myTrans.AddNewlyCreatedDBObject(EntityIn, True)
                myTrans.Commit()
                Return EntityIn.ObjectId
            End Using
        End Function

 

0 Likes
Message 13 of 17

chiefbraincloud
Collaborator
Collaborator

"What object needs to be disposed. ??"

 

All Objects that implement iDisposable should be disposed.

All DBobject and DBobject derived objects implement iDisposable, as far as I know. 

 

We don't add an object to the transaction.

 

Transaction.AddNewlyCreatedDBOobject(entity, true)

 

That is how an object is 'added to the transaction'.  When this is done, and the transaction is properly disposed (wether committed or not) the transaction will dispose of the original object.  If this is not done (ie. an exception prior) then the object needs disposed explicitly.

 

We do use the transaction to wrap the adding (writing) of the object to the database ... simarly read access. We commit the transaction if we want changes to appear in the database.

 

FYI, I have read many times, and can somewhat understand how, even (especially) if the transaction only performs Read Only opperations, it should still be committed, because the commit operation has less overhead than the Abort operation, which will happen any time a transaction is disposed without being committed.  The only time you should explicitly abort a transaction, or implicitly abort a transaction by calling dispose without calling commit, is if there are changes to Objects associated with that transaction (in write mode, New objects or edited objects) that you do Not want to be comitted to the database. 

 

Lastly, my experience is quite heavy on the AutoCAD side (since V.10, ~1991), but I've only been in the .NET framework since late 2006, on Acad 2007.  I'm still learning, and don't propose to be the consumate expert, but all I have said here is based on what I have learned.  I monitor this site mostly for the opportunity to learn from others, but when I feel have something to contribute, I do.

 

 

 

Dave O.                                                                  Sig-Logos32.png
0 Likes
Message 14 of 17

chiefbraincloud
Collaborator
Collaborator

First, My comment was only meant to give you credit for first proposing to reset or recreate the PL reference.  I realized after the fact of my post that while I attempted to explain the why a little more than you did, your post was in fact correct in addressing the problem.

 

Second, I can't believe Jerry didn't put a Try/Catch in there, which, in essence,  assumes that the Entity passed is valid (and the DB reference is valid), but regardless, the Using statement on the transaction, combined with the AddNewlyCreatedDBObject, will automatically dispose of the original object if the function completes successfully, making our point valid, that the original PL reference is no longer valid, and has to be recreated.

Dave O.                                                                  Sig-Logos32.png
0 Likes
Message 15 of 17

chiefbraincloud
Collaborator
Collaborator
I feel it worth mentioning...

 

Jeffrey_H wrote: 

"For Example

1. Let user select two points and draw rectangle

2. keep drawing rectangles for every two points until user presses escape

or

1. User selected point is the center of a predetermined size rectangle.

 

Then a for loop would probably not be the best solution.

 

If he would state the problem there are experienced and smart guys like Kerry and chiefbraincloud out there that will help him out."

 

I chose not to address how he is going to construct his loop, or get his points for the rectangles.  He did not ask that question, and I'm not sure I would even try to answer it if he did, at least not on this forum.  That is more of a basic programming point, rather than an AutoCAD API specific point.

 

That's my general rule.  Attempt to address the presented problem, without giving a general programming tutorial in the process.

 

Dave O.                                                                  Sig-Logos32.png
0 Likes
Message 16 of 17

Anonymous
Not applicable

I apoligize if my post seemed like I was trying to have a go at someone.

That is not what I intended.

 

k5xh,

You posted that the number of rectangles depended on user input. Do the points where the rectangle are drawn depend on user input? If so I have a routine that I can modify that mifgt help you out.

0 Likes
Message 17 of 17

chiefbraincloud
Collaborator
Collaborator

I did not take it that way, and I did not intend to be confrontational, either.

 

This is, after all, called a Discussion Group.  I was just discussing.

Dave O.                                                                  Sig-Logos32.png
0 Likes