Discussion of other Lisp dialects (Arc, Clojure, AutoLisp, XLISP, etc.)
-
michielmm
- Posts: 2
- Joined: Tue Oct 11, 2011 9:37 pm
Post
by michielmm » Tue Oct 11, 2011 9:47 pm
Hi all,
I am rather new to AutoLISP and I'm still learning how to properly program it. I am running a AutoLISP to generate a field of circular polylines with position x,y and radius R read from a (user-selected) file.
At the moment I read the file completely before I start generating the polylines, but this causes me to run into the error "internal stack limit reached (simulated)". If I understood correctly, this means that I try to have to much in the memory at the same time, right?!
What I would like to do to get rid of this problem is to read the file line-by-line and write a polyline for each line immediately so that I only have to keep single lines in stack.
Can somebody help me/give me some pointers on how to adapt the code below to do this?!
Thanks!
Code: Select all
;; convert string to list of strings
(defun strlist (strExp strDel / strLst)
(while (setq pos (vl-string-position (ascii strDel) strExp))
(setq itm (substr strExp 1 pos))
(setq strLst (append strLst (list itm)))
(setq strExp (substr strExp (+ pos 2)))
)
(setq strLst (append strLst (list strExp)))
)
; read file
(defun readfile (fname / line)
(if (setq line (read-line fname))
(if (eq "" line)
(readfile fname)
(cons ( strlist (vl-string-trim " " line) " ") (readfile fname))
)
)
)
;main prog
(defun C:CONN (/ adata fd fname itema)
(setq fd (getfiled "* Select \"PointA\" Data File *" (getvar "dwgprefix") "txt" 8))
(setq fname (open fd "R"))
(setq adata (readfile fname))
(close fname)
(setq adata (mapcar (function (lambda(x)(vl-string-subst " " "\t" (car x)))) adata)
adata (mapcar (function (lambda(x)(vl-string-subst " " "\t" x))) adata)
adata (mapcar (function (lambda(x)(strlist x " "))) adata)
adata (mapcar (function (lambda (x)
(mapcar 'atof
(mapcar (function (lambda (y)
(vl-string-subst "." "," y))) x))))
adata)
)
(while (setq itema (car adata))
(entmake (list
'(0 . "LWPOLYLINE")
'(100 . "AcDbEntity")
(cons 410 (getvar "CTAB"))
'(8 . "0")
'(62 . 7)
'(100 . "AcDbPolyline")
'(90 . 2)
'(70 . 1)
(cons 43 0.5)
(cons 10 (list (- (car itema)(/ (caddr itema) 2)) (cadr itema)))
'(42 . 1.0)
(cons 10 (list (+ (car itema)(/ (caddr itema) 2 )) (cadr itema)))
'(42 . 1.0)
(cons 210 (list 0.0 0.0 1.0))))
(setq adata (cdr adata))
)
(command "._zoom" "_e")
(princ)
)
-
michielmm
- Posts: 2
- Joined: Tue Oct 11, 2011 9:37 pm
Post
by michielmm » Thu Oct 13, 2011 1:50 pm
Hi all,
Just for the benefit of others: I solved the issue. I decided to learn a little more about LISP and rewrite the code altogether. Here it is:
Code: Select all
;;==============START OF THE ACTUAL CODE============================================================
;===================================================================================================
;= Function PARSE_NUMS (string)
;= Arguments: string - Text string to be comma parsed
;= Returns: A list of the elements of the string converted to numbers
;= Copyright Jeff Winship 2003. All rights reserved.
;= www.pixelgraphicsinc.com
;==========================================================================================30/3/2003
(defun parse_nums (st / a k lst)
(setq k 1)
(setq a "")
(setq lst nil)
(repeat (strlen st)
(if (= (substr st k 1) ",")
(progn
(setq lst (append lst (list (atof a))))
(setq a "")
)
(setq a (strcat a (substr st k 1)))
)
(setq k (+ k 1))
)
(setq lst (append lst (list (atof a))))
)
;=========================================================================================================
;= Main Function C:rndfield
;= Arguments: none (prompts for user selected file)
;= Returns: plotted circles of radius R at x and y positions as described in the file (x,y,R)
;=
;= IMPORTANT NOTE, READ BEFORE USE:
;= For some reason my version of AutoCAD (2010) fails if this LISP routine and the .txt file are in the
;= folder. I do not know why, but it might be a problem for other AutoCAD versions as well.
;= MAKE SURE THAT THE .txt FILE IS IN A DIFFERENT FOLDER THAN THE LISP FILE (SUBFOLDER IS ALSO WORKING)
;================================================================================================12/10/2011
(defun C:rndfield (/ dataline line fname fd)
; Prompt user to pick the input file, which should be .txt
(setq fd (getfiled "* Select \"Pillar Construction\" Data File *" (getvar "dwgprefix") "txt" 8))
; Actually open the filename for reading and give it fname as handle
(setq fname (open fd "R"))
(setq dataline (read-line fname)) ;read the first line of data
(while (/= dataline "EOF") ;the EOF should be included as last line in the datafile!!!
(setq dataline (parse_nums dataline)) ;reformat the data to a CAD readable list
;operations to generate a circle at location dataline(1), dataline(2) with radius dataline(3)
;the normal circle command is not used, because outputcity prefers to have polylines
(entmake (list
'(0 . "LWPOLYLINE")
'(100 . "AcDbEntity")
(cons 410 (getvar "CTAB"))
'(8 . "0")
'(62 . 7)
'(100 . "AcDbPolyline")
'(90 . 2)
'(70 . 1)
(cons 43 0.5)
(cons 10 (list (- (car dataline)(/ (caddr dataline) 2)) (cadr dataline)))
'(42 . 1.0)
(cons 10 (list (+ (car dataline)(/ (caddr dataline) 2 )) (cadr dataline)))
'(42 . 1.0)
(cons 210 (list 0.0 0.0 1.0))))
;end of the operation
(setq dataline (read-line fname)) ;read a new line
)
; Close the file
(close fname)
; Zoom to fit all structures on the screen
(command "._zoom" "_e")
; Print empty line to avoid `nil' response from the LISP routine
(princ)
)
;Print this command in the commandline of AutoCAD as instruction on how to execute
(princ "\n\t\t***\tType rndfield to execute\t***")
(princ)