enthralled Posted January 18, 2023 Posted January 18, 2023 (edited) Hello, Can anyone help me with a way to automate the following steps: 1- User Selects multiple polylines 2- User inputs a number for maximum length of polyline segments 3- Lisp Finds segments within the polylines that are greater than a user specified length 4.a- Lisp Adds a vertex at mid point of each of these segments 4.b- If 1 vertex at mid point is not enough to achieve a length below the specified max, then it will add vertices that are equidistant (having uniform lengths, see attached image for clarification) Note that the polylines must keep their original properties (layrer/color, etc), including direction/orientation (start/end). Attached Image to show result (dimensions only for clarification, not needed in the lisp) + Sample CAD drawing. The closest that I found is this: maxsegmentlength.lsp by dlanorh (although it adds vertex exactly at distance, instead of dividing the segment equally). Thanks. Bhannes Network.dwgFetching info... Edited January 18, 2023 by enthralled Quote
Tsuky Posted January 18, 2023 Posted January 18, 2023 (edited) This? (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:div-vertex_po ( / ss max_l n ent obj_vla pr dist_end dist_start seg_len div l_div l) (princ "\nSelect polylines.") (while (null (setq ss (ssget '((0 . "LWPOLYLINE"))))) (princ "\nSelect is empty, or isn't POLYLINE!") ) (initget 7) (setq max_l (getdist "\nMax length between vertex: ")) (repeat (setq n (sslength ss)) (setq ent (ssname ss (setq n (1- n))) obj_vla (vlax-ename->vla-object ent) pr (fix (vlax-curve-getEndParam ent)) ) (repeat (fix (vlax-curve-getEndParam ent)) (setq dist_end (vlax-curve-GetDistAtParam ent pr) dist_start (vlax-curve-GetDistAtParam ent (setq pr (1- pr))) seg_len (- dist_end dist_start) div (1+ (fix (/ seg_len max_l))) l_div (/ seg_len div) l l_div ) (while (< l seg_len) (add_vtx obj_vla (vlax-curve-getparamatdist ent (- dist_end l)) ent) (setq l (+ l l_div)) ) ) ) (prin1) ) Edited January 18, 2023 by Tsuky 3 1 Quote
enthralled Posted January 19, 2023 Author Posted January 19, 2023 On 1/18/2023 at 4:09 PM, Tsuky said: This? (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:div-vertex_po ( / ss max_l n ent obj_vla pr dist_end dist_start seg_len div l_div l) (princ "\nSelect polylines.") (while (null (setq ss (ssget '((0 . "LWPOLYLINE"))))) (princ "\nSelect is empty, or isn't POLYLINE!") ) (initget 7) (setq max_l (getdist "\nMax length between vertex: ")) (repeat (setq n (sslength ss)) (setq ent (ssname ss (setq n (1- n))) obj_vla (vlax-ename->vla-object ent) pr (fix (vlax-curve-getEndParam ent)) ) (repeat (fix (vlax-curve-getEndParam ent)) (setq dist_end (vlax-curve-GetDistAtParam ent pr) dist_start (vlax-curve-GetDistAtParam ent (setq pr (1- pr))) seg_len (- dist_end dist_start) div (1+ (fix (/ seg_len max_l))) l_div (/ seg_len div) l l_div ) (while (< l seg_len) (add_vtx obj_vla (vlax-curve-getparamatdist ent (- dist_end l)) ent) (setq l (+ l l_div)) ) ) ) (prin1) ) Expand Thanks, works perfect. Much appreciated! Quote
enthralled Posted March 18 Author Posted March 18 On 1/18/2023 at 4:09 PM, Tsuky said: This? (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:div-vertex_po ( / ss max_l n ent obj_vla pr dist_end dist_start seg_len div l_div l) (princ "\nSelect polylines.") (while (null (setq ss (ssget '((0 . "LWPOLYLINE"))))) (princ "\nSelect is empty, or isn't POLYLINE!") ) (initget 7) (setq max_l (getdist "\nMax length between vertex: ")) (repeat (setq n (sslength ss)) (setq ent (ssname ss (setq n (1- n))) obj_vla (vlax-ename->vla-object ent) pr (fix (vlax-curve-getEndParam ent)) ) (repeat (fix (vlax-curve-getEndParam ent)) (setq dist_end (vlax-curve-GetDistAtParam ent pr) dist_start (vlax-curve-GetDistAtParam ent (setq pr (1- pr))) seg_len (- dist_end dist_start) div (1+ (fix (/ seg_len max_l))) l_div (/ seg_len div) l l_div ) (while (< l seg_len) (add_vtx obj_vla (vlax-curve-getparamatdist ent (- dist_end l)) ent) (setq l (+ l l_div)) ) ) ) (prin1) ) Expand When running the above on a poyline with segment length exactly = 10 and specifying a max length between vertex of 1, it's adding vertex every 0.9091 instead of adding every 1. Is there an easy fix? Thanks! Quote
LanloyLisp Posted March 18 Posted March 18 On 3/18/2025 at 7:13 AM, enthralled said: When running the above on a poyline with segment length exactly = 10 and specifying a max length between vertex of 1, it's adding vertex every 0.9091 instead of adding every 1. Is there an easy fix? Thanks! Expand (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:div-vertex_po ( / ss max_l n ent obj_vla pr dist_end dist_start seg_len div l_div l) (princ "\nSelect polylines.") (while (null (setq ss (ssget '((0 . "LWPOLYLINE"))))) (princ "\nSelect is empty, or isn't POLYLINE!") ) (initget 7) (setq max_l (getdist "\nMax length between vertex: ")) (repeat (setq n (sslength ss)) (setq ent (ssname ss (setq n (1- n))) obj_vla (vlax-ename->vla-object ent) pr (fix (vlax-curve-getEndParam ent)) ) (repeat (fix (vlax-curve-getEndParam ent)) (setq dist_end (vlax-curve-GetDistAtParam ent pr) dist_start (vlax-curve-GetDistAtParam ent (setq pr (1- pr))) seg_len (- dist_end dist_start) div (if (zerop (rem seg_len max_l))(fix (/ seg_len max_l))(1+ (fix (/ seg_len max_l)))) l_div (/ seg_len div) l l_div ) (while (< l seg_len) (add_vtx obj_vla (vlax-curve-getparamatdist ent (- dist_end l)) ent) (setq l (+ l l_div)) ) ) ) (prin1) ) Hi enthralled, check the quick fix above. Quote
enthralled Posted March 18 Author Posted March 18 (edited) On 3/18/2025 at 8:44 AM, LanloyLisp said: (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:div-vertex_po ( / ss max_l n ent obj_vla pr dist_end dist_start seg_len div l_div l) (princ "\nSelect polylines.") (while (null (setq ss (ssget '((0 . "LWPOLYLINE"))))) (princ "\nSelect is empty, or isn't POLYLINE!") ) (initget 7) (setq max_l (getdist "\nMax length between vertex: ")) (repeat (setq n (sslength ss)) (setq ent (ssname ss (setq n (1- n))) obj_vla (vlax-ename->vla-object ent) pr (fix (vlax-curve-getEndParam ent)) ) (repeat (fix (vlax-curve-getEndParam ent)) (setq dist_end (vlax-curve-GetDistAtParam ent pr) dist_start (vlax-curve-GetDistAtParam ent (setq pr (1- pr))) seg_len (- dist_end dist_start) div (if (zerop (rem seg_len max_l))(fix (/ seg_len max_l))(1+ (fix (/ seg_len max_l)))) l_div (/ seg_len div) l l_div ) (while (< l seg_len) (add_vtx obj_vla (vlax-curve-getparamatdist ent (- dist_end l)) ent) (setq l (+ l l_div)) ) ) ) (prin1) ) Hi enthralled, check the quick fix above. Expand Thanks, here's my result (attached DWG + Screenshot), still not working as intended. 0.91 and 0.96 segments should instead be =1 : div-vertex_po.dwgFetching info... Edited March 18 by enthralled Quote
LanloyLisp Posted March 18 Posted March 18 On 3/18/2025 at 9:02 AM, enthralled said: Thanks, here's my result (attached DWG + Screenshot), still not working as intended. 0.91 and 0.96 segments should instead be =1 : div-vertex_po.dwg 61.46 kB · 0 downloads Expand (defun NearestINT (num f / i r) ;; num - real / integer ;; f - fuzz (setq i (float (fix num)) r (- num i)) (cond ((< r f) i) ((> r (abs (1- f))) (1+ i)) (T num) ) ) (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:div-vertex_po ( / ss max_l n ent obj_vla pr dist_end dist_start seg_len div l_div l) (princ "\nSelect polylines.") (while (null (setq ss (ssget '((0 . "LWPOLYLINE"))))) (princ "\nSelect is empty, or isn't POLYLINE!") ) (initget 7) (setq max_l (getdist "\nMax length between vertex: ")) (repeat (setq n (sslength ss)) (setq ent (ssname ss (setq n (1- n))) obj_vla (vlax-ename->vla-object ent) pr (fix (vlax-curve-getEndParam ent)) ) (repeat (fix (vlax-curve-getEndParam ent)) (setq dist_end (vlax-curve-GetDistAtParam ent pr) dist_start (vlax-curve-GetDistAtParam ent (setq pr (1- pr))) seg_len (- dist_end dist_start) div (fix (/ (nearestint seg_len 1e-4) max_l)) l_div (/ seg_len div) l l_div ) (while (< l seg_len) (add_vtx obj_vla (vlax-curve-getparamatdist ent (- dist_end l)) ent) (setq l (+ l l_div)) ) ) ) (prin1) ) check above, hopefully, this one is will working now. NearestINT function has been added, you can adjust it to your desired precision Quote
enthralled Posted March 19 Author Posted March 19 On 3/18/2025 at 11:44 AM, LanloyLisp said: (defun NearestINT (num f / i r) ;; num - real / integer ;; f - fuzz (setq i (float (fix num)) r (- num i)) (cond ((< r f) i) ((> r (abs (1- f))) (1+ i)) (T num) ) ) (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:div-vertex_po ( / ss max_l n ent obj_vla pr dist_end dist_start seg_len div l_div l) (princ "\nSelect polylines.") (while (null (setq ss (ssget '((0 . "LWPOLYLINE"))))) (princ "\nSelect is empty, or isn't POLYLINE!") ) (initget 7) (setq max_l (getdist "\nMax length between vertex: ")) (repeat (setq n (sslength ss)) (setq ent (ssname ss (setq n (1- n))) obj_vla (vlax-ename->vla-object ent) pr (fix (vlax-curve-getEndParam ent)) ) (repeat (fix (vlax-curve-getEndParam ent)) (setq dist_end (vlax-curve-GetDistAtParam ent pr) dist_start (vlax-curve-GetDistAtParam ent (setq pr (1- pr))) seg_len (- dist_end dist_start) div (fix (/ (nearestint seg_len 1e-4) max_l)) l_div (/ seg_len div) l l_div ) (while (< l seg_len) (add_vtx obj_vla (vlax-curve-getparamatdist ent (- dist_end l)) ent) (setq l (+ l l_div)) ) ) ) (prin1) ) check above, hopefully, this one is will working now. NearestINT function has been added, you can adjust it to your desired precision Expand Hi, sorry for taking from your time. Now I'm getting segments greater than the specified max (1). If there's no easy fix, then it's okay. Thanks. This is the result: div-vertex_po_2.dwgFetching info... Quote
LanloyLisp Posted March 19 Posted March 19 (defun NearestINT (num f / i r) ;; num - real / integer ;; f - fuzz (setq i (float (fix num)) r (- num i)) (cond ((< r f) i) ((> r (abs (1- f))) (1+ i)) (T num) ) ) (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:div-vertex_po ( / ss max_l n ent obj_vla pr dist_end dist_start seg_len1 seg_len2 div l_div l) (princ "\nSelect polylines.") (while (null (setq ss (ssget '((0 . "LWPOLYLINE"))))) (princ "\nSelect is empty, or isn't POLYLINE!") ) (initget 7) (setq max_l (getdist "\nMax length between vertex: ")) (repeat (setq n (sslength ss)) (setq ent (ssname ss (setq n (1- n))) obj_vla (vlax-ename->vla-object ent) pr (fix (vlax-curve-getEndParam ent)) ) (repeat (fix (vlax-curve-getEndParam ent)) (setq dist_end (vlax-curve-GetDistAtParam ent pr) dist_start (vlax-curve-GetDistAtParam ent (setq pr (1- pr))) seg_len1 (- dist_end dist_start) seg_len2 (nearestint seg_len1 1e-4) div (if (equal (fix seg_len2) seg_len2 0.0)(fix (/ seg_len2 max_l))(1+ (fix (/ seg_len2 max_l)))) l_div (/ seg_len2 div) l l_div ) (while (< l seg_len2) (add_vtx obj_vla (vlax-curve-getparamatdist ent (- dist_end l)) ent) (setq l (+ l l_div)) ) ) ) (prin1) ) Hi enthralled, please try the 3rd revision. 1 Quote
enthralled Posted March 19 Author Posted March 19 On 3/19/2025 at 7:41 AM, LanloyLisp said: (defun NearestINT (num f / i r) ;; num - real / integer ;; f - fuzz (setq i (float (fix num)) r (- num i)) (cond ((< r f) i) ((> r (abs (1- f))) (1+ i)) (T num) ) ) (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:div-vertex_po ( / ss max_l n ent obj_vla pr dist_end dist_start seg_len1 seg_len2 div l_div l) (princ "\nSelect polylines.") (while (null (setq ss (ssget '((0 . "LWPOLYLINE"))))) (princ "\nSelect is empty, or isn't POLYLINE!") ) (initget 7) (setq max_l (getdist "\nMax length between vertex: ")) (repeat (setq n (sslength ss)) (setq ent (ssname ss (setq n (1- n))) obj_vla (vlax-ename->vla-object ent) pr (fix (vlax-curve-getEndParam ent)) ) (repeat (fix (vlax-curve-getEndParam ent)) (setq dist_end (vlax-curve-GetDistAtParam ent pr) dist_start (vlax-curve-GetDistAtParam ent (setq pr (1- pr))) seg_len1 (- dist_end dist_start) seg_len2 (nearestint seg_len1 1e-4) div (if (equal (fix seg_len2) seg_len2 0.0)(fix (/ seg_len2 max_l))(1+ (fix (/ seg_len2 max_l)))) l_div (/ seg_len2 div) l l_div ) (while (< l seg_len2) (add_vtx obj_vla (vlax-curve-getparamatdist ent (- dist_end l)) ent) (setq l (+ l l_div)) ) ) ) (prin1) ) Hi enthralled, please try the 3rd revision. Expand Thanks it works! At some places, the lisp is creating vertices at locations where a vertex already exists before running the lisp, resulting in duplicate vertex with zero length segments. can this be avoided? Quote
enthralled Posted March 19 Author Posted March 19 On 3/19/2025 at 7:41 AM, LanloyLisp said: (defun NearestINT (num f / i r) ;; num - real / integer ;; f - fuzz (setq i (float (fix num)) r (- num i)) (cond ((< r f) i) ((> r (abs (1- f))) (1+ i)) (T num) ) ) (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:div-vertex_po ( / ss max_l n ent obj_vla pr dist_end dist_start seg_len1 seg_len2 div l_div l) (princ "\nSelect polylines.") (while (null (setq ss (ssget '((0 . "LWPOLYLINE"))))) (princ "\nSelect is empty, or isn't POLYLINE!") ) (initget 7) (setq max_l (getdist "\nMax length between vertex: ")) (repeat (setq n (sslength ss)) (setq ent (ssname ss (setq n (1- n))) obj_vla (vlax-ename->vla-object ent) pr (fix (vlax-curve-getEndParam ent)) ) (repeat (fix (vlax-curve-getEndParam ent)) (setq dist_end (vlax-curve-GetDistAtParam ent pr) dist_start (vlax-curve-GetDistAtParam ent (setq pr (1- pr))) seg_len1 (- dist_end dist_start) seg_len2 (nearestint seg_len1 1e-4) div (if (equal (fix seg_len2) seg_len2 0.0)(fix (/ seg_len2 max_l))(1+ (fix (/ seg_len2 max_l)))) l_div (/ seg_len2 div) l l_div ) (while (< l seg_len2) (add_vtx obj_vla (vlax-curve-getparamatdist ent (- dist_end l)) ent) (setq l (+ l l_div)) ) ) ) (prin1) ) Hi enthralled, please try the 3rd revision. Expand I tried asking Gemini for a fix for both, the max length issue and duplicate nodes, I got the following, I don't know how well it achieves the result, but it works, do you think it's okay to use: ;; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/add-vertex-to-2d-3d-plines-depending-on-a-specific-distance/m-p/11688584/highlight/true#M442151 ;; https://www.cadtutor.net/forum/topic/76685-adding-vertex-to-segments-of-polylines-that-are-greater-than-a-specified-length/#comment-610360 ;; modified by "gemini-2.0-flash-thinking-exp-01-21" To enforce the specified maximum segment length and prevent duplicate vertices, the code was modified to use ceiling division for segmenting and to check for existing vertices before adding new ones. (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:AVPLSX ( / ss max_l n ent obj_vla pr dist_end dist_start seg_len div l_div l new_vtx_pt existing_vtx_coords vtx_index pt_param tol) (vla-startundomark (vla-get-ActiveDocument (vlax-get-acad-object))) ; Start undo mark here (princ "\nSelect polylines.") (while (null (setq ss (ssget '((0 . "LWPOLYLINE"))))) (princ "\nSelect is empty, or isn't POLYLINE!") ) (initget 7) (setq max_l (getdist "\nMax length between vertex: ")) (setq tol 1e-8) ; Define tolerance for comparing points (repeat (setq n (sslength ss)) (setq ent (ssname ss (setq n (1- n))) obj_vla (vlax-ename->vla-object ent) pr (fix (vlax-curve-getEndParam ent)) ) (repeat (fix (vlax-curve-getEndParam ent)) (setq dist_end (vlax-curve-GetDistAtParam ent pr) dist_start (vlax-curve-GetDistAtParam ent (setq pr (1- pr))) seg_len (- dist_end dist_start) ;; div (1+ (fix (/ seg_len max_l))) div (if (= max_l 0.0) 1 (max 1 (1+ (fix (- (/ seg_len max_l) 0.0000000001))))) l_div (/ seg_len div) l l_div ) (while (< l seg_len) (setq new_vtx_pt (vlax-curve-getpointatdist ent (- dist_end l))) (setq pt_param (vlax-curve-getParamAtPoint ent new_vtx_pt)) (setq existing_vtx_coords nil) ; Initialize existing vertex coordinates list (setq vtx_index 0) (while (<= vtx_index (fix (vlax-curve-getEndParam ent))) ; Iterate through existing vertices (setq existing_vtx_pt (vlax-curve-getpointatparam ent vtx_index)) (if (equal existing_vtx_pt new_vtx_pt tol) ; Check if existing vertex is at new point within tolerance (progn (setq existing_vtx_coords T) ; Mark that a vertex exists (setq vtx_index (1+ (fix (vlax-curve-getEndParam ent)))) ; Exit loop ) (setq vtx_index (1+ vtx_index)) ) ) (if (not existing_vtx_coords) ; If no existing vertex found, add new vertex (add_vtx obj_vla (vlax-curve-getparamatdist ent (- dist_end l)) ent) ) (setq l (+ l l_div)) ) ) ) (vla-endundomark (vla-get-ActiveDocument (vlax-get-acad-object))) ; End undo mark (prin1) ) Quote
LanloyLisp Posted March 19 Posted March 19 On 3/19/2025 at 8:02 AM, enthralled said: I tried asking Gemini for a fix for both, the max length issue and duplicate nodes, I got the following, I don't know how well it achieves the result, but it works, do you think it's okay to use: ;; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/add-vertex-to-2d-3d-plines-depending-on-a-specific-distance/m-p/11688584/highlight/true#M442151 ;; https://www.cadtutor.net/forum/topic/76685-adding-vertex-to-segments-of-polylines-that-are-greater-than-a-specified-length/#comment-610360 ;; modified by "gemini-2.0-flash-thinking-exp-01-21" To enforce the specified maximum segment length and prevent duplicate vertices, the code was modified to use ceiling division for segmenting and to check for existing vertices before adding new ones. (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:AVPLSX ( / ss max_l n ent obj_vla pr dist_end dist_start seg_len div l_div l new_vtx_pt existing_vtx_coords vtx_index pt_param tol) (vla-startundomark (vla-get-ActiveDocument (vlax-get-acad-object))) ; Start undo mark here (princ "\nSelect polylines.") (while (null (setq ss (ssget '((0 . "LWPOLYLINE"))))) (princ "\nSelect is empty, or isn't POLYLINE!") ) (initget 7) (setq max_l (getdist "\nMax length between vertex: ")) (setq tol 1e-8) ; Define tolerance for comparing points (repeat (setq n (sslength ss)) (setq ent (ssname ss (setq n (1- n))) obj_vla (vlax-ename->vla-object ent) pr (fix (vlax-curve-getEndParam ent)) ) (repeat (fix (vlax-curve-getEndParam ent)) (setq dist_end (vlax-curve-GetDistAtParam ent pr) dist_start (vlax-curve-GetDistAtParam ent (setq pr (1- pr))) seg_len (- dist_end dist_start) ;; div (1+ (fix (/ seg_len max_l))) div (if (= max_l 0.0) 1 (max 1 (1+ (fix (- (/ seg_len max_l) 0.0000000001))))) l_div (/ seg_len div) l l_div ) (while (< l seg_len) (setq new_vtx_pt (vlax-curve-getpointatdist ent (- dist_end l))) (setq pt_param (vlax-curve-getParamAtPoint ent new_vtx_pt)) (setq existing_vtx_coords nil) ; Initialize existing vertex coordinates list (setq vtx_index 0) (while (<= vtx_index (fix (vlax-curve-getEndParam ent))) ; Iterate through existing vertices (setq existing_vtx_pt (vlax-curve-getpointatparam ent vtx_index)) (if (equal existing_vtx_pt new_vtx_pt tol) ; Check if existing vertex is at new point within tolerance (progn (setq existing_vtx_coords T) ; Mark that a vertex exists (setq vtx_index (1+ (fix (vlax-curve-getEndParam ent)))) ; Exit loop ) (setq vtx_index (1+ vtx_index)) ) ) (if (not existing_vtx_coords) ; If no existing vertex found, add new vertex (add_vtx obj_vla (vlax-curve-getparamatdist ent (- dist_end l)) ent) ) (setq l (+ l l_div)) ) ) ) (vla-endundomark (vla-get-ActiveDocument (vlax-get-acad-object))) ; End undo mark (prin1) ) Expand It seems perfectly fine and much better. (vla-get-ActiveDocument (vlax-get-acad-object)) - this can be set to a variable. 1 Quote
enthralled Posted March 19 Author Posted March 19 On 3/19/2025 at 9:47 AM, LanloyLisp said: It seems perfectly fine and much better. (vla-get-ActiveDocument (vlax-get-acad-object)) - this can be set to a variable. Expand Thank a lot! Quote
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.