Visual LISP, AutoLISP and General Customization

Visual LISP, AutoLISP and General Customization

Reply
Contributor
msingh_autocad
Posts: 17
Registered: ‎04-27-2011
Message 1 of 12 (252 Views)
Accepted Solution

Need advice on choosing the right tool / mix of tools for scripting

252 Views, 11 Replies
04-27-2011 10:45 PM

I am looking to automate the drawing of a certain drawing (multiple layers, 2 dimensional). My platform is AutoCAD 2011 for Mac.

 

I expect that I will be going through various iterations of this drawing and want to automate this as much as possible.

 

What I want to do is to draw rectangles (nothing complicated) that are expressible in the following pseudocode:

 

list_of_widths1=[200,300,400];

list_of_lengths1=[1000,1200,2000,2200];

 

some_other_variables

 

.

.

.

 

for i1=1:length(list_of_widths1)

  for j1=1:length(list_of_lengths1)

  x1=result of calculation 1 (function of i1 and some_other_variables);

  y1=result of calculation 2 (function of j1 and some_other_variables);

  draw rectangle with width = i1 and length = j1 at (x1,y1)

     end

end

 

I have been reading up on script files (invoked using script command) and AutoLISP files (invoked using appload command).

 

It appears that the drawing script does not have any complicated constructs such as loops or arithmetic operations. And the AutoLISP (from what I have quickly read about it) does not have any drawing commands.

 

Is it even possible to do what I seek to do above ?

 

Looks like I need to mix the two. Can I embed drawing commands in AutoLISP ?

 

I am somewhat new (used it very briefly 16 years ago, but then never touched it until now) to AutoCAD (though not to using layout programs or scheme).

------------------------------------------------------------------------


AutoCAD 2011 on Mac OSX 10.6.7.
*Expert Elite*
Kent1Cooper
Posts: 5,368
Registered: ‎09-13-2004
Message 2 of 12 (232 Views)

Re: Need advice on choosing the right tool / mix of tools for scripting

04-28-2011 05:32 AM in reply to: msingh_autocad

msingh_autocad wrote:

....

What I want to do is to draw rectangles ....

.... 

I have been reading up on script files (invoked using script command) and AutoLISP files (invoked using appload command).

 

It appears that the drawing script does not have any complicated constructs such as loops or arithmetic operations. And the AutoLISP (from what I have quickly read about it) does not have any drawing commands.

 

Is it even possible to do what I seek to do above ?

 

Looks like I need to mix the two. Can I embed drawing commands in AutoLISP ?

....


It's not as simple as that.  With certain limitations, you can include Lisp expressions such as arithmetic operations in a Script, or a menu macro item.  And AutoLISP files are actually made available using appload, but whether doing that invokes anything depends on how the code in the file is written.  More often, you need to then enter a command name that's defined in the file, to have it do its thing.

 

Yes, you can certainly embed drawing commands in AutoLISP.  Poke around this forum a little and you'll find countless examples.  Look at the AutoLISP functions (command) and (vl-cmdf).  If the command in question is a drawing command, you can also make entities with (entmake).  If it's an editing command, you can often achieve the same by applying (subst) to an entity's data list.  Etc., etc., ....

 

You would do well to just look over the relevant parts of Help's Customization Guide and the AutoLISP Tuturial first.  Also search the Discussion Group for something related to what you want to do.  It's certainly doable, with things like those lists in the right format, etc.  If there's something you can't figure out, write back.

Kent Cooper
Contributor
SafetyFish
Posts: 16
Registered: ‎04-11-2011
Message 3 of 12 (223 Views)

Re: Need advice on choosing the right tool / mix of tools for scripting

04-28-2011 06:32 AM in reply to: msingh_autocad

Actually, there are a number of drawing tools in autolisp. I have just recently (the past 3-4 weeks) discovered them myself.

 

The most complicated, but by far the most useful, drawing tool in autolisp is entmake. You could also use command. For entmake, you must become very familiar with the dxf codes. Good instructions on using entmake to draw things using entmake can be found here. I can't help you with the the (command) option because I haven't really explored it, but I know it exists.

 

http://www.dailyautocad.com/2009/10/autolisp10-using-entmake-function-to.html

 

These examples are extremely simplified. The best resource I have found for DXF codes is this:

 

http://images.autodesk.com/adsk/files/acad_dxf2.pdf

 

Another great resource is this:

 

http://docs.autodesk.com/ACD/2011/ENU/filesALR/WS1a9193826455f5ff1a32d8d10ebc6b7ccc-6ade.htm

 

I reccomend this website for learning autolisp:

 

http://www.afralisp.net/autolisp/

 

I would also suggest you write the entmake functions separately from your major drawing code. I, too, find myself drawing some rectangles in precise places repeatedly. I have copied below the function I made for myself to draw a rectangle. It's rather messy, but you should be able to at least get the idea. It was one of the first pieces of lisp I wrote.

 

If you're very new to scripting/programming and you do not have a preferred development environment yet, I have been using notepad++ with great success to create my .lsp files. I hope all this helps you!

 

(defun DrawLWPlineFromLines (PointList Thickness / NPts DFXlist index)
; This function takes a list variable with a set of points in it


;pointlist: ((# # #) (# # #) (# # #) (# # #) etc)

;and uses this list to create a polygon shape of linetype lwpolyline
;thickness is a number

(setq Npts (length pointlist)); assign number of points to variable
(setq index 0); set index to default variable of 0
(setq DFXlist (list
    (cons 0 "LWPolyline"); Entity Type
    (cons 8 (getvar "clayer")); Grab current layer
    (cons 62 7) ; lines colored white/black
    (cons 100 "AcDbEntity"); subclass old acad
    (cons 100 "AcDbPolyline"); subclass new acad
    (cons 90 Npts); Number of vertices in pline, or number of points from point list
    (cons 70 1); PL flag; 0=open, 1=closed
    (cons 43 Thickness); Line Thickness
))

(repeat npts
    (setq DFXlist (append DFXlist (list ; make dfxlist equal to dfxlist + whatever else I add in this loop
        (cons 10 (nth index pointlist))
        ; add points to dfx list based on index (loop iteration and list place)
    )))
    (setq index (+ index 1)); counter
)
(terpri)
;(prin1 dfxlist)
(terpri)

(entmake DFXlist); create polyline
)
(defun SolidHatchLWPLpolygon (EntityName Color / DFXlist NumVer Pair EntDFX VertexList index)
;this function takes the hex name of an entity and an acad color number and hatches said entity said solid color
;before building dfx codes list, take entity name and grab number of vertices
(setq numver (cdr (assoc 90 (entget entityname))))
; assign vertices in object to list, somehow.
;must first create entdfx by assigning entget(entityname)
(setq entdfx (entget entityname))
(foreach pair entdfx
    (if (= (car pair) 10)
        (setq vertexlist (append vertexlist (list
            (cons (car pair) (list (nth 1 pair) (nth 2 pair) 0.0))
        )))
    )    
)    
;begin dfx codes list
(setq DFXlist    (list
    (cons 0 "HATCH")
    (cons 100 "AcDbEntity")
    (cons 67 0)
    (cons 410 "MODEL")
    (cons 8 (getvar "CLAYER"))
    (cons 62 Color)
    (cons 100 "AcDbHatch")
    (cons 10 (list (nth 1 (nth 0 vertexlist)) (nth 2 (nth 0 vertexlist)) 0.0))
    (cons 210 (list 0.0 0.0 1.0))
    (cons 2 "SOLID")
    (cons 70 1)
    (cons 71 0)
    (cons 91 1)
    (cons 92 7)
    (cons 72 1)
    (cons 73 1)
    (cons 93 numver)
))

(setq index 0) ; set index to default 0


;now put vertices in dfxlist
(repeat numver
    (setq dfxlist (append dfxlist (list
        ;(cons 72 1);;; all this stuff commented out to try and make the @!#$%!@#@&##!! hatch work
        
        (cons 10 (cdr(nth index vertexlist)))
        (cons 42 0.0)
    )))
    (setq index (+ index 1))
    ;(setq dfxlist (append dfxlist (list
    ;    (if (= index numver)
    ;        (cons 11 (cdr(nth 0 vertexlist)))
    ;        (cons 11 (cdr(nth index vertexlist)))
    ;    )
    :smileywink:))
)
(setq dfxlist (append dfxlist (list
    (cons 97 0)
    ;(cons 330 entityname)
    (cons 75 0)
    (cons 76 1)
    (cons 47  0.2)
    (cons 98 0)
    (cons 450  0)
    (cons 451  0)
    (cons 460  0.0)
    (cons 461  0.0)
    (cons 452  1)
    (cons 462  1.0)
    (cons 453  2)
    (cons 463  0.0)
    (cons 63  5)
    (cons 421  255)
    (cons 463  1.0)
    (cons 63  7)
    (cons 421  16777215)
    (cons 470 "LINEAR")

)))
(entmake dfxlist)
)

 

 

Contributor
msingh_autocad
Posts: 17
Registered: ‎04-27-2011
Message 4 of 12 (215 Views)

Re: Need advice on choosing the right tool / mix of tools for scripting

04-28-2011 07:58 AM in reply to: SafetyFish

Thanks for the responses.

 

Safetyfish, that was an incredibly informative and helpful response. Thanks.

 

My question - how much of a clear demarcation is there between AutoLISP and VLISP ? I am running this on a Mac, so I do not want to run into issues with internal calls to .com, .net objects and the like.

------------------------------------------------------------------------


AutoCAD 2011 on Mac OSX 10.6.7.
*Expert Elite*
Kent1Cooper
Posts: 5,368
Registered: ‎09-13-2004
Message 5 of 12 (209 Views)

Re: Need advice on choosing the right tool / mix of tools for scripting

04-28-2011 09:24 AM in reply to: SafetyFish

SafetyFish wrote:

.... 

The most complicated, but by far the most useful, drawing tool in autolisp is entmake. You could also use command. ...

.... 

(defun DrawLWPlineFromLines (PointList Thickness / NPts DFXlist index)
; This function takes a list variable with a set of points in it


;pointlist: ((# # #) (# # #) (# # #) (# # #) etc)

;and uses this list to create a polygon shape of linetype lwpolyline
;thickness is a number

(setq Npts (length pointlist)); assign number of points to variable
(setq index 0); set index to default variable of 0
(setq DFXlist (list
    (cons 0 "LWPolyline"); Entity Type
    (cons 8 (getvar "clayer")); Grab current layer
    (cons 62 7) ; lines colored white/black
    (cons 100 "AcDbEntity"); subclass old acad
    (cons 100 "AcDbPolyline"); subclass new acad
    (cons 90 Npts); Number of vertices in pline, or number of points from point list
    (cons 70 1); PL flag; 0=open, 1=closed
    (cons 43 Thickness); Line Thickness
))

(repeat npts
    (setq DFXlist (append DFXlist (list ; make dfxlist equal to dfxlist + whatever else I add in this loop
        (cons 10 (nth index pointlist))
        ; add points to dfx list based on index (loop iteration and list place)
    )))
    (setq index (+ index 1)); counter
)
(terpri)
;(prin1 dfxlist)
(terpri)

(entmake DFXlist); create polyline
)
....


[By the way, "Thickness" in the code above should be "Width" instead -- "thickness" has a specific and different meaning in AutoCAD entities: vertical thickness/height up off the drawing plane.  See Thickness in the General category in the Properties Box for a selected Polyline, vs. Segment widths and Global width in the Geometry category.]

 

I agree that (entmake) is more complicated, and sometimes a lot.  It's necessary in certain situations [you can't use (command) in a reactor, for instance], and it's advisable in others [if you have a large enough number of things to make all at one shot, you might start to notice the shorter amount of time it can take].

 

But to illustrate how much more complicated it can be, this code using the (command) function instead will do exactly the same thing that the above-quoted code does: make a closed polyline on the current Layer, with [for whatever reason] a forced color of white/black, from a specified list of points, and at a specified global width.

 

(defun LWPpts (lst wid); = LightWeightPolyline from points
  (command "_.pline" (car lst) "_w" wid "")
  (foreach pt (cdr lst) (command pt))
  (command "_c" "_.chprop" "_l" "" "_c" 7 "")
)

Usage would be the same -- type in or enter from other code:

(lwppts ptlist wid)

where 'ptlist' is a list of points [or a variable containing one], and 'wid' is a numerical value [or a variable containing one].

 

I suppose to make it truly and completely equivalent, maybe a line like this:
(setvar 'plinetype 2)

[1 rather than 2 would also do] could be added at the beginning to ensure that it makes a Lightweight Polyline, if you think there's any chance that System Variable might be set to 0 and cause a "heavy" one.

 

No need to know DXF codes, or tell it how many vertices there are, or tell it to use the current Layer, or give it three entries just to define what kind of entity it is, or use any variables....  The PLINE command itself does for you a lot of what (entmake) needs you to spell out.  That's what makes it so much less complicated -- I think of a command as essentially a kind of code-shortcutting sub-routine.

 

[Oh, and if you're drawing rectangles as in your original question, and they're orthogonally oriented, you can make it perhaps even simpler by using the Rectang command -- you only need to give it two opposite corners, not all four, and the Polyline entity type result is inherent in the command.]

Kent Cooper
Contributor
msingh_autocad
Posts: 17
Registered: ‎04-27-2011
Message 6 of 12 (203 Views)

Re: Need advice on choosing the right tool / mix of tools for scripting

04-28-2011 10:24 AM in reply to: msingh_autocad

Kent,

 

That was a very startling demonstration of complicated nature of entmake.

 

Online references are rife with claims that using command is much slower that AutoLISP. Would this slow down the session irrevocably, or does the session speed up again as soon as command is executed ?

 

What are implications for cross platform use ? I am using this on a Mac.

 

 

------------------------------------------------------------------------


AutoCAD 2011 on Mac OSX 10.6.7.
Contributor
msingh_autocad
Posts: 17
Registered: ‎04-27-2011
Message 7 of 12 (201 Views)

Re: Need advice on choosing the right tool / mix of tools for scripting

04-28-2011 10:34 AM in reply to: Kent1Cooper

I will be using the rectangle command. How does one hatch it with the current layer's colors ?

------------------------------------------------------------------------


AutoCAD 2011 on Mac OSX 10.6.7.
*Expert Elite*
dgorsman
Posts: 5,218
Registered: ‎10-12-2006
Message 8 of 12 (196 Views)

Re: Need advice on choosing the right tool / mix of tools for scripting

04-28-2011 11:33 AM in reply to: msingh_autocad

"Slower" is relative.  In most cases people have to code loops in the hundred- or even thousand-cycle range or compare expired time in milliseconds to demonstrate.  Note the delays are only while the function is executing.

 

Since you are on Mac, your options for LISP are quite limited at this time.  No VLISP means (entmake...), (entget...), and other DXF-based function calls are all you have to go with.  For somebody thats just beginning, I would recommend the simplicity of the (command...) route.

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
Adopt. Adapt. Overcome. Or be overcome.
A good question will be halfway to a good answer.


*Expert Elite*
Kent1Cooper
Posts: 5,368
Registered: ‎09-13-2004
Message 9 of 12 (190 Views)

Re: Need advice on choosing the right tool / mix of tools for scripting

04-28-2011 02:01 PM in reply to: msingh_autocad

msingh_autocad wrote:

I will be using the rectangle command. How does one hatch it with the current layer's colors ?


See whether Message 3 on this thread:

http://forums.autodesk.com/t5/Visual-LISP-AutoLISP-and-General/Wanted-Bhatch-options-prompts-etc-exp...

answers that for you.

Kent Cooper
Contributor
msingh_autocad
Posts: 17
Registered: ‎04-27-2011
Message 10 of 12 (186 Views)

Re: Need advice on choosing the right tool / mix of tools for scripting

04-29-2011 12:21 AM in reply to: Kent1Cooper

Thanks for the hint. I figured this one out on my own.

 

Simple way to hatch something you added last:

 

  (command "-HATCH" "Properties" "Solid" "Select" "Last" "" "" "")

 

Here is a neat function that does rectangle drawing and hatching in one step:

 

 

(defun hatchedrectdraw1 ( pt1 pt2); Draw a hatched rectangle between pt1 and pt1 (opposite corners)
 (command "rectang" pt1 pt2)
 (command "-HATCH" "Properties" "Solid" "Select" "Last" "" "" "")
  )

 

------------------------------------------------------------------------


AutoCAD 2011 on Mac OSX 10.6.7.
Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.
Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.