How to select and remove entities below a certain z

How to select and remove entities below a certain z

Anonymous
Not applicable
765 Views
7 Replies
Message 1 of 8

How to select and remove entities below a certain z

Anonymous
Not applicable

Hello guys, 

 

I'm just learing some basic expression to automate some routines using AutoLisp, but stuck in one issue. I'd like to remove entities below a certain z level and tried to find out some solutions in this forum, but no success. 

 

My current code seems like

 

(defun c:test()
(command "._ucsicon" "off" "._ucs" "view")
(setq objekte (ssget "_X" '((0 . "3DSOLID")(-4 . "*,*,<")(10 0.0 0.0 10.0))))
(if objekte
(command "._erase" objekte "")
)
(command "._ucs" "p" "._ucsicon" "on")
)

 

All 3D entities are below z=1 so I expected I could delete everything with z =10. But nothing was selected with ssget function. Can you help me out? 

 

Thanks in advance. 

 

Best,

Yun

 

0 Likes
766 Views
7 Replies
Replies (7)
Message 2 of 8

hmsilva
Mentor
Mentor

Hi Yun,

 

your code is correct, the problem is the Object...

 

3DSOLIDS don't have dxf 10 to filter (the data is encrypted).

One way is using the boundingbox method which returns, the lower left corner and the upper right corner from the solid...

 

(if (setq ss (ssget "_X" (list '(0 . "3DSOLID") (cons 410 (getvar 'CTAB)))))
  (repeat (setq i (sslength ss))
    (setq hnd (ssname ss (setq i (1- i)))
          obj (vlax-ename->vla-object hnd)
    )
    (vla-getboundingbox obj 'mn 'mx)
    (setq llpt (vlax-safearray->list mn)
          urpt (vlax-safearray->list mx)
    )
    (if (or (< (caddr llpt) 10.0)
            (< (caddr urpt) 10.0)
        )
      (vla-delete obj)
    )
  )
)

 

Hope that helps

Henrique

 

EESignature

Message 3 of 8

Anonymous
Not applicable

Thanks so much for your prompt and walkaround solution. I didn't know that 3DSOLID has no dxf 10 property. Your method looks great, but I'd like to know if there is any way to use ssget with _w filter? I also tried with a statement like (setq objekte (ssget "_w" '(-20 -20 -20) '(20 20 20))), but nothing was selected. 

 

Thanks. 

Yun

0 Likes
Message 4 of 8

Kent1Cooper
Consultant
Consultant
@hmsilva wrote:

...

 

....
(if (or (< (caddr llpt) 10.0) (< (caddr urpt) 10.0) ) (vla-delete obj) ....

That looks like it would delete things that have any part that extends below Z=10.  If you want to get rid of only things that are entirely below that level, I think you would want:
....

    (if (and (< (caddr llpt) 10.0)
            (< (caddr urpt) 10.0)

....

 

But come to think of it, the (and) or (or) functions shouldn't be necessary -- to get things that extend below that level at all, it could check only the Z coordinate of the lower left corner of the bounding box, and to get those entirely below that level, it could check only the Z coordinate of the upper right corner.

Kent Cooper, AIA
Message 5 of 8

hmsilva
Mentor
Mentor

@Anonymous wrote:

Thanks so much for your prompt and walkaround solution. I didn't know that 3DSOLID has no dxf 10 property. Your method looks great, but I'd like to know if there is any way to use ssget with _w filter? I also tried with a statement like (setq objekte (ssget "_w" '(-20 -20 -20) '(20 20 20))), but nothing was selected. 


You're welcome, Yun

 

The

(setq objekte (ssget "_w" '(-20 -20 -20) '(20 20 20)))

should work as expected, if there are objects completely inside the window.

 

 

Henrique

 

EESignature

0 Likes
Message 6 of 8

hmsilva
Mentor
Mentor

@Kent1Cooper wrote:
 

That looks like it would delete things that have any part that extends below Z=10.  If you want to get rid of only things that are entirely below that level, I think you would want:
....

    (if (and (< (caddr llpt) 10.0)
            (< (caddr urpt) 10.0)

....

But come to think of it, the (and) or (or) functions shouldn't be necessary -- to get things that extend below that level at all, it could check only the Z coordinate of the lower left corner of the bounding box, and to get those entirely below that level, it could check only the Z coordinate of the upper right corner.


Fully agree!

 

Henrique

EESignature

0 Likes
Message 7 of 8

Anonymous
Not applicable

Thank you Kent and Henrique, 

I just tried Henrique's suggestion, but it seems taking long when I have many (>100) solids with tens of thousand surfaces. I guess ssget with _w filter would be faster than checking the boundary box method, but it does not work properly. Do I need to translate the coordinates from WCS to UCS? I read some articles saying _w filter works with UCS, but I don't quite understand how to use it. 

 

Best, 

Yun

0 Likes
Message 8 of 8

hmsilva
Mentor
Mentor

Yun,

 

the provided points are in the current UCS.

To translate from WCS to the current UCS, try

 

(trans pt 0 1)

 

EDIT:

 

will erase all solids, in a top view, inside the window from -20,-20 to 20,20

 

(command "_-view" "_front")
(if (setq objekte (ssget "_w" '(-20 -20 -20) '(20 20 20) '((0 . "3DSOLID"))))
  (command "._erase" objekte "")
  )
(command "_-view" "_top")

 

 

Henrique

 

 

EESignature

0 Likes