Lisp to remove the penultimate and antepenultimate vertices of multiple polylines

Lisp to remove the penultimate and antepenultimate vertices of multiple polylines

mikael.macial
Explorer Explorer
941 Views
14 Replies
Message 1 of 15

Lisp to remove the penultimate and antepenultimate vertices of multiple polylines

mikael.macial
Explorer
Explorer

I'd like to create a lisp that removes the 3rd last (antepenultimate) and 2nd last (penultimate) vertices of the selected polylines.

 

All the polylines have more than 4 vertices, usually 5.

 

I've tried to use chatgpt to generate some, but none of them worked.

 

It looks like a simple lisp to create, but i'm not good at codes..

 

Can you guys help me?

0 Likes
Accepted solutions (1)
942 Views
14 Replies
Replies (14)
Message 2 of 15

komondormrex
Mentor
Mentor

are plines all-line-segment-ed?

if they are, you may check the code below.

 

 

(foreach pline_object (mapcar 'vlax-ename->vla-object 
							(vl-remove-if 
								'listp 
									(mapcar 
										'cadr 
											(ssnamex (ssget '((0 . "lwpolyline"))))
									)
							)
					   )
		(setq last_point (vlax-curve-getendpoint pline_object)
		      last_point (list (car last_point) (cadr last_point))
		      pline_vertices_raw_list (append (reverse (cddr (cddr (cddr (reverse (vlax-get pline_object 'coordinates)))))) last_point)
		)
		(vla-put-coordinates pline_object (vlax-safearray-fill (vlax-make-safearray 
										vlax-vbdouble
										(cons 0 (1- (length pline_vertices_raw_list)))
								   )
							       pline_vertices_raw_list
			  			)
		)
)

 

 

0 Likes
Message 3 of 15

-didier-
Advisor
Advisor
Accepted solution

Bonjour @mikael.macial 

 

I've tried to use chatgpt to generate some, but none of them worked.
this is a real false good idea, this is false advertising this AI

 

I’m not sure if @komondormrex 's answer is correct based on the question. Because the last vertex has to stay

You ask to remove the 3rd last (ante penultimate) and 2nd last (penultimate) leaving the last one in place

Then I propose this, the command name is TEST :

 

(defun removenth (n lst / i rtn);found on the swamp by Jeff_M
    (reverse (progn (setq i -1)
                 (foreach x lst (if (/= n (setq i (1+ i)))(setq rtn (cons x rtn))))
                 rtn)
        )
)
(defun delpa (ent / coords coords2)
    ;Lisp to remove the penultimate and antepenultimate vertices of multiple polylines
    (if
        (and (>= (cdr (assoc 90 (entget ent))) 4)
             (setq ent (vlax-ename->vla-object ent))
             )
        (progn
            (setq coords (vlax-get ent 'coordinates))
            (setq coords2 coords)
            (setq len (length coords))
            (setq pos (- len 3))
            (repeat 4 (setq coords (removenth (- (length coords)3) coords)))
            (vlax-put ent 'coordinates coords)
            )
        (alert "Bad polyline")
        )
    )
(defun c:test ( / n ss coords ent)
    (setq n -1)
    (setq ss (ssget '((0 . "LWPOLYLINE"))))		
    (repeat (sslength ss)
        (setq ent (ssname ss (setq n (1+ n))))
        (delpa ent)
        )
    )

 

 

I've tried to use chatgpt to generate some, but none of them worked.
This is a real false good idea, this is false advertising this AI

 

let me know if that’s right, please

Amicalement

Éternel débutant.. my site for learning : Programmer dans AutoCAD

DA

EESignature

Message 4 of 15

mikael.macial
Explorer
Explorer
it worked perfectly, exactly how i imagined!
what a fast solution!!

thank you very much!!

about the AI, wasn't my intention to say it doesn't work..
it was I that couldn't make it work for me, certainly because a lack of knowledge of how to ask and to interpretate the code that it generated for me.

thanks again!!
0 Likes
Message 5 of 15

mikael.macial
Explorer
Explorer
Sorry, I can't identify the command of this lisp, so wasn't able to test this one..
0 Likes
Message 6 of 15

Kent1Cooper
Consultant
Consultant

 

(defun C:WHAT (/ pl verts)
  (setq pl (car (entsel "\nPolyline to have two vertices prior to last one removed: ")))
  (if (> (setq verts (cdr (assoc 90 (entget pl)))) 3); long enough?
    (progn ; then
      (command "_.pedit" pl "_edit")
      (repeat (- verts 4) (command "_next"))
      (command "_straighten" "_next" "_next" "_next" "_go" "_exit" "")
    ); progn
  ); if
  (prin1)
)

 

It checks whether there are enough vertices, but does not check [but could be made to] whether what you picked was a Polyline.  Works only with LWPolylines, but could be enhanced to work on 2D "heavy" and 3D ones [they don't have (assoc 90), so number of vertices has to be calculated differently].  And note that in a closed one, the last vertex is not back at the first one -- if that's what you mean, this won't do, because the Next option under the Edit vertex option won't keep going back to the start.

Kent Cooper, AIA
0 Likes
Message 7 of 15

-didier-
Advisor
Advisor

Bonjour @mikael.macial 

 

You're welcome, I’m glad to be of service.

It doesn't if the polylines have a bulge, OK ?

Don’t talk to me about chatgpt, I’d like to stay calm.

 

Amicalement

Éternel débutant.. my site for learning : Programmer dans AutoCAD

DA

EESignature

Message 8 of 15

mikael.macial
Explorer
Explorer

ok, thanks again!!

0 Likes
Message 9 of 15

komondormrex
Mentor
Mentor

@-didier- surely i missed the point.

@mikael.macial check the update.

0 Likes
Message 10 of 15

mikael.macial
Explorer
Explorer
didn't worked..

- started the command and got the message "Polyline to have two vertices prior to last one removed"
- selected the polyline
- got the error "bad argument type: lentityp nil"

the objects that I'm testing are polylines, created with the PLINE command (just to reassure).
0 Likes
Message 11 of 15

mikael.macial
Explorer
Explorer
what is the command to start the lisp?

i usually see in the codes a line with "(defun C: 'command to use the lisp' ....
0 Likes
Message 12 of 15

Kent1Cooper
Consultant
Consultant

@mikael.macial wrote:
didn't worked..

- started the command and got the message "Polyline to have two vertices prior to last one removed"
- selected the polyline
- got the error "bad argument type: lentityp nil"

the objects that I'm testing are polylines, created with the PLINE command (just to reassure).

It worked for me, and I just tried some more, successfully.  Are they LightWeight Polylines?  PLINETYPE System Variable = 1 or 2 when they were drawn?  Properties calls them "Polyline," not "2D Polyline" or "3D Polyline"?  LIST reports them as "LWPOLYLINE"?

 

But I suspect those are not the problem -- they would not result in the error message you got, which I get if I miss in picking one.

Kent Cooper, AIA
0 Likes
Message 13 of 15

mikael.macial
Explorer
Explorer
PLINETYPE System Variable = 1 or 2 when they were drawn? - = 2
Properties calls them "Polyline," not "2D Polyline" or "3D Polyline"? - just "Polyline"
LIST reports them as "LWPOLYLINE"? - Yes

got it to work, probably had pasted it wrong before..

just as a feedback:
- worked as I wanted, but can't select more than one object at the same time (or preferably make a selection box)
- doesn't seems to work if already selected the object before the command

@Anonymous Lisp works great and very clean

but thanks for the help!!
it still works fine and would help me!
glad to see a community so helpful! =]
0 Likes
Message 14 of 15

Kent1Cooper
Consultant
Consultant

@mikael.macial wrote:
....
- worked as I wanted, but can't select more than one object at the same time (or preferably make a selection box)
- doesn't seems to work if already selected the object before the command
....

I could have worked those in originally if you had mentioned them.  Try this [lightly tested]:

(defun C:PLVR (/ ss n pl verts) ; = PolyLine Vertex Removal
  (if (ssget "_I" '((0 . "LWPOLYLINE"))); pre-selection containing Polyline(s)?
    (setq ss (ssget "_:L-I" '((0 . "LWPOLYLINE")))); then [only unlocked ones]
    (progn ; else
      (prompt "\nTo remove two vertices prior to last one(s) from Polyline(s),")
      (setq ss (ssget "_:L" '((0 . "LWPOLYLINE")))); User select
    ); progn
  ); if
  (if ss
    (repeat (setq n (sslength ss))
      (setq pl (ssname ss (setq n (1- n))))
      (if (> (setq verts (cdr (assoc 90 (entget pl)))) 3); long enough?
        (progn ; then
          (command "_.pedit" pl "_edit")
          (repeat (- verts 4) (command "_next"))
          (command "_straighten" "_next" "_next" "_next" "_go" "_exit" "")
        ); progn
      ); if
    ); repeat
    (prompt "\nNo Polylines on unlocked Layers selected."); else
  ); if [selection]
  (prin1)
)

 

Kent Cooper, AIA
0 Likes
Message 15 of 15

ronjonp
Mentor
Mentor

Another for fun 🙂

(defun c:foo (/ o p s)
  ;; RJP » 2023-05-05
  ;; Remove the 2nd and 3rd to last vertexes of LWPOLYLINES
  (if (setq s (ssget ":L" '((0 . "LWPOLYLINE") (-4 . ">") (90 . 3))))
    (foreach e (vl-remove-if 'listp (mapcar 'cadr (ssnamex s)))
      (setq p (reverse (vlax-get (setq o (vlax-ename->vla-object e)) 'coordinates)))
      (vlax-put o 'coordinates (append (reverse (cdddr (cdddr p))) (reverse (mapcar '+ '(0 0) p))))
    )
  )
  (princ)
)
(vl-load-com)
0 Likes