Polyline Start and End XYZ to text file

Polyline Start and End XYZ to text file

Anonymous
Not applicable
1,844 Views
13 Replies
Message 1 of 14

Polyline Start and End XYZ to text file

Anonymous
Not applicable

Hi,

 

I'm new to Auto CAD and Auto LISP, so be gentle...

 

I'm trying to put together a LISP to generate a csv or txt file of selected polylines start and End XYZ points which can be sorted in order by the Start X point.

 

The output should be

start x, start y, start z, end x, end y, end x

 

I have seen different examples of what I'm trying to do and have tried modifying these with out any success

 

Any help would be greatly appreciated!

0 Likes
1,845 Views
13 Replies
Replies (13)
Message 2 of 14

JBerns
Advisor
Advisor

@Anonymous,

 

Please post the code you have developed  to date.

 

Will the polylines always be Open type?

 

After processing the selection set in AutoCAD (collect polylines, get start/end points, and write to CSV), I would use the sort tools in Excel.

 

Looking forward to your reply.

 

 

Regards,

Jerry

-----------------------------------------------------------------------------------------
CAD Administrator
Using AutoCAD & Inventor 2025
Autodesk Certified Instructor
Autodesk Inventor 2020 Certified Professional
Autodesk AutoCAD 2017 Certified Professional
0 Likes
Message 3 of 14

Anonymous
Not applicable

@JBerns 

 

Thanks for the reply.

 

Polylines will be Open

 

Below is what i found posted on here by someone else (cant remember who, sorry!)and tweaked to fit my needs

 

(defun c:crb ( / ss f file start end s xs ys zs xe ye ze)
(vl-load-com)
(setq ss (ssget "X" '((0 . "LWPOLYLINE"))))
(setq f (getfiled "Enter Filename" )(getvar "dwgname") file (open f "w") s (vla-get-activeselectionset (vla-get-activedocument (vlax-get-acad-object))))

(vlax-for poly s
(setq
start (vlax-curve-getstartpoint poly)
end (vlax-curve-getendpoint poly)
start (mapcar 'set '(xs ys zs) start)
end (mapcar 'set '(xe ye ze) end)
xs (rtos xs 2 4)
ys (rtos ys 2 4)
zs (rtos zs 2 4)
xe (rtos xe 2 4)
ye (rtos ye 2 4)
ze (rtos ze 2 4)
)
(write-line (strcat xs "," ys "," zs "," xe "," ye "," ze) file)
)
(close file)
(princ)
)

0 Likes
Message 4 of 14

GeeHaa
Collaborator
Collaborator

This might work for you. Beware of the file it writes too. Be sure to change it so it doesn't overwrite any file with the NAME POLYOUTxxx. I didn't have the time to make it check to see if the file exists.

0 Likes
Message 5 of 14

Anonymous
Not applicable

@GeeHaa 

 

Thanks for the reply, but...

 

I cant find or see where the written file is?!

0 Likes
Message 6 of 14

JBerns
Advisor
Advisor

@Anonymous,

 

I modified your code to resolve some errors.

 

The sample drawing contained lines, not polylines. The new code warns if no polylines found.

The original GETFILED statement was trying to open a CSV file instead of creating a CSV file.

Added checks to ensure valid selection set, new filename for CSV, and file can be opened for writing.

Report if export was successful.

 

Here is the code:

 

(defun c:crb (/ ss f file start end s xs ys zs xe ye ze)
  ;; load Visual LISP
  (vl-load-com)
  ;; select polylines
  (setq ss (ssget "X" '((0 . "LWPOLYLINE"))))
  ;; if selection set found
  (if ss
    (progn
      ;; get CSV file name
      (setq
	f (getfiled "Enter CSV filename" (getvar "dwgprefix") "CSV" 1)
      )
      ;; test for success
      (if f
	(progn
	  ;; open file for writing
	  (setq file (open f "w"))
	  ;; test for success
	  (if file
	    (progn
	      (setq
		s (vla-get-activeselectionset
		    (vla-get-activedocument (vlax-get-acad-object))
		  )
	      ) ;_setq
	      (vlax-for	poly s
		(setq
		  start	(vlax-curve-getstartpoint poly)
		  end	(vlax-curve-getendpoint poly)
		  start	(mapcar 'set '(xs ys zs) start)
		  end	(mapcar 'set '(xe ye ze) end)
		  xs	(rtos xs 2 4)
		  ys	(rtos ys 2 4)
		  zs	(rtos zs 2 4)
		  xe	(rtos xe 2 4)
		  ye	(rtos ye 2 4)
		  ze	(rtos ze 2 4)
		) ;_setq
		(write-line
		  (strcat xs "," ys "," zs "," xe "," ye "," ze)
		  file
		) ;_write-line
	      ) ;_vlax-for
	      (close file)
	      (princ "Export complete.")
	    ) ;_progn
	    (alert "Unable to open CSV file for writing.")
	  ) ;_if
	) ;_progn
	(alert "Unable to create CSV file.")
      ) ;_if
    ) ;_progn
    (alert "No polylines found in drawing.")
  ) ;_if
  (princ)
)

 

Open the code above in VLIDE and use the format tool to correct indentations.

 

I did not thoroughly check the accuracy of the exported values, but after a quick look, it appeared okay.

 

I welcome your feedback.

 

 

Regards,

Jerry

-----------------------------------------------------------------------------------------
CAD Administrator
Using AutoCAD & Inventor 2025
Autodesk Certified Instructor
Autodesk Inventor 2020 Certified Professional
Autodesk AutoCAD 2017 Certified Professional
0 Likes
Message 7 of 14

Anonymous
Not applicable

@JBerns 

 

Thanks for tidying up my code, that works fine!

 

If only now i could get the output list sorted by Start X point

0 Likes
Message 8 of 14

JBerns
Advisor
Advisor

@Anonymous,

 

Try this code to improve the GETFILED statement:

_$ (getfiled "Enter CSV filename" (vl-filename-base (getvar "dwgname")) "CSV" 1)

 

I have been unable to set a default filename based on the current drawing's path (dwgprefix). 

Perhaps someone else can assist.

 

How often do you need to export this sorted list?

If infrequently, use the sort tool in Excel.

You could "write" the column headers to the CSV file to make it easier to sort in Excel.

 

If you need to export CSV files often and want them sorted before export, I think you will need to use lists.

Lee Mac (http://www.lee-mac.com/ ) may have some useful code to help with list sorting.

 

 

Regards,

Jerry

-----------------------------------------------------------------------------------------
CAD Administrator
Using AutoCAD & Inventor 2025
Autodesk Certified Instructor
Autodesk Inventor 2020 Certified Professional
Autodesk AutoCAD 2017 Certified Professional
0 Likes
Message 9 of 14

JBerns
Advisor
Advisor

@Anonymous,

 

If this code has been helpful, I would welcome if you would Mark as Solved.

 

Kind regards,

Jerry

-----------------------------------------------------------------------------------------
CAD Administrator
Using AutoCAD & Inventor 2025
Autodesk Certified Instructor
Autodesk Inventor 2020 Certified Professional
Autodesk AutoCAD 2017 Certified Professional
0 Likes
Message 10 of 14

nislam04
Participant
Participant
Hello sir,
I hope you are doing fine.
 
How can I put a comma after Z1 (Start Z) please. I attached my version of the file here.
 

Regards,

 

Engr. Md. Nurul Islam
B.Sc. Engineer (Civil)

= = = = =  = = = = = = = = = = = =

 

 

 

0 Likes
Message 11 of 14

john.uhden
Mentor
Mentor

I was thinking that the code, though quite good, could be streamlined a little

 

(substr (apply 'strcat (mapcar '(lambda (x)(strcat "," (rtos x 2 4))(apply 'append start end)))) 2)
;; Oops, forgot the b.

 

Though I don't have any AutoCAD working to test it.

John F. Uhden

0 Likes
Message 12 of 14

JBerns
Advisor
Advisor

@john.uhden,

Where should this code change be applied?

-----------------------------------------------------------------------------------------
CAD Administrator
Using AutoCAD & Inventor 2025
Autodesk Certified Instructor
Autodesk Inventor 2020 Certified Professional
Autodesk AutoCAD 2017 Certified Professional
0 Likes
Message 13 of 14

john.uhden
Mentor
Mentor

There is no need to use my suggestion instead of what's there.  I was just demonstrating other methods using a couple of functions that many are not familiar or comfortable with.

What was written is easier to understand anyway.

John F. Uhden

0 Likes
Message 14 of 14

JBerns
Advisor
Advisor

@nislam04,

 

I used the VLIDE 'Format' tool to improve readability of your posted code.

Here are the changes I made to add a comma (,) after the Z1 value:

 

Original:

(if (= tip "LWPOLYLINE")
  (while (setq eg (member (assoc 10 eg) eg))
    (setq ;|a000|;
          pnt (cdr (car eg))
          $rr (cons (dfn_ent_point10 "2,3" pnt) $rr)
          eg  (cdr eg)
    )
  )
)

Modified:

(if (= tip "LWPOLYLINE")
  (while (setq eg (member (assoc 10 eg) eg))
    (setq ;|a000|;
          pnt (cdr (car eg))
          $rr (cons (strcat (dfn_ent_point10 "2,3" pnt) ",") $rr)
	  eg  (cdr eg)
    );_setq
  );_while
);_if

 

This resulted in an extra comma after the last coordinate.

I added code to remove the extra comma from the first element in the $rr list.

Here are the code changes:

Original:

(if (/= $rr nil)
  (setq ;|a000|;
        tmp (apply (read rst) (reverse $rr))
        fly (open fna "a")
        nop (write-line tmp fly)
        nop (close fly)
  )
)

Modified:

(if (/= $rr nil)
  (progn
    ;; remove "," from first element in list
    (if (= (substr (car $rr) (strlen (car $rr)) 1) ",")
      (setq
	$rr (LM:SubstNth
	      (substr (car $rr) 1 (1- (strlen (car $rr)))) ;; first element in list with ending "," removed
	      0                                            ;; position 0 in $rr list
	      $rr                                          ;; the list
	    );_LM:SubstNth
      );_setq
    );_if
    ;;
    (setq ;|a000|;
          tmp (apply (read rst) (reverse $rr))
	  fly (open fna "a")
	  nop (write-line tmp fly)
	  nop (close fly)
    );_setq
  );_progn
);_if

 

I used (and credited) code from Lee Mac ( @Lee_Mac ) to substitute the first element in the list with the string that has had the extra comma removed.

Source: http://www.lee-mac.com/substn.html 

;;---------------------=={ Subst Nth }==----------------------;;
;; ;;
;; Substitutes an item at the nth position in a list. ;;
;;------------------------------------------------------------;;
;; Author: Lee Mac, Copyright © 2011 - www.lee-mac.com ;;
;;------------------------------------------------------------;;
;; Arguments: ;;
;; a - item to substitute ;;
;; n - position in list to make the substitution ;;
;; l - list in which to make the substitution ;;
;;-----------------------------------------------------Show more-------;;
;; Returns: Resultant list following the substitution ;;
;;------------------------------------------------------------;;
(defun LM:SubstNth ( a n l / i )
(setq i -1)
(mapcar '(lambda ( x ) (if (= (setq i (1+ i)) n) a x)) l))

 

Be advised - your code does not output the correct Z value for LWPolylines that are not at elevation Z=0.

 

I have attached the code with my changes shown above.

 

I hope this is helpful. Please mark as solution if this answers your request.

 

Regards,

Jerry

-----------------------------------------------------------------------------------------
CAD Administrator
Using AutoCAD & Inventor 2025
Autodesk Certified Instructor
Autodesk Inventor 2020 Certified Professional
Autodesk AutoCAD 2017 Certified Professional
0 Likes