Jump to content

Recommended Posts

Posted

Hello,

 

I'm working on a project that involves a lot of manual tasks like repetitive drawing and writing texts.

I'm new to AutoLISP and scripting but i have a little background in programming. I'm trying to write a routine but i cant find any documentation on command syntaxes for the default commands in AutoCAD such as drawing a line, spline, hatch, creating and setting up layers. Is there any place where i can find this information?

Posted

Just look into any of the code in the lisp section thousands of examples, any way inside your Autocad is a sample lisp tutorial called "Down the Garden Path" also go to Afralisp has some good beginner lisps.

 

Your 1st item

 

(command "line" (getpoint "\nPick 1st point ") (getpoint "\nPick 2nd point ") "") ; so pick 2 points the "" means end command.

 

There are ebooks etc cheaper than paper version.

 

"like repetitive drawing and writing texts" yes that is where lisp can help, explain what your doing, image or dwg is helpful and we may be able to get you started on your learning journey. Time diff, 4+ hours manual to edit a dwg, its now 2.5 minutes using custom lisp.

 

  • Like 1
Posted

The goal is to make a command that draws a borehole stick, like the one in the image.

 

There are plines, hatches and numbers;

First of all the user is asked how long is the stick: in this case it's 4.

-> The code will draw the 4 bars (width and height of each one is predetermined but not required as user input);

-> The code will write the text counting from 0 to 4 at the top of each bar;

The prompt will then ask a text to be written on the right side of the stick: in this case 1/63, 2/57, 3, 4.

-> The code will write each text in the center-right of the stick for as many as the number os sticks;

 

It would be great if i could create a layer for each of the elements, the pline, the white hatch and the black hatch so then i can control and customize them easily.

 

Thank you for your response and recommendations.

example.bmp

Posted
32 minutes ago, Matielo said:

The goal is to make a command that draws a borehole stick, like the one in the image.

 

There are plines, hatches and numbers;

First of all the user is asked how long is the stick: in this case it's 4.

-> The code will draw the 4 bars (width and height of each one is predetermined but not required as user input);

-> The code will write the text counting from 0 to 4 at the top of each bar;

The prompt will then ask a text to be written on the right side of the stick: in this case 1/63, 2/57, 3, 4.

-> The code will write each text in the center-right of the stick for as many as the number os sticks;

 

It would be great if i could create a layer for each of the elements, the pline, the white hatch and the black hatch so then i can control and customize them easily.

 

Thank you for your response and recommendations.

example.bmp 509.74 kB · 1 download

I forgot to mention that the insertion point of the top sticker will be asked first, then the comand will run and draw from there.

Posted

Like BigAl, there are many many examples out there, some resources are better than others, and for example this forum is generally very good.

 

LISP is great in that there are usually 3 or 4 ways to make the same thing appear on a drawing, which also makes it trickier as there is often no single correct answer.

 

Looking at BigAls answer above using a command the format in the code is simila to:

(command "CommandName" ".....anything else for that commend" )

I usually get the formatting I want by runnig nthrough the command in AutoCAD with a couple of extra tips, so using the above, 'line'

 

In your LISP start with

(command ;; to tell the LSIP to use an AutoCAD command (note that the ;; starts a comment, anything afterwards is ignored on that line

"line" ;; the command to use, you can also use "_line" and "_.LINE" the prefixes "_" to run the command through the command prompt and "." that the command is written in English (in cse other languages are used, makes it more versatile)

 

Running the command 'line' it is asking for a point "LINE: Select First Point:"

 

pause ;; tells the LISP to wait for user input. Can also use the LISP to put in a point, use a variable name here

 

So next I do what it wants and select a point, it asks "LINE Specify Nect Point or [Undo]", again put in your code what is asked

 

 

and so on... some commands need you to end them with a "" (as above)

 

 

You don't -need- a reference for all the commands, just to know how to build up the line in the LISP, hoping that the above will give you a hint - try it. 

 

 

 

 

Then you can make entities with entmake, VLA, ....... some are faster than others but unless you are doing it to hundreds of object that speed difference is so small compared to the speed of the user.

  • Like 1
Posted

And this might give you a start using these examples - should be enough after this for you to work it all out?

 

(defun c:testthis ( / MyW MyH acount MySeg MyPt)
  (setq MyW 5) ; variable MyW -  width
  (setq MyH 10) ; variable MyH - height
  (setq acount 0) ; a variable
  (setq MySeg (getint "How Many Segments")) ; set variable from user input 'int' (typical syntacx "get___")
  (setq MyPt (getpoint "Insertion Point")) ; set variable .. guess what this does

  (while (< acount MySeg) ; a while loos
    (command "_.rectang" MyPt (mapcar '+ (list MyW MyH 0) MyPt)) ; CAD command used in the LISP. MapCar '+ adds list 1 to list 2
    (command "-hatch" "S" (entlast) "" "") ; CAD commanbdd, HAtch. (entlast) selects the last entity to be created and still in the drawing
    (setq MyPt (mapcar '+ (list 0 MyH 0) MyPt)) ; LISP variable, MapCAr '+ adds list 1 to list 2
    (setq acount (+ acount 1)) ; increase counter
  ) ; end while loop
                  
  (princ) ; end silently
) ; end LISP 

 

 

Reckon you can do the fiddling about to insert text and to shade every other block

  • Like 2
Posted

Thank you Steven, this will be VERY helpful.

 

I'll work on the next steps to write the texts.

 

So far i got to this point where the bar is drawn from top to bottom and i can change the layer that the objects are draw into.

But the problem is i cant write the input text as a loop or the code will stop.

 

(defun c:stic ( / MyW MyH acount MySeg MyPt n color)
  (setq MyW 5) ; variable MyW -  width
  (setq MyH -10) ; variable MyH - height
  (setq acount 0) ; a variable
  (setq MySeg (getint "How Many Segments")) ; set variable from user input 'int' (typical syntacx "get___")
  (setq MyPt (getpoint "Insertion Point")) ; set variable .. guess what this does
  (setq color 0)
  
  (repeat MySeg
    (command "_.rectang" MyPt (mapcar '+ (list MyW MyH 0) MyPt))
    (if (= color 0) (command "_.clayer" "Hatch1") (command "_.clayer" "Hatch2"))
    (command "-hatch" "S" (entlast) "" "")
    ;(command "_.text" "J" "L" MyPt "" "" getstring) this command makes the loop stop
    (command "_.clayer" "Line")
    (command "_.text" "J" "R" MyPt "" "" acount "")
    (setq MyPt (mapcar '+ (list 0 MyH 0) MyPt))
    (if (= color 0) (setq color 1) (setq color 0))
    (setq acount (+ acount 1))
  ) ; end while loop
  (command "_.text" "J" "R" MyPt "" "" acount "") ;draw last number
  (command "_.text" "J" "L" (mapcar '+ MyPt (list (+ MyW 2) 0 0)) "" "" getstring "") ;draw last text

                  
  (princ) ; end silently
) ; end LISP

 

bar.bmp

Posted

few things why i don't like (command

 

snaps put "_non" infront of points or depending on zoom level could snap to close objects  (pickbox size)  even if osmode = 0

(command "_.text" "J" "R" "_non" MyPt "" "" acount "")
(command "_.rectang" "_non" MyPt "_non" (mapcar '+ (list MyW MyH 0) MyPt))

;(command "_.text" "J" "L" MyPt "" "" getstring) this command makes the loop stop
fixed
;(command "_.text" "J" "L" "_non" MyPt "" "" (getstring)) ;has to be wrapped to work (...) can add prompt like (getpoint "\nInsertion Point")

 

entmake

(entmakex (list '(0 . "TEXT") (cons 10  MyPt) (cons 40 (getvar textsize))  (cons 1  str))))

http://docs.autodesk.com/ACD/2014/ENU/index.html?url=files/GUID-62E5383D-8A14-47B4-BFC4-35824CAE8363.htm,topicNumber=d30e678406

 

  • Like 1
Posted

I was so close haha.

 

Thank you for your reply and recommendation.

 

I'm afraid i dont understand how to use the text entities info from the link you sent. It seems like "cons" calls for the entity and assign it a value.

The entmake code doesnt work in the place of the text command. 🤔

Posted
7 minutes ago, Matielo said:

I was so close haha.

 

Thank you for your reply and recommendation.

 

I'm afraid i dont understand how to use the text entities info from the link you sent. It seems like "cons" calls for the entity and assign it a value.

The entmake code doesnt work in the place of the text command. 🤔

 

entmake is the fastest, hence most efficient, way to create any object in AutoCAD. It takes in an association list of dotted pairs to make the entity. Since you said you are new to AutoLISP, you may find some things overwhelming in terms of cons and entmakex, as the codes 10, 40, etc. may mean different things across different entities. Which is probably why the suggestion of others made use of the easiest function to understand, namely "command" (which is the slowest, hence most inefficient, way).

 

To give just a bit on insight for entmake, for a text,

 

0 - Object Type

10 - Primary point (Text point)

40 - Text Height

1 - Text String

7 - Text Style

 

But for example, in an mline, 40 indicates multiline scale. I never really memorise all the numbers myself and only remember the important ones. As an example running

 

(entget (car (entsel)))

and then picking a text returns the association list of dotted pairs listing the details of the entity that you would pass onto the entmake function, like the below:

 

image.png.95b1ca3175a724b80d38516d40209675.png 

 

As you can see in mhupp's association list entmake, all the required codes are there, and hence the entity can be successfully created. Every object in AutoCAD will always return a similar list to the entget function.

 

32 minutes ago, Matielo said:

It seems like "cons" calls for the entity and assign it a value.

 

cons basically constructs the dotted pair necessary to create the object. So in mhupp's code for example, (cons 40 (getvar textsize)) first obtains the current text height, and then creates the dotted pair... (40 . 3.5) in the case above.

 

However, knowing how "command" works is also a good thing. The "command" function basically takes in any arguments of inputs, which is all then passed into the command line, much like pasting a text direct into the command line.

  • Like 2
Posted

Alright, its much more clear now.

 

So we can create basically everything with the entmake. You only need to know its associated parameters.

 

Another thing thats in my mind in the moment is the fact that it is possible to create scripts from excel and then drag them directly to AutoCAD.

It seems it works just like the AutoLISP code, and it's possible to automate A LOT of manual work.

Posted (edited)
38 minutes ago, Matielo said:

Alright, its much more clear now.

 

So we can create basically everything with the entmake. You only need to know its associated parameters.

 

Another thing thats in my mind in the moment is the fact that it is possible to create scripts from excel and then drag them directly to AutoCAD.

It seems it works just like the AutoLISP code, and it's possible to automate A LOT of manual work.

 

Yes, you certainly can.

 

I would find the more professional way of doing this using Script Files. You can read about them here.

 

However, what I think is better is to use macros, with the flexibility of prompting for user input.

Edited by Jonathan Handojo
  • Like 1
Posted (edited)

Jonathon "entmake is the fastest" I am not going to test but the guys at Bricscad said Vl-add is fastest to make objects.

 

Matielo I would go down using (command while you learn much easier to understand what your doing. Or start using Visual Lisp as its more descriptive what its doing.

 

(command "pline" pt1 pt2 pt3 pt4 "C") draws say a rectang.

 

Contrary to mhupp's suggestion I have not had problems with setting osnap to 0 (setvar 'osmode 0) you can also set to "all off" 16384. Inserting 1000 blocks on a zoomed out dwg plus text, plus, plus works fine. Only time you can have a problem is if Autocad can not see objects on screen when doing some selection's a buggy problem since forever. 

 

You can drag and drop lisp.

 

If your good at Excel macro's then write in VBA you just have to get the VBA extension for your version. Yeah I know VBA will be discontinued like 8 years ago now ?

 

Here is some examples of entmake functions 

entmake functions.lsp

Edited by BIGAL
  • Like 3
Posted
14 hours ago, BIGAL said:

Jonathon "entmake is the fastest" I am not going to test but the guys at Bricscad said Vl-add is fastest to make objects.

I use mainly AutoCAD, and if my memory serves right, I recall @ronjonp mentioning it to me in another post where he outlined the time difference between using vla-add and entmake. I can't remember exactly where though.

  • Like 1
Posted

OSMode: set it to 0 works but of course reset the value afterward. _non is a little less typing I think

Speeds: All well and good if you are dealing with 1000s of objects, most times I am not so am not worried. I use more time in the day talking to the receptionists in the office than the millisecond longer it takes to draw a line. I do what I can get to work.

Entmake and command - I think we all started out making LISPs with command line, get into at and gives a lot more control, however we all know how to do stuff using commands and that is a nice way to start

 

 

  • Agree 1
Posted

MHUPP beat me to it, in LISP a command has to be between brackets (  ) - your loop failed because getstring didn't have brackets, and so was expecting to insert the contents of a variable getstring... which doesn't exist.

 

I also changed this line to offset the text (a copy of the last line really - which you should be able to spot what to do to correct that too).

 

 

The next little thing that LISPs confused me is the IF statement, if you have more than 1 statement to work on for that condition you need to put that inside '(progn .... ) lke below - should be obvious where to put this in

 

 

  (repeat MySeg
    (command "_.rectang" MyPt (mapcar '+ (list MyW MyH 0) MyPt))

(if (= (rem acount 2) 0) ;; if, then the condition in between bracket. rem: remainder, 2 divided acount by 2
  (progn ;;I am doing 2 things with an even number
    (if (= color 0) (command "_.clayer" "Hatch1") (command "_.clayer" "Hatch2")) ;statement 1
    (command "-hatch" "S" (entlast) "" "") ; statement 2
  ) ; end progn
  () ; left this in here, the 'else' though it isn't needed. If else has several statments it needs progn like above
) ; end if

    (command "_.text" "J" "L" (mapcar '+ MyPt (list (+ MyW 2) 0 0)) "" "" (getstring) )

 

 

 

 

and so back to the discussion about speed, entmake, and commands

  • Like 1
Posted
22 hours ago, Jonathan Handojo said:

 

Yes, you certainly can.

 

I would find the more professional way of doing this using Script Files. You can read about them here.

 

However, what I think is better is to use macros, with the flexibility of prompting for user input.

 

This is very nice. I found some excel files made by an engineer here in the office i work and started from there. I'm able to draw the sticks shown in the figure. As many as needed. The only problem is that it takes too long for switching between layers then to make a rectangle, text o hatch. I dont know it its possible to make the calculations and append them to a list and then create all rectangles at the same time, then the texts and finally the hatches. It woult cut the time needed as is would only need to switch layers 3 times instead for each stick of each borehole.

 

Next step is to draw a polyline with coordinates from a list.

It's important to say that im working in excel beacause i did not find a way of making a function that takes all the information from a file. I'm very positive it is possible, but i dont have yet the knowledge to do that.

 

19 hours ago, BIGAL said:

Jonathon "entmake is the fastest" I am not going to test but the guys at Bricscad said Vl-add is fastest to make objects.

 

Matielo I would go down using (command while you learn much easier to understand what your doing. Or start using Visual Lisp as its more descriptive what its doing.

 

(command "pline" pt1 pt2 pt3 pt4 "C") draws say a rectang.

 

Contrary to mhupp's suggestion I have not had problems with setting osnap to 0 (setvar 'osmode 0) you can also set to "all off" 16384. Inserting 1000 blocks on a zoomed out dwg plus text, plus, plus works fine. Only time you can have a problem is if Autocad can not see objects on screen when doing some selection's a buggy problem since forever. 

 

You can drag and drop lisp.

 

If your good at Excel macro's then write in VBA you just have to get the VBA extension for your version. Yeah I know VBA will be discontinued like 8 years ago now ?

 

Here is some examples of entmake functions 

entmake functions.lsp 11.95 kB · 1 download

Well thank you for this file. It will be very helpful once i get the hang of creating entities. In my case i think it would make a great difference working with entmake instead of (command.

I have processed 2 boreholes containing 26 rectangles each. I'm working on a project that has more than 161 boreholes and it takes like 5 seconds to make them all. I've been thinking about how lists can help me.

 

sticks.bmp

Posted
22 minutes ago, Steven P said:

MHUPP beat me to it, in LISP a command has to be between brackets (  ) - your loop failed because getstring didn't have brackets, and so was expecting to insert the contents of a variable getstring... which doesn't exist.

 

I also changed this line to offset the text (a copy of the last line really - which you should be able to spot what to do to correct that too).

 

 

The next little thing that LISPs confused me is the IF statement, if you have more than 1 statement to work on for that condition you need to put that inside '(progn .... ) lke below - should be obvious where to put this in

 

 

  (repeat MySeg
    (command "_.rectang" MyPt (mapcar '+ (list MyW MyH 0) MyPt))

(if (= (rem acount 2) 0) ;; if, then the condition in between bracket. rem: remainder, 2 divided acount by 2
  (progn ;;I am doing 2 things with an even number
    (if (= color 0) (command "_.clayer" "Hatch1") (command "_.clayer" "Hatch2")) ;statement 1
    (command "-hatch" "S" (entlast) "" "") ; statement 2
  ) ; end progn
  () ; left this in here, the 'else' though it isn't needed. If else has several statments it needs progn like above
) ; end if

    (command "_.text" "J" "L" (mapcar '+ MyPt (list (+ MyW 2) 0 0)) "" "" (getstring) )

 

 

 

 

and so back to the discussion about speed, entmake, and commands

 

Thank you! I'll take a look at your solution and i bet theres a lot to learn there (specially if else condition).

 

One thing i have to say is that it is kinda weird that we have to put first the operator then the values. Got lost on there many times already and i'm working with this only for 2 days lmao.

 

 

Posted (edited)

@BIGAL another thing I like about vl-add is you can add things inide blocks with out having to go into edit mode. just have to remeber that the base point is 0,0,0.

 

--edit

and remember to regen or block won't look like it updated.

Edited by mhupp
Posted
1 hour ago, Matielo said:

 

Thank you! I'll take a look at your solution and i bet theres a lot to learn there (specially if else condition).

 

One thing i have to say is that it is kinda weird that we have to put first the operator then the values. Got lost on there many times already and i'm working with this only for 2 days lmao.

 

 

It's definitely a long journey to learn this language. I would have already posted a solution if I wanted to, but seeing the amount of effort you've put into learning, I thought I'd step back and see how you do, whilst at the same time offer any insights and suggestions when you're stuck. I think others feel the same way. So far you're doing great and learning a bunch.

 

Speaking of suggestions: instead of a polyline with a hatch, it appears that your task seems doable by just drawing the polyline top down, whilst setting the polyline thickness in the beginning (unless you need a different hatch pattern of course). So instead of:

 

    (command "_.rectang" MyPt (mapcar '+ (list MyW MyH 0) MyPt))
    (command "-hatch" "S" (entlast) "" "")

 

You could set the polyline thickness before the repeat loop using:

(setvar "PLINEWID" MyW)

 

and then draw the polyline like so:

(command "_PLINE" MyPt (mapcar '+ MyPt (mapcar '+ MyPt (list 0 MyH 0))) "")

So then it saves having to do an extra command.

 

On a note, if you'd like, I can create a sample command to show another approach in which it could be done, all layers considered. I would only need the sample csv file with all the information. If you needed to input the text on the right manually, it defeats the efficiency purpose, so then what you've got is fine.

  • Like 1

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...