Nikon Posted July 22 Posted July 22 (edited) How to count the number of objects inside the selected outline. How to do it with lisp. What commands should I use? Tell me, please. Edited July 25 by Nikon Quote
CyberAngel Posted July 22 Posted July 22 The very simple way is to use your outline as a bounding box, which can function as a window for a selection set. Note that the selection method for the ssget command lets you use a rectangle or a polygon, and at the same time you can specify whether objects on the boundary are included. If the second outline is a circle, you may have a little more trouble. I can't find any way to use a circle as a window. Which is not to say there isn't one. Quote
BIGAL Posted July 23 Posted July 23 Two options with SSGET "WP" within polygon or "CP" crossing polygon. For the red its a case of just getting the vertices of say a pline. Note a trick must add 1st point as last point so shape is closed. Re the blue circle again use points but calculated as a series of chords, the more chords the more accurate search. This is from a couple of days ago 10 sides you may need more like 50. (defun poly10 (cen rad / lst) (setq lst '()) (setq ang2 (/ (* pi 2.) 10.)) (repeat 11 (setq pt (polar cen ang2 rad)) (setq lst (cons pt lst)) (setq ang2 (+ ang2 inc)) ) (setq ss2 (ssget "CP" lst )) (if (= ss2 nil) (progn (alert "No objects found will now exit ")(exit)) ) (princ) ) Maybe post a real dwg to look at. Quote
Nikon Posted July 23 Author Posted July 23 @BIGAL @CyberAngel thanks I can use the polygon command instead of a circle (more precision is not needed) or use the Lee Mac SegmentCurveV1-1.lsp program to replace the circle with a polyline. I just don't know how to start, which lisp command is doing the counting. I think you need to point to the contour first, then select the element to count? Is it easier to select a contour and fill it with elements with the specified step? Ideally, I would like to be able to fill the outline with elements in a staggered order, but this is probably very difficult... -count-outline-.dwg Quote
fuccaro Posted July 23 Posted July 23 (defun c:pp() (setq pl (car (entsel "select border polyline\n")) points (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget pl))) ) (strcat (itoa (sslength (ssget "cp" points))) " entities found") ) This will count the entities inside the polyline and also those crossing it. For the circle: convert it first to a closed polyline containing only line segments. Good luck! 1 Quote
CyberAngel Posted July 23 Posted July 23 5 hours ago, Nikon said: @BIGAL @CyberAngel thanks I can use the polygon command instead of a circle (more precision is not needed) or use the Lee Mac SegmentCurveV1-1.lsp program to replace the circle with a polyline. I just don't know how to start, which lisp command is doing the counting. I think you need to point to the contour first, then select the element to count? Is it easier to select a contour and fill it with elements with the specified step? Ideally, I would like to be able to fill the outline with elements in a staggered order, but this is probably very difficult... -count-outline-.dwg 689.23 kB · 1 download If it's not obvious from fuccaro's code, the counting is the easiest part. Once you create a selection set, you have a list of the elements. sslength tells you how long the list is, and thus how many elements you selected. Quote
Nikon Posted July 23 Author Posted July 23 (edited) 1 hour ago, fuccaro said: (defun c:pp() (setq pl (car (entsel "select border polyline\n")) points (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget pl))) ) (strcat (itoa (sslength (ssget "cp" points))) " entities found") ) T h a n k s ! It's very simple and it works very well! Edited July 23 by Nikon Quote
Nikon Posted July 23 Author Posted July 23 6 hours ago, fuccaro said: (defun c:pp() (setq pl (car (entsel "select border polyline\n")) points (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget pl))) ) (strcat (itoa (sslength (ssget "cp" points))) " entities found") ) An interesting feature is that the elements are counted together with the contour, that is, in fact, there are 1 fewer elements. This must be borne in mind... Quote
fuccaro Posted July 24 Posted July 24 Yes, you are right! (defun c:pp() (setq pl (car (entsel "select border polyline\n")) points (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget pl))) ) (strcat (itoa (1- (sslength (ssget "cp" points)))) " entities found") ) This will subtract one before it displays the result... but: What if there are two (or more) identical border polylines one on the top of the other(s)? The program will count them all but it will subtract only one from the result! Maybe you will wish to use WP instead of CP in the SSGET. That way the program will count only the entities inside the borders. And an other limitation coming up in my mind: the border polyline must contain no arcs, just straight segments. This Lisp will ignore the bulge factors. 1 Quote
Nikon Posted July 24 Author Posted July 24 (edited) 3 hours ago, fuccaro said: (defun c:pp() (setq pl (car (entsel "select border polyline\n")) points (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget pl))) ) (strcat (itoa (1- (sslength (ssget "cp" points)))) " entities found") ) @fuccaro Thanks, the "WP" option is better suited for my task. (defun c:CP-count() (setq pl (car (entsel "select border polyline\n")) points (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget pl))) ) (strcat (itoa (1- (sslength (ssget "_cp" points)))) " entities found") ) (defun c:WP-count() (setq pl (car (entsel "select border polyline\n")) points (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget pl))) ) (strcat (itoa (1- (sslength (ssget "_WP" points)))) " entities found") ) Another limitation is that the calculation is carried out only on the visible part of the contour. All elements inside the contour should be visible on the screen. Edited July 24 by Nikon Quote
Steven P Posted July 24 Posted July 24 I think it was MHUPP who put me onto the following 2 snippets, save the current zoom with ZoomCurrent, and return to it with ZoomSaved can be used to show all the outline and return the screen to how the user had it at the start of the LISP: Example 3 lines at the end to show it working ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun ZoomCurrent ( / vc sz ) ;; record the current zoom (setq vc (getvar 'viewctr)) (setq sz (getvar 'viewsize)) (list vc sz) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun ZoomSaved ( vcsz / ) ;; zoom to zoom. car: centre coordinate, cadr scale factor (command "Zoom" "c" (car vcsz) (cadr vcsz)) (princ) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;Zoom operation (setq vcsz (ZoomCurrent)) (command "zoom" "object" pause) (ZoomSaved vcsz) 1 Quote
fuccaro Posted July 24 Posted July 24 2 hours ago, Nikon said: Another limitation is that the calculation is carried out only on the visible part of the contour. All elements inside the contour should be visible on the screen. Hm... that's strange! What AutoCAD are you using? This problem was solved by Autodesk sometime in 2006 or so. I did a quick test. I drew some lines inside a closed polyline and I run the Lisp. Next I used zoom/pan to move the lines off screen. Even when just a small part of the polyline was on the screen and all the lines were outside, I've got the same results. I use AutoCAD 2024. Let's ask for help: Can somebody please give it a try and post here a feed-back? Quote
Nikon Posted July 24 Author Posted July 24 15 minutes ago, fuccaro said: What AutoCAD are you using? I have a localized version of AutoCAD 2015 In the localized version of AutoCAD 2020 it works fine... Quote
Nikon Posted July 24 Author Posted July 24 56 minutes ago, Steven P said: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun ZoomCurrent ( / vc sz ) ;; record the current zoom (setq vc (getvar 'viewctr)) (setq sz (getvar 'viewsize)) (list vc sz) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun ZoomSaved ( vcsz / ) ;; zoom to zoom. car: centre coordinate, cadr scale factor (command "Zoom" "c" (car vcsz) (cadr vcsz)) (princ) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;Zoom operation (setq vcsz (ZoomCurrent)) (command "zoom" "object" pause) (ZoomSaved vcsz) This will work if i will enlarge the image to highlight the outline, then not all the elements are visible on the screen?.. Quote
Steven P Posted July 24 Posted July 24 1 hour ago, fuccaro said: Hm... that's strange! What AutoCAD are you using? This problem was solved by Autodesk sometime in 2006 or so. I did a quick test. I drew some lines inside a closed polyline and I run the Lisp. Next I used zoom/pan to move the lines off screen. Even when just a small part of the polyline was on the screen and all the lines were outside, I've got the same results. I use AutoCAD 2024. Let's ask for help: Can somebody please give it a try and post here a feed-back? Not with this LISP but with another (cable route drawing, a long polyline) it wasn't working properly so had to go zoom out, do selection, zoom back again. I know he has had it on this page on his website for a while so newer CAD might have fixed this but Lee Mac refers to it in his ssget reference page (CP, W and WP I think). I think I started on my cable route LISP using 2018 or something like that. Bearing in mind that those who follow this thread might have early versions of CAD it is worth noting this even if it is fixed now. Quote
Steven P Posted July 24 Posted July 24 51 minutes ago, Nikon said: This will work if i will enlarge the image to highlight the outline, then not all the elements are visible on the screen?.. Do a zoom all - it makes little difference zoom object or zoom all so long as the outline is visible. In reality I'll do zoom all and then zoom 0.95 (zoom out a little more) just in case. 1 Quote
BIGAL Posted July 24 Posted July 24 @Nikon Just a comment from like 30 years ago, draw a shape, ie pline, pick control point, overfill with required objects, change layer of objects within pline and turn off, erase the dummy layer of objects, turn objects back on. Then count. Hey that's the method ! Used this for concrete on ground slabs for the waffle panels did trim on waffles also. 1 Quote
Nikon Posted July 25 Author Posted July 25 7 hours ago, BIGAL said: Just a comment from like 30 years ago, draw a shape, ie pline, pick control point, overfill with required objects, change layer of objects within pline and turn off, erase the dummy layer of objects, turn objects back on. Then count. Hey that's the method ! Used this for concrete on ground slabs for the waffle panels did trim on waffles also. I do this: execute the "array" command, stretch array the desired distance along the contour, then execute "EXPLODE" command, i count the number of elements inside the contour, then /2, since I need a staggered order. It turns out a lot of actions... Quote
BIGAL Posted July 25 Posted July 25 (edited) Ok the code I use is copyrighted by a former company I worked for, but a hint you just pick lower left then upper right and work out your array rows and columns, all inside lisp. If I redid would use bounding box of the object so get the 2 points required then go outwards from these 2 points for array. Edited July 25 by BIGAL 1 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.