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

Ribbon polyline command

19 REPLIES 19
SOLVED
Reply
Message 1 of 20
sjg
Advisor
1247 Views, 19 Replies

Ribbon polyline command

Creating a ribbon for Partial Customization files in the CUI, and I am trying to setup some buttons for existing polylines for example underground electric and overhead electric. When writing the macro what are some ideas for creating a polyline with the proper linetype for that particular object rather than changing the layer in layer properties dialogue.
Steve Goessling
Land Consultants
Civil3D 2015
Windows 7, 64 bit
Intel i7 2600 @ 3.40Ghz
16 GB RAM
Nvidia Quadro 600
19 REPLIES 19
Message 2 of 20
fenton.webb
in reply to: sjg

Can't you just use the -layer command?




Fenton Webb
AutoCAD Engineering
Autodesk

Message 3 of 20
hmsilva
in reply to: fenton.webb

Or -ltype command?

Henrique

EESignature

Message 4 of 20
sjg
Advisor
in reply to: hmsilva

Yeah after I wrote this, I figured it out. Next question is if I have a layer set and then use my macro to draw a line, how would I set back to previous layer.
Steve Goessling
Land Consultants
Civil3D 2015
Windows 7, 64 bit
Intel i7 2600 @ 3.40Ghz
16 GB RAM
Nvidia Quadro 600
Message 5 of 20
Kent1Cooper
in reply to: sjg


@sjg wrote:
Yeah after I wrote this, I figured it out. Next question is if I have a layer set and then use my macro to draw a line, how would I set back to previous layer.

There are many routines on this forum that do that, usually by first saving the current Layer name to a variable, setting to the desired Layer to draw something, and re-setting the original Layer current at the end.  Search for

 

(setq SomeVariableName (getvar 'clayer))

or

(setq SomeVariableName (getvar "clayer"))

 

near the beginning of routines, and

 

(setvar 'clayer SomeVariableName)

or

(setvar "clayer" SomeVariableName)

 

near the end, or near the beginning in an error handler.  Obviously you can't search for SomeVariableName, so search for the blue parts [not case-sensitive].  It can also be done within a Layer command, but I think doing it by way of the CLAYER System Variable is more common.

Kent Cooper, AIA
Message 6 of 20
sjg
Advisor
in reply to: Kent1Cooper

I appreciate your help, this is a learning experience. See the following code ^C^C(setq oldlayer (getvar "clayer"));-layer;S;V-UTIL-ELEC;;-lt;Set;"Ex U.E._LC";;pline;/(setvar "clayer" old layer); Everything seems to be working but I can't seem to figure out the pause for user input tried the /,, but that is for just one click. Is there a symbol for multiple user inputs. Thanks again.
Steve Goessling
Land Consultants
Civil3D 2015
Windows 7, 64 bit
Intel i7 2600 @ 3.40Ghz
16 GB RAM
Nvidia Quadro 600
Message 7 of 20
fenton.webb
in reply to: sjg

You have to essentially do this, but in LISP

 

http://adndevblog.typepad.com/autocad/2012/04/synchronously-send-and-wait-for-commands-in-autocad-us...




Fenton Webb
AutoCAD Engineering
Autodesk

Message 8 of 20
BlackBox_
in reply to: sjg


@sjg wrote:
I appreciate your help, this is a learning experience. See the following code ^C^C(setq oldlayer (getvar "clayer"));-layer;S;V-UTIL-ELEC;;-lt;Set;"Ex U.E._LC";;pline;/(setvar "clayer" old layer); Everything seems to be working but I can't seem to figure out the pause for user input tried the /,, but that is for just one click. Is there a symbol for multiple user inputs. Thanks again.

PAUSE in a macro is a backslash "\" and not a forwardslash "/" as in your code.

 

Also, your macro is subject to failure, specifically the failure to restore the original layer in the event of user hitting esc, or an actual error... For this sort of (complex?) task, I prefer to actually code this in LISP, and have the macro call the LISP... Example:

 

Sample macro, demand loads the LISP:

 

^C^C^P(if (not c:FOO)(load "FOO.lsp")) FOO ^P

 

Sample LISP (saved to "FOO.lsp" and located within your SFSP😞

 

(defun c:FOO (/ *error* clayer celtype)

  (defun *error* (msg)
    (and clayer (setvar 'clayer clayer))
    (and celtype (setvar 'celtype celtype))
    (cond ((not msg))                                                   ; Normal exit
          ((member msg '("Function cancelled" "quit / exit abort")))    ; <esc> or (quit)
          ((princ (strcat "\n** Error: " msg " ** ")))                  ; Fatal error, display it
    )
    (princ)
  )

  (if (and (setq clayer (getvar 'clayer))
           (setvar 'clayer "V-UTIL-ELEC")
           (setq celtype (getvar 'celtype))
           (setvar 'celtype "Ex U.E._LC")
      )
    (progn
      (command "._pline")
      (while (= 1 (logand (getvar 'cmdactive) 1))
        (command pause)
      )
    )
  )
  (*error* nil)
)

 

HTH



"How we think determines what we do, and what we do determines what we get."

Message 9 of 20
BlackBox_
in reply to: fenton.webb


@fenton.webb wrote:

You have to essentially do this, but in LISP

 

http://adndevblog.typepad.com/autocad/2012/04/synchronously-send-and-wait-for-commands-in-autocad-us...


Hi Fenton,

 

I'm not sure that mentally porting C#.NET code to LISP is a reasonable expectation in this instance (I could be wrong), as the OP is merely asking for assistance with a moderately complex macro... I'd venture the guess that even fewer of us in this thread could do so.

 

 

 

Separately, FWIW - In your DevBlog article, this line is chopped (not fully viewable, no matter the width of my browser) due to Namespace qualification:

 

string cmdNames = (string)Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("CMDNAMES");

 

acad.devblog.code.format.png

 

 

... Perhaps including the using calls would help to mitigate this, and make future articles more readable for those who do not copy the code into VS; specifically the addition of:

 

using acApp = Autodesk.AutoCAD.ApplicationServices.Application;

// <snip>

                // see what commands are active
                string cmdNames = (string)acApp.GetSystemVariable("CMDNAMES");

// <snip>

 

Cheers

 



"How we think determines what we do, and what we do determines what we get."

Message 10 of 20
fenton.webb
in reply to: BlackBox_

The example I posted obviously got the ball rolling, thanks BlackBox!




Fenton Webb
AutoCAD Engineering
Autodesk

Message 11 of 20
sjg
Advisor
in reply to: fenton.webb

Attached is what I came up with, it works like I would was wanting it to, please review.
Steve Goessling
Land Consultants
Civil3D 2015
Windows 7, 64 bit
Intel i7 2600 @ 3.40Ghz
16 GB RAM
Nvidia Quadro 600
Message 12 of 20
BlackBox_
in reply to: fenton.webb


@fenton.webb wrote:

... thanks BlackBox!


You're welcome, my friend. 

 

Cheers



"How we think determines what we do, and what we do determines what we get."

Message 13 of 20
BlackBox_
in reply to: sjg


@sjg wrote:
Attached is what I came up with, it works like I would was wanting it to, please review.

... Did you try the code posted here?

 

 



"How we think determines what we do, and what we do determines what we get."

Message 14 of 20
sjg
Advisor
in reply to: sjg

Sorry, not yet. I will try it tomorrow. I am new to lisp and trying to understand basic functions. Is it possible if you could kind of explain your lisp, if not that's fine. I appreciate your help.
Steve Goessling
Land Consultants
Civil3D 2015
Windows 7, 64 bit
Intel i7 2600 @ 3.40Ghz
16 GB RAM
Nvidia Quadro 600
Message 15 of 20
BlackBox_
in reply to: sjg


@sjg wrote:
Sorry, not yet. I will try it tomorrow. I am new to lisp and trying to understand basic functions. Is it possible if you could kind of explain your lisp, if not that's fine. I appreciate your help.

No worries; we all start somewhere.

 

To start you'd want to copy the LISP code into a new, empty text file, and save it as "FOO.lsp" to a location included within your Support File Search Paths (SFSP). Then you'd copy, and paste the sample macro, into one the desired CUI component(s). Save your CUI, and try the button/menu.

 

The macro first checks to see if the command has been defined, and if not will load the dependent LISP file ("FOO.lsp" which should be saved to your SFSP), and then calls the command. This is beneficial as it only loads the code into memory when needed, rather than loading at drawing open, which takes some (small?) amount of time depending on how many routines you have loaded at drawing open.

 

The LISP that is loaded, and subsequently called does essentially the same as your original, working macro, but with the added benefit of error handling, and proper restoration of system variable(s).

 

I hope you find this useful.

 

Cheers



"How we think determines what we do, and what we do determines what we get."

Message 16 of 20
sjg
Advisor
in reply to: BlackBox_

Sample code worked like a charm. I like how the sample lisp eliminates all the steps, where my lisp lists all the steps in the command line. Thanks again.
Steve Goessling
Land Consultants
Civil3D 2015
Windows 7, 64 bit
Intel i7 2600 @ 3.40Ghz
16 GB RAM
Nvidia Quadro 600
Message 17 of 20
BlackBox_
in reply to: sjg


@sjg wrote:
Sample code worked like a charm. I like how the sample lisp eliminates all the steps, where my lisp lists all the steps in the command line. Thanks again.

That is kind of you to say; I'm happy to help.

 

Cheers :beer:



"How we think determines what we do, and what we do determines what we get."

Message 18 of 20
Kent1Cooper
in reply to: BlackBox_


@BlackBox_ wrote:
.... 

The macro first checks to see if the command has been defined, and if not will load the dependent LISP file ("FOO.lsp" which should be saved to your SFSP), and then calls the command. This is beneficial as it only loads the code into memory when needed, rather than loading at drawing open....


An alternative way to do the same is to use the (autoload) function to "prime" AutoCAD with the command name, but to not actually load the .lsp file unless and until the command is called for.  A line like this in acaddoc.lsp will do that:

 

(autoload "FOO" '("FOO"))

 

If you do it that way, the macro can be simply:
 

^C^CFOO

 

If the command is already defined, it will use it.  If not, (autoload)'s "priming" will kick in and it will load the file and use the command.

 

I like that approach [even if the (autoload) line makes acaddoc.lsp take a few milliseconds more to run], because:
1.  it doesn't force a check on whether the command is defined [that also takes a tiny bit of time] every time you pick on the menu item that contains the macro, and

2.  you can call the command the first time by typing FOO if you prefer, and are not required to use the menu item the first time just to get the command loaded in.  Typing it can be a lot faster if you know the command name and the menu item requires any navigation to get to [pull-down or screen menu that may need to be taken down a level or more, toolbar or tool palette that may need to be brought up, etc.].

 

It also simplifies things if you have one .lsp file that defines multiple commands, which you can (autoload) all together:
 

(autoload "FOO" '("FEE" "FI" "FO" "FUM"))

with macros that similarly don't all individually need to check whether their command has been defined:

^C^CFEE

^C^CFI

^C^CFO

^C^CFUM

If and when any of those commands is called for for the first time, whether via its macro or by typing, the file with all of them will be loaded.  [That could be an argument for not defining multiple commands in one file, if the loading of several when you need only one is considered unnecessary overhead.  With only closely-related commands defined together in common files, the counter-argument can be made that it reduces the number of files and simplifies management of them, and often, if you're using one of them, you're likely to also have a need for others from the same file.]

Kent Cooper, AIA
Message 19 of 20
BlackBox_
in reply to: Kent1Cooper


@Kent1Cooper wrote:

@BlackBox_ wrote:
.... 

The macro first checks to see if the command has been defined, and if not will load the dependent LISP file ("FOO.lsp" which should be saved to your SFSP), and then calls the command. This is beneficial as it only loads the code into memory when needed, rather than loading at drawing open....


An alternative way to do the same is to use the (autoload) function to "prime" AutoCAD with the command name, but to not actually load the .lsp file unless and until the command is called for.  A line like this in acaddoc.lsp will do that:

 

(autoload "FOO" '("FOO"))

 

If you do it that way, the macro can be simply:
 

^C^CFOO

 

If the command is already defined, it will use it.  If not, (autoload)'s "priming" will kick in and it will load the file and use the command.

 

I like that approach [even if the (autoload) line makes acaddoc.lsp take a few milliseconds more to run], because:
1.  it doesn't force a check on whether the command is defined [that also takes a tiny bit of time] every time you pick on the menu item that contains the macro, and

2.  you can call the command the first time by typing FOO if you prefer, and are not required to use the menu item the first time just to get the command loaded in.  Typing it can be a lot faster if you know the command name and the menu item requires any navigation to get to [pull-down or screen menu that may need to be taken down a level or more, toolbar or tool palette that may need to be brought up, etc.].

 

It also simplifies things if you have one .lsp file that defines multiple commands, which you can (autoload) all together:
 

(autoload "FOO" '("FEE" "FI" "FO" "FUM"))

with macros that similarly don't all individually need to check whether their command has been defined:

^C^CFEE

^C^CFI

^C^CFO

^C^CFUM

If and when any of those commands is called for for the first time, whether via its macro or by typing, the file with all of them will be loaded.  [That could be an argument for not defining multiple commands in one file, if the loading of several when you need only one is considered unnecessary overhead.  With only closely-related commands defined together in common files, the counter-argument can be made that it reduces the number of files and simplifies management of them, and often, if you're using one of them, you're likely to also have a need for others from the same file.]


I am familiar with AUTOLOAD; it is very useful, and I use it often.

 

I too prefer to demand load my commands, and find it advantageous to make the command available from both a would-be menu/button macro, and command line (which I use predominantly myself).

 

I really only implement macro based CUI components for internal resources intended to be distributed throughout the region I am responsible for as part of Enterprise CUI, or as of late, for apps being prepared/submitted to Autodesk Exchange (as it is a submittal requirement).

 

I was simply explaining the procedure, and benefit over a basic (non-error handling) macro... Nothing more.

 

Interesting that here you're all for the additional features, etc. when your myriad other offerings are, well, not... It's nice to see that the pendulum can swing the other way, Kent.

 

Cheers



"How we think determines what we do, and what we do determines what we get."

Message 20 of 20
BlackBox_
in reply to: BlackBox_

FWIW - I thought where this topic was headed sounded familiar, I should have just quoted this post instead.



"How we think determines what we do, and what we do determines what we get."

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

Post to forums  

Autodesk Design & Make Report

”Boost