ScribbleJ Posted December 17, 2008 Posted December 17, 2008 I've just re-sparked my interest in writing Lisp routines since I have the need to automate some of my task. One of which at the moment is inserting multiple blocks into a drawing based on a list of coordinates. The only problem I'm having now is I can't seem to make it work nor have I been successful in finding one in my search on the internet. I have found several great sites that are a great help with lisp My goal is to create a defun command that will loop itself and just retrieve the coordinates from a text file I have created with LDD points export. But since my experience is lacking and I'm just getting back into it I have not been able to create this type of lisp. It seems (in theory) to be a simple and straight forward Lisp but so far with my lack of knowledge it has been a total flop. In a nutshell I have a text file with well over 200 coordinates that I want to insert blocks at and I would like to create a lisp routine that references this list of coordinates for each insertion point. Here is what I have so far (which is not much). (defun C:ITREE () (command "Insert" "Tree" "1" "1" "0" "") Where would I create the loop for this and where do I put the (setq file (open "testfile.txt" "r")) part? Would it look something like this? (defun C:ITREE () (command "Insert" "Tree" "1" "1" "0" (setq file (open "testfile.txt" "r")) "") Or am I completely out in space somewhere? Scribbs Quote
Lee Mac Posted December 17, 2008 Posted December 17, 2008 Don't know if this would work? (defun c:ITREE (/ *error* file1) (defun *error* (msg) (setvar "cmdecho" 1) (if (= msg "") (princ "\nFunction Complete.") (princ "\nError or Esc Pressed.") ) ;_ end if ) ;_ end defun (selfile) (setvar "cmdecho" 0) (setq file1 (open file "r")) (while (/= (read-line file1) nil) (command "-insert" "C:\\" ;<<< --- INSERT BLOCK FILEPATH HERE (read-line file1) "" "" "0" ) ;_ end command ) ;_ end while (*error* "") (princ) ) ;_ end defun (defun selfile () (setq file (getfiled "Select a Text File" "C:/" "csv" 9 ) ;_ end getfiled ) ;_ end setq ) ;_ end defun Quote
BIGAL Posted December 18, 2008 Posted December 18, 2008 As Lee Mac is saying you must open the file first then run a loop to read a line at a time and insert a block. Repeat till end of file is reached. Quote
ScribbleJ Posted December 18, 2008 Author Posted December 18, 2008 Wow! This is way more than I would have imagined it would be to such (seemly) simple process. Even though I have trouble creating lisp from scratch I can read them and understand what they can do. Most of the time. This one looks like it will work Lee. I appreciate your time. I will try this out as soon as I get to work in the morning. I could VPN but I'm too damn tired at the moment. I really look forward to learning how to get to this point in writing lisp myself. Thanks again Lee. BIGAL what you said makes perfect since to me after reading what Lee Mac added. BTW how do you put the code in a neat frame like that? I do understand HTML but I have not gotten this complex with it. Thanks Scribs Quote
Lee Mac Posted December 18, 2008 Posted December 18, 2008 Hi Scribble, Thanks for your message, just wrap your code in [ code] [/ code] tags (without the spaces), to put it in the frame. Or, alternatively, select all your code and click on the # button on the post text editor. Quote
Lee Mac Posted December 18, 2008 Posted December 18, 2008 Wow! This is way more than I would have imagined it would be to such (seemly) simple process. It could probably be made simpler by using a default text file (iradicating the need for the separate (defun selfile) program. Also, I have added an error handler which makes it look more complicated than it is. In writing it, I wasn't sure if you were after a LISP to insert a single block numerous times, or lots of different blocks at lots of different coordinates - if it was the latter, obviously the LISP will need to be altered somehwhat. Also, one more thing, I have left the filepath for the block blank, but remember (and you probably know this already) to use a double backslash \\ to indicate the single backslash \. i.e. C:\\Users\\Lee Mac\\Documents\\block.dwg Quote
Lee Mac Posted December 18, 2008 Posted December 18, 2008 EDIT: posted LISP updated - forgot to localise the *error* Quote
ScribbleJ Posted December 18, 2008 Author Posted December 18, 2008 It could probably be made simpler by using a default text file (iradicating the need for the separate (defun selfile) program. Also, I have added an error handler which makes it look more complicated than it is. Yeah I noticed that. I'm glad you added that because now I know how the syntax looks. In writing it, I wasn't sure if you were after a LISP to insert a single block numerous times, or lots of different blocks at lots of different coordinates - if it was the latter, obviously the LISP will need to be altered somewhat.The former is correct. I just wanted to be able to place one tree block on each coordinate so we can show which trees would need to be cut down. For instance a block of a tree with an X through it to denote demolition. Also, one more thing, I have left the filepath for the block blank, but remember (and you probably know this already) to use a double backslash \\ to indicate the single backslash \. i.e. C:\\Users\\Lee Mac\\Documents\\block.dwg Actually I did not know this. Thanks for the heads-up. Does the format of the file with the coordinates matter? From what I can tell it will except the file format of the coordinates as the command expects them to see them. (i.e. x,y or y,x) Does this read the entire set of coordinates all at once and store them in memory or does it read them one line at a time? If the latter how does it know to move onto the next line after it places the block? If you don't mind would you comment on each line of code starting at the (selfile) so that I can wrap my head around it and turn this into a greater learning process? Some of it I understand but a few lines I do not because I am not familiar with some of the operators and arguments. Thanks Scribs Quote
Lee Mac Posted December 18, 2008 Posted December 18, 2008 Ok, first I will admit - I have never used this method for inserting a block into a drawing and haven't actually tested my posted LISP yet either. But I read something about the read-line command earlier that day and thought I'd try and use it. But I'll help as much as I can. Does the format of the file with the coordinates matter? From what I can tell it will except the file format of the coordinates as the command expects them to see them. (i.e. x,y or y,x) Does this read the entire set of coordinates all at once and store them in memory or does it read them one line at a time? If the latter how does it know to move onto the next line after it places the block? The read-line syntax will read the file line by line until it returns nil - as I say I have not tried to use it before, so I am not sure if I have even used it correctly. But I would say that the co-ordinates need to be in the form that the command would expect them. (defun c:ITREE (/ file1) (defun *error* (msg) ; define error handler (setvar "cmdecho" 1) ; if an error set the command echo back to 1 (if (= msg "") ; if the msg argument with the error is "" (princ "\nFunction Complete.") ; then print Function Complete (princ "\nError or Esc Pressed.") ; otherwise print Error... ) ;_ end if ) ;_ end defun (selfile) ; invoke selfile (setvar "cmdecho" 0) ; turn off the command echo (for when we use the insert) (setq file1 (open file "r")) ; open the selected file for reading (while ; as it says on the tin (/= (read-line file1) nil) ; up until the readline cannot read any more lines (command "-insert" ; invoke insert "C:\\" ;<<< --- INSERT BLOCK FILEPATH HERE (read-line file1) ; read a line of the file selected "" ; x scale factor 1 "" ; y scale factor 1 "0" ; no rotation ) ;_ end command ) ;_ end while (*error* "") ; < call error handler with msg = "", to reset cmdecho (princ) ; exit cleanly ) ;_ end defun (defun selfile () (setq file (getfiled "Select a Text File" ; <<-- Title of Dialog Box "C:/" ; Default Path to display files "txt" ; file extension to look for (was on csv - sorry) 9 ; bit argument --> 8 + 1 --> look in ACAD help for meanings, it'll explain better ) ;_ end getfiled ) ;_ end setq ) ;_ end defun There was a slight error in the selfile, I picked it up and changed it in this version. Quote
ScribbleJ Posted December 18, 2008 Author Posted December 18, 2008 Thanks Lee. I am going to give it a test run at lunch time. I will post the results here for feedback. Quote
Lee Mac Posted December 18, 2008 Posted December 18, 2008 Nice, it will be interesting to see if it works or not Quote
ScribbleJ Posted December 21, 2008 Author Posted December 21, 2008 Just an update Lee. Sorry I have not posted an update about the Lisp you wrote for me but emergencies came up and then I had to dive into Civil 3D for a volume balance calc for some detention ponds. I will get to the lisp soon. Hopefully this week. Quote
Lee Mac Posted December 21, 2008 Posted December 21, 2008 Hey, no probs. - do what you gotta do Quote
BIGAL Posted December 23, 2008 Posted December 23, 2008 Not sure but doing (read line) twice may do just that ! Skip a line each loop? lisp carries out each instruction within pairs try (while (setq new_line (read-line fileopen)) code here then use variable new_line if its Nil loop exits ) ;end while Quote
BIGAL Posted December 23, 2008 Posted December 23, 2008 Forgot do you now want the code for reading a xyz file, how is your file set up does it use commas to seperate variables or are the x y z a set number of characters ? 100.123, 200,456,300.789 123456789012345678901 100.123 200.456 300.789 Quote
Lee Mac Posted December 23, 2008 Posted December 23, 2008 Not sure but doing (read line) twice may do just that ! Skip a line each loop? lisp carries out each instruction within pairs try (while (setq new_line (read-line fileopen)) code here then use variable new_line if its Nil loop exits ) ;end while Good point AL, and good solution - I must admit, I have never used this method for inserting blocks into drawings, and my posted LISP was untested also. - but thanks for your input. Quote
wannabe Posted December 23, 2008 Posted December 23, 2008 Have you guys figured this one out? I would be quite keen to use it myself and could provide you with some feedback if necessary (relating to its function, not its code). currently I use Microstation for this tool. But I plan on doing an all encompassing form driven block/coordinate functions menu when I feel more competent with C#. Quote
Lee Mac Posted December 23, 2008 Posted December 23, 2008 Hiya Wannabe, This should worked (although untested!): (defun c:ITREE (/ *error* file1 blk pts) (defun *error* (msg) (setvar "cmdecho" 1) (if (= msg "") (princ (strcat (itoa blk) " Blocks Inserted.")) (princ "\nError or Esc Pressed.") ) ;_ end if ) ;_ end defun (selfile) (setvar "cmdecho" 0) (setq file1 (open file "r") blk 0 ) ;_ end setq (while (/= (setq pts (read-line file1)) nil) (command "-insert" [b][color=Red]"C:\\" ;<<< --- INSERT BLOCK FILEPATH HERE[/color][/b] pts "" "" "0") ;_ end command (setq blk (1+ blk)) ) ;_ end while (*error* "") (close file1) (princ) ) ;_ end defun (defun selfile () (setq file (getfiled "Select a Text File" "C:\\" "txt" 9 ) ;_ end getfiled ) ;_ end setq ) ;_ end defun Remember to Insert the block filepath! Quote
ScribbleJ Posted December 23, 2008 Author Posted December 23, 2008 Forgot do you now want the code for reading a xyz file, how is your file set up does it use commas to seperate variables or are the x y z a set number of characters ? 100.123, 200,456,300.789 123456789012345678901 100.123 200.456 300.789 The order of the file does not matter because I can export to any format, (i.e. xyz, yxz, etc and comma, tab or space delimited). My preference though would be yxz comma delimited. Quote
BIGAL Posted December 23, 2008 Posted December 23, 2008 Here is two example the first uses fixed lengths for x yx z etc (please note code wont work as is but can be used within you program check brackets etc) (defun lay_name () (setq ans "") (setq char_found "") (while (/= x y) (setq char_found (substr new_line x 1)) (setq x (+ x 1)) ; (if (= char_found (chr 92)) (if (= char_found " ") (setq x y) (setq ans (strcat ans char_found)) ) ) ) (while (setq new_line (read-line fo)) (setq x 1) (setq y 17) (lay_name) (setq new_name ans ) (setq x 17) (setq y 32) (lay_name) (setq name ans) (setq x 33) (setq y 36) (lay_name) (setq col ans) (setq x 37) (setq y 47) (lay_name) (setq line ans) (setq ans_var (strcat "(" "setq " name " " (chr 34) new_name (chr 34) ")" )) (setq ans_col (strcat "(" "setq " (strcat name "col") " " col ")" )) (setq ans_line (strcat "(" "setq " (strcat name "lin") " " (chr 34) line (chr 34) ")" )) 2nd example is comma delimted (defun xyz () (setq ans "") (setq char_found "") (while (/= char_found ",") (setq char_found (substr new_line x 1)) (setq x (+ x 1)) (setq ans (strcat ans char_found)) ) ;end while ) ;end defun (defun xyzend () (setq ans "") (setq char_found "") (while (/= char_found (chr 13)) (setq char_found (substr new_line x 1)) (setq x (+ x 1)) (setq ans (strcat ans char_found)) ) ;end while ) ;end (setq xyzfiles (getfiled "\nENTER CO-ORD File name " "" "" 4)) (setq fopen (open xyzfiles "R")) (SETQ XX 1) (while (setq new_line (read-line fopen)) (PRINC XX) (setq x 1) (setq y 5) (xyz) (setq ptno ans) ;pull ptno out (xyz) (setq easting ans) (xyz) (setq northing ans) (xyzend) (setq height ans) 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.