Jen Posted August 21, 2019 Posted August 21, 2019 Hi there. I'm working on a lisp that, in part, detects whether there are blocks within a certain distance of a block or how close those other blocks are. For example, I may check to see if there are blocks within 60' to the North or South or between 20' and 40' to the East or West of the block I'm analyzing. Is there anything in autolisp or vlisp that would detect objects in proximity to a given object like this? Or do I need to keep doing it the long way. So far, what I've been doing is this: 1. Determine coordinates of the corners of the area I want to check for nearby objects. 2. Create a selection set of all blocks within a box formed by those coordinates. 3. Check the selection set to see if it has any of the blocks I'm looking for. This works ok, but takes a long time to process as many blocks as I'm checking. I'd like to be able to then check exactly how far away those nearby blocks are from the original block. Before I add code to do that, I wanted to see if there's a way for lisp to basically "see" the nearby objects instead of using my current long method. Thanks in advance for any pointers in the right direction. Quote
BIGAL Posted August 22, 2019 Posted August 22, 2019 Thinking two WP within polygon ssget the first is blocks inside your desired area, 2nd is all blocks within larger area. Ok now subtract the inside blocks from outside blocks selection. Using a getclosestpointto would give the distance from the inside outline to each outer block, A bit unstable as shape of block will effect some of the answers. What happens with a block just crossing the inner boundary in or out ? Can you post a sample dwg ? Quote
Jen Posted August 23, 2019 Author Posted August 23, 2019 Thanks for the reply BIGAL. My current approach uses selection sets similarly to what you're suggesting. It's finding the objects ok, but I was hoping there might be an easier/faster way for CAD to "see" if there's anything near an object. I did not know about getclosestpointo through, and I think that may be key. Most of my lisp experience is not with vlisp, but I'm working on learning vlisp. Block shape is always a perfect rectangle, so no concern there. Block crossing boundary is in the ss. I use CP rather than WP for my selections because I want to know if any part of the block is near. End goal of this is illustrated in example drawing. Red block is block being analyzed. Goal is to see if it is within distance D1 from the edge. Since blocks are typically evenly spaced, I've been checking for blocks incremental distances away and counting how many are there based on how far apart they should be. If there are enough, it's not the edge yet. If there aren't, it might be the edge. Problem I'm running into is incremental distances are discrete, so it's estimating D1 and assuming how many blocks should be included. If it estimates D1 too high, it expects too many blocks and thinks it found the edge. It would be better if I could somehow determine D1. Sample1.dwg Quote
BIGAL Posted August 24, 2019 Posted August 24, 2019 Hmmmm Pick bottom point of gap pick top point block below drag a line across the two points establish D1 The line across gets all the entities using ssget "f" Compare D1 to blocks using closestpointto and 2nd pick point no idea if it works a random idea. Quote
Roy_043 Posted August 25, 2019 Posted August 25, 2019 (edited) If the rectangular blocks are always positioned orthogonally then using the vla-getboundingbox function would be my way to approach this. Edited August 25, 2019 by Roy_043 Quote
Roy_043 Posted August 25, 2019 Posted August 25, 2019 Example code: (defun KGA_Geom_ObjectBoundingbox (obj / ptBL ptTR) (vla-getboundingbox obj 'ptBL 'ptTR) (list (vlax-safearray->list ptBL) (vlax-safearray->list ptTR)) ) (defun KGA_Conv_Pickset_To_EnameList (ss / i ret) (if ss (repeat (setq i (sslength ss)) (setq ret (cons (ssname ss (setq i (1- i))) ret)) ) ) ) (defun c:Test ( / base basePt box eastDis southDis ss ssOut xMax xMin yMax yMin) (if (and (setq ss (ssget "_X" '((0 . "INSERT") (410 . "Model")))) (or (< 1 (sslength ss)) (prompt "\nOnly one block found ") ) (setq base (car (entsel "\nSelect base block: "))) (= "AcDbBlockReference" (vla-get-objectname (vlax-ename->vla-object base))) (setq eastDis (getdist "\nEast distance: ")) (setq southDis (getdist "\nSouth distance: ")) ) (progn (setq basePt (car (KGA_Geom_ObjectBoundingbox (vlax-ename->vla-object base)))) ; BL point of base block. (setq xMin (car basePt)) (setq xMax (+ xMin eastDis)) (setq yMax (cadr basePt)) (setq yMin (- yMax southDis)) (ssdel base ss) (setq ssOut (ssadd)) (foreach enm (KGA_Conv_Pickset_To_EnameList ss) (setq box (KGA_Geom_ObjectBoundingbox (vlax-ename->vla-object enm))) ; Format: (BLpoint TRpoint). (if (and (<= xMin (caar box) xMax) ; Check X coord of BL point. (<= yMin (cadadr box) yMax) ; Check Y coord of TR point. ) (ssadd enm ssOut) ) ) ) ) (sssetfirst nil ssOut) (princ) ) Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.