Z value correction for 3d polyline lisp

Z value correction for 3d polyline lisp

yu85.info
Collaborator Collaborator
916 Views
10 Replies
Message 1 of 11

Z value correction for 3d polyline lisp

yu85.info
Collaborator
Collaborator

Hi, I need help modifying this LISP 

 

I have a DWG file (example attached)  with multiple 3D polylines, and some of the vertices have a Z value of 0. I need a LISP script that will automatically copy the Z value from the nearest vertex that isn't 0.

Specifically, if the first vertex has a Z value of 0, it should get the Z value from the next vertex. If there are consecutive vertices with a Z value of 0, each one should get the Z value from the nearest next vertex that isn't 0.

Thank you very much in advance

(defun c:fix3dpolys ()
(vl-load-com)
(setq ss (ssget '((0 . "POLYLINE3D"))))
(if ss
(progn
(setq count 0)
(repeat (sslength ss)
(setq ent (ssname ss count))
(setq obj (vlax-ename->vla-object ent))
(if (= (vla-get-Type obj) acPolyline3D)
(progn
(setq vertices (vlax-get obj 'Coordinates))
(setq new-vertices '())
(setq prev-z nil)
(while vertices
(setq x (car vertices))
(setq y (cadr vertices))
(setq z (caddr vertices))
(if (and (= z 0.0) prev-z)
(setq z prev-z))
(setq new-vertices (append new-vertices (list x y z)))
(setq prev-z z)
(setq vertices (cdddr vertices)))
(vla-put-Coordinates obj (vlax-make-variant new-vertices vlax-vbDouble))
(setq count (1+ count))
)
)
)
(princ (strcat "\n" (itoa count) " 3D polyline(s) updated."))
)
(princ "\nNo 3D polylines selected.")
)
(princ)
)

 

0 Likes
Accepted solutions (2)
917 Views
10 Replies
Replies (10)
Message 2 of 11

Kent1Cooper
Consultant
Consultant

@yu85.info wrote:

.... I need a LISP script that will automatically copy the Z value from the nearest vertex that isn't 0.

.... each one should get the Z value from the nearest next vertex that isn't 0.

....


The nearest non-zero value in either direction, or the first non-zero Z value following?  And if the nearest in either direction, do you mean the closest in vertex count along the Polyline, or the closest in XY location?  The differences could be significant in methodology.

EDIT:  And if it's the first non-zero value following, which I think would be much easier to encode, what if the last Z value is zero?  I assume you would want to set it to the closest preceding non-zero value.

Kent Cooper, AIA
Message 3 of 11

yu85.info
Collaborator
Collaborator

@Kent1Cooper thanks for replying. The result should be that no vertex will have a 0 value. So what comes easier for you is preferred. But the value should be taken from a vertex from the same 3d polyline. If it is the last one so the value should be taken from the vertex before it. Hope I made my self clear enough

Thanks again 

0 Likes
Message 4 of 11

Moshe-A
Mentor
Mentor
Accepted solution

@yu85.info  hi,

 

check this one.

 

enjoy

Moshe

 

(defun c:fix3dpoly (/ ss ename AcDb3dPline doubles^ coords^ i p idx l savedZ currZ vert)
 (if (setq ss (ssget '((0 . "polyline") (100 . "AcDb3dPolyline"))))
  (foreach ename (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))
   (setq AcDb3dPline (vlax-ename->vla-object ename))
   (setq doubles^ (vlax-safearray->list (vlax-variant-value (vla-get-coordinates AcDb3dPline))))

   (setq i 0)
   (repeat (setq l (/ (vl-list-length doubles^) 3))
    (setq coords^ (cons (list (nth i doubles^) (nth (1+ i) doubles^) (nth (+ i 2) doubles^)) coords^))
    (setq i (+ i 3))
   )

   (setq j -1)
   (setq p (vl-some (function (lambda (vert) (setq j (1+ j)) (if (not (equal (caddr vert) 0.0 1e-2)) j))) coords^))

   (setq idx l savedZ (caddr (nth p coords^)))
   (foreach vert coords^
    (setq idx (1- idx))
    (setq currZ (caddr vert))
    (if (equal currZ 0.0 1e-2)
     (vla-put-coordinate AcDb3dPline idx (vlax-3d-point (list (car vert) (cadr vert) savedZ)))
     (setq savedZ currZ)
    ); if
   ); foreach
     
   (vlax-release-object AcDb3dPline)
  ); foreach
 ); if

 (princ)
)

 

Message 5 of 11

yu85.info
Collaborator
Collaborator

Like always, @Moshe-A did it again💪

Thank you very much friend 

0 Likes
Message 6 of 11

komondormrex
Mentor
Mentor

seems he did not

komondormrex_0-1734430810997.png

 

0 Likes
Message 7 of 11

Kent1Cooper
Consultant
Consultant
Accepted solution

@komondormrex wrote:

seems he did not ....


Not if the closest non-zero value in either direction is wanted -- that was my question in Message 2.  But it did assign the closest non-zero value following [the other possibility in my question], which I believe Message 3 finds acceptable.  @yu85.info can clarify, I hope.

Kent Cooper, AIA
Message 8 of 11

yu85.info
Collaborator
Collaborator

@Kent1Cooper @komondormrex I see your point. But for my need I believe @Moshe-A work is something to be thankful for.

0 Likes
Message 9 of 11

Moshe-A
Mentor
Mentor

@komondormrex  a écrit :

seems he did not

 

i my place there is a saying, The Work of the Righteous is done by others 😀


 thank you @yu85.info 

0 Likes
Message 10 of 11

komondormrex
Mentor
Mentor

@Kent1Cooper wrote:

if the closest non-zero value in either direction is wanted...

do you really believe that closeness is considered in terms of direction?

which gas station is closest to the car?

komondormrex_0-1734503270130.png

 

0 Likes
Message 11 of 11

Kent1Cooper
Consultant
Consultant

@komondormrex wrote:

.... do you really believe that closeness is considered in terms of direction?

Not knowing what the application is, I'm only relying on Message 3 which indicates that direction is not an essential criterion.

Kent Cooper, AIA
0 Likes