Lisp - New to Bricscad

Hello everyone -  I am in the process of attempting to modify my acad electrical tools package to work in bricscad.    I have about six hours into this and most of the code is working ( lisp and dcl).

A few questions:

1.   I am trying to use (entnext (entlast)) and (entnext (entnext (entlast))) to select attributes of blocks just inserted.  I am getting an error because what is returned is not in current space. 

(command "attedit" "" "" "" "" (entnext (entlast)) "v" "r" ......

My workaround is to just use entlast, and then use next within the attedit command,  but that is leading to other problems.

2.  Does the shorthand quote function not work at all ?    trying to pass a value from a list,    the value could be an integer or a variable.   In the list it may be 123 512 ... or 'os  (os is an integer variable for current osmode setting)

3. How does one autoload a lisp function when bricscad opens and keep it till the program shuts down ?  I am manually loading  functions using apload,  seems like they don't work in subsequent drawings.

 

Thanks in advance - Jay Petersen 

 

Comments

  • 1.
    Seems like a bug. This does work:
    (command "attedit" "" "" "" "" (entlast) (entnext (entlast)) "" "text" "replace" "My new text" "quit")

    2.
    Shorthand for quote works fine. Of course if you put a variable in a quoted list it will not be evaluated. Example:
    (setq os 4)
    (setq mylist '(1 2 os)) ; => (1 2 OS)
    (setq mylist (list 1 2 os)) ; => (1 2 4)

    3.
    Create a file on_doc_load.lsp in your support folder with lines like:
    (load "Mylisp1")
    (load "Mylisp2")

    ...
    Note: autoload is a specific lisp function used for on-demand-loading of command functions.

  • Scrap my first answer. It doesn't work:
    (command "attedit" "" "" "" "" (entlast) (entnext (entnext (entlast))) "" "text" "replace" "My new text 2" "quit") ; => changes the first attribute
    Works the same as:
    (command "attedit" "" "" "" "" (entlast) "" "text" "replace" "My new text 3" "quit") ; => changes the first attribute


    Have you tried (entmod ...)?

  • Thanks Roy.    Are you using the pro version ?  I am not.  I wonder if there are any lisp differences.    I get the not in current space message your way or mine.    I use entmod to change things in other places in my program,  this module just uses attedit.    If I can't get my lisp functions to work without minimal rewriting,  then no money is saved using bricscad.   

    my workaround is using the entlast function alone,  as you showed last.   Running into other problems.

    with the quote and os issue,  i worked around it by assiging an  integer that i'm not using elsewhere and then a subsequent if statement to assign the variable,  that's now ok

    Thanks with the autoload stuff.

    All of my code works with acad 2008,   does anyone have a list of syntax differences between brics and acad lisp?

    I had to modify how i was using (command "mtext"  to (command "-mtext"

    Jay

  • Lisp differences between Classic and Pro?
    No.

    Not in current space message.
    I get the same message. I'm pretty sure it is a bug and you should report it as such.

    Entmod+minimal rewriting.
    Depending on what you wish to accomplish, using entmod instead of attedit to change the attribute value doesn't seem like a lot of work:
    ; (changeAttVal (entnext (entlast)) "new text")
    (defun changeAttVal (ent val)
      (entmod
        (subst (cons 1 val) (assoc 1 (entget ent)) (entget ent))
      )
    )
    But no doubt you already have your own special entmod functions.

    The quote and os issue.
    I don't quite follow your explanation, but does Autocad behave differently here?

    Syntax differences between Bricscad and acad lisp.
    Since compatibility is a main issue for Bricscad developers, there ideally shouldn't be any... Filing a support request is a good idea if you come across these types of issues.

  • I agree that using entmod to change an attribute value is relatively easy,   however I am changing values, colors, layers, heights, angles etc ....

    Basically the routine inserts blocks into drawings,  but completely handles layers scales annotation ht's  depending on diferent client and in-house parameters.  Each block has a data list associated with it including image tile, location x&y scale .... preset attribute values and osmode for insert:

    see the 512 and 'os below

    '("i7" "Rectangle 4" "symb\\" "rect4" "rect4" 0.75 0.75 "ann" JEM 512 "no" "no" "edit" "." "y" 1)

    '("i8" "hex 1" "symb\\" "za_hex" "hex1" 0.375 0.375 "ann" JEM 'os "noR" "no" "edit" "." "y" 1)

    (setq osmode (nth 9 (nth n bdata))    ;  this line sets osmode to either an integer.  ie 512 or the current program osmode variable os.   It didn't like the 'os in the list.    No problems with acad2008 with any of this stuff.

    will report these as bugs.

     

    thx   Jay

     

  • Hello, Jay,
    there is indeed a SIGNIFICANT difference between OS and 'OS ...
    the quote causes to take the SYMBOL instead of its value ...

    Try this in Acad :
    (setq os 123) -> 123 -> the value
    (setq lst (list 1 2 os)) -> (1 2 123) -> evaluated OS value
    (setq lst '(1 2 os)) -> (1 2 OS) -> OS is taken as symbol
    (setq lst '(1 2 'os)) -> (1 2 (QUOTE OS))

    The same behaviour is in Bricscad ...
    beside a formal (but not functional) difference :
    (setq lst '(1 2 'os)) -> (1 2 'OS)

    In generally, be very careful when using quote for a symbol ...
    if you want to get the value of a symbol, always do not use the quote.

    Similar, your sample in Acad :
    (setq lst '("i8" "hex 1" "symb\\" "za_hex" "hex1" 0.375 0.375 "ann" JEM 'os "noR" "no" "edit" "." "y" 1))
    ->
    ("i8" "hex 1" "symb\\" "za_hex" "hex1" 0.375 0.375 "ann" JEM (QUOTE OS) "noR"
    "no" "edit" "." "y" 1)

    Same in Bricscad :
    ("i8" "hex 1" "symb\\" "za_hex" "hex1" 0.375 0.375 "ann" JEM 'OS "noR" "no" "edit" "." "y" 1)

    So in result, your list definition is wrong ... if Acad does indeed uses (QUOTE OS) as value, then
    it is clearly a but in Acad :-)

    Correct definition of your list would be :
    (setq lst (list "i8" "hex 1" "symb\\" "za_hex" "hex1" 0.375 0.375 "ann" JEM os "noR" "no" "edit" "." "y" 1))

    You can only use the QUOTE in case that all list members are literal values, but not symbol names.

    I hope this clears the situation ?
    Many greetings

  • Just forgotten - the problem with (entnext) :

    Indeed, there is a problem in Bricscad currently - the CAD core sometimes can return
    the next entity from a different space/layout ...
    So what you described is this incorrect behaviour :
    1. assume, (entnext) reaches the last entity in your current layout
    2. also assume, there was an automatic viewport created in other layout, by switching into that layout
    3. now, (entnext) will also switch to that layout :-(

    You can verify using
    (setq ename (entnext ename))
    (entget ename)

    => you will quickly recognise that a VIEWPORT entity is sometimes returned.
    that clearly causes the trouble you mentioned.

    This issue is currently about to be fixed (or at least, to be improved).

    Workaround :
    for the entity returned by (entnext), check whether 410 value matches the current
    layout, which is (getvar "clayout") ... if it is different, then (entnext) switched into
    another layout, and iterating using (entnext) should be stopped.

    At least, that workaround is also compatible with Acad, and prevents the problem.

    Many greetings

  • Thanks torsten -  I did try the OS without quotes in my list and it did not work.   I have worked around that problem,  so it's ok anyways.  

    Jay petersen

  • Hi everybody!

    @Torsten: It is true (according to my tests) that Bricscad returns also elements from layouts using entnext and entlast. However, this behaviour is the same in Acad too. (Then changes to the last element in the DB when switching to a different layout are a little confusing too me though.)

    Anyway, this does not seem to be the problem described above. Also on a new drawing when I create a block with an attribute manually (entlast then gives me the insert - everything in Modelspace) - even then it brings the error message with the wrong space when trying to select the Attribute with (entnext(entlast)).
    (Error-Message in German:
    Attribute wählen: (entnext(entlast))
    <Entity name: 05e63520>
    Attribute wählen:
    1 war nicht im aktuellen Bereich
    1 gefunden.
    Attribute wählen:

    Although it says "1 gefunden" in one of the lines, nothing is selected if I continue with pressing enter.

    @Jay: When I type "(setq osmode 0 os 512 bdata (list '(a b c) '(a b 'os)) osmode (nth 2 (nth 1 bdata)))" then Acad returns "(QUOTE OS)" and Bcad returns " 'OS", which is both actually the same. Those would then be the values of your variable "osmode". Would it be okay for you to paste the line(s) of code that process(es) the variable "osmode". I also can not understand how the behaviour would be different from Acad. If you paste the line(s) to show what your code does with "osmode", then maybe it will become clearer. Thanx.

  • > You can only use the QUOTE in case that all list members are literal values, but not symbol names. (#7 T.M.)

    This is not correct. You can use a symbol name in a quoted list. Of course you then need eval to get to the symbol's vale:

    (setq os 4)
    (setq mylist '(1 2 os)) ; => (1 2 OS)
    (eval (caddr mylist)) ; => 4
    (setq os 512)
    (eval (caddr mylist)) ; => 512


    In Jay's example:
    (setq os 135)
    (setq lstA '("i7" "Rectangle 4" "symb\\" "rect4" "rect4" 0.75 0.75 "ann" JEM 512 "no" "no" "edit" "." "y" 1))
    (setq lstB '("i8" "hex 1" "symb\\" "za_hex" "hex1" 0.375 0.375 "ann" JEM os "noR" "no" "edit" "." "y" 1))
    ;;; Note: no additional quote before os
    (setq osmode (eval (nth 9 lstA))) ; => 512
    (setq osmode (eval (nth 9 lstB))) ; => 135

  • Hello, All :-)

    @Jay - yes, I read that you found working code ... but it is highly interesting to see your
    original code, so that I can compare with Acad behaviour, to improve our Lisp engine,
    preventing similar confusion for future ...
    So I'm really interested to see your original code, where 'os is working for Acad -
    Thanks in advance

    @Stephan - hello, yes, you are right :-) Even Acad sometimes returns an element from
    different layout ... but Bricscad (currently) is still different here, it reports that automatically
    created viewport (in layout) - once you have switched into the layout - much more often
    then Acad does ... this is where Bricscad is currently improving ...
    Jay had reported 2 problems - the QUOTE problem, and the (entnext) problem, so I replied to
    both topics.
    But you are right - the problems reported to attributes should really be investigated; Jay filed
    a support request for.

    @Roy - yes, of course, you can use symbol names like 'os in quoted list ... and it needs to be
    evaluated afterwards, fully correct :-)
    I refered to the code as Jay has shown ... directly using list entries.

    Greetings to all, Torsten

  • Here are all the pieces of code that work in acad 2008 (and every version I have used in 12 years). Basically part of a block insert routine. bdata list controls all aspects of block insertion. os controls osmode during insertion. Sometimes it is desireable for osmode to stay whith whatever you are using. Thats what the 'os does. OS is the current osmode variable.

     (setq path "F:\\CPSBLKS\\custblks\\"

    bdata (list

    " "Rectangle 4" "symb\\" "rect4" "rect4" 0.75 0.75 "ann" JEM 512 "no" "no" "edit" "." "y" 1)

    '("i8" "hex 1" "symb\\" "za_hex" "hex1" 0.375 0.375 "ann" JEM 'os "noR" "no" "edit" "." "y" 1)

    (setq osmode (nth 9 (nth n bdata)))

     

    (command "osmode" osmode )

     work around is just put 500 in place of osmode and then (if (= osmode 500) (setq osmode os))

     

    I have not had a problem with acad returning the wrong entnext data

     

  • @Jay - now I think I can explain what happens ...
    mainly, your code never worked properly since Acad R 12 :-)

    Please let me explain - you can follow in Acad as well, and you will see what happens :

    I used slightly simplified code :
    (setq os (getvar "osmode"))
    (setq bdata '("i8" "hex 1" "symb\\" "za_hex" "hex1" 0.375 0.375 "ann" JEM 'os "noR" "no" "edit" "." "y" 1))
    (setq osmode (nth 9 bdata))
    (command "osmode" osmode )

    Initially, I had OSMODE system variable set to 1 ...
    using
    (setq osmode (nth 9 bdata)) ; -> (quote OS) resp. 'OS, which is the same.
    now set "osmode" system variable to 0, and verify the Lisp variables :
    !os => 1
    !osmode => (quote os) resp. 'os
    (command "osmode" osmode ) => makes NOTHING in Acad !!

    Input of (quote OS) does not make sense to Acad command interface, and it is simply ignored !
    Object snap did not change at all ...

    The difference with Bricscad is, that Bricscad repeats the input prompt for (command "osmode" ...),
    so the input sequence gets scrambled ... that is what you recognised.

    Therefore, please do not use your workaround - your list definition is wrong;
    please use correct list with :
    '("i8" "hex 1" "symb\\" "za_hex" "hex1" 0.375 0.375 "ann" JEM 'os "noR" "no" "edit" "." "y" 1)) ;; os without ' quote

    use os instead of 'os is fine for both Acad and Bricscad.

    I hope this finally clears this problem ?

  • You are right,   It isn't returning the value,  just ignoring it later.    If i go to OS without quote,  it works,  but i need to use EVAL to get the value.   

    OK lets put this one to bed.

     

    jay 

  • Dear Jay, thanks for reply ...
    when using OS without quote, there is no need to use (eval) ...
    in opposite, (eval) could be used with original code :

    (command "_osmode" os)
    or
    (command "_osmode" (eval 'os))
    then it would work ...

    However, it might be even better to use
    (setvar "osmode" os)
    instead :-)

    Greetings, Torsten

  • Torsten -  sitting at my acad station right now.   Eval seems to be needed in acad 2008.

    Using OS without quotes in the list.

    (setq osmode (nth 9 (nth n bdata)))

     

    (command "osmode" (eval osmode) )

    command line shows from princ :  OSMODE VARIABLE =OS

    jay

    (PRINC "OSMODE VARIABLE =")(PRINC OSMODE)
  • Dear Jay, yes, because you probably still have '(... 'os ...) ?
    with your original list definition, indeed, (eval os) will return the value ...
    but if your list contains os without quote, then you can use os directly :-)

This discussion has been closed.