Deviations from AutoCAD functionality for those porting existing software

Hello, I'm not sure where I should be putting this. I don't see most of these as bugs necessarily, but I thought I should at least share what I found. I just finished porting our MPT product, which is a mix of ARX and lisp, to Bricscad 12 and 13 and encountered the following "deviations" from AutoCAD functionality. I'm also including work arounds where available. Please keep in mind that much of this code is ancient and in some cases likely uses rather outdated techniques.

1. Prompt / getkword behavior change
In AutoCAD you could comibine prompts and the getkword function like this:
[code]
    (initget "R A X")
    (prompt "\nRelative/Absolute rotation/eXit? <") (prompt RorA)</div>
    (setq RorA1 (getkword ">: "))
[/code]
which would result in this at the command line:
Relative/Absolute rotation/eXit? :

In Briscad it results in this:
Relative/Absolute rotation/eXit?
>:

2. The getkwork is apparently always placed on a new line.

Should be replaced with:
    (setq RorA1 (getkword(strcat "\nRelative/Absolute rotation/eXit? <" RorA ">: ")))

NOTE this applies to all "get" functionality, i.e. getstring, getreal, etc. regardless of if initget is used.

3. Lisp -> ARX -> acedCommand issue

If a lisp command calls an ARX command that then calls another command via acedCommand, the order is messed up. The acedCommand call will wait until the original lisp call is done. There is no work around for this.

4. entmake limitation

Apparently entmake cannot be used to redefine anonymous blocks. It works fine for regular blocks, but anonymous blocks disappear. There is no work around for this, at least not in lisp.

5. Menu issues

Bricscad does not support using '+' to break lines in the menu file and they must be removed

6. Use of variables within the macro is not supported were strings are asked for (i.e. !var will be interpreted literally in lieu of evaluated where a string is being requested such as for a block name)

7. Hatch prompts are different

Examples:
[code]
    (if isBCad
      (if (= mscc_hatch "1")(command "._hatch" "_s" (entlast) "" "_p" "ansi32" h_scl (/ (* angr 180) pi) ""))
      (if (= mscc_hatch "1")(command "._hatch" "_steel" h_scl (/ (* angr 180) pi) (entlast) ""))
    )

    (if isBCad
      (command "._hatch" "_s" "L" "" "_p" "_U" "45" space "_N" "")
      (command "._HATCH" "_U" "45" SPACE "_N" "_L" "")
    )
[/code]
8. DCL \t issue

Bricscad doesn't appear to honor \t in DCL they must be removed for the text to display correctly.

9. Polygon prompts are different

use something like this:
[code]
    (if isBCad
      (if (= mscc_plug "1") (command "._POLYGON" "6" mscc_cp (strcat "@0," (rtos PR 2 6))))
      (if (= mscc_plug "1") (command "._POLYGON" "6" mscc_cp "_C" PR))
    )
[/code]
10. ~ from inside lisp doesn't work

While manually typing a ~ at the command line will raise a browse dialog, this does not work when called from (command) i.e. (command "._linetype" "L" "*" "~")

The work around is to pass two ~'s like this:
(command "._linetype" "L" "*" "~" "~" "")

11. Linetype spacing data changed

In V13, there is no longer any 49 data for linetypes, at least not for the center linetype. MPT used that information in the mscc_gen_cen function and so is now faked (assumes standard spacing from basic AutoCAD install).
[code]
      (if 49_grp
        (setq 49_a (cdr (nth 0 49_grp))
              49_b (abs (cdr (nth 1 49_grp)))
              49_c (cdr (nth 2 49_grp))
              49_d (abs (cdr (nth 3 49_grp)))
              49_tot (* (+ 49_a 49_b 49_c 49_d) dscl)
        )

        (setq 49_a 1.25 ;;**In Bricscad V13 there is no data here so fake it for now.
              49_b 0.25
              49_c 0.25
              49_d 0.25
              49_tot (* (+ 49_a 49_b 49_c 49_d) dscl)
        )
      )
[/code]
12. SSGet order is reversed

The result of the (ssget) function is reversed from AutoCAD so if looking for the last item in a selection, you need to look for the first in bcad like this:
(setq m_en (ssname ss (if isbcad 0 (1- (sslength ss)))))

13. XData difference

In AutoCAD xdata looks like:
((1001 . "LYR_STD") (1000 . "BASIC"))

while in Bricscad it’s:
(("LYR_STD" (1000 . "BASIC")))

Fix where xl is the returned xdata list:
[code]
        (if isBCad
          (setq nxl (car(subst(list(cons 1001 _appname)(cadr(assoc _appname xl)))(assoc _appname xl) xl)))
          (setq nxl xl)
        )
[/code]
14. ucs command prompts are different for Bricscad:

in AutoCAD this works: (command "._ucs" "_R" "PRE-ENLARGE" "" "_DEL" "PRE-ENLARGE")
This is required in Bricscad: (command "._ucs" "_R" "PRE-ENLARGE" "._ucs" "_DEL" "PRE-ENLARGE")

Use this to support both:
[code]
  (command "._ucs" "_R" "PRE-ENLARGE")
  (if(wcmatch (getvar "cmdnames") "*UCS*")
    (command "_DEL" "PRE-ENLARGE")
    (command "._ucs" "_DEL" "PRE-ENLARGE")
  )
[/code]

Comments

  • Dear Steve,
    just some answers ...

    for #13 XData :
    under which conditions do you get ((1001 . "LYR_STD") (1000 . "BASIC")) in AutoCAD,
    where BricsCAD does not return the same sequence ?
    As this should be fixed, indeed.
    Using (entget ename (lisp "*")) or (entget ename (lisp "MyApp")) returns the same
    list using -3 sentinel as AutoCAD does

    for #1 / #2 :
    yes, this is a known difference ... I will try to get this fixed for Lisp + BRX;
    internally that extra newline is necessary for some connabds, but for Lisp + BRX we
    should find a way to suppress extra newline

    for #3 Lisp -> ARX -> acedCommand :
    will try to reproduce, this needs to be fixed

    for #4 (entmake) for existing anonymous blocks
    shouldn't (entmod) be used better ? (entmake) always creates a new object ...
    maybe, you can erase the existing block definition just before creating a new one ?

    for #5 '+' syntax in menus
    already fixed, will be in upcoming V13.2.

    for #11 '49' missing DXF code for linetypes
    I will fix this right afterwards

    for #12 (ssget) order
    yes, also a known issue ... I already have a fix for this, which will provide
    same order as AutoCAD does, for "X", "C", "CP", "W", "WP" modes ... will likely
    be included in one of next BricsCAD;
    BUT
    it is simply not correct to rely on particular order of entities within a selectionset;
    of course, AutoCAD has that behaviour, but it is not guaranteed at all.
    Furthermore, ARX/BRX provide reactor interfaces for entity selection - therefore, applications
    can add/remove entities to/from selectionsets, causing unpredictable entity order.

    So in summary, it is bad application logic to rely on the entity order - strongly
    advised to rework the application logic here.

    As mentioned, it will get better in BricsCAD, but likely will never be 100% as in AutoCAD.

    --------

    For these and the others, please feel free to send us a "support request" (bug report),
    1 item per request please, so we can better schedule the issues to our developers.

    Especially the issue #3, #6, #8, #11, #13 seem worth to be documented.
    If possible, please provide a sample dwg and/or some Lisp snippets to reproduce,
    this makes it easier for us to reproduce.
  • @Steve:

    You should be aware that many commands will accept keywords that are not shown on the command line.
    For example:
    #9
    (command "._POLYGON" "6" mscc_cp "_C" PR)
    Also works in BricsCAD.
    #14
    (command "._ucs" "_R" "PRE-ENLARGE" "" "_DEL" "PRE-ENLARGE")
    Also works in BricsCAD.

    Regarding issue #11:
    Note that there are in fact two standard linetype files (imperial and metric).
    But, FWIW, I cannot reproduce the problem (BricsCAD V13.1.22):
    [code](entget (tblobjname "ltype" "center")) =>
    (
      (-1 . )
      (0 . "LTYPE")
      (5 . "9E")
      (330 . )
      (100 . "AcDbSymbolTableRecord")
      (100 . "AcDbLinetypeTableRecord")
      (2 . "CENTER")
      (70 . 0)
      (3 . "Center ____ _ ____ _ ____ _ ____ _ ____ _ ____")
      (72 . 65)
      (73 . 4)
      (40 . 50.8)
      (49 . 31.75)
      (74 . 0)
      (49 . -6.35)
      (74 . 0)
      (49 . 6.35)
      (74 . 0)
      (49 . -6.35)
      (74 . 0)
    )[/code]

  • The Forum has eaten some of the entiylist in my previous post. It should be:
    [code](
      (-1 . <Entity name: 0ce4a6f0>)
      (0 . "LTYPE")
      (5 . "9E")
      (330 . <Entity name: 0ce68660>)
      (100 . "AcDbSymbolTableRecord")
      (100 . "AcDbLinetypeTableRecord")
      (2 . "CENTER")
      (70 . 0)
      (3 . "Center ____ _ ____ _ ____ _ ____ _ ____ _ ____")
      (72 . 65)
      (73 . 4)
      (40 . 50.8)
      (49 . 31.75)
      (74 . 0)
      (49 . -6.35)
      (74 . 0)
      (49 . 6.35)
      (74 . 0)
      (49 . -6.35)
      (74 . 0)
    )[/code]
  • @Steve:
    Oops:
    #9
    (command "._POLYGON" "6" mscc_cp "_C" PR)
    Does work in BricsCAD but the result differs from:
    (command "._POLYGON" "6" mscc_cp (strcat "@0," (rtos PR 2 6)))
  • Dear Steve, Dear Roy,

    for #11 : linetype dxf 49
    indeed, (entget (tblobjname "LTYPE" ...)) works correctly;
    it is (tblsearch) and (tblnext) which incorrectly omitted dxf 49 ... as the data list shows, Acad creates the datalist not by internal (entget),
    but in dedicated code; we also do so since V13, for performance reasons.

    The issue with dxf 49 has been fixed internally, and such case was added to the test system.

    for #13 XData list
    I'm highly interested to get this solved, if there is any difference to AutoCAD - please provide a small sample and/or code snippet

    Many greetings !
  • for #13 XData : 
    under which conditions do you get ((1001 . "LYR_STD") (1000 . "BASIC")) in AutoCAD,
    where BricsCAD does not return the same sequence ?
    As this should be fixed, indeed.
    Using (entget ename (lisp "*")) or (entget ename (lisp "MyApp")) returns the same
    list using -3 sentinel as AutoCAD does

    I suspect this is due to using Xdata on layer 0 combined with very old code. We are setting and getting the data via result buffers in C++ and we have written a wrapper class for managing the result buffers so unfortunately it's rather difficult to isolate the specific code involved. The bottom line is that using the same wrapper in both AutoCAD and Bricscad produced different results as I have described. I have attached a drawing with xdata on layer 0 if that will help. As requested I will post a support request for this as well.


    for #4 (entmake) for existing anonymous blocks 
    shouldn't (entmod) be used better ? (entmake) always creates a new object ...
    maybe, you can erase the existing block definition just before creating a new one ?


    In this case we are using entmake to redefine a dimension that already exists in the drawing so I don't think erasing the definition will work, at least not without a lot of extra work.


    for #12 (ssget) order
    yes, also a known issue ... I already have a fix for this, which will provide
    same order as AutoCAD does, for "X", "C", "CP", "W", "WP" modes ... will likely
    be included in one of next BricsCAD;
    BUT
    it is simply not correct to rely on particular order of entities within a selectionset;
    of course, AutoCAD has that behaviour, but it is not guaranteed at all.
    Furthermore, ARX/BRX provide reactor interfaces for entity selection - therefore, applications
    can add/remove entities to/from selectionsets, causing unpredictable entity order.

    So in summary, it is bad application logic to rely on the entity order - strongly
    advised to rework the application logic here.


    Agreed, as mentioned, this is very old code, however, in this case it is dealing with objects we created in a previous operation so the order is "known".

    For these and the others, please feel free to send us a "support request" (bug report), 
    1 item per request please, so we can better schedule the issues to our developers.

    Especially the issue #3, #6, #8, #11, #13 seem worth to be documented.
    If possible, please provide a sample dwg and/or some Lisp snippets to reproduce,
    this makes it easier for us to reproduce.

    Will do.

    layer0xdatatest.dwg

  • @Steve:
    Oops:
    #9
    (command "._POLYGON" "6" mscc_cp "_C" PR)
    Does work in BricsCAD but the result differs from:
    (command "._POLYGON" "6" mscc_cp (strcat "@0," (rtos PR 2 6)))

    Exactly! For my purposes, the odd rotation the first method produces is very bad.
    Thanks
  • Dear Steve

    for #13 XData :
    so I assume, your C++ code returns the XData resbuf list via acedRetList()/ads_retlist() fucntion ?
    Can you document that resbuf list list here, so we can simulate such acedRetList/sds_retlist() with such a data list, and see
    why our Lisp returns a different representation ?
    Mainly, the sequence of resbuf type + value ... it is then easy to construct such data in our test system.

    for #12 ssget order
    as mentioned, most cases are already fixed internally, on my machine ... so good chances to get that fixed in one of upcoming BricsCAD versions.

    Many greetings !
  • issue #13. XData difference
    just fixed in our code ... now behaves as expected; many thanks !
  • Regarding #8 DCL issues, when using RADIO buttons;

    ACAD the buttons all appear as unchecked in the Dialog Box and there is a nil value for all variables.

    Bricscad the 1st button appears checked however returns a nil value, letting the user think the button as it appears is acceptable.

    This requires the use of a conditional statement to be sure the results are as expected.


  • @Bruce:
    You are right, but the problem only seems to occur when the radio_column or radio_row is the first 'clickable' tile in the dialog. When you say 'returns a nil value' I assume you mean the callback function for the radio_button is not triggered even though is appears as selected.

    After some experiments I have found a workaround for this. Don't know how this will work in AutoCAD.

    LSP:
    [code](defun c:DCL_Test ( / N_Accept N_Option1 N_Option2 N_Option3 dclFile)
      (defun N_Accept ()
        (print (get_tile "options"))
        (print (get_tile "option1"))
        (print (get_tile "option2"))
        (print (get_tile "option3"))
      )
      (defun N_Option1 ()
        (print "Option 1 was selected")
      )
      (defun N_Option2 ()
        (print "Option 2 was selected")
      )
      (defun N_Option3 ()
        (print "Option 3 was selected")
      )
      (setq dclFile (load_dialog "DCL_Test"))
      (new_dialog "DCL_Test" dclFile)
      (action_tile "option1" "(N_Option1)")
      (action_tile "option2" "(N_Option2)")
      (action_tile "option3" "(N_Option3)")
      (action_tile "accept" "(N_Accept)")
      (start_dialog)
      (unload_dialog dclFile)
      (princ)
    )[/code]

    DCL:
    [code]DCL_Test : dialog {
      label = "DCL_Test";
      : radio_column {
        key = "options";
        value = "";                                                        // Set value as workaround for radio problem.
        : radio_button {key = "option1"; label = "Option 1"; value = "1";} // Set value as workaround for radio problem.
        : radio_button {key = "option2"; label = "Option 2";}
        : radio_button {key = "option3"; label = "Option 3";}
      }
      ok_only;
    }[/code]
  • Dear Bruce, Dear Roy,

    indeed, using "radio_buttons" the Lisp code should definitely set initial conditions ...
    as for "radio buttons", one of them must always be selected, so it seems to be moe an AutoCAD issue,
    which allows this unlogical behaviour.

    But it is also a question of good style, to initialise the DCL values when the dialog is opened, not relying on defaults
    (ok, maybe for edit fields etc.).

    However, I will check with Tijs, if we can mimic this (formally incorrect) AutoCAD behaviour here.

    Many greetings !
  • Torsten,

    I am ok with how things are now, I was just bringing to the attention of any interested programers.  However as Roy pointed out, even within Bricscad the only instance where the 1st radio button appears selected is if the radio column/row is the first set of inputs within the DCL.

    Bruce
This discussion has been closed.