Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Adding/Removing vertex to several plines at once

23 REPLIES 23
SOLVED
Reply
Message 1 of 24
aabfm
3225 Views, 23 Replies

Adding/Removing vertex to several plines at once

Hi,

I'm looking for something that, after selecting several plines (overlaped or not), I can insert/remove vertexes.

Does anyone have a solution for this?

Thanks in advance.

 

23 REPLIES 23
Message 2 of 24
thavasi1982
in reply to: aabfm

I have attached a file. You can refer and develop. STM
Message 3 of 24
aabfm
in reply to: thavasi1982

Hummm... Need help...

Where is the file?

Message 4 of 24
Kent1Cooper
in reply to: aabfm


@aabfm wrote:

Hi,

I'm looking for something that, after selecting several plines (overlaped or not), I can insert/remove vertexes.

....


After establishing the Polylines as a selection set [here called ss] by whatever means you choose to use, this is one way to do that:

 

(while

  (setq x (ssname ss 0))

  (command "_.pedit" x "_e")

  (while (> (getvar 'cmdactive) 0) (command pause))

  (ssdel x ss)

)

Kent Cooper, AIA
Message 5 of 24
stevor
in reply to: aabfm

1. Where is the attachement?

You tell us.

Use the 'BROWSE' icon at the bottom of the Reply window to find your drawing,

OK it and it should shoow up in the Attachments box.

 

Also, to get more viewers, make a special version of the DWG that

includes only ythe objects of interest, no reactors,

and saved in 2000 format.

 

2. Vertices - how do you wish to locate the new points?

S
Message 6 of 24
aabfm
in reply to: stevor

(defun c:mpedit
	(while
		(setq x (ssname ss 0))
		(command "_.pedit" x "_e")
		(while (> (getvar 'cmdactive) 0) (command pause))
		(ssdel x ss)
	)
)

 I edited your code adding the first and the last lines but it returns syntax error...

Message 7 of 24
Kent1Cooper
in reply to: aabfm


@aabfm wrote:
(defun c:mpedit
	(while
		(setq x (ssname ss 0))
		(command "_.pedit" x "_e")
		(while (> (getvar 'cmdactive) 0) (command pause))
		(ssdel x ss)
	)
)

 I edited your code adding the first and the last lines but it returns syntax error...


You need to give it a place to list local variables, even if you don't use any [though you should]:
 

(defun C:mpedit (/ x)
 

[If you don't declare any variables local, you still need an empty pair of parentheses there.]

 

And you may as well include the selection in the routine, rather than needing to establish it first [untested]:

 

(defun c:mpedit (/ ss x)

  (setq ss (ssget '((0 . "*POLYLINE"))))
  (while
    (setq x (ssname ss 0))
    (command "_.pedit" x "_e")
    (while (> (getvar 'cmdactive) 0) (command pause))
    (ssdel x ss)
  )
)

Kent Cooper, AIA
Message 8 of 24
aabfm
in reply to: Kent1Cooper

First off all thanks for the LSIP tip.

 

-x-x-

 

The code works but it only edits one pline at time.

Take a look at the file I send in attach, 3 plines, each of them with 3 segments, and the middle segment of all of them are overlapped.

I need the code to insert an extra vertex to all of 3 middle segments just as if it was just a single pline being edited with pedit->edit vertex->insert, and for instance this vertex is at the center of the circle.

Message 9 of 24
Kent1Cooper
in reply to: aabfm


@aabfm wrote:

.... 

The code works but it only edits one pline at time.

Take a look at the file I send in attach, 3 plines, each of them with 3 segments, and the middle segment of all of them are overlapped.

I need the code to insert an extra vertex to all of 3 middle segments just as if it was just a single pline being edited with pedit->edit vertex->insert, and for instance this vertex is at the center of the circle.


It works for me.  It does require that you pay attention to the PEDIT prompts, including after editing vertices, eXit to get out of the edit-vertex option and another space/Enter to finish with that Polyline, after which the edit-vertex "X" mark appears at the start of the next Polyline in the selection set.

 

In your sample drawing situation, you can't go immediately from the edit-vertex option to the insert option unless you want the added vertex within the first segment -- in your case, you need to hit space/Enter to move to the second vertex before asking to insert one at the center of the Circle.

 

It worked for me, adding the vertex to each Polyline one at a time.  If your intent is to do that to all three of those Polylines without User interaction other than selecting them and specifying the location of the added vertex, that could all be built in.  But if they might not always be three-segment Polylines, and the added one might not always be in the middle of the second segment, you would either have to make different routines for different circumstances, or the routine would need to be a lot more sophisticated if it's supposed to [for example] find the segment that runs closest to the added-vertex location, and add it within that segment rather than within some other one.

Kent Cooper, AIA
Message 10 of 24
aabfm
in reply to: Kent1Cooper

That's exactly how you said on your last paragraph.

My issue is that I'm working on a draying with tons of layers, where instead of only 3 plines I have at least 47 plines overlaped.

Suddenly I need to modify their path, i.e. to include 1, 2, etc extra vertexes, and I need to do it one-by-one which is a real pain...

😞

Message 11 of 24
Kent1Cooper
in reply to: aabfm


@aabfm wrote:

....I'm working on a draying with tons of layers, where instead of only 3 plines I have at least 47 plines overlaped.

Suddenly I need to modify their path, i.e. to include 1, 2, etc extra vertexes, and I need to do it one-by-one which is a real pain...


That doesn't sound like it can be automated any further, but the routine will at least let you select them all at once instead of individually, and will jump directly from Pediting one to the next.

 

If you need to add vertices at the same place and within each Polyline's segment that coincides with a segment of all the other Polylines [as the middle segments of all of them in your sample drawing do], consider this approach to process any number of them at once:

 

Draw a little Circle over somewhere along that segment.  Use Trim with the Circle as the cutting edge, and the Fence option to cut a little piece out of all the Polylines at once.  Then dump the Circle, and Stretch the newly-cut ends of all of the Polylines to the new vertex location [two Stretch operations].  A routine could be made [and one may already be on this forum somewhere] to then Pedit/Join back together the parts on each Layer with only their Layer's other half, if you need them rejoined.

Kent Cooper, AIA
Message 12 of 24
aabfm
in reply to: Kent1Cooper

Thanks for your help, before posting anything else onto this thread I'll try another approach for my drawing.

 

Message 13 of 24
Hallex
in reply to: aabfm

Try this code to add the new vertex

{code}

(defun C:demo (/ adoc endpar near newpt objs sf ss util)
  (setq adoc (vla-get-activedocument (vlax-get-acad-object))

 util (vla-get-utility adoc)
  )
  (setq ss (ssget))
  (setq objs (mapcar 'vlax-ename->vla-object
       (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))
      )
  )
  (setq newpt (getpoint "\nPick a new vertex location: "))
  ;;/*; thanks to Peter Jamtgaard
  (foreach obj objs
    (setq near (vlax-curve-getclosestpointto obj newpt))
    (if (> (length near) 2.0)
      (setq near (reverse (cdr (reverse near))))
    )
    (setq endpar (+ 1.0 (float (fix (vlax-curve-getparamatpoint obj near)))))
    (vlax-invoke obj 'Addvertex endpar (reverse (cdr (reverse newpt))))
    ;;*/;
    (vla-createtypedarray util 'sf vlax-vbdouble (car newpt) (cadr newpt))
    (setq sf (vlax-make-variant sf))
    (vla-put-coordinate obj (fix endpar) sf)

  )
  (princ)
)
(vl-load-com)
(princ)

{code}

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 14 of 24
aabfm
in reply to: Hallex

Fantastic!!!! Almost there!!!!

Just a small tiny think, I'm working on a (/&%$#""$% of a UCS and when I use this LISP the new vertex goes to the moon. None the less, I also tried on a blank drawing and it works perfectly.

 

Thus, I added the line

 

(trans newpt 1 0)

 

as it follows

 

(defun C:mpedit (/ adoc endpar near newpt objs sf ss util)
  (setq adoc (vla-get-activedocument (vlax-get-acad-object))
 util (vla-get-utility adoc)
  )
  (setq ss (ssget))
  (setq objs (mapcar 'vlax-ename->vla-object
       (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))
      )
  )
  (setq newpt (getpoint "\nPick a new vertex location: "))
  ;;/*; thanks to Peter Jamtgaard
  (trans newpt 1 0)
  (foreach obj objs
    (setq near (vlax-curve-getclosestpointto obj newpt))
    (if (> (length near) 2.0)
      (setq near (reverse (cdr (reverse near))))
    )
    (setq endpar (+ 1.0 (float (fix (vlax-curve-getparamatpoint obj near)))))
    (vlax-invoke obj 'Addvertex endpar (reverse (cdr (reverse newpt))))
    ;;*/;
    (vla-createtypedarray util 'sf vlax-vbdouble (car newpt) (cadr newpt))
    (setq sf (vlax-make-variant sf))
    (vla-put-coordinate obj (fix endpar) sf)
  )
  (princ)
)
(vl-load-com)
(princ)

 

but without any success.

Any ideas?

Message 15 of 24
Hallex
in reply to: aabfm

Please do not name your command as MPEDIT

because it is core AutoCAD command

Try this simple way

{code}

(defun C:MPLEDIT (/ adoc endpar near newpt objs sf ss util)
  (setq adoc (vla-get-activedocument (vlax-get-acad-object))
 util (vla-get-utility adoc)
  )
  (vla-startundomark adoc)
  (command "_ucs" "_W")
  (setq ss (ssget))
  (setq objs (mapcar 'vlax-ename->vla-object
       (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))
      )
  )
  (setq newpt (getpoint "\nPick a new vertex location: "))
  ;;/*; thanks to Peter Jamtgaard

  (foreach obj objs
    (setq near (vlax-curve-getclosestpointto obj newpt))
    (if (> (length near) 2.0)
      (setq near (reverse (cdr (reverse near))))
    )
    (setq endpar (+ 1.0 (float (fix (vlax-curve-getparamatpoint obj near)))))

    (vlax-invoke obj 'addvertex endpar (reverse (cdr (reverse newpt))))
    ;;*/;

    (vla-createtypedarray util 'sf vlax-vbdouble (car newpt) (cadr newpt))
    (setq sf (vlax-make-variant sf))
    (vla-put-coordinate obj (fix endpar) sf)
  )
  (command "_ucs" "_P")
  (vla-endundomark adoc)
  (princ)
)
(vl-load-com)
(princ)

{code}

You may want to play with vla-translatecoordinates method, see the Help file

 

~'J'~

 

 

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 16 of 24
aabfm
in reply to: Hallex

GREAT!!!!

Several headaches avoided!!!!

Thanks a lot!!!

Message 17 of 24
Hallex
in reply to: Kent1Cooper

You're welcome

Glad if this helps

Cheers 🙂

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 18 of 24
Haider_of_Sweden
in reply to: Hallex

Hi!

 

Why does this one work on a selected polyline, ie I dont need to pick polyline after running the comand

(defun C:InsertVertOld (/ adoc endpar near newpt objs sf ss util)
  (setq adoc (vla-get-activedocument (vlax-get-acad-object))

 util (vla-get-utility adoc)
  )
  (setq ss (ssget))
  (setq objs (mapcar 'vlax-ename->vla-object
       (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))
      )
  )
  (setq newpt (getpoint "\nPick a new vertex location: "))
  ;;/*; thanks to Peter Jamtgaard
  (foreach obj objs
    (setq near (vlax-curve-getclosestpointto obj newpt))
    (if (> (length near) 2.0)
      (setq near (reverse (cdr (reverse near))))
    )
    (setq endpar (+ 1.0 (float (fix (vlax-curve-getparamatpoint obj near)))))
    (vlax-invoke obj 'Addvertex endpar (reverse (cdr (reverse newpt))))
    ;;*/;
    (vla-createtypedarray util 'sf vlax-vbdouble (car newpt) (cadr newpt))
    (setq sf (vlax-make-variant sf))
    (vla-put-coordinate obj (fix endpar) sf)

  )
  (princ)
)
(vl-load-com)
(princ)

 

 

While this one requires a selection after running the command, ie it ignores my previous selection

(defun C:INSERTVERT (/ adoc endpar near newpt objs sf ss util)
  (setq adoc (vla-get-activedocument (vlax-get-acad-object))
 util (vla-get-utility adoc)
  )
  (vla-startundomark adoc)
  (command "_ucs" "_W")
  (setq ss (ssget))
  (setq objs (mapcar 'vlax-ename->vla-object
       (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))
      )
  )
  (setq newpt (getpoint "\nPick a new vertex location: "))
  ;;/*; thanks to Peter Jamtgaard

  (foreach obj objs
    (setq near (vlax-curve-getclosestpointto obj newpt))
    (if (> (length near) 2.0)
      (setq near (reverse (cdr (reverse near))))
    )
    (setq endpar (+ 1.0 (float (fix (vlax-curve-getparamatpoint obj near)))))

    (vlax-invoke obj 'addvertex endpar (reverse (cdr (reverse newpt))))
    ;;*/;

    (vla-createtypedarray util 'sf vlax-vbdouble (car newpt) (cadr newpt))
    (setq sf (vlax-make-variant sf))
    (vla-put-coordinate obj (fix endpar) sf)
  )
  (command "_ucs" "_P")
  (vla-endundomark adoc)
  (princ)
)
(vl-load-com)
(princ)

 

 

 

2) is it possible to keep the polyline selected, so that I can press space to run the command again and continuing adding verts

 

 

3) does any of the scripts have the ability to remove verts? I can only make it add verts.

Message 19 of 24


@Haider_of_Sweden wrote:

Why does this one work on a selected polyline, ie I dont need to pick polyline after running the comand

(defun C:InsertVertOld
....
  (setq ss (ssget))
....

While this one requires a selection after running the command, ie it ignores my previous selection

(defun C:INSERTVERT
....
  (command "_ucs" "_W")
  (setq ss (ssget))
....

....


That is, I expect, because of the UCS command.  A plain (ssget) will "get" any pre-selected object(s) at the time, but the (command) function in the second one wipes out the pre-selection.

 

[That assumes I understand correctly what you're talking about -- I would say "after calling or invoking or starting the command," rather than after running it, which to me implies completion of it.]

Kent Cooper, AIA
Message 20 of 24


@Haider_of_Sweden wrote:

....

2) is it possible to keep the polyline selected, so that I can press space to run the command again and continuing adding verts

....


(defun C:InsertVertOld (/ adoc endpar near newpt objs sf util) ; <--removed ss
  ....
;;; (setq ss (ssget)) ; <-- not that, but instead:
  (if (not ss) (setq ss (ssget)))
....

 

But I would also suggest you change the name of that variable.  The 'ss' variable name is common for selection sets, and could be overwritten by some other routine between your uses of it here, if it is not localized within that other routine.  If it's a global variable, name it something distinctive to this routine, such as IVss [and be sure to change the name at all occurrences].

Kent Cooper, AIA

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost