Count the number of polylines(shapes) inside a closed polyline

Count the number of polylines(shapes) inside a closed polyline

nanja_c86
Enthusiast Enthusiast
1,114 Views
10 Replies
Message 1 of 11

Count the number of polylines(shapes) inside a closed polyline

nanja_c86
Enthusiast
Enthusiast

I'm seeking a Lisp routine that can count the number of polylines within a closed polyline and categorize them by their color type. Additionally, I would like the routine to display an alert message for each color count. Attached is a sample DWG file for reference. In this file, the purple boundary represents the overall boundary within which I need to count blue, magenta, and yellow polylines and display an alert message for each color count. Any guidance or assistance on how to achieve this would be highly appreciated. Thank you!

0 Likes
Accepted solutions (3)
1,115 Views
10 Replies
Replies (10)
Message 2 of 11

komondormrex
Mentor
Mentor

check the following

 

(defun c:plines_enclosed (/ pline_list encloser color_list colors colors_string)
	(setq pline_list (vl-remove-if 'listp (mapcar 'cadr (ssnamex (ssget "_wp" (mapcar 'cdr (vl-remove-if-not '(lambda (group) (= 10 (car group))) (entget (setq encloser (car (entsel "\nPick enclosing pline: ")))))) '((0 . "lwpolyline"))))))
		  color_list (vl-remove nil (mapcar '(lambda (pline) (cdr (assoc 62 (entget pline)))) pline_list))
		  colors (vl-sort color_list '<)
		  colors (mapcar '(lambda (color) (cons color (- (length color_list) (length (vl-remove color color_list))))) colors)
		  colors_string (apply 'strcat (mapcar '(lambda (color) (strcat "Color " (itoa (car color)) " - " (itoa (cdr color)) " pcs.\n")) colors))
	)
	(alert (strcat "Enclosed plines are\n" colors_string))
	(princ)
)

 

Message 3 of 11

john.uhden
Mentor
Mentor

@nanja_c86 ,

Here we go again... inside or outside a closed polyline boundary.

First you must define "inside" vs. "outside."

Does inside mean that all parts of the "inside" polyline must be totally inside the boundary polyline (not even touching)?

OR does inside mean that any part of an "inside" polyline be inside (crossed by) the boundary polyline?

And might the boundary polyline have bulged (arced) segments?

The answers to these questions make a huge difference in the required code and the accuracy of the results.

John F. Uhden

0 Likes
Message 4 of 11

nanja_c86
Enthusiast
Enthusiast
Accepted solution

@john.uhden 

For clarity and specificity in our request, here's a refined response considering the questions asked:

Thank you for pointing out the crucial details that need clarification. Here are the specifics:

  1. Definition of "Inside": For our purposes, "inside" means that all parts of the polyline must be totally within the boundary polyline, without touching or crossing the boundary.

  2. Boundary Polyline Segments: Yes, the boundary polyline may include bulged (arced) segments.

Also need to the alert message to display as 

  • Color 2 (Yellow) represents a "2-port".
  • Color 5 (Blue) represents a "4-port".
  • Color 6 (Magenta) represents an "8-port".

    Your insight on these details is invaluable. Could you advise on how to proceed with these specifications in mind?
0 Likes
Message 5 of 11

nanja_c86
Enthusiast
Enthusiast

@komondormrex 
I'm incredibly grateful for the Lisp routine you've provided—it's been a huge help. If it's not too much trouble, could I ask for one more modification? I'm aiming to further refine the function to identify polylines as "2-port," "4-port," or "8-port" based on their color (with color codes 2 for yellow, 5 for blue, and 6 for magenta, respectively).

Would you be able to adjust the code to include this feature? Your expertise has been invaluable, and I greatly appreciate any additional assistance you can provide.

Thank you once again for your support and guidance.

0 Likes
Message 6 of 11

komondormrex
Mentor
Mentor

sure

 

(defun c:plines_enclosed (/ pline_list color_list colors colors_string)
	(setq pline_list (vl-remove-if 'listp (mapcar 'cadr (ssnamex (ssget "_wp" (mapcar 'cdr 
		  																			  (vl-remove-if-not '(lambda (group) (= 10 (car group))) 
																					  					 (entget (car (entsel "\nPick enclosing pline: ")))
																					  )
																			  ) 
																			 '((0 . "lwpolyline") (-4 . "<or") (62 . 2) (62 . 5) (62 . 6) (-4 . "or>"))
																 )
														)
										  )
					 )
		  color_list (mapcar '(lambda (pline) (cdr (assoc 62 (entget pline)))) pline_list)
		  colors (mapcar '(lambda (color) (cons (cdr (assoc color '((2 . "2-port") (5 . "4-port") (6 . "8-port")))) 
		  										(- (length color_list) (length (vl-remove color color_list)))
										  )
						  ) 
						  (vl-sort color_list '<)
				 )
		  colors_string (apply 'strcat (mapcar '(lambda (color) (strcat (car color) " - " (itoa (cdr color)) " pcs.\n")) colors))
	)
	(alert (strcat "Enclosed plines are\n\n" colors_string))
	(princ)
)

 

Message 7 of 11

komondormrex
Mentor
Mentor
Accepted solution

sure

(defun c:plines_enclosed (/ pline_list color_list colors colors_string)
	(setq pline_list (vl-remove-if 'listp (mapcar 'cadr (ssnamex (ssget "_wp" (mapcar 'cdr 
		  																			  (vl-remove-if-not '(lambda (group) (= 10 (car group))) 
																					  					 (entget (car (entsel "\nPick enclosing pline: ")))
																					  )
																			  ) 
																			 '((0 . "lwpolyline") (-4 . "<or") (62 . 2) (62 . 5) (62 . 6) (-4 . "or>"))
																 )
														)
										  )
					 )
		  color_list (mapcar '(lambda (pline) (cdr (assoc 62 (entget pline)))) pline_list)
		  colors (mapcar '(lambda (color) (cons (cdr (assoc color '((2 . "2-port") (5 . "4-port") (6 . "8-port")))) 
		  										(- (length color_list) (length (vl-remove color color_list)))
										  )
						  ) 
						  (vl-sort color_list '<)
				 )
		  colors_string (apply 'strcat (mapcar '(lambda (color) (strcat (car color) " - " (itoa (cdr color)) " pcs.\n")) colors))
	)
	(alert (strcat "Enclosed plines are\n\n" colors_string))
	(princ)
)

 

Message 8 of 11

nanja_c86
Enthusiast
Enthusiast
Thank you. Working Great.
0 Likes
Message 9 of 11

calderg1000
Mentor
Mentor
Accepted solution

Regards @nanja_c86 

Try this code

;;;___
(defun c:Lwc (/ lp ln y b m j k w txf)
  (setq lp
         (mapcar 'cdr
                 (vl-remove-if-not '(lambda (j) (= (car j) 10))
                                   (entget (car (entsel
                                                  "Select a closed polyline: "
                                                )
                                           )
                                   )
                 )
         )
  )
  (setq ln (vl-remove-if 'listp
                         (mapcar 'cadr
                                 (ssnamex (ssget "Wp" lp '((-4 . "<OR")
                                                          (-4 . "<AND")(0 . "lwpolyline")(62 . 2)(-4 . "AND>")
                                                          (-4 . "<AND")(0 . "lwpolyline")(62 . 5)(-4 . "AND>")
                                                          (-4 . "<AND")(0 . "lwpolyline")(62 . 6)(-4 . "AND>")
                                                          (-4 . "OR>")
                                                  )
                                          )
                                 )
                         )
           )
  )
  (setq y 0
        m 0
        b 0
  )
(foreach k ln
    (cond
      ((= (cdr (assoc 62 (entget k))) 2) (setq y (1+ y)))
      ((= (cdr (assoc 62 (entget k))) 5) (setq b (1+ b)))
      ((= (cdr (assoc 62 (entget k))) 6) (setq m (1+ m)))
      (t nil)
   )
 )
(setq y (cons "Color 2 (Yellow)" y)
      b (cons "Color 5 (Blue)" b)
      m (cons "Color 6 (Magenta)" m)
      tx "\n"
      )
(alert
(foreach w (list m b y)
       (setq tx(strcat "\n" (car w) " represents a  "(itoa (cdr w)) "-port" tx))
  )
) 
)

 


Carlos Calderon G
EESignature
>Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.

Message 10 of 11

john.uhden
Mentor
Mentor

@calderg1000 ,

That's great for a polyline boundary with all straight segments, but what if one or more segments is bulged?

Hint:  You've got to add more points along bulged segments, but speed is inversely proportional to accuracy.  Such is life.

John F. Uhden

0 Likes
Message 11 of 11

daniel_cadext
Advisor
Advisor

I was thinking IntersectWith

sorry its python but you'll get the idea

def PyRxCmd_doit() -> None:
    try:
        es = Ed.Editor.entSel("\nPick it: ", Db.Polyline.desc())
        
        opl = Db.Polyline(es[1])
        filter = [(Db.DxfCode.kDxfStart, "LWPOLYLINE")] #add color yadada
        ss = Ed.Editor.selectWindowPolygon(opl.toPoint3dList(),filter)
        
        for id in ss[1].objectIds():
            pl = Db.Polyline(id, Db.OpenMode.kForWrite)
            if pl.layer() != "0":
                continue
            inter = opl.intersectWith(pl,Db.Intersect.kExtendThis)
            if len(inter) == 0:
                pl.setColorIndex(1)
    
    except Exception as err:
        traceback.print_exception(err)

 

found.png

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
0 Likes