Jump to content

SSGET - Polyline Select by Closed = Yes


GregGleason

Recommended Posts

I am have a selection that is to get closed polylines on the indicated layer. The goal is if the closed polyline has 6 vertices then that polyline will be changed to another layer.

 

I need help with the middle bit.

 

(defun c:Test ( / in ss en get vtx)
 (if (setq in -1 ss (ssget "_C" '(7.244 2.071) '(16.665 10.003) '((0 . "*POLYLINE") (8 . "DIMLDR") [color=red](70 . 1)[/color])))
   (while (setq en (ssname ss (setq in (1+ in))))
     [color=purple]{count vertices of closed polyline}
     {if vertex count = 6 change to another layer}[/color]
     )
   )
 (princ)
 )

Does the selection at least appears that it will work?

 

Greg

Link to comment
Share on other sites

I am have a selection that is to get closed polylines on the indicated layer. The goal is if the closed polyline has 6 vertices then that polyline will be changed to another layer.

 

There are many ways to approach this:

 

If you are only working with 2D polylines (LWPOLYLINEs), then you can filter the polylines by number of vertices directly from the ssget filter list, using DXF group 90:

([color=BLUE]defun[/color] c:test1 ( [color=BLUE]/[/color] i s x )
   ([color=BLUE]if[/color]
       ([color=BLUE]setq[/color] s
           ([color=BLUE]ssget[/color] [color=MAROON]"_C"[/color]
              '( 7.244  2.071)
              '(16.665 10.003)
              '(
                   (0 . [color=MAROON]"LWPOLYLINE"[/color])
                   (8 . [color=MAROON]"DIMLDR"[/color])
                   (90 . 6)
                   (-4 . [color=MAROON]"&="[/color]) (70 . 1)
               )
           )
       )
       ([color=BLUE]repeat[/color] ([color=BLUE]setq[/color] i ([color=BLUE]sslength[/color] s))
           ([color=BLUE]setq[/color] x ([color=BLUE]entget[/color] ([color=BLUE]ssname[/color] s ([color=BLUE]setq[/color] i ([color=BLUE]1-[/color] i)))))
           ([color=BLUE]entmod[/color] ([color=BLUE]subst[/color] '(8 . [color=MAROON]"PolylinesWith6Vertices"[/color]) ([color=BLUE]assoc[/color] 8 x) x))
       )
   )
   ([color=BLUE]princ[/color])
)

 

Note that DXF group 70 is bit-coded, therefore I have used the Bitwise Masked Equals operator in the filter list to essentially perform a (= 1 (logand 1 (cdr (assoc 70 )))) check. You can find more information about this technique here.

 

However, if you are working with a combination of both 2D lightweight polylines (LWPOLYLINEs) and 2D & 3D 'heavy' polylines (POLYLINEs), you would need to perform the check on the number of vertices from within the loop, as the number of vertices is not stored in the DXF data for a POLYLINE entity.

 

For this, you could use the following:

([color=BLUE]defun[/color] c:test2 ( [color=BLUE]/[/color] c e i s x )
   ([color=BLUE]if[/color]
       ([color=BLUE]setq[/color] s
           ([color=BLUE]ssget[/color] [color=MAROON]"_C"[/color]
              '( 7.244  2.071)
              '(16.665 10.003)
              '(
                   (-4 . [color=MAROON]"<OR"[/color])
                       (-4 . [color=MAROON]"<AND"[/color])
                           (0 . [color=MAROON]"POLYLINE"[/color])
                           (-4 . [color=MAROON]"<NOT"[/color])
                               (-4 . [color=MAROON]"&"[/color]) (70 . 80)
                           (-4 . [color=MAROON]"NOT>"[/color])
                       (-4 . [color=MAROON]"AND>"[/color])
                       (-4 . [color=MAROON]"<AND"[/color])
                           (0 . [color=MAROON]"LWPOLYLINE"[/color])
                           (90 . 6)
                       (-4 . [color=MAROON]"AND>"[/color])
                   (-4 . [color=MAROON]"OR>"[/color])
                   (8 . [color=MAROON]"DIMLDR"[/color])
                   (-4 . [color=MAROON]"&="[/color]) (70 . 1)
               )
           )
       )
       ([color=BLUE]repeat[/color] ([color=BLUE]setq[/color] i ([color=BLUE]sslength[/color] s))
           ([color=BLUE]setq[/color] i ([color=BLUE]1-[/color] i)
                 e ([color=BLUE]ssname[/color] s i)
                 x ([color=BLUE]entget[/color] e)
                 c 0
           )
           ([color=BLUE]if[/color] ([color=BLUE]=[/color] [color=MAROON]"POLYLINE"[/color] ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 0 x)))
               ([color=BLUE]while[/color] ([color=BLUE]=[/color] [color=MAROON]"VERTEX"[/color] ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 0 ([color=BLUE]entget[/color] ([color=BLUE]setq[/color] e ([color=BLUE]entnext[/color] e))))))
                   ([color=BLUE]setq[/color] c ([color=BLUE]1+[/color] c))
               )
               ([color=BLUE]setq[/color] c 6)
           )
           ([color=BLUE]if[/color] ([color=BLUE]=[/color] c 6)
               ([color=BLUE]entmod[/color] ([color=BLUE]subst[/color] '(8 . [color=MAROON]"PolylinesWith6Vertices"[/color]) ([color=BLUE]assoc[/color] 8 x) x))
           )
       )
   )
   ([color=BLUE]princ[/color])
)

 

Here, note the use of the additional bitwise test on the value of DXF group 70 when filtering POLYLINE entities to exclude 3D polygon meshes (DXF group 70 = 16) and polyface meshes (DXF group 70 = 64). This is equivalent to (zerop (logand 80 (cdr (assoc 70 ))))

Link to comment
Share on other sites

I also liked this one :

 

 (1+ (vlax-curve-getendparam (vlax-ename->vla-object (car (entsel "\nSelect polyline: "))))) 

http://forums.augi.com/showthread.php?48293-No-of-Vertices-in-a-PolyLine/page2

 

I'm not sure about the 1+ though...

 

but I admit , most of the time the only polylines I use in my field of work (electrical / instrumentation) are just plain square (and boring) 2D poly's so I don't really know what I'm talking about...

 

gr. Rlx

Edited by rlx
Link to comment
Share on other sites

There are many ways to approach this:

 

If you are only working with 2D polylines (LWPOLYLINEs), then you can filter the polylines by number of vertices directly from the ssget filter list, using DXF group 90:

([color=BLUE]defun[/color] c:test1 ( [color=BLUE]/[/color] i s x )
   ([color=BLUE]if[/color]
       ([color=BLUE]setq[/color] s
           ([color=BLUE]ssget[/color] [color=MAROON]"_C"[/color]
              '( 7.244  2.071)
              '(16.665 10.003)
              '(
                   (0 . [color=MAROON]"LWPOLYLINE"[/color])
                   (8 . [color=MAROON]"DIMLDR"[/color])
                   (90 . 6)
                   (-4 . [color=MAROON]"&="[/color]) (70 . 1)
               )
           )
       )
       ([color=BLUE]repeat[/color] ([color=BLUE]setq[/color] i ([color=BLUE]sslength[/color] s))
           ([color=BLUE]setq[/color] x ([color=BLUE]entget[/color] ([color=BLUE]ssname[/color] s ([color=BLUE]setq[/color] i ([color=BLUE]1-[/color] i)))))
           ([color=BLUE]entmod[/color] ([color=BLUE]subst[/color] '(8 . [color=MAROON]"PolylinesWith6Vertices"[/color]) ([color=BLUE]assoc[/color] 8 x) x))
       )
   )
   ([color=BLUE]princ[/color])
)

 

Note that DXF group 70 is bit-coded, therefore I have used the Bitwise Masked Equals operator in the filter list to essentially perform a (= 1 (logand 1 (cdr (assoc 70 )))) check. You can find more information about this technique here.

 

However, if you are working with a combination of both 2D lightweight polylines (LWPOLYLINEs) and 2D & 3D 'heavy' polylines (POLYLINEs), you would need to perform the check on the number of vertices from within the loop, as the number of vertices is not stored in the DXF data for a POLYLINE entity.

 

For this, you could use the following:

([color=BLUE]defun[/color] c:test2 ( [color=BLUE]/[/color] c e i s x )
   ([color=BLUE]if[/color]
       ([color=BLUE]setq[/color] s
           ([color=BLUE]ssget[/color] [color=MAROON]"_C"[/color]
              '( 7.244  2.071)
              '(16.665 10.003)
              '(
                   (-4 . [color=MAROON]"<OR"[/color])
                       (-4 . [color=MAROON]"<AND"[/color])
                           (0 . [color=MAROON]"POLYLINE"[/color])
                           (-4 . [color=MAROON]"<NOT"[/color])
                               (-4 . [color=MAROON]"&"[/color]) (70 . 80)
                           (-4 . [color=MAROON]"NOT>"[/color])
                       (-4 . [color=MAROON]"AND>"[/color])
                       (-4 . [color=MAROON]"<AND"[/color])
                           (0 . [color=MAROON]"LWPOLYLINE"[/color])
                           (90 . 6)
                       (-4 . [color=MAROON]"AND>"[/color])
                   (-4 . [color=MAROON]"OR>"[/color])
                   (8 . [color=MAROON]"DIMLDR"[/color])
                   (-4 . [color=MAROON]"&="[/color]) (70 . 1)
               )
           )
       )
       ([color=BLUE]repeat[/color] ([color=BLUE]setq[/color] i ([color=BLUE]sslength[/color] s))
           ([color=BLUE]setq[/color] i ([color=BLUE]1-[/color] i)
                 e ([color=BLUE]ssname[/color] s i)
                 x ([color=BLUE]entget[/color] e)
                 c 0
           )
           ([color=BLUE]if[/color] ([color=BLUE]=[/color] [color=MAROON]"POLYLINE"[/color] ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 0 x)))
               ([color=BLUE]while[/color] ([color=BLUE]=[/color] [color=MAROON]"VERTEX"[/color] ([color=BLUE]cdr[/color] ([color=BLUE]assoc[/color] 0 ([color=BLUE]entget[/color] ([color=BLUE]setq[/color] e ([color=BLUE]entnext[/color] e))))))
                   ([color=BLUE]setq[/color] c ([color=BLUE]1+[/color] c))
               )
               ([color=BLUE]setq[/color] c 6)
           )
           ([color=BLUE]if[/color] ([color=BLUE]=[/color] c 6)
               ([color=BLUE]entmod[/color] ([color=BLUE]subst[/color] '(8 . [color=MAROON]"PolylinesWith6Vertices"[/color]) ([color=BLUE]assoc[/color] 8 x) x))
           )
       )
   )
   ([color=BLUE]princ[/color])
)

 

Here, note the use of the additional bitwise test on the value of DXF group 70 when filtering POLYLINE entities to exclude 3D polygon meshes (DXF group 70 = 16) and polyface meshes (DXF group 70 = 64). This is equivalent to (zerop (logand 80 (cdr (assoc 70 ))))

 

Lee, you are da man! Thank you, sir! Worked like a Rolex.

 

Greg

Link to comment
Share on other sites

Just an alternative and Lee you have given me the answer for some old code, using VL you can get the co-ordinates and how many adding the "is it a Polyline or a Lwpolyline" ? The number of x y or xyz points is divided by either 2 or 3. Will have a play. It will not work with some of the other objects that you have checked for.

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...