I've the following AutoLISP code
(defun graph ( pts sls tls ) ( (lambda ( l ) (foreach x l (text (cdr x) (itoa (car x)) 0.0 1)) (mapcar '(lambda ( a b / p q r ) (setq p (cdr (assoc a l)) q (cdr (assoc b l)) r (angle p q) ) (entmake (list '(0 . "LINE") (cons 10 p) (cons 11 q) '(62 . 8))) (text (mapcar '(lambda ( x y ) (/ (+ x y) 2.0)) p q) (rtos (distance p q) 2) (if (and (< (* pi 0.5) r) (<= r (* pi 1.5))) (+ r pi) r) 2 ) ) sls tls ) ) (mapcar 'cons (vl-sort (append sls tls) '<) pts) ) ) (defun text ( p s a c ) (entmake (list '(0 . "TEXT") (cons 10 p) (cons 11 p) (cons 50 a) (cons 01 s) (cons 62 c) '(40 . 2) '(72 . 1) '(73 . 2) ) ) )
and the input is
(graph '((75 25) (115 45) (90 60) (10 5) (45 0) (45 55) (0 25)) '(1 1 1 1 2 2 3 4 4 5 6) '(2 3 4 5 3 6 6 5 7 7 7) )
The 2D geometry created from the above is exported as a dxf file from AutoCAD.
The actual input is generated in Python
pts = [(75, 25), (115, 45), (90, 60), (10, 5), (45, 0), (45, 55), (0, 25)]sls = [1 1 1 1 2 2 3 4 4 5 6] tls = [2 3 4 5 3 6 6 5 7 7 7]
I would like to know how to use the python data types as input and directly interface with AutoCAD from Python, save the AutoCAD output as a dxf file.
Solved! Go to Solution.
Hi All,
I just wanted to keep everyone posted that the issue posted in the last comment hasn't been solved yet.
"This opens the AutoCAD application, but the command in .src isn't sent. It just opens the drawing file. "
Some command is going wrong with the script file. Since it still opens the drawing, I think it is the (load ...), either because of secureload not set to 0 or the loadpath is not correct. Let's add the secureload the same way as with com, so the script should look like this:
open
<filepath>
(setq *LOAD_SECURITY_STATE* (getvar 'SECURELOAD))
(setvar "SECURELOAD" 0)
(load "...")
(graph ... ... ...)
(setvar "SECURELOAD" *LOAD_SECURITY_STATE*)
saveas 16 dxf
<filepath>
quit
load path should have double "\" or single "/" as path delimiters.
If you add the graph-defun-lisp to the startup-suite of AutoCAD, that (load ...) command is not needed.
AutoCAD scripts are a bit fiddly with the correctness. If it stops again at some point, try to see the messages AutoCAD has written into its command line. That should tell, where the script requires some other answer than what the .scr is giving to it. For example saving and closing might introduce extra yes/no-questions depending on if you save to default format or not, so you might need a yes or a no at some point in the end of the script
Hi @Anonymous
I have been trying to generate a drawing from Python and the output dxf files aren't generated for some reason
when 3D points are present ( test1 and 2 in the python file link below).
Could you please have a look at this python script which includes the functions discussed above for running autocad and the autolisp code that called from python is available here?
I would also like to know if it is possible to specify the units . I want to set the units in `Engineering` `Microns` for the dxf output.
My autocad hangs completely on the (graph ...)-line, I think the command line can only accept lines that are quite short. The point list goes easily over that character limit.
I think this can be fixed by separating lists by newline instead of space. Other way would be to write the (graph ... ) in a new .lsp file and then, in the script, load the new lisp file instead of giving the graph-command. I'd go with the lisp file as it produces cleaner output and is faster, since the command line doesn't have to parse so many lines.
So in write_scr, remove f"{graph}\n" and replace with '(load "file.lsp")' in which the file.lsp has that (graph ...) call written to it. Something like this:
with open(graph_command_file, 'w') as outfile:
outfile.write(f"{graph}\n")
with open(GRAPH_SCR_FILE, 'w') as outfile:
outfile.write("open\n" +
f"{GRAPH_DWG_FILE}" + "\n"
"(setq *LOAD_SECURITY_STATE* (getvar 'SECURELOAD))\n" +
'(setvar "SECURELOAD" 0)\n' +
rf'(load "{GRAPH_LISP_FILE}")' + "\n"
rf'(load "{graph_command_file}")' + "\n"
'(setvar "SECURELOAD" *LOAD_SECURITY_STATE*)\n'
"saveas dxf 16\n" +
rf"{GRAPH_DXF_FILE}" +"\n"+
"quit"
)
Multiple drawings in the same script might produce a problem later on (you'd need multiple lsp-command files, one for each input dwg). If you need to process multiple files in same .scr, go with replacing the " ".join(...) by "\n".join(...) in iter_to_lisp_string.
My autocad hangs completely on the (graph ...)-line, I think the command line can only accept lines that are quite short. The point list goes easily over that character limit.
Yes, I experienced the same issue while running it manually in AutoCAD and it worked only after changing the point list to multiple lines.
I've now followed what was suggested above. `graph_command` is written to a lsp file (in a single line). The output dxf file is generated now but the drawing isn't created and it returns an empty file, unfortunately.
Could you please check these updates?
Thanks a lot for your time and kind attention.
I don't see what goes wrong. In the python file, there is indentation missing on GRAPH_COMMAND_FILE-write, but I assume you fixed that since the lisp file was created. On my machine this works great. In the script, load GRAPH_COMMAND_FILE should have "\\" or single "/" as path separators, maybe check that?
In the script, load GRAPH_COMMAND_FILE should have "\\" or single "/" as path separators, maybe check that?
Ahh, this worked! Thanks a lot. Since GRAPH_LISP_FILE worked with '\' I thought that shouldn't be a problem.
May I know if it is possible to set the units in `Microns`?
System variable INSUNITS controls that, 13 means microns. In script (setvar 'insunits 13) before drawing the graph.
For the 'Engineering', if you want the texts to show in that format, use (rtos number 3) when converting number to string, mode 3 means 'engineering'. I don't know if the drawing can be put to 'engineering-mode' if you mean that. Does anyone else know?
Can't find what you're looking for? Ask the community or share your knowledge.