Autolisp - write polylines in txt file

Autolisp - write polylines in txt file

Anonymous
Not applicable
2,450 Views
11 Replies
Message 1 of 12

Autolisp - write polylines in txt file

Anonymous
Not applicable

Hello,

 

in this case I have different polylines and each was drawn in its own corresponding layer. I want to get the coordinates of the points of the plines written in a txt file. 

(defun polyout()

(setq i 0)			;Zählschleife  
(setq Polycoordinates (open "C:/Temp/Polycoordinates.tmp" "w"))
(setq CEbenenfile (open "C:/Temp/CEbenen.tmp" "r"))

(while (< i Mc)		;while-Schleife zum Einlesen der C-Ebenen
(progn
	(setq zeileCE_string (read-line CEbenenfile))
	(if zeileCE_string	;Abfrage ob Wert in txt drin steht
	(progn
		(setq zeileCE_wert (atof zeileCE_string))	
	
		(setq lay_current 
					(strcat 
						"C"
						(AddLeadingZeros (rtos zeileCE_wert 2 0) 3)          	;z.B. C000-Ebene
						"-EBENE"
					);strcat
		);SETQ

		(if (setq sset (ssget "X" '((0 . "LWPOLYLINE,POLYLINE"))))
		(progn
			(setq ed (entget (sset)))
			(setq p (cdr (assoc 10 ed)))
			(write-line p Polycoordinates)		
		);PROGN
		);IF
		
	);PROGN
	);IF
	(setq i (+ i 1))
);PROGN	
);WHILE
(close CEbenenfile)
(close Polycoordinates)


);DEFUN

The code before  >>

(if (setq sset (ssget "X" '((0 . "LWPOLYLINE,POLYLINE"))))

<< is correct. So choosing the layer is working. I just don't know how the get the information of the polylines in a txt.

0 Likes
Accepted solutions (1)
2,451 Views
11 Replies
Replies (11)
Message 2 of 12

Ranjit_Singh
Advisor
Advisor

Hi ruppelr. I cannot understand all the comments. Can you explain what you are trying to do. I see there is a file to be read from and one you are writing to. I am confused because the title suggests you are selecting some polylines in the drawing and writing out their co-ordinates. What are we reading form the CEbenen.tmp file? Provide some more information what you are trying to achieve. Maybe post a format of the desired output file and/or input file?

0 Likes
Message 3 of 12

Kent1Cooper
Consultant
Consultant

@Anonymous wrote:

..... 

....
(if (setq sset (ssget "X" '((0 . "LWPOLYLINE,POLYLINE")))) (progn (setq ed (entget (sset))) (setq p (cdr (assoc 10 ed))) (write-line p Polycoordinates) );PROGN );IF ....

..... I just don't know how the get the information of the polylines in a txt.


You can't use (entget) on a selection set [not to mention that sset there should not be in parentheses], but only on an entity name, which needs to be pulled out of the selection set  And even correcting for that, the above will only get you the first vertex.  Try something like this [untested]:

  (if (setq sset (ssget "X" '((0 . "LWPOLYLINE"))))
    (repeat (setq n (sslength sset))
      (setq ed (entget (ssname sset (setq n (1- n)))))
      (foreach pt ; list of vertex locations
        (mapcar 'cdr ; strip 10's off of entity data stripped down to:
          (vl-remove-if-not
            '(lambda (x) (= (car x) 10)); keep vertex entries only
            ed
          ); ...remove...
        ); mapcar
        (write-line pt Polycoordinates)
      ); foreach
    ); repeat
  ); if

Notice that I limited it to LWPolylines, because "heavy" Polylines don't store vertex locations in the same way.  That can be overcome if you need it, but it's more complicated.

 

[I haven't tested whether writing a point list of numbers works with (write-line), without converting that to a text string, or perhaps using (princ)/(print)/(prin1) instead, but try it.  If it doesn't work, that can also be overcome, but will likewise take more code.  If it does work, it will give you the lists in parentheses, which can also be stripped off if you need that.]

Kent Cooper, AIA
0 Likes
Message 4 of 12

Anonymous
Not applicable

Hello Kent,

 

thank you for that. Unfortunately. As you mentioned there is some trouble converting the Points into string - but I have no experience with VisualLisp...

 

		(if (setq sset (ssget "X" '((0 . "LWPOLYLINE"))))
			(repeat (setq n (sslength sset))
			(setq ed (entget (ssname sset (setq n (1- n)))))
			(foreach pt ; list of vertex locations
			(mapcar 'cdr ; strip 10's off of entity data stripped down to:
				(vl-remove-if-not
					'(lambda (x) (= (car x) 10)); keep vertex entries only
					ed
				); ...remove...
			); mapcar
			
			(setq pt_string (rtos pt 2 3))
			(write-line pt_string Polycoordinates)
			
			); foreach
			); repeat
		);IF

The first point of the pline was displayed on the screen. So the Loop was worked out just one time.

 

 

This is the result I get after the first point:

bad Argument type: numberp:Nil

 

The aim is to get the Points in a txt file not to Screen it 😕

 

 

   

0 Likes
Message 5 of 12

Anonymous
Not applicable

Hi Ranjit,

 

sorry for that. You don't Need to think about the CEbenen and Addleadingzeros. This is Little bit to difficult to explain and would go beyond the scope.

There are only for choosing the right layer and this is working properly 🙂

 

 

0 Likes
Message 6 of 12

Ranjit_Singh
Advisor
Advisor

I am still unlclear on the original code. However, try the below. It should output co-ordinates to a file of your choice. You may want to add error trap.

 

(defun c:polyout  (/ entdata ss1 file1)
 (if (and (setq ss1 (ssget '((0 . "POLYLINE,LWPOLYLINE"))))
          (setq file1 (getfiled "Save output file as" "" "" 1))
          (setq file1 (open file1 "w")))
  (mapcar '(lambda (x)
            (cond ((= (cdr (assoc 0 x)) "LWPOLYLINE")
                   (mapcar '(lambda (x) (write-line (strcat (rtos (cadr x)) "," (rtos (caddr x))) file1))
                           (vl-remove-if-not '(lambda (y) (= (car y) 10)) x)))
                  ((setq entdata (entget (entnext (cdr (assoc -1 x)))))
                   (while (/= "SEQEND" (cdr (assoc 0 entdata)))
                    (write-line (strcat (rtos (cadr (assoc 10 entdata))) "," (rtos (caddr (assoc 10 entdata))))
                                file1)
                    (setq entdata (entget (entnext (cdr (assoc -1 entdata)))))))))
          (mapcar '(lambda (x) (entget (cadr x))) (cdr (reverse (ssnamex ss1)))))) ; if
 (close file1)
 (setq file1 ())
 (gc)
 (princ))

 

0 Likes
Message 7 of 12

Anonymous
Not applicable

Thank you for that, Ranjit. Is it possible to make this routine automatically choosing the right polyline in the right layer?

 

As you can see I already did an while-loop where the right layer is set to search in it. I need now the code to choose the polyline in this layer and save the coordinates in the txt file.

 

I tried the dollowing code, but still without success.

 

(defun polyout()

(setq i 0)			;Zählschleife  
(setq Polycoordinates (open "C:/Temp/Polycoordinates.tmp" "w"))
(setq CEbenenfile (open "C:/Temp/CEbenen.tmp" "r"))

(while (< i Mc)		;while-Schleife zum Einlesen der C-Ebenen
(progn
	(setq zeileCE_string (read-line CEbenenfile))
	(if zeileCE_string	;Abfrage ob Wert in txt drin steht
	(progn
		(setq zeileCE_wert (atof zeileCE_string))	
	
		(setq lay_current 
					(strcat 
						"C"
						(AddLeadingZeros (rtos zeileCE_wert 2 0) 3)          	;z.B. C000-Ebene
						"-EBENE"
					);strcat
		);SETQ

		(write-line lay_current Polycoordinates)
		
		(if (setq sset (ssget "X" (list '(0 . "LWPOLYLINE") (cons 8 lay_current))))
		(progn	
			(repeat (setq n (sslength sset))
				
				(setq ed (entget (ssname sset (setq n (1- n)))))
				
				(foreach pt ; list of vertex locations
					(mapcar 'cdr ; strip 10's off of entity data stripped down to:
						(vl-remove-if-not
							'(lambda (x) (= (car x) 10)); keep vertex entries only
							ed
						); ...remove...
					); mapcar
				
			); repeat
			

		);PROGN	
		);IF
		
			(setq cnt 0)
			(repeat (length pt) ; length=gibt Ganzzahl zurück, welche der Anzahl Elemente von selset entspricht
				(setq nme (nth cnt pt))  ;nth gibt das n-te Element (cnt) einer Liste (pt) zurück
				(prin1 nme Polycoordinates)
				(setq cnt (1+ cnt)) 
				;(prin1 nme Polycoordinates)
			);REPEAT
		
	);PROGN
	);IF
	(setq i (+ i 1))
);PROGN	
);WHILE
(close CEbenenfile)
(close Polycoordinates)


);DEFUN
0 Likes
Message 8 of 12

Ranjit_Singh
Advisor
Advisor

Do you want to output only polylines that are on a specific layer? Or do you want to output all polylines in the drawing but have them sorted by layer?

0 Likes
Message 9 of 12

dbroad
Mentor
Mentor

In

(while (< i Mc)

where is Mc set?

Architect, Registered NC, VA, SC, & GA.
0 Likes
Message 10 of 12

Ranjit_Singh
Advisor
Advisor
Accepted solution

Not sure what is the right polyline and the right layer? Can you explain the logic that determines the right polyline and the right layer. If you simply want all polylines to be grouped out by layer then try this modified version of the code I posted previously. This will not ask you to select any polylines, but simply output all polylines by  layer names

 

Spoiler
(defun c:polyout  (/ a laylst entdata ss1 file1)
 (setq file1 (open (getfiled "Save output file as" "" "" 1) "w")
       a     (tblnext "LAYER" T))
 (while a (setq laylst (cons (cdr (assoc 2 a)) laylst)) (setq a (tblnext "LAYER")))
 (mapcar '(lambda (y)
           (if (setq ss1 (ssget "_x" (list (cons 0 "POLYLINE,LWPOLYLINE") (cons 8 y))))
            (progn (write-line (strcat "Layer Name: " y) file1)
                   (mapcar '(lambda (x)
                             (cond ((= (cdr (assoc 0 x)) "LWPOLYLINE")
                                    (mapcar '(lambda (x) (write-line (strcat (rtos (cadr x)) "," (rtos (caddr x))) file1))
                                            (vl-remove-if-not '(lambda (y) (= (car y) 10)) x))
                                    (write-line "" file1))
                                   ((setq entdata (entget (entnext (cdr (assoc -1 x)))))
                                    (while (/= "SEQEND" (cdr (assoc 0 entdata)))
                                     (write-line (strcat (rtos (cadr (assoc 10 entdata))) "," (rtos (caddr (assoc 10 entdata))))
                                                 file1)
                                     (setq entdata (entget (entnext (cdr (assoc -1 entdata))))))
                                    (write-line "" file1))))
                           (mapcar '(lambda (x) (entget (cadr x))) (ssnamex ss1))))) ; if
           )
         (reverse laylst))
 (close file1)
 (setq file1 ())
 (gc)
 (princ))
0 Likes
Message 11 of 12

john.uhden
Mentor
Mentor

You are getting excellent help from excellent contributors.  Praise them.

Does precision, LUPREC, make any difference, 4 places, 6 places, 10 places, 16 places (max)?

How about LUNITS?

We all want your solution to be the best that you can expect.

It seems to me that your intended use of the textual data might make a big difference.

Enlighten us as to how you would use the file(s).  I was thinking that maybe just DXFOUT might work.

Oooh, have you any regard for bulged segments, or closure, or curve fitted?

John F. Uhden

0 Likes
Message 12 of 12

Anonymous
Not applicable

My project is splitted into two steps: First reading in a txt file and draw polylines on the basis of this information in AutoCAD, to modify them afterwards (first lsp program). In the second step giving out the polylines back to another txt. file (second lsp. program, which I was looking for).

 

Mc is the number of layers. (e.g. Mc = 24, but this number variates to the txt file, which I want to read in and is saved in the Header of the CEbenen file). The layer names are generated out of a combination of the numbers saved in the CEbenen-file (e.g. (Header,..,) 0,15,30...,360).

 

Addleadingzeros is to standardizate the layer names: (C000-Ebene, C095-Ebene, C180-Ebene)

 

(defun AddLeadingZeros (a d / b)
(strcat (substr "000000000" 1 (if (>= d (setq b (strlen (itoa (fix (atof a)))))) (- d b) 0))a)
);defun

 

 

0 Likes