How to create a lisp to insert blocks with AutoLISP?

How to create a lisp to insert blocks with AutoLISP?

ireliontt
Explorer Explorer
3,081 Views
10 Replies
Message 1 of 11

How to create a lisp to insert blocks with AutoLISP?

ireliontt
Explorer
Explorer

So, I am kinda new to the AutoLisp world and I wanted to create a lisp that defines a command named "FF" to insert specific blocks. For example, the user types FF, then defines the first point and then types a string like "TFN". The thing is, in this string all characters are blocks, F corresponds to a block, and so do N and T. Here is the code:

 

 

(defun c:FF () 
(setq P (getpoint "Define origin:"))
(setvar aux 1)
(setq seq (getstring "Define the sequence of blocks:"))
(foreach str seq
     (command "insert" str (polar P (* pi 2) (aux*2)))
     (incf aux) 
)
)

 

 

It's supossed to look like this:

ireliontt_1-1680563474532.png

By the way, the "aux" variable is used to create separation between the blocks.

Autocad 2010 does recognize the command FF, then requires a point, but when the point is defined it returns this: error: bad argument type: (or stringp symbolp): nil 

0 Likes
Accepted solutions (1)
3,082 Views
10 Replies
Replies (10)
Message 2 of 11

paullimapa
Mentor
Mentor

since autocad does not have a system variable named aux you cannot do a setvar

I assume you want to do a setq:

 

(setq aux 1)

 

Also what is incf function?

(incf aux) 

This should be defined somewhere at the beginning like (defun incf ()....

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 3 of 11

Sea-Haven
Mentor
Mentor

 A few things missing in code something like this maybe.

 

(setq aux 100)
(setq pt (getpoint "\nPick start point"))
(while (/= (setq seq (getstring "Define the sequence of blocks Enter to exit:")) "")
 (command "-insert" seq "s" 1 pt 0.0)
 (setq pt (mapcar '+ pt (list aux 0.0 0.0)))
) ;endwhile 

 

will help

 

 

 

0 Likes
Message 4 of 11

Kent1Cooper
Consultant
Consultant

In addition to issues others have raised....

 

(foreach) requires a list, not a text string.   Fortunately, there's an AutoLisp function that will turn a string into a list of ASCII character numbers, and from that list you can turn those back into individual-character text strings as Block names, assuming those single characters are, in fact, the Block names:

 

(foreach char (vl-string->list seq)

   (command "_.insert" (chr char) ....

 

In your example string:

(vl-string->list "TFN")

returns
(84 70 78)

and

(chr 84)

turns that first one back into "T".

 

Another possibility would be to use (substr) to pull each individual character out as a Block name, but I think a (repeat) or (while) function with a counter variable would be needed.

Kent Cooper, AIA
Message 5 of 11

ivanovsky
Enthusiast
Enthusiast

there are some bugs in your code, i fixed some,

here is my modified code,

(defun c:FF (/ aux p seq) 
(setq P (getpoint "Define origin:"))
(setq aux 1)
(setq seq (getstring "Define the sequence of blocks:"))
(foreach str seq
     (command "insert" str (polar P (* pi 2) (* aux 2)))
     (incf aux)))

but,

the "exploding string" procedure is still to be modified,

you could use some other guy's reply.

0 Likes
Message 6 of 11

Sea-Haven
Mentor
Mentor

Further to Kents good idea try this.

(defun c:test ( / aux pt seq char )
(setq aux 100)
(setq pt (getpoint "\nPick start point"))
(setq seq (getstring "Define the sequence of blocks Enter to exit:"))
(foreach char (vl-string->list seq)
 (command "-insert" (chr char) "s" 1 pt 0.0)
 (setq pt (mapcar '+ pt (list aux 0.0 0.0)))
) ;endforeach
(princ)
)

It would be better to use say a,b,c then can have aa,bbbbb,c.

 

0 Likes
Message 7 of 11

ireliontt
Explorer
Explorer

Thank you for the help guys. It's almost done, there's just one issue. Here is the current version of the code:

(defun c:FF ( / aux P fio char )
(setq P (getpoint "\nDefina a origem:"))
(setq aux 1)
(setq fio (getstring "\nEntre com a sequencia da fiacao:"))
(foreach char (vl-string->list fio)
 (command "-insert" (chr char) "s" 1 P 0.0)
 (setq P (mapcar '+ P (list aux 0.0 0.0)))
) ;endforeach
)

 Somehow, the code is inserting all three block as one:

ireliontt_0-1681317908326.png

 

Here is the Autocad prompt:

-insert Enter block name or [?] <N>: T
Units: Millimeters   Conversion:    1.0000
Specify insertion point or [Basepoint/Scale/Rotate]: s Specify scale factor for 
XYZ axes <1>: 1 Specify insertion point or [Basepoint/Scale/Rotate]:
Specify rotation angle <0>: 0.000000000000000
Command: -insert Enter block name or [?] <T>: F
Units: Millimeters
Specify insertion point or [Basepoint/Scale/X/Y/Z/Rotate]: s Specify scale 
factor for XYZ axes <1>: 1 Specify insertion point or 
[Basepoint/Scale/X/Y/Z/Rotate]:
Specify rotation angle <0>: 0.000000000000000
Command: -insert Enter block name or [?] <F>: N
Units: Millimeters   Conversion:    1.0000
Specify insertion point or [Basepoint/Scale/Rotate]: s Specify scale factor for 
XYZ axes <1>: 1 Specify insertion point or [Basepoint/Scale/Rotate]:
Specify rotation angle <0>: 0.000000000000000

 

0 Likes
Message 8 of 11

Kent1Cooper
Consultant
Consultant
Accepted solution

Do you have running Object Snap mode(s) turned on?  Does it work if you do this?

(command "-insert" (chr char) "s" 1 "_non" P 0.0)
Kent Cooper, AIA
0 Likes
Message 9 of 11

ireliontt
Explorer
Explorer
Thank you man!! It works just fine now!!
0 Likes
Message 10 of 11

Kent1Cooper
Consultant
Consultant

You're welcome.  Just for general reference, any time things or parts of things are drawn but end up in different positions/locations than you expect, running Object Snap is the most likely culprit.  Second most likely is probably UCS differences.

Kent Cooper, AIA
0 Likes
Message 11 of 11

Sea-Haven
Mentor
Mentor

Like Kent's suggestion this is what I use in nearly all my code,

 

(defun c:FF ( / aux P fio char oldsnap)
(setq oldsnap (getvar 'osmode))
(setvar 'osmode 0)
.... all the code
(setvar 'osmode oldsnap)
(princ)
)

 

 

If still problem try 16384 instead of 0.

0 Likes