Extract a rectangle

Extract a rectangle

saitoib
Advocate Advocate
430 Views
3 Replies
Message 1 of 4

Extract a rectangle

saitoib
Advocate
Advocate
Hi all.
In the case of Attachment 1, when I want to extract a rectangle tangent to rectangle A, I can process it with Lisp as follows.
(defun c:test2 (/ ent pts ss)
  (setq ent (car (entsel)))
  (setq pts (mapcar 'cdr (vl-remove-if '(lambda (x) (/= (car x) 10)) (entget ent))))
  (setq ss (ssget "_CP" pts (list (cons 0 "LWPOLYLINE"))))
  (ssdel ent ss)
)
スクリーンショット 2023-02-15 160853.png

In the case of the attached figure 2, is it possible to extract the rectangles B1 and B2 at once by making the rectangles A1 and A2 a List or a selection set?
スクリーンショット 2023-02-15 161130.png

Thank you.
Saitoib
0 Likes
Accepted solutions (1)
431 Views
3 Replies
Replies (3)
Message 2 of 4

ВeekeeCZ
Consultant
Consultant

Well, it seems easy when both neighboring rectangles share 2 vertices... you need to select all the green plines (possibly all limited by layer, close, 4 vertices...) and then find the one that shares 2 vertices.

 

So it will help to know the other circumstances from a real drawing, not just from a diagram.

 

If you're about to write it yourself, THESE functions would help you.

0 Likes
Message 3 of 4

Kent1Cooper
Consultant
Consultant
Accepted solution

If the entity names of the two A rectangles are already in a list, try:

(defun c:test3 (/ ent pts ss)
  (foreach ent yourlist
    (setq pts (mapcar 'cdr (vl-remove-if '(lambda (x) (/= (car x) 10)) (entget ent))))
    (setq ss (ssget "_CP" pts (list (cons 0 "LWPOLYLINE"))))
    (ssdel ent ss)
    (setq resultlist (cons ss resultlist))
  ); foreach
)
 
If there will always be only one B rectangle for each A rectangle, they could be extracted so the resultlist is a list of those entity names, rather than a list of selection sets containing one thing each.  They could be put into a selection set rather than a list.
 
If they're already in a selection set:
(defun c:test4 (/ ent pts ss)
  (setq resultSS (ssadd)); initially empty
  (repeat (setq n (sslength yourSS
    (setq ent (ssname yourSS (setq n (1- n))))
    (setq pts (mapcar 'cdr (vl-remove-if '(lambda (x) (/= (car x) 10)) (entget ent))))
    (setq ss (ssget "_CP" pts (list (cons 0 "LWPOLYLINE"))))
    (ssdel ent ss)
    (ssadd (ssname ss 0) resultSS)
  ); repeat
)
 
That does assume only one B per A, and puts the B's into a selection set.  If there might be more than one, it would need to step through the ss set each time to add each item in it to the resultSS.
Kent Cooper, AIA
0 Likes
Message 4 of 4

saitoib
Advocate
Advocate

@ВeekeeCZ 

Thanks for your response.

@Kent1Cooper 

that's so, isn't it
I think I can solve this problem by using a list as an argument and using foreach.
I'll give it a try.
Thank you very much.

Saitoib
0 Likes