Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Total lisp newbie looking for help

16 REPLIES 16
Reply
Message 1 of 17
spence138
259 Views, 16 Replies

Total lisp newbie looking for help

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.
16 REPLIES 16
Message 2 of 17
tom_brabant
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 "")
)
Message 3 of 17
scot-65
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
A gift of extraordinary Common Sense does not require an Acronym Suffix to be added to my given name.


Message 4 of 17
spence138
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"
Message 5 of 17
Chatchawal
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}
Message 6 of 17
spence138
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
Message 7 of 17
spence138
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.
Message 8 of 17
Chatchawal
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.
Message 9 of 17
spence138
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.
Message 10 of 17
spence138
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
Message 11 of 17
Chatchawal
in reply to: spence138

1 &4 Result from the mistake of the first code listing.

2. Use APPLOAD command , Click 'Contents' in 'Startup suite'.
Add this file to automatically load every time.

3. ???
Message 12 of 17
spence138
in reply to: spence138

I think I figured out the answer to my question 1, when I run the command from the command line instead of from inside the lisp editor the command seems to end normally.

I used your previous example and modified the case2 file to the following:
{code}(defun c:case (/ oldosmode epl e p orig_layer prefix target_layer msg tmp)
(setq oldosmode (getvar "osmode"))
(if (not #angle)
(setq #angle "0")
)
(if (setq epl (entsel "\nSelect object to get layer prefix:"))
(progn
(setq e (car epl)
p (getpoint "\nSpecify insertion point: ")
orig_layer (cdr (assoc 8 (entget e)))
prefix (substr (cdr (assoc 8 (entget e))) 1 3)'
target_layer (strcat prefix "CASING")
)
(foreach msg (list "\nSpecify rotation angle: <" #angle "> ")
(princ msg)
)
(initget 32)
(setq tmp (getorient p))
(if tmp
(setq #angle (angtos tmp 0))
)
(setvar "cmdecho" 0)
(setvar "osmode" 0)
(command "layer" "m" target_layer "")
(command "-insert" "CASING_STD" p 1 1 #angle)
(setvar "osmode" oldosmode)
(command "layer" "s" orig_layer "")
(setvar "cmdecho" 1)
)
(princ "\nNo object found!!!")
)
(princ)
){code}

I'm unsure what purpose the (initget 32) serves though, is it what causes the dashed line to be displayed when selecting the angle?
Message 13 of 17
Chatchawal
in reply to: spence138

From 'AutoLISP Reference guide', Initget section:

32 (bit 5) Uses dashed lines when drawing a rubber-band line or box. For those functions with which the user can specify a point by selecting a location in the drawing area, this bit value causes the rubber-band line or box to be dashed instead of solid. (Some display drivers use a distinctive color instead of dashed lines.) If the system variable POPUPS is 0, AutoCAD ignores this bit.


- Notice on the line (foreach msg (list "\nSpecify rotation angle: <"> "),
It's BUG on this webboard when using < Character, it truncate some words.
So I posted the latest revision as the attachment.

- Your coding (command "layer" "s" orig_layer "") => Reset to The previous layer ,
The best practice in LISP coding.
Message 14 of 17
spence138
in reply to: spence138

I attempted to modify the Case code to insert a multileader on the ##_TEXT layer but am having little luck. I figure the problem is the initget function but for the life of me I can't grasp what the help doc is talking about, partially because it says "The bits can be added together in any combination to form a value between 0 and 255." but it lists values up to 1024.
Message 15 of 17
EC-CAD
in reply to: spence138

Here's a problem.
You 'start' the command mleader.. and give it a point.
But, that's not all the mleader needs for input.
You will want to 'wait' until the mleader command is finished,
before going on to next operation..
So, try this change:
...
(command "cmleaderstyle" "std_16" "mleader" p);Set mleader style & begin mleader
(while (> (getvar "cmdactive") 0)
(command pause)
); while
(setvar "osmode" oldosmode)
...
Bob
Message 16 of 17
spence138
in reply to: spence138

Thanks for the help Bob, that took care of the final problem.

I also found some info on another post about making sure the multitext box opens for the multileader instead of being limited to a single line of text on the command line. So the attached file works very nicely now.

Thanks again to everyone that helped!
Message 17 of 17
Chatchawal
in reply to: spence138

From your attachment and EC-CAD coding ,
That's Nice coding for Multileader on 'Size_TEXT' Layer.

And I add a little tuning as per this attachment.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost