Check Z Of 2D Polylines

Check Z Of 2D Polylines

christianbaileypaulsen1
Advocate Advocate
2,710 Views
31 Replies
Message 1 of 32

Check Z Of 2D Polylines

christianbaileypaulsen1
Advocate
Advocate

When programming for cnc we make our bits cut .005 into the table. So that the Z value of out cuts are -.005. After creating a program we must read through all the Nc code which could be pages, and make sure none of the Z values are below -.005. Then we go to front view of out cnc drawing and look if anything is further below than Z -.005. When doing hundreds of programs this adds hours of work. I was wanting to create a lisp would check if there is anything in the project less than -.005. Then maybe select those object so that i can see which ones they are and fix them. This would save me hours a day and allow me to work much more efficiently. Any advice is welcome. Thank you. Im not good at coding at all but ill try to give an idea below so you guys can see im at least trying. 

 

If Z < -.005

{ Select object}

else

{Dont select Object}

 

... Repeat for all objects in drawing until everything has been checked.

 

I really appriciate everyone's help, even if you just read this thread and didn't say anything.

 

0 Likes
2,711 Views
31 Replies
Replies (31)
Message 2 of 32

Ranjit_Singh
Advisor
Advisor

I am not sure if you mean the Elevation property of a polyline. If so, you can simply do a QSELECT

elevation_polylines.png

0 Likes
Message 3 of 32

christianbaileypaulsen1
Advocate
Advocate

That worked really good for before i program i have to check and make sure none of the polylines are below zero. Thank you for that. My original explanation was bad but now that im looking at a program its a bit more complicated. When i cnc i select a polyline and it creates a block around that polyline that is the cut path. That block is nothing more than a 3d polyline that the router bit will follow. So it starts at Z = 1 then will plunge down to a depth of Z = -.005  and go around the entire cut path.and then come back up to Z = 1 at the end of the cut. So the 3d polyline in the block actually has multiple z values along the way with -.005 being the lowest it should go. Anything lower than -.005 will cut into the table and break the machine. So i tried to go to quick select and check all block references in the drawing, but it only has a "Position Z" property that can be selected and its value is 1. There is no property that allows me to check the lowest point of the block. Sorry if this is confusing. If any additional information is needed please let me know. Thank you.

0 Likes
Message 4 of 32

Ranjit_Singh
Advisor
Advisor

Share one of your drawings/blocks and explain what you need to find out. Based on what I understand there is a 3d polyline in a block and you want to know if it has any vertices at elevation less than -0.005? Correct?

If it does have such vertices then do you wan those vertices to be adjusted to -0.005?

Are there more than one type of blocks (s)? Are there multiple 3d polylines in a block?

It would be helpful if you answered those and also provided a dwg file.

0 Likes
Message 5 of 32

john.uhden
Mentor
Mentor

Ranjit is one of the best helpers here, if not the best.

 

Answer his questions and he (or even we) will find or write you a solution.

Might you ever have a condition where the polyline elevations are fine, but the block insertion is wrong?

Or maybe you are just referring to the polyline as a block and it's not nested at all?

John F. Uhden

0 Likes
Message 6 of 32

Kent1Cooper
Consultant
Consultant

@christianbaileypaulsen1 wrote:

.... I was wanting to create a lisp would check if there is anything in the project less than -.005. ....


For the initial test of whether you need to go looking at all, something as simple as:

 

(< (caddr (getvar 'extmin)) -0.005)

 

will return T if there's anything at all in the drawing that extends below that level, or nil if there isn't.  Do a REGEN or ZOOM Extents first, because the EXTMIN value [and also EXTMAX, but you don't care about that] gets updated farther out  whenever something is added or changed in a way that goes beyond the current extents, but it doesn't get pulled back in  when such things are Erased or Moved or Trimmed or whatever to pull the extents inward, until a REGEN or ZOOM Extents [or maybe ZOOM All -- I forget].

 

If that returns T, go to a view from the side, and select things with a crossing window [a routine could be made to do that for you].  The complication is that a crossing window whose upper edge is at  Z = -0.005 will find things that reach  that level but don't go below  it.  Some kind of tolerance could be built in, or you [or a routine for you] could use what it finds and evaluate each item on its own for whether it reaches too low -- its bounding box will tell you that quite easily, so it's not necessary to step through and check all vertices, etc.

Kent Cooper, AIA
0 Likes
Message 7 of 32

christianbaileypaulsen1
Advocate
Advocate

I will attach an example. Thank you both for trying to help me out. Ill also try to be as detailed as possible in my explanation, as im not sure if you both have cnc knowledge.

 

I first open a cnc template. I will then paste my 3d part to the right of the template. I then will flatshot my 3d part and trace it with a polyline on the object layer. Once i have my polyline i will drag it onto my template. So i will have the polyline of the object i want to cut on my template in the object layer. before acutally starting programming i must make sure this polylines elevation is 0, which was simplified with the help of the first reply. From there i will open up my cnc program in autocad. I then have to "geoshape" my polyline which converts it to a 2d polyline on the nc_shape layer. The polyline will still exist with the 2d polyline over it. I could delete or leave the polyline there, it doesnt matter. The cnc program only works with 2d polylines. I then select my outside cut knowledge and select the "geoshape" of the object i want to cut. This is where it inserts the block. I need to make sure this blocks lowest point is not lower than -.005. The top of the cut will be at Z=1 and the lowest point should be at -005, you can see where the cut starts and where it ends if you go to a iso view. Ill get you guys any information you need so just let me know. Thank you.

0 Likes
Message 8 of 32

Kent1Cooper
Consultant
Consultant

In that drawing, my suggested test confirms you have a violation:

 

Command: (< (caddr (getvar 'extmin)) -0.005)
T

 

or, to be more specific:

 

Command: (caddr (getvar 'extmin))
-0.755

 

is how far down it goes.  I moved it up 0.75, REGENerated, and then got:

 

Command: (< (caddr (getvar 'extmin)) -0.005)
nil

 

It's easy to see what goes below looking from any sideways viewpoint.

Kent Cooper, AIA
Message 9 of 32

christianbaileypaulsen1
Advocate
Advocate

Sorry to be difficult but could you post your exact code. I tried inputting your stuff but im not very good. Theres a problem when i try to defun.

0 Likes
Message 10 of 32

Ranjit_Singh
Advisor
Advisor

Still not sure what we are looking for. There are all these entities in your block

("INSERT" . "OBJECT") 
("TEXT" . "NC_CUT") 
("POLYLINE" . "NC_INDEX") 
("VERTEX" . "NC_INDEX") 
("VERTEX" . "NC_INDEX") 
("SEQEND" . "NC_INDEX") 
("TEXT" . "NC_CUT") 
("TEXT" . "NC_CUT") 
("TEXT" . "NC_CUT") 
("TEXT" . "NC_CUT") 
("POLYLINE" . "NC_CUT") 
("VERTEX" . "NC_CUT") 
("VERTEX" . "NC_CUT") 
("SEQEND" . "NC_CUT") 
("POLYLINE" . "NC_CUT") 
("VERTEX" . "NC_CUT") 
("VERTEX" . "NC_CUT") 
("SEQEND" . "NC_CUT") 
("TEXT" . "NC_CUT") 
("LWPOLYLINE" . "NC_CCW") 
("TEXT" . "NC_CUT") 
("POLYLINE" . "NC_CUT") 
("VERTEX" . "NC_CUT") 
("VERTEX" . "NC_CUT") 
("SEQEND" . "NC_CUT") 
("LWPOLYLINE" . "NC_CCW") 
("TEXT" . "NC_CUT") 
("LWPOLYLINE" . "NC_CCW") 
("POLYLINE" . "NC_CUT") 
("VERTEX" . "NC_CUT") 
("VERTEX" . "NC_CUT") 
("SEQEND" . "NC_CUT") 
("POLYLINE" . "NC_INDEX") 
("VERTEX" . "NC_INDEX") 
("VERTEX" . "NC_INDEX") 
("SEQEND" . "NC_INDEX") 
("TEXT" . "NC_CUT") 
("POLYLINE" . "NC_INDEX") 
("VERTEX" . "NC_INDEX") 
("VERTEX" . "NC_INDEX") 
("SEQEND" . "NC_INDEX")

Is there a specific layer your are targeting?

Below routine will report all the vertices of 3d polylines. Not sure if this is what you are looking for

(defun c:somefunc  (/ ent etdata)
 (setq ent (car (entsel "\nSelect block: "))
       ent (cdr (assoc -2 (tblsearch "block" (cdr (assoc 2 (entget ent)))))))
 (while ent
  (if (= "VERTEX" (cdr (assoc 0 (setq etdata (entget ent)))))
   (print (cdr (assoc 10 etdata))))
  (setq ent (entnext ent)))
 (princ))

vertex_elevations.gif

 

0 Likes
Message 11 of 32

christianbaileypaulsen1
Advocate
Advocate

I just got back into work and tried out your command. The problem i have with that is that the third coordinate in the information that comes back, isnt the z relative to the whole drawing. Its the z of the vertice relative to that block. Its setting the highest point of the block to 0 on the z axis. So with the block having a actual high point of z = .5 and a low point of z = -.755, the value that gets returned is -1.255. I know this is becoming difficult so please bear with me. I did some research on the block to try to further understand what is needed. I exploded the block and looked at everything inside of it. The two red polylines are what actually determines the cut, the 3d polylines and text should be irrelevant for what we are trying to do. Those polyilines within the block have a specific elevation property that can be read. I dont know if there is a way for you to actually pull all the polylines out of the block and read their elevations.

0 Likes
Message 12 of 32

Kent1Cooper
Consultant
Consultant

@christianbaileypaulsen1 wrote:

Sorry to be difficult but could you post your exact code. I tried inputting your stuff but im not very good. Theres a problem when i try to defun.


I hadn't put it into any defined function -- I just used the code strings mentioned directly.  But maybe something like this, assuming you're starting in WCS plan view:

 

(defun C:TooDeep ()
  (if (< (caddr (getvar 'extmin)) -0.005)
    (progn ; then
      (alert "Something's cutting too deep!")
      (command
        "_.dview" "" "_points" "_none" "0,0,0" "_none" "1,0,0" ""
        "_.zoom" "_extents"
      ); command
    ); progn
    (prompt "You're in the clear.")
  ); if
); defun

 

 

Then if anything extends too low, after OKing the alerts and the Zoom Extents you'll be looking at it on edge from the right [down the X axis from positive-X territory].  It could be from any direction you prefer, and it could be done with a change in UCS instead of just view direction.

 

If you want it to then select  anything that drops too low, that could be attempted, but see the last paragraph in Post 6, and the results could be affected by how big the drawing extents are in relation to the penetration depth.

Kent Cooper, AIA
0 Likes
Message 13 of 32

Ranjit_Singh
Advisor
Advisor

@christianbaileypaulsen1 wrote:

I just got back into work and tried out your command. The problem i have with that is that the third coordinate in the information that comes back, isnt the z relative to the whole drawing. Its the z of the vertice relative to that block. Its setting the highest point of the block to 0 on the z axis. So with the block having a actual high point of z = .5 and a low point of z = -.755, the value that gets returned is -1.255. I know this is becoming difficult so please bear with me. I did some research on the block to try to further understand what is needed. I exploded the block and looked at everything inside of it. The two red polylines are what actually determines the cut, the 3d polylines and text should be irrelevant for what we are trying to do. Those polyilines within the block have a specific elevation property that can be read. I dont know if there is a way for you to actually pull all the polylines out of the block and read their elevations.



Try below. It pulls the co-ordinates for the polylines along with the z values

;:Ranjit Singh
;;10/5/17
(defun c:somefunc  (/ ang ent etdata inpt xfac yfac zfac lst)
 (mapcar '(lambda (x)
           (setq ent  (cdr (assoc -2 (tblsearch "block" (cdr (assoc 2 (setq etdata (entget x)))))))
                 inpt (cdr (assoc 10 etdata))
                 ang  (cdr (assoc 50 etdata))
                 xfac (cdr (assoc 41 etdata))
                 yfac (cdr (assoc 42 etdata))
                 zfac (cdr (assoc 43 etdata)))
           (while ent
            (if (= "LWPOLYLINE" (cdr (assoc 0 (entget ent))))
             (print (mapcar '(lambda (x)
                              (mapcar '+
                                      inpt
                                      (polar '(0 0 0)
                                             (+ ang (angle '(0 0 0) (mapcar '* (list xfac yfac zfac) x)))
                                             (distance '(0 0 0) (mapcar '* (list xfac yfac zfac) x)))))
                            (vl-remove nil
                                       (mapcar '(lambda (x)
                                                 (if (= (car x) 10)
                                                  (reverse (cons (cdr (assoc 38 lst)) (reverse (cdr x))))))
                                               (setq lst (entget ent)))))))
            (setq ent (entnext ent)))
           (princ "\n========"))
         (mapcar 'cadr (ssnamex (ssget '((0 . "INSERT"))))))
 (princ))

lwpol_vertex_elevations.gif

 

0 Likes
Message 14 of 32

Kent1Cooper
Consultant
Consultant

@Kent1Cooper wrote:

....

If you want it to then select  anything that drops too low, that could be attempted, ....


I was thinking about a crossing-window selection in that from-the-side point of view, but instead, it can just check objects for their own bounding boxes, in the same way the drawing as a whole is checked, for violation of that level.  There's certainly no need to plow through nested Polylines in Block definitions and look at all their vertices.

 

Very lightly tested:

 

(defun C:TooDeep (/ candidates item minpt maxpt)
  (if (< (caddr (getvar 'extmin)) -0.005); ANYTHING in the drawing too low?
    (progn ; then -- find it/them
      (setq
        TooDeep (ssadd); initially empty selection set
        candidates (ssget "_X" (list '(0 . "INSERT,*POLYLINE") (cons 410 (getvar 'ctab))))
      ); setq
      (repeat (setq n (sslength candidates))
        (setq item (ssname candidates (setq n (1- n))))
        (vla-getboundingbox (vlax-ename->vla-object item) 'minpt 'maxpt)
        (if (< (caddr (vlax-safearray->list minpt)) -0.005); too deep?
          (ssadd item TooDeep); then -- put it in selection
        ); if
      ); repeat
      (alert "Too-deep things are in a selection\nset in the TooDeep variable.")
    ); progn
    (prompt "You're in the clear."); else
  ); if
  (princ)
); defun

I restricted it to Blocks and Polylines, since those seem to be the candidates in your situation, but you can vary that to look for other possible stuff that might dip too low.

 

HOWEVER, I did have trouble at first.  I was in a drawing in which I had used DVIEW and its View Block, which meant I had AVE_RENDER and AVE_GLOBAL Blocks [yes, it turns out, actually Inserted on the ASHADE Layer] with null extents, and got an error message to that effect.  When I got rid of those Blocks, it worked.  If you might have that, and don't want to get rid of those, each 'item' should be checked for Block name, and those eliminated from consideration before trying to get their bounding boxes.

 

EDIT:  Come to think of it, that (alert) should probably be replaced with:

 

      (if (> (sslength TooDeep) 0); any of the Blocks/Polylines too deep?
(alert "Too-deep things are in a selection\nset in the TooDeep variable."); then
(prompt "\nNo Blocks or Polylines go too deep."); else
); if

since the first test is for whether anything  goes too low, and it could just be your Title Block or some stray piece of Text or something that got shifted downward somehow. 

Kent Cooper, AIA
0 Likes
Message 15 of 32

christianbaileypaulsen1
Advocate
Advocate

Your first set of code worked great. When i try to put in the second code you added i get a error that i cant figure out. I went back to the first part and tried to add a variable for material thickness, but the math where i try to do ((-materialthickness)-(-.005)) seems to give me a error. I will post my full code. Maybe its a simple fix, but if you could paste your full code with the two parts together, and my material thickness variable id appreciate it. Thank you very much. As far as i can tell we are getting super close. Thank you.

 

(defun C:TooDeep (/ candidates item minpt maxpt materialthickness)
  (setq materialthickness (getreal "Enter material thickness:"))
  (if (< (caddr (getvar 'extmin)) ((-materialthickness)-(-0.005)); ANYTHING in the drawing too low?
    (progn ; then -- find it/them
      (setq
        TooDeep (ssadd); initially empty selection set
        candidates (ssget "_X" (list '(0 . "INSERT,*POLYLINE") (cons 410 (getvar 'ctab))))
      ); setq
      (repeat (setq n (sslength candidates))
        (setq item (ssname candidates (setq n (1- n))))
        (vla-getboundingbox (vlax-ename->vla-object item) 'minpt 'maxpt)
        (if (< (caddr (vlax-safearray->list minpt)) -0.005); too deep?
          (ssadd item TooDeep); then -- put it in selection
       (if (> (sslength TooDeep) 0); any of the Blocks/Polylines too deep?
        (alert "Too-deep things are in a selection\nset in the TooDeep variable."); then
        (prompt "\nNo Blocks or Polylines go too deep."); else
      ); if
  (princ)
); defun
0 Likes
Message 16 of 32

Kent1Cooper
Consultant
Consultant

@christianbaileypaulsen1 wrote:

Your first set of code worked great. When i try to put in the second code you added i get a error that i cant figure out. I went back to the first part and tried to add a variable for material thickness, but the math where i try to do ((-materialthickness)-(-.005)) seems to give me a error. ....

 

....
(setq materialthickness (getreal "Enter material thickness:")) (if (< (caddr (getvar 'extmin)) ((-materialthickness)-(-0.005)); ANYTHING in the drawing too low? ....
(repeat (setq n (sslength candidates)) (setq item (ssname candidates (setq n (1- n)))) (vla-getboundingbox (vlax-ename->vla-object item) 'minpt 'maxpt) (if (< (caddr (vlax-safearray->list minpt)) -0.005); too deep? (ssadd item TooDeep); then -- put it in selection (if (> (sslength TooDeep) 0); any of the Blocks/Polylines too deep? (alert "Too-deep things are in a selection\nset in the TooDeep variable."); then (prompt "\nNo Blocks or Polylines go too deep."); else ); if (princ) ); defun

Read up on the (-) AutoLisp function, and the arguments it wants.  Assuming you mean the material thickness goes downward from 0, and you want to know if anything extends more than 0.005 below the bottom  of the material, try:

 

(if (< (caddr (getvar 'extmin)) (- (+ materialthickness 0.005)))

 

or

 

(if (< (caddr (getvar 'extmin)) (- 0 materialthickness 0.005))

 

And you put the revised (alert) in incorrectly -- the (if) check on the item depth isn't closed, and the (repeat) function needs to be completed before  it looks at whether anything went too deep, and you've lose the closings of some functions.  Try this re-arrangement of the latter part:

      (repeat (setq n (sslength candidates))
        (setq item (ssname candidates (setq n (1- n))))
        (vla-getboundingbox (vlax-ename->vla-object item) 'minpt 'maxpt)
        (if (< (caddr (vlax-safearray->list minpt)) (- 0 materialthickness 0.005)); too deep?
          (ssadd item TooDeep); then -- put it in selection

        ); if [individual-item depth]

      ); repeat
      (if (> (sslength TooDeep) 0); any of the Blocks/Polylines too deep?
        (alert "Too-deep things are in a selection\nset in the TooDeep variable."); then
        (prompt "\nNo Blocks or Polylines go too deep."); else
      ); if [whether it was Blocks/Polylines that go too deep, or something else

    ); progn -- 'then' argument if anything at all goes too deep

    (prompt "You're in the clear."); 'else' [nothing at all goes too deep]

  ); if [whether or not anything at all goes too deep]
  (princ)

); defun

Kent Cooper, AIA
0 Likes
Message 17 of 32

christianbaileypaulsen1
Advocate
Advocate

i couldve swore it was working friday but today when i try to use it i get a message at the bottom saying.

 

Command: TOODEEP
Enter material thickness:.75
AutoCAD variable setting rejected: "OSMODE" nil

 

Like i said i thought it was working friday before i left work. The only problem was that if something was too deep, i didnt know what was too deep. Is there any way the items that are too deep can be added to a selection set?

 

0 Likes
Message 18 of 32

Kent1Cooper
Consultant
Consultant

@christianbaileypaulsen1 wrote:

....
AutoCAD variable setting rejected: "OSMODE" nil

.... 


Looks like you threw in something to reset OSMODE, but it's giving it something with no value set, which probably means you either didn't put anything in to save its initial value first, or maybe spelled the variable name differently in the resetting from the spelling in the saving.

Kent Cooper, AIA
0 Likes
Message 19 of 32

Kent1Cooper
Consultant
Consultant

@christianbaileypaulsen1 wrote:

.... if something was too deep, i didnt know what was too deep. Is there any way the items that are too deep can be added to a selection set?

 


It should be doing that -- putting them into the selection set in the TooDeep variable.  Post your latest full version -- if it's about exactly how revisions were incorporated, it could be related to the OSMODE problem.

Kent Cooper, AIA
0 Likes
Message 20 of 32

christianbaileypaulsen1
Advocate
Advocate

This is what i have after i tried to put the pieces of code you gave me together. I wasnt getting a selection set earlier, but when i added your new code it stopped working so maybe the selection set will work after the error im getting is fixed.

(defun C:TooDeep (/ candidates item minpt maxpt materialthickness)
  (setq materialthickness (getreal "Enter material thickness:"))
  (if (< (caddr (getvar 'extmin)) (- 0 materialthickness 0.005))
					; ANYTHING in the drawing too low?
    (progn				; then -- find it/them
      (setq
	TooDeep	(ssadd)			; initially empty selection set
	candidates
	 (ssget	"_X"
		(list '(0 . "INSERT,*POLYLINE")
		      (cons 410 (getvar 'ctab))
		)
	 )
      )					; setq
      (repeat (setq n (sslength candidates))
	(setq item (ssname candidates (setq n (1- n))))
	(vla-getboundingbox
	  (vlax-ename->vla-object item)
	  'minpt
	  'maxpt
	)
	(if (< (caddr (vlax-safearray->list minpt))
	       (- 0 materialthickness 0.005)
	    )				; too deep?
	  (ssadd item TooDeep)		; then -- put it in selection
	)				; if [individual-item depth]
      )					; repeat
      (if (> (sslength TooDeep) 0)	; any of the Blocks/Polylines too deep?
	(alert
	  "Too-deep things are in a selection\nset in the TooDeep variable."
	)				; then
	(prompt "\nNo Blocks or Polylines go too deep.") ; else
      )					; if [whether it was Blocks/Polylines that go too deep, or something else
    )					; progn -- 'then' argument if anything at all goes too deep
    (prompt "You're in the clear.")	; 'else' [nothing at all goes too deep]
  )					; if [whether or not anything at all goes too deep]
  (princ)
)					; defun

 

0 Likes