ClareSelley Posted July 2, 2012 Posted July 2, 2012 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. Quote
stevesfr Posted July 2, 2012 Posted July 2, 2012 @Clare, post the two lisps you found, or links, and we'll see if someone can "mash" the two together for you. cheers Quote
ClareSelley Posted July 2, 2012 Author Posted July 2, 2012 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. Quote
Lee Mac Posted July 2, 2012 Posted July 2, 2012 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]) Quote
MSasu Posted July 2, 2012 Posted July 2, 2012 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) ) Quote
BlackBox Posted July 2, 2012 Posted July 2, 2012 (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 July 3, 2012 by BlackBox Code revised Quote
BlackBox Posted July 2, 2012 Posted July 2, 2012 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. Quote
Tharwat Posted July 2, 2012 Posted July 2, 2012 Renderman , one simple wrong in writing the variable name . (if shell (vlax-release-object shell)) Which must be oShell Quote
BlackBox Posted July 2, 2012 Posted July 2, 2012 Thanks, Tharwat! (... Thanks a lot, fat fingers! ) In addition to this correction, I've added support for 3D (Heavy) Polylines as well. Quote
Lee Mac Posted July 2, 2012 Posted July 2, 2012 For fun: Renderman, note that the center of the bounding box will rarely be equal to the centroid. Quote
Tharwat Posted July 2, 2012 Posted July 2, 2012 Thanks, Tharwat! (... Thanks a lot, fat fingers! ) Cheers buddy . In addition to this correction, I've added support for 3D (Heavy) Polylines as well. Very interesting indeed . Quote
asos2000 Posted July 2, 2012 Posted July 2, 2012 3 Types of output attached dwg and csv files TST.zip Quote
Lee Mac Posted July 2, 2012 Posted July 2, 2012 In addition to this correction, I've added support for 3D (Heavy) Polylines as well. Be careful of LType Gen Quote
BlackBox Posted July 2, 2012 Posted July 2, 2012 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. Quote
Lee Mac Posted July 2, 2012 Posted July 2, 2012 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'? Quote
Lee Mac Posted July 2, 2012 Posted July 2, 2012 (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. Quote
BlackBox Posted July 2, 2012 Posted July 2, 2012 ... however in real-world applications, I'm sure that you will agree that such polylines will rarely be entirely rectangular or symmetrical. 100% agree. 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). Quote
BlackBox Posted July 2, 2012 Posted July 2, 2012 Note that this filter will allow the user to select open polylines with LType Gen on, and polyline meshes. Always happy to not help 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. Quote
Lee Mac Posted July 2, 2012 Posted July 2, 2012 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. 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.