Visual LISP, AutoLISP and General Customization

Visual LISP, AutoLISP and General Customization

Reply
Contributor
spence138
Posts: 17
Registered: ‎09-12-2008
Message 1 of 17 (100 Views)

Total lisp newbie looking for help

100 Views, 16 Replies
02-05-2009 07:53 AM
I know little-to-nothing about lisp so far and haven't had a lot of time to study. I have been trying to learn some by looking at examples and trying to figure out how the commands work within the example but progress is slow. I've been using the following as a button macro for a while and it works ok, but I would like to improve upon it with lisp if possible.

^C^C_ai_molc \-insert CASING \1;; (add a third ";" to the end if desired rotation angle is always zero)

The user selects an object on the desired layer if the current layer is not correct and then it inserts the CASING block at the location of choosing. The problem is that often there is nothing nearby (w/o panning & zooming around) to select on the proper layer. So what I usually end up doing is selecting the object I'm placing the casing on (in this case a water main) and then moving the block to the proper layer afterwards. What I would like is for a lisp or macro that will set the proper layer based upon the layer of an object selected. For example, using the following layers:

12_CASING
12_PIPE
12_TEXT

If I selected an object on layer 12_PIPE, I would like the block (or multileader) to be placed on layer 12_CASING (or 12_TEXT).

If this is possible, I would also like to have another version that uses a Multileader (with a specific style) instead of a block. Thanks in advance for any help you can offer.
Distinguished Contributor
tom_brabant
Posts: 404
Registered: ‎12-08-2003
Message 2 of 17 (100 Views)

Re: Total lisp newbie looking for help

02-05-2009 08:46 AM in reply to: spence138
Below is something that might at least aid your research.
If you invoke test and pick an entity near one of its endpoints, it should draw a circle of unit radius exactly upon the endpoint, then change the layer of this circle to the layer of the picked entity.


(defun c:test ()
(setq pickdata (entsel " pick object near endpoint ")
entity (car pickdata)
pickpoint (cadr pickdata)
pickpoint_endpoint (osnap pickpoint "end")
layer (cdr (assoc 8 (entget entity)))
)
(command "circle" pickpoint_endpoint 1.0)
(command "chprop" (entlast) "" "lay" layer "")
)
*Expert Elite*
scot-65
Posts: 2,179
Registered: ‎12-11-2003
Message 3 of 17 (100 Views)

Re: Total lisp newbie looking for help

02-05-2009 04:28 PM in reply to: spence138
For your first part, direct the object to the target layer after creation instead of
setting the environment, then adding the object, then restoring the environment.
You have to remember that *Cancel* will disrupt everything...

Maybe create subroutines that can help you with this chore:

(defun DIRECTTOLAYER-L ( a / )
(command ".CHPROP" "L" "" "Layer" a "")
(princ)
);end

(defun DIRECTTOLAYER-P ( a / )
(command ".CHPROP" "P" "" "Layer" a "")
(princ)
);end

Place the above in your acaddoc or acad or MNL file and you are ready to go...

At the end of your macro just add the following:
^C^C_ai_molc \-insert CASING \1;;\(DIRECTTOLAYER-L "MyNewLayer")
Where "My New Layer" is the target layer name...

Keep Going!
Scot-65
Dyslexia is a permanent physical disability that cannot be seen.
Introverts is proof that there is indeed intelligent life on this planet.
Contributor
spence138
Posts: 17
Registered: ‎09-12-2008
Message 4 of 17 (100 Views)

Re: Total lisp newbie looking for help

02-06-2009 05:29 AM in reply to: spence138
> {quote:title=scot-65 wrote:}{quote}
> At the end of your macro just add the following:
> ^C^C_ai_molc \-insert CASING \1;;\(DIRECTTOLAYER-L "MyNewLayer")
> Where "My New Layer" is the target layer name...
>
> Keep Going!

The problem with going this route is that the target layer name will vary often within a single file as there are CASING layers for all water main sizes between 2 and 48 inches. I was playing with the code left by Tom and was trying replace this line;
{code}layer (cdr (assoc 8 (entget entity))){code}
with something like this;
{code}layer (strcat (substr ((cdr (assoc 8 (entget entity)) 1 3) "_CASING")){code}
or this;
{code}layer (cdr (assoc 8 (entget entity)))
newlayer (strcat (substr (layer 1 3) "_CASING")){code}
If I understand the strcat & substr commands correctly; the substr (layer 1 3) should pull the layer variable value (in this case 12_PIPE), begin at the begining and retain only the first 3 characters (12_); and then the strcat should combine that with the "_CASING" giving the result of "12_CASING". But unfortunately this code gives me error: bad function: "12_PIPE"
Distinguished Contributor
Chatchawal
Posts: 124
Registered: ‎09-22-2008
Message 5 of 17 (100 Views)

Re: Total lisp newbie looking for help

02-06-2009 06:05 AM in reply to: spence138
My assumption :
The selected object may be on 2_PIPE, 8_PIPE, ... 48_PIPE layer.
And the insertion block must be on SIZE_CASING layer when SIZE=2, ... , 48.

If It's correct, Try these routines.

{code};;; Use the nearest point on the selected object as the insertion point.
(defun c:case (/ epl e p prefix target_layer)
(if (setq epl (entsel "\nSelect object to get layer prefix:"))
(progn
(setq e (car epl)
p (osnap (cadr epl) "Near")
prefix (substr (cdr (assoc 8 (entget e))) 1 3)
target_layer (strcat prefix "CASING")
)
(setvar "cmdecho" 0)
(command "layer" "m" target_layer "")
(command "-insert" "CASING" p 1 1 1 0)
(setvar "cmdecho" 1)
)
(princ "\nNo object found!!!")
)
(princ)
)
;;; Specify an insertion point by User.
(defun c:casep (/ epl e p prefix target_layer)
(if (setq epl (entsel "\nSelect object to get layer prefix:"))
(progn
(setq e (car epl)
prefix (substr (cdr (assoc 8 (entget e))) 1 3)
target_layer (strcat prefix "CASING")
)
(initget 1)
(setq p (getpoint "\nSpecify insertion point: "))
(setvar "cmdecho" 0)
(command "layer" "m" target_layer "")
(command "-insert" "CASING" p 1 1 1 0)
(setvar "cmdecho" 1)
)
(princ "\nNo object found!!!")
)
(princ)
){code}
Contributor
spence138
Posts: 17
Registered: ‎09-12-2008
Message 6 of 17 (100 Views)

Re: Total lisp newbie looking for help

02-06-2009 06:16 AM in reply to: spence138
Chatchawal,

The casing block already exists in the file as do all the proper layers but after selecting the object to get the layer prefix the command window returns:
{code}Select object to get layer prefix:
"CASING.dwg": Can't find file in search path:
C:\Documents and Settings\spencejt\My Documents\ (current directory)
M:\WV_SOUTH\Mercer Summers\
C:\Documents and Settings\spencejt\Application Data\Autodesk\AutoCAD Map 3D
2009\R17.2\enu\support\
M:\CAD_STDS\
C:\Program Files\AutoCAD Map 3D 2009\support\
C:\Program Files\AutoCAD Map 3D 2009\fonts\
C:\Program Files\AutoCAD Map 3D 2009\help\
C:\Program Files\AutoCAD Map 3D 2009\Express\
C:\Program Files\AutoCAD Map 3D 2009\support\color\
C:\Program Files\AutoCAD Map 3D 2009\FDO\bin\
C:\Program Files\Raster Design 2009 OE\
C:\Program Files\AutoCAD Map 3D 2009\drv\
C:\Program Files\AutoCAD Map 3D 2009\
*Invalid*{code}
After I break the command the layer is being set correctly which is awsome! The problem seems to be with the block insertion which I'm trying to work out. Edited by: spence138 on Feb 6, 2009 9:25 AM
Contributor
spence138
Posts: 17
Registered: ‎09-12-2008
Message 7 of 17 (100 Views)

Re: Total lisp newbie looking for help

02-06-2009 06:30 AM in reply to: spence138
I figured out the problem with the error I was getting, the block name is actually CASING_STD and once I fixed that it worked though. The only problem I see now is it doesn't let me choose a rotation angle when placing the block.
Distinguished Contributor
Chatchawal
Posts: 124
Registered: ‎09-22-2008
Message 8 of 17 (100 Views)

Re: Total lisp newbie looking for help

02-06-2009 06:33 AM in reply to: spence138
The above coding list , mistake on

(command "-insert" "CASING" p 1 1 1 0)

It should be

(command "-insert" "CASING" p 1 1 0)

For zero rotation angle.


Try the new revision:
As per the attachment.
Contributor
spence138
Posts: 17
Registered: ‎09-12-2008
Message 9 of 17 (100 Views)

Re: Total lisp newbie looking for help

02-06-2009 07:01 AM in reply to: spence138
Sweet that seems to do it though I needed to remove one of the 1's! Thank you very much for the help with this.

I do have a couple questions about this though.
1. After dropping in the block and picking the rotation point the command line pauses and I must right or left click to end the command, is this normal or can I add some code to end the command automatically?
2. What do I need to do to force this lisp to load automatically?
3. Is it possible to call an action-macro instead of inserting a block? I have an action-macro that begins the multileader command using a specific style, or can that be done w/o the action-macro?
4. After running this command the cpu will spike for several seconds and sometimes I am unable to select any window on the desktop (autocad, visual lisp, explorer, etc.) for a short time (up to a couple minutes so far). Even if I make a window active using alt-tab the mouse still has no effect on it.
Contributor
spence138
Posts: 17
Registered: ‎09-12-2008
Message 10 of 17 (100 Views)

Re: Total lisp newbie looking for help

02-06-2009 07:01 AM in reply to: spence138
Hmm. Seems that having the discussion groups open in more than one tab within explorer causes posts to be posted multiple times.

Edited by: spence138 on Feb 6, 2009 10:02 AM

Just saw your other post and am testing it out now. Edited by: spence138 on Feb 6, 2009 10:04 AM
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.