Lucay Posted Monday at 07:44 PM Posted Monday at 07:44 PM Hello, I've been having trouble lately making an autolisp program that allows me to return the names of buildings that are included (totally or not) in a hatched area. In my case, the colour of the hatched area is important but I'm not going to linger on the colour because if the code works for one colour there shouldn't be any problems for the others. Here's the considered approach: - select the hatches that might contain buildings - analyse each hatch and check whether buildings are actually contained within it - create a list of the buildings' names contained in the hatches and write the names in an Excel file The hatches in question can be of any shape (rectangular, circular, etc.) An example of an autocad file is attached: - a layer "polylines" containing the polylines representing the outlines of the buildings - a layer "numero" containing the names of the buildings (inside the outlines) - a final layer "hatch" containing the hatches Test AUTOCAD.dwg This is the basis of my code: (setq names (ssadd)) (setq Build (ssadd)) ; selecting the hatches and get their outlines (if (setq ss (ssget "x" (list '(0 . "HATCH") '(62 . 4)))) ; blue hactches (repeat (setq i (sslength ss)) (setq Contours (mapcar 'cdr (vl-remove-if-not '(lambda (p) (= (car p) 10)) (entget (ssname ss (setq i (1- i))))))) (setq Contours (cdr Contours)) ; "Contours" = building outlines (setq Contours (reverse (cdr (reverse Contours)))) ;get a selection of the polylines inside the hatches (if Contours (progn (setq ss_bat (ssget "_CP" Contours '((0 . "LWPOLYLINE") (8 . "polylignes")))) [...]; get the list of each building to get the names after (see lines below) -> fill "Build" ) (princ "no contours") ) ) ) ; get the list of names of the buildings (repeat (setq j (sslength sel)) (if (setq sel (ssget "_CP" (mapcar 'cdr (vl-remove-if-not '(lambda (p) (= (car p) 10)) (entget (ssname Build (setq j (1- j)))) ) ) '((0 . "TEXT,MTEXT") (8 . "numero"))) ) (progn (setq text (cdr (assoc 1 (entget (ssname sel 0))))) (setq names (cons text names)) ) ) ) I have 2 problems at the moment: - if the hatches are in the shape of a circle, I don't have enough points when I want to retrieve the outline to accurately determine whether a building is in the hatched area or not. - I don't know how to get a list of each individual polyline from the building selection (see the [...] inside the code above) If you could give me any hints or help, I'd be very grateful. Thanks Quote
GLAVCVS Posted Monday at 10:39 PM Posted Monday at 10:39 PM (edited) Yes Getting the list of hatch points is one of the biggest difficulties in your program, especially if it is circular hatching or similar. You cannot get a coherent perimeter from the entity list. I tried a couple of times but had to resign myself to doing it with 'hatchedit'. Is it possible that there is someone who can prove otherwise? Edited Monday at 10:46 PM by GLAVCVS Quote
BIGAL Posted Monday at 11:20 PM Posted Monday at 11:20 PM I used HatchB.lsp and yes got a pline as the defining shape, it appears to have two vertices so could check for that and make a series of points that would be the pline as facets. ; may be able to use (setq ent (entlast)) if a pline has been made with 2 points. (setq ent (car (entsel "\nPick hatch boundary "))) (setq co-ord (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget ent)))) (setq mp (mapcar '* (mapcar '+ (car co-ord) (cadr co-ord)) '(0.5 0.5))) (setq rad (distance mp (car co-ord))) (setq inc (/ (* pi 2) 20)) ; may want more than 20 (setq pts '()) (setq ang 0.0) (repeat 21 (setq pt (polar mp ang rad)) (setq pts (cons pt pts)) (setq ang (+ ang inc)) ) Quote
GLAVCVS Posted 17 hours ago Posted 17 hours ago 9 hours ago, BIGAL said: Utilicé HatchB.lsp y sí, obtuve una pline como forma definitoria, parece tener dos vértices, así que pude verificarlo y hacer una serie de puntos que serían la pline como facetas. It's interesting But, at least for me, it doesn't work correctly. I've drawn a polyline with the points that the function calculates when selecting the yellow circle and this is what I get: Quote
GLAVCVS Posted 16 hours ago Posted 16 hours ago And if the hatch has several arcs to compose an irregular shape, it doesn't work well either. In the following image you can see the perimeter returned by the function when the cyan hatch is selected. It is interesting to note that all the perimeters returned by the function seem to want to pass through the point 0,0 Quote
GLAVCVS Posted 16 hours ago Posted 16 hours ago Furthermore, the function in no case returns the inner perimeter Quote
Saxlle Posted 7 hours ago Posted 7 hours ago This should be helpful when you trying something to select inside the CIRCLE (like from attached example file). (setq ent_circle (car (entsel "\nSelect the CIRCLE:")) num 50 ;; number of times to repeat inside "repeat" function. Can be changeable, depends of density between the points. ang 0.0 ;; default angle tot (+ pi pi) inc (/ tot (float num)) cen (cdr (assoc 10 (entget ent_circle))) ;; CIRCLE base point rad (cdr (assoc 40 (entget ent_circle))) ;; radius of the CIRCLE ) (repeat num (setq lst (cons (polar cen ang rad) lst)) ;; creating a LIST with "points" on the CIRCLE (setq ang (+ ang inc)) ) (setq entSelection (ssget "CP" lst '((0 . "LWPOLYLINE")))) ;; make a selection set from previous list of points (lst). SSGET filter can be changed After executing the code, you will get this (picture 1). I changed the color into to the orange, just to make it easier to see all polylines. Maybe the second approach can be also helpful. (setq entOne (car (entsel "\nSelect the first HATCHED area:")) objOne (vlax-ename->vla-object entOne) ) (vla-getboundingbox objOne 'minPtOne 'maxPtOne) ;; get the boundingbox from hatch (setq ptMinOne (vlax-safeArray->list minPtOne) ;; get the lower left point ptMaxOne (vlax-safeArray->list maxPtOne) ;; get the upper right point ) (if (not (tblsearch "LAYER" "TEST_BOUNDARY")) ;; this is just for testing (progn (command "-layer" "m" "TEST_BOUNDARY" "c" 1 "" "s" "TEST_BOUNDARY" "") ) (progn (command "clayer" "TEST_BOUNDARY") ) ) (command-s "_RECTANG" ptMinOne ptMaxOne) ;; make a rectangle to wrap everything around the hatch (setq entlastOne (entlast) objRectangOne (vlax-ename->vla-object entlastOne)) (setq coordsOne (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget entlastOne)))) ;; get the coordinates from previous maded rectangle (setq ssOutside (ssget "WP" coordsOne '((0 . "LWPOLYLINE")))) ;; make a selection set from previous list of points (coordsOne). SSGET filter can changed After executing the code, you will get this (picture 2). I changed the color into to the orange, just to make it easier to see all polylines and you will se a red rectangle which I get from boundingbox. But if you have this next situation, you can think about changing the "hatch pattern" (something about "ANSI 31"). When you change the "hatch pattern" you can explode it and you will get a bunch o lines. Then, you can create a selection set with filter and then iterate through the loop, and make a new selection set only from lines which are croosing through the "buildings" (picture 3, just an example). You can see how the line will intersect the buildings (red circles), and after the loop was finished, undo everything to get previous "hatch pattern", you will get a new selection set list with buildings who belongs to the hatched area, and than you can iterate through the new selection set to get the data (names) of the buildings. I hope it will be helpful, or make a starting point to think about the solution. Also, tried the Bigals code, but something weird happening, like GLAVCVS say. Best regards. Quote
Lucay Posted 5 hours ago Author Posted 5 hours ago Thank you guys for your help. Several comments: Indeed @GLAVCVS, when you get the points of the hatch outline, it always (at least every time I checked) takes the (0 0) points, that's why I remove the first point in "Contours" in my basis code, I do not know why.. @Saxlle, thank you for your help, the tip to use ANSI type hatches and explode it is quite intersting! Having the outline points independently of the hatch shape seems very complicated. Even if I make several cases for circles, rectangles et, I can still have hatches like the blue one GLAVCVS told about earlier... 11 hours ago, GLAVCVS said: I'll try to work on it in the next few days Quote
Saxlle Posted 5 hours ago Posted 5 hours ago You're welcome @Lucay. Than, if you are going to have irregular shapes, than I would think about the 3rd solution which I described, that is going to help you. Maybe something unexpectedly can happend, but let us know if it's happen. Best regards. Quote
BIGAL Posted 3 hours ago Posted 3 hours ago (edited) The problem with the pline being multi objects ars & lines etc. This seemed to work, to get points. Point them on a dummy layer then use ssget, after got points erase the selection set. Yes used HatchB.lsp to make outline. (setvar 'osmode 0) (setvar 'pdmode 34) (setq obj (vlax-ename->vla-object (car (entsel "\nPick hatch object ")))) (setq len (vlax-get obj 'length)) (setq inc ( / len 40)) (setq ch 0.0) (repeat 40 (setq pt (vlax-curve-getpointatdist obj ch)) (command "point" pt) (setq ch (+ ch inc)) ) Need some real shapes to check properly. Edited 3 hours ago by BIGAL Quote
GLAVCVS Posted 1 hour ago Posted 1 hour ago If you try to run: (vl-cmdf "_hatchedit" (car (entsel "\nSelect HATCH... ")) "_boundary" "_polyline" "_no") you will generate a perimeter polyline of the selected hatch. It will create polylines for both the outer perimeter and the inner ones, if there are any. From these polylines, which have arcs, you need to get the list of points VID-20250212-WA0000.mp4 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.