Change first and last vertex of 3D polyline.

Change first and last vertex of 3D polyline.

PkostrzewaM3SXC
Participant Participant
416 Views
3 Replies
Message 1 of 4

Change first and last vertex of 3D polyline.

PkostrzewaM3SXC
Participant
Participant

Hello everyone,

I'm trying to write a routine to change the Z value of 3D polylines based on user input, but I'm getting nowhere.

I searched the forums and it does not seem like there is anything similar, unless im using wrong terminology.

 

What I want to do is to select multiple polylines, and cycle through them changing first and last vertex by the same value.

1. Select 3D Polylines.

2. Type Z value change for first and last vertex.

 

Any chance you guys have seen something similar that I could try amending?
Thanks for your help in advance.

0 Likes
Accepted solutions (1)
417 Views
3 Replies
Replies (3)
Message 2 of 4

komondormrex
Mentor
Mentor
Accepted solution

hey there,

check the following

 

(defun c:first_last_Z_3d_pline (/ 3dpline_sset z_value coordinates)
  (if (setq 3dpline_sset (ssget ":l" '((0 . "polyline") (-4 . "&=") (70 . 8))))
    (progn
      (setq z_value (getreal "\nEnter new Z value for first/last vertex: "))
      (foreach 3dpline (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex 3dpline_sset))))
        (setq coordinates (vlax-get 3dpline 'coordinates))
        (vlax-put 3dpline 'coordinates (append (list (car coordinates) (cadr coordinates) z_value)
					       (reverse (cdr (reverse (cdddr coordinates))))
					       (list z_value)
				       )
  	)
      )
    )
  )
  (princ)
)

 

 

0 Likes
Message 3 of 4

Sea-Haven
Mentor
Mentor

Another allows you to skip start or end or change 1 or both.

 

SeaHaven_0-1715739646037.png

 

; thanks to BeekeeCZ for this function
(defun :nireplace (lst idx new / i)
  (setq i -1)
  (mapcar (function (lambda (itm) (if (= (car idx) (setq i (1+ i)))
    (if (= 1 (length idx))
      new
      (:nireplace itm (cdr idx) new))
    itm)))
	lst)
)

(defun c:1stlast ( / 3dpline obj lst x y z )

(setq 3dpline (ssname (ssget "_+.:E:S" '((0 . "polyline") (-4 . "&=") (70 . 8))) 0))
(setq obj (vlax-ename->vla-object 3dpline))
(setq lst (vlax-get obj 'coordinates))

(if (not AH:getvalsm)(load "Multi Getvals.lsp"))
(setq x (nth 0 lst)
  Y (nth 1 lst)
  Z (nth 2 lst)
)

(setq ans (AH:getvalsm (list "Start pt " "X " 5 4 (rtos x 2 2) "Y " 5 4 (rtos y 2 2) "Z " 5 4 (rtos z 2 2) )))
(setq x (atof (nth 0 ans))
  Y (atof (nth 1 ans))
  Z (atof (nth 2 ans))
)

(setq lst (:nireplace lst '(0) x))
(setq lst (:nireplace lst '(1) y))
(setq lst (:nireplace lst '(2) z))

(setq len (length lst))
(setq x (nth (- len 3) lst)
  Y (nth (- len 2)  lst)
  Z (nth (- len 1)  lst)
)

(setq ans (AH:getvalsm (list "End pt " "X " 5 4 (rtos x 2 2) "Y " 5 4 (rtos y 2 2) "Z " 5 4 (rtos z 2 2) )))
(setq x (atof (nth 0 ans))
  Y (atof (nth 1 ans))
  Z (atof (nth 2 ans))
)

(setq lst (:nireplace lst (list (- len 3)) x))
(setq lst (:nireplace lst (list (- len 2)) y))
(setq lst (:nireplace lst (list (- len 1)) z))

(vlax-put obj 'coordinates lst)

(princ)
)

 

Can be one dcl using Multi getvals 2col, will leave that for end user.

 

0 Likes
Message 4 of 4

PkostrzewaM3SXC
Participant
Participant

Hey! 

Thank you so much , it made my life a lot easier.
What I was looking for was slightly different, but I managed to amend your code.

(defun c:firstlast (/ 3dpline_sset z_value coordinates)
  (if (setq 3dpline_sset (ssget ":l" '((0 . "polyline") (-4 . "&=") (70 . 8))))
    (progn
      (setq z_value (getreal "\nEnter Z value to be lowered/raised by: "))
      (foreach 3dpline (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex 3dpline_sset))))
        (setq coordinates (vlax-get 3dpline 'coordinates))
        (vlax-put 3dpline 'coordinates (append (list (car coordinates) (cadr coordinates) (+ (caddr coordinates) z_value))
					       (reverse (cdr (reverse (cdddr coordinates))))
					       (list (+ (last coordinates) z_value))
				       )
  	)
      )
    )
  )
  (princ)
)