Jump to content

Recommended Posts

Posted

Hi,

 

I have many polylines (all on one layer, all closed).

 

I need to extract (in a text or preferably CSV format) the handle of the polyline and the centroid.

 

So the end result would look like:

 

06HF, 30.5, 50.5

H32S, 48.2, 30.4

 

And so on.

 

I can find scripts to extract the handle, and scripts that find the centroid/vertices, but I can't for the life of me find one that does both - and my attempts at mashing one together (I don't know LISP - I need to learn!) have failed. :(

 

My boss has given me 'til Tuesday (Tomorrow) to find a way to do this - or I have to do what I need to do with this manually, which would take FOREVER!

 

Thanks,

 

Clare.

  • Replies 31
  • Created
  • Last Reply

Top Posters In This Topic

  • BlackBox

    9

  • Lee Mac

    8

  • ClareSelley

    6

  • MSasu

    3

Top Posters In This Topic

Posted

@Clare, post the two lisps you found, or links, and we'll see if someone can "mash" the two together for you.

cheers

Posted

Gah, as it's being moderated due to links...

 

1 is Lee Mac's GetHand lsp:

 

(defun c:getHand (/ ss file)
 (vl-load-com)
 (if (and (setq ss (ssget))
          (setq file (getfiled "Output File" "" "txt;csv" 9)))
   (progn
     (setq file (open file "a"))
     (mapcar
       (function
         (lambda (x)
           (write-line
             (cdr (assoc 5 x)) file)))
       (mapcar 'entget
         (vl-remove-if 'listp
           (mapcar 'cadr (ssnamex ss)))))
     (close file))
   (princ "*Cancel*"))
 (princ))

That gets the handles.

 

Next to each handle I need the Centroid co-ordinates. Again Lee Mac has code, but I can't mesh the 2:

 

(defun c:pc ( / acdoc acspc acsel reg ) (vl-load-com) ;; © Lee Mac 2011

 (setq acdoc (vla-get-ActiveDocument (vlax-get-acad-object))
       acspc (vlax-get-property acdoc (if (= 1 (getvar 'CVPORT)) 'Paperspace 'Modelspace))
 )
 (if (ssget '((0 . "LWPOLYLINE") (-4 . "&=") (70 . 1)))
   (progn
     (vlax-for obj (setq acsel (vla-get-ActiveSelectionSet acdoc))
       (vlax-invoke acspc 'addpoint
         (trans (vlax-get (setq reg (car (vlax-invoke acspc 'addregion (list obj)))) 'Centroid) 1 0)
       )
       (vla-delete reg)
     )
     (vla-delete acsel)
   )
 )
 (princ)
)

 

Any help is appreciated. :)

Posted

Hi Clare,

 

Try something like this:

 

[color=GREEN];; Extract Handles and Centroids to CSV  -  Lee Mac 2012[/color]

([color=BLUE]defun[/color] c:hcext ( [color=BLUE]/[/color] ad as cn fd fn rg sp )
   ([color=BLUE]if[/color]
       ([color=BLUE]and[/color]
           ([color=BLUE]ssget[/color] '((0 . [color=MAROON]"LWPOLYLINE"[/color]) (-4 . [color=MAROON]"&="[/color]) (70 . 1)))
           ([color=BLUE]setq[/color] fn ([color=BLUE]getfiled[/color] [color=MAROON]"Create Output File"[/color] [color=MAROON]""[/color] [color=MAROON]"csv"[/color] 1))
       )
       ([color=BLUE]progn[/color]
           ([color=BLUE]setq[/color] ad ([color=BLUE]vla-get-activedocument[/color] ([color=BLUE]vlax-get-acad-object[/color]))
                 sp ([color=BLUE]vlax-get-property[/color] ad ([color=BLUE]if[/color] ([color=BLUE]=[/color] 1 ([color=BLUE]getvar[/color] 'cvport)) 'paperspace 'modelspace))
                 fd ([color=BLUE]open[/color] fn [color=MAROON]"w"[/color])
           )
           ([color=BLUE]write-line[/color] [color=MAROON]"Handle,Centroid X,Centroid Y"[/color] fd)
           ([color=BLUE]vlax-for[/color] ob ([color=BLUE]setq[/color] as ([color=BLUE]vla-get-activeselectionset[/color] ad))
               ([color=BLUE]setq[/color] rg ([color=BLUE]car[/color] ([color=BLUE]vlax-invoke[/color] sp 'addregion ([color=BLUE]list[/color] ob)))
                     cn ([color=BLUE]trans[/color] ([color=BLUE]vlax-get[/color] rg 'centroid) 1 0)
               )
               ([color=BLUE]vla-delete[/color] rg)
               ([color=BLUE]write-line[/color] ([color=BLUE]strcat[/color] ([color=BLUE]vla-get-handle[/color] ob) [color=MAROON]","[/color] ([color=BLUE]rtos[/color] ([color=BLUE]car[/color] cn)) [color=MAROON]","[/color] ([color=BLUE]rtos[/color] ([color=BLUE]cadr[/color] cn))) fd)
           )
           ([color=BLUE]vla-delete[/color] as)
           ([color=BLUE]close[/color] fd)
       )
   )
   ([color=BLUE]princ[/color])
)
([color=BLUE]vl-load-com[/color]) ([color=BLUE]princ[/color])

Posted

Something like this?

(defun c:pc ( / acdoc acspc acsel reg ) (vl-load-com) ;; © Lee Mac 2011

 (setq acdoc (vla-get-ActiveDocument (vlax-get-acad-object))
       acspc (vlax-get-property acdoc (if (= 1 (getvar 'CVPORT)) 'Paperspace 'Modelspace))
 )
 (if (ssget '((0 . "LWPOLYLINE") (-4 . "&=") (70 . 1)))
   (progn
     (vlax-for obj (setq acsel (vla-get-ActiveSelectionSet acdoc))
       (vlax-invoke acspc 'addpoint
         [color=magenta](print [/color](trans (vlax-get (setq reg (car (vlax-invoke acspc 'addregion (list obj)))) 'Centroid) 1 0)[color=magenta])[/color]
       )
       (vla-delete reg)
      [color=magenta](princ (cdr (assoc 5 (entget (vlax-vla-object->ename obj)))))[/color]
     )
     (vla-delete acsel)
   )
 )
 (princ)
)

Posted

PERFECT! Thank you so much! :D

Posted (edited)

For fun:

 

(defun c:EHC () (c:ExportHandleCentroid))
(defun c:ExportHandleCentroid  (/ *error* wcs ss path acApp acDoc oSpace
                               oShell file oRegion centroid)
 ;; RenderMan, 2012
 ;; Special thanks to Lee Mac for demonstrating the region functionality!
 (princ "\rEXPORTHANDLECENTROID ")
 (vl-load-com)

 (defun *error*  (msg)
   (if oShell
     (vlax-release-object oShell))
   (if file (close file))
   (if oRegion (vla-delete oRegion))
   (cond ((not msg))                                                   ; Normal exit
         ((member msg '("Function cancelled" "quit / exit abort")))    ; <esc> or (quit)
         ((princ (strcat "\n** Error: " msg " ** "))))                 ; Fatal error, display it
   (princ))

 (prompt "\nSelect polylines to extract handle and centroid: ")

 (if
   (and (setq wcs (= 1 (getvar 'worlducs)))
        (setq ss (ssget '((0 . "LWPOLYLINE") (70 . 1))))
        (setq path
               (strcat (vl-filename-directory (vl-filename-mktemp))
                       "\\Handles & Centroids.csv"))
        (setq acApp (vlax-get-acad-object))
        (setq acDoc (vla-get-activedocument acApp))
        (setq oSpace (vlax-get-property
                       acDoc
                       (if (= 1 (getvar 'cvport))
                         'paperspace
                         'modelspace)))
        (setq oShell
               (vla-getinterfaceobject acApp "Shell.Application")))
    (progn
      (setq file (open path "w"))
      (write-line "Handle, X, Y, Z" file)
      (vlax-for oPline (setq ss (vla-get-activeselectionset acDoc))
        (setq oRegion
               (car (vlax-invoke oSpace 'addregion (list oPline))))
        (setq centroid (trans (vlax-get oRegion 'centroid) 1 0))
        (vla-delete oRegion)
        (write-line
          (strcat (vla-get-handle oPline)
                  ","
                  (rtos (car centroid))
                  ","
                  (rtos (cadr centroid))
                  ","
                  (rtos (caddr centroid)))
          file))
      (setq file (close file))
      (setq oRegion nil)
      (vla-delete ss)
      (vlax-invoke oShell 'open path)
      (*error* nil))
    (cond
      (wcs (*error* "Nothing selected"))
      (ss (*error* "No file specified"))
      ((*error* "The current drawing is not in WCS"))))
 (princ))

Edited by BlackBox
Code revised
Posted
Something like this?

(defun c:pc ( / acdoc acspc acsel reg ) (vl-load-com) ;; © Lee Mac 2011

 (setq acdoc (vla-get-ActiveDocument (vlax-get-acad-object))
       acspc (vlax-get-property acdoc (if (= 1 (getvar 'CVPORT)) 'Paperspace 'Modelspace))
 )
 (if (ssget '((0 . "LWPOLYLINE") (-4 . "&=") (70 . 1)))
   (progn
     (vlax-for obj (setq acsel (vla-get-ActiveSelectionSet acdoc))
       (vlax-invoke acspc 'addpoint
         [color=magenta](print [/color](trans (vlax-get (setq reg (car (vlax-invoke acspc 'addregion (list obj)))) 'Centroid) 1 0)[color=magenta])[/color]
       )
       (vla-delete reg)
      [color=magenta](princ (cdr (assoc 5 (entget (vlax-vla-object->ename obj)))))[/color]
     )
     (vla-delete acsel)
   )
 )
 (princ)
)

 

I'm not sure that the centroid of a Region is the same as that which is calculated via the Polyline's BoundingBox. Also, why not simply extract the Handle Property from the Polyline Object, rather than convert Vla-Object to Ename, and pull from Entity Data? Just curious, my friend.

Posted

Renderman , one simple wrong in writing the variable name .

 

(if shell       (vlax-release-object shell))

 

Which must be oShell :)

Posted

Thanks, Tharwat! :beer: (... Thanks a lot, fat fingers! :lol:)

 

In addition to this correction, I've added support for 3D (Heavy) Polylines as well.

Posted
For fun:

 

Renderman, note that the center of the bounding box will rarely be equal to the centroid.

Posted
Thanks, Tharwat! :beer: (... Thanks a lot, fat fingers! :lol:)

 

 

Cheers buddy .

 

 

In addition to this correction, I've added support for 3D (Heavy) Polylines as well.

 

Very interesting indeed .:thumbsup:

Posted
In addition to this correction, I've added support for 3D (Heavy) Polylines as well.

 

Be careful of LType Gen ;)

Posted
Renderman, note that the center of the bounding box will rarely be equal to the centroid.

 

I was just testing that, and confirmed that both the BoundingBox for a rectangle, and an identical region are the same. However, a region in an irregular "L" shape also yields a centroid that is not equal to the inside center of the polyline on which the region is based either.

 

If memory serves, this is a topic we discussed in the past, and while I grant you that the region centroid is better, it's still lacking the true centroid of the polyline. This even holds true with Gile's OSNAP plug-in (i.e., 'CTR) unfortunately.

Posted
I was just testing that, and confirmed that both the BoundingBox for a rectangle, and an identical region are the same. However, a region in an irregular "L" shape also yields a centroid that is not equal to the inside center of the polyline on which the region is based either.

 

The rectangular (including square) case will be one of the few cases for which they are equal, since the bounding box will obviously be equal to the polyline. Other cases of equality would be where the shape is symmetrical, however in real-world applications, I'm sure that you will agree that such polylines will rarely be entirely rectangular or symmetrical.

 

If memory serves, this is a topic we discussed in the past, and while I grant you that the region centroid is better, it's still lacking the true centroid of the polyline.

 

What is the 'true centroid'?

Posted
(0 . "*POLYLINE") (-4 . "<NOT") (70 . 0) (-4 . "NOT>")

 

Note that this filter will allow the user to select open polylines with LType Gen on, and polyline meshes.

Posted

... however in real-world applications, I'm sure that you will agree that such polylines will rarely be entirely rectangular or symmetrical.

 

100% agree. :thumbsup:

 

What is the 'true centroid'?

 

The absolute center of any

[*]Polyline (within the entity), and not simply the half-sum of all of it's vertices which commonly resides outside of an entity (obviously varying by shape).

Posted
Note that this filter will allow the user to select open polylines with LType Gen on, and polyline meshes.

 

Always happy to not help :rofl:

 

Actually, I appreciate the point being clarified, as we only use dashed line types for existing features which are typically open. In any event, this may only be limited to our purposes, and others may suspect me of being the worst LISP coder ever. :geek:

Posted
The absolute center of any

[*]Polyline (within the entity), and not simply the half-sum of all of it's vertices which commonly resides outside of an entity (obviously varying by shape).

 

But the centroid isn't the "half-sum of all of it's vertices" - this will only yield the same result for regular polygons; here is how I calculate the centroid for a polygon - but again, this will lie outside for some polygons (L-shapes for example), but to my knowledge this is a property of the centroid definition.

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...