Default AutoCAD - Add Vertices at Interval - Multiple Polylines Simultaneously

Default AutoCAD - Add Vertices at Interval - Multiple Polylines Simultaneously

Tiago.CaldeiraPZ4FE
Contributor Contributor
4,084 Views
13 Replies
Message 1 of 14

Default AutoCAD - Add Vertices at Interval - Multiple Polylines Simultaneously

Tiago.CaldeiraPZ4FE
Contributor
Contributor

Hi all,

I was wondering if someone could help out getting Vertices inserted into multiple polylines (simultaneously) at a specified interval. It must work with arcs as well.

I've searched the web and I've found the following LISP, which works fine but only selects 1 object at a time.


(defun c:demo ( / add_vtx pl int in pt flag )

(vl-load-com)

(defun add_vtx ( obj add_pt ent_name / bulg )
(vla-addVertex
obj
(1+ (fix add_pt))
(vlax-make-variant
(vlax-safearray-fill
(vlax-make-safearray vlax-vbdouble (cons 0 1))
(list
(car (trans (vlax-curve-getpointatparam obj add_pt) 0 ent_name))
(cadr (trans (vlax-curve-getpointatparam obj add_pt) 0 ent_name))
)
)
)
)
(setq bulg (vla-GetBulge obj (fix add_pt)))
(vla-SetBulge obj
(fix add_pt)
(/
(sin (/ (* 4 (atan bulg) (- add_pt (fix add_pt))) 4))
(cos (/ (* 4 (atan bulg) (- add_pt (fix add_pt))) 4))
)
)
(vla-SetBulge obj
(1+ (fix add_pt))
(/
(sin (/ (* 4 (atan bulg) (- (1+ (fix add_pt)) add_pt)) 4))
(cos (/ (* 4 (atan bulg) (- (1+ (fix add_pt)) add_pt)) 4))
)
)
(vla-update obj)
)

(setq pl (car (entsel "\nSelect pline entity")))
(if (not (wcmatch (cdr (assoc 0 (entget pl))) "*POLYLINE"))
(progn
(alert "\nPicked entity isn't polyline - quitting")
(exit)
)
(if (and (or (eq (cdr (assoc 70 (entget pl))) 0) (eq (cdr (assoc 70 (entget pl))) 1)) (eq (cdr (assoc 0 (entget pl))) "POLYLINE"))
(progn
(setq flag T)
(command "_.convertpoly" "l" pl "")
)
(if (not (eq (cdr (assoc 0 (entget pl))) "LWPOLYLINE"))
(progn
(alert "\nYou picked 3d polyline - quitting")
(exit)
)
)
)
)
(setq int (getdist "\nEnter Interval: "))
(setq in int)
(while (setq pt (vlax-curve-getPointAtDist pl int))
(add_vtx (vlax-ename->vla-object pl) (vlax-curve-getparamatpoint pl (vlax-curve-getclosestpointto pl pt)) pl)
(setq int (+ int in))
)
(if flag
(command "_.convertpoly" "h" pl "")
)
(princ)
)

0 Likes
Accepted solutions (1)
4,085 Views
13 Replies
Replies (13)
Message 2 of 14

devitg
Advisor
Advisor

@Tiago.CaldeiraPZ4FE , will be the interval the same for all polylines. ?

 

If possible, upload your sample.dwg 

0 Likes
Message 3 of 14

Tiago.CaldeiraPZ4FE
Contributor
Contributor

Hi there @devitg ,

 

Thanks for replying.

 

Yes, the interval would be applicable to all polylines selected. 

The purpose is to convert these lines to Civil 3D feature lines and have no need to insert elevation points afterwards. Besides, civil 3d only allows for editing one feature line at a time.

 

EDIT: Posted LISP works fine with arc / curves. It only needs to fix the selection to be multiple object.

0 Likes
Message 4 of 14

devitg
Advisor
Advisor

@Tiago.CaldeiraPZ4FE  please upload your sample dwg , and state the step/polylenght  ratio

0 Likes
Message 5 of 14

Tiago.CaldeiraPZ4FE
Contributor
Contributor

Sample drawing provided as attachment.

 

The desired incremental step would be 5m.

0 Likes
Message 6 of 14

Kent1Cooper
Consultant
Consultant
Accepted solution

@Tiago.CaldeiraPZ4FE wrote:

....

The desired incremental step would be 5m.


It seems to me this can be quite a bit simpler:

 

(defun C:AV5 ; = Add Vertices every 5 drawing units
  (/ peac pieces ss n pl)
  (setq peac (getvar 'peditaccept))
  (setvar 'peditaccept 1)
  (setq pieces (ssadd))
  (prompt "\nTo add vertices every 5 drawing units to Polyline(s), Line(s) and/or Arc(s),")
  (if (setq ss (ssget "_:L" '((0 . "LINE,ARC,*POLYLINE"))))
    (repeat (setq n (sslength ss)); then
      (setq pl (ssname ss (setq n (1- n))))
      (while (> (vlax-curve-getDistAtParam pl (vlax-curve-getEndParam pl)) 5)
        (command "_.break" pl "_non" (vlax-curve-getPointAtDist pl 5) "@")
        (ssadd pl pieces)
        (setq pl (entlast))
      ); while
      (ssadd (entlast) pieces); remainder at end
      (command "_.pedit" "_multiple" pieces "" "_join" 0 "")
    ); repeat
  ); if
  (setvar 'peditaccept peac)
  (princ)
); defun

 

That has the 5-unit interval built in, but it could be made to ask the User for the interval.

 

Kent Cooper, AIA
Message 7 of 14

Tiago.CaldeiraPZ4FE
Contributor
Contributor

This looks fantastic !!!

 

Thanks mate. You helped me a lot.

0 Likes
Message 8 of 14

Kent1Cooper
Consultant
Consultant

You're welcome.  It occurs to me that if any selected object is already no longer than 5 units, the 'pieces' variable will end up holding the last object in the drawing, whatever that is and whether or not it has any relation to the purpose, and it will [try to] PEDIT that, which might be acceptable if it's an appropriate kind of thing, but it could be something un-PEDITable and cause an error, or it could be a Line or Arc that was not among your selection and that you don't want turned into a Polyline.  The routine could be made to account for that possibility, if you need it to.

 

If your selection includes any Line(s)/Arc(s) that are no longer than 5 units, would you want them converted into Polylines even though no vertices will be added?  Or left as they are?

Kent Cooper, AIA
0 Likes
Message 9 of 14

CADaSchtroumpf
Advisor
Advisor

You can transform the code that you have find to this. Is more fast that using command break and pedit.

(vl-load-com)
(defun add_vtx (obj add_pt ent_name / bulg)
  (vla-addVertex
    obj
    (1+ (fix add_pt))
    (vlax-make-variant
      (vlax-safearray-fill
        (vlax-make-safearray vlax-vbdouble (cons 0 1))
          (list
            (car (trans (vlax-curve-getpointatparam obj add_pt) 0 ent_name))
            (cadr (trans (vlax-curve-getpointatparam obj add_pt) 0 ent_name))
          )
      )
    )
  )
  (setq bulg (vla-GetBulge obj (fix add_pt)))
  (vla-SetBulge obj
    (fix add_pt)
    (/
      (sin (/ (* 4 (atan bulg) (- add_pt (fix add_pt))) 4))
      (cos (/ (* 4 (atan bulg) (- add_pt (fix add_pt))) 4))
    )
  )
  (vla-SetBulge obj
    (1+ (fix add_pt))
    (/
      (sin (/ (* 4 (atan bulg) (- (1+ (fix add_pt)) add_pt)) 4))
      (cos (/ (* 4 (atan bulg) (- (1+ (fix add_pt)) add_pt)) 4))
    )
  )
  (vla-update obj)
)
(defun c:AddVtx2Dist ( / js AcDoc Space interval n obj ename v_length)
  (princ "\nSelect pline entity.")
  (setq js (ssget '((0 . "LWPOLYLINE"))))
  (cond
    (js
      (setq
        AcDoc (vla-get-ActiveDocument (vlax-get-acad-object))
        Space
        (if (= 1 (getvar "CVPORT"))
          (vla-get-PaperSpace AcDoc)
          (vla-get-ModelSpace AcDoc)
        )
      )
      (initget 6)
      (setq interval (getdist "\nAdd vertex at every interval <1.0>?: "))
      (if (not interval) (setq interval 1.0))
      (repeat (setq n (sslength js))
        (setq
          obj (ssname js (setq n (1- n)))
          ename (vlax-ename->vla-object obj)
          v_length 0.0
        )
        (while (< v_length (vlax-curve-getDistAtParam ename (vlax-curve-getEndParam ename)))
          (if (not (equal (fix (vlax-curve-getEndParam ename)) v_length 1E-13))
            (progn
              (add_vtx ename (vlax-curve-getParamAtDist ename v_length) obj)
              (setq v_length (+ interval v_length))
            )
            (setq v_length (+ interval v_length))
          )
        )
      )
    )
  )
  (prin1)
)
Message 10 of 14

CADaSchtroumpf
Advisor
Advisor

You can transform the code that you have find to this. Is more fast that using command break and pedit.

 

(vl-load-com)
(defun add_vtx (obj add_pt ent_name / bulg)
  (vla-addVertex
    obj
    (1+ (fix add_pt))
    (vlax-make-variant
      (vlax-safearray-fill
        (vlax-make-safearray vlax-vbdouble (cons 0 1))
          (list
            (car (trans (vlax-curve-getpointatparam obj add_pt) 0 ent_name))
            (cadr (trans (vlax-curve-getpointatparam obj add_pt) 0 ent_name))
          )
      )
    )
  )
  (setq bulg (vla-GetBulge obj (fix add_pt)))
  (vla-SetBulge obj
    (fix add_pt)
    (/
      (sin (/ (* 4 (atan bulg) (- add_pt (fix add_pt))) 4))
      (cos (/ (* 4 (atan bulg) (- add_pt (fix add_pt))) 4))
    )
  )
  (vla-SetBulge obj
    (1+ (fix add_pt))
    (/
      (sin (/ (* 4 (atan bulg) (- (1+ (fix add_pt)) add_pt)) 4))
      (cos (/ (* 4 (atan bulg) (- (1+ (fix add_pt)) add_pt)) 4))
    )
  )
  (vla-update obj)
)
(defun c:AddVtx2Dist ( / js AcDoc Space interval n obj ename v_length)
  (princ "\nSelect pline entity.")
  (setq js (ssget '((0 . "LWPOLYLINE"))))
  (cond
    (js
      (setq
        AcDoc (vla-get-ActiveDocument (vlax-get-acad-object))
        Space
        (if (= 1 (getvar "CVPORT"))
          (vla-get-PaperSpace AcDoc)
          (vla-get-ModelSpace AcDoc)
        )
      )
      (initget 6)
      (setq interval (getdist "\nAdd vertex at every interval <1.0>?: "))
      (if (not interval) (setq interval 1.0))
      (repeat (setq n (sslength js))
        (setq
          obj (ssname js (setq n (1- n)))
          ename (vlax-ename->vla-object obj)
          v_length 0.0
        )
        (while (< v_length (vlax-curve-getDistAtParam ename (vlax-curve-getEndParam ename)))
          (if (not (equal (fix (vlax-curve-getEndParam ename)) v_length 1E-13))
            (progn
              (add_vtx ename (vlax-curve-getParamAtDist ename v_length) obj)
              (setq v_length (+ interval v_length))
            )
            (setq v_length (+ interval v_length))
          )
        )
      )
    )
  )
  (prin1)
)

 

Message 11 of 14

Kent1Cooper
Consultant
Consultant

@CADaSchtroumpf wrote:

You can transform the code that you have find to this. Is more fast that using command break and pedit.


Yes, it's faster, if the few seconds matter.  I did the Break and Pedit version partly because it's so much simpler [not just shorter, but no need to worry about bulge factors, whether you're in Paper or Model Space, conversion to VLA objects, etc.), but there's another advantage.  If you have blips turned on as I normally do, you can watch it do its thing [which is kind of fun], and you get visual confirmation that all the Polylines selected were, in fact, processed.  I can imagine using something with no such visual clue, and wondering whether anything actually happened, and whether it happened to all of them.

Kent Cooper, AIA
0 Likes
Message 12 of 14

ronjonp
Mentor
Mentor

@Kent1Cooper  You already know my opinion about command calls 😂 but your code works fine and is short and sweet. One thing I'd add is an undo begin/end. If you have a large selection and made a mistake, you will need to undo as many times as your PEDIT command is called. 🍻

 

*EDIT .. there are also a ton of routines HERE to add a vertex to a polyline. And a comprehensive list of polyline edit functions HERE.

0 Likes
Message 13 of 14

Kent1Cooper
Consultant
Consultant

@ronjonp wrote:

.... One thing I'd add is an undo begin/end. ....


Yes, and *error* handling to ensure the changed System Variable gets reset, and if the OP wants, a request to the User for the interval.

Kent Cooper, AIA
0 Likes
Message 14 of 14

ronjonp
Mentor
Mentor

@Kent1Cooper wrote:

@ronjonp wrote:

.... One thing I'd add is an undo begin/end. ....


Yes, and *error* handling to ensure the changed System Variable gets reset, and if the OP wants, a request to the User for the interval.


For sure. 🍻

0 Likes