vle-getgeomextents

I'm having trouble making vle-getgeomextents work and think I must be missing something.  I'm trying to get an aligned bounding box for a block that is rotated.  vle-getgeomextents works as expected for a non-rotated symbol.  My intent was to store the block rotation, reset the rotation to 0.0, then run vle-getgeomextents. 
[code](defun c:geo ( / a b c d)
  (setq a (entlast))
  (setq b (vle-getgeomextents a))
  (setq c (car b))
  (setq d (cadr b))
  (command "rectangle" c d)
  (vle-entmod 50 a 0.0)
;  (setq a (entlast))
  (setq b (vle-getgeomextents a))
  (setq c (car b))
  (setq d (cadr b))
  (command "rectangle" c d)
)
[/code]
Before running the code above insert a block in a drawing and rotate the block to an angle other than 0.0.  I would expect one rectangle for the limits of the rotated symbol and one for the symbol at 0.0 rotation.  What I see is two rectangles for the original rotated symbol.  Re-reading the block with (setq a (entlast)) does not change the output.  Running (TRANS) on the points does not help.  I can code this with vla-GetBoundingBox but I'd rather avoid safearrays.  Probably something simple I'm overlooking.  Any help appreciated.

Comments

  • Dear Martin,

    like the native (ARX/BRX) interface of getGeomExtents(), vle-GetGeomExtents also + always returns the minimum + maximum extent points,
    regardless of object rotation;
    to properly return rotated extents would require 4 result points, but that is not provided by native GetGeomExtents() interface.

    The same applies to vla-getBoundingBox function, it uses the same interface ...
    so there is likely no other approach as to "manually" add rotation to result points :-(

    many greetings !
  • This may be a case where the OSMODE setting leads to unexpected results.
    Try setting the OSMODE to zero.
    Or use:
    [code](command "rectangle" "_non" c "_non" d)[/code]
  • BTW: 'Re-reading the block with (setq a (entlast))' will not work because of the newly created rectangle.

  • like the native (ARX/BRX) interface of getGeomExtents(), vle-GetGeomExtents also + always returns the minimum + maximum extent points,
    regardless of object rotation;

    Torsten,

    I am not trying to add rotation to a point set.  I am setting the rotation of an existing block to 0.0 and vle-GetGeomExtents is returning points for the block before I changed the rotation to 0.

    If I insert a block and rotate it 45 degrees vle-GetGeomExtents returns the correct points for the rotated object in Bricscad.  If I then run (vle-entmod 50 a 0.0) the block should not be rotated any more.  When I look at the block data after (vle-entmod 50 a 0.0) the dxf 50 code is 0.0.  If I run vle-GetGeomExtents again in Bricscad after setting the block rotation to 0.0 Bricscad still gives the points for the block rotated 45 degrees, not the points for the block rotated 0.0.  If I do the same in Autocad 2010 I get very different results.  For the attached drawing I created two identical files.  I inserted the electrical receptacle block at 0,0,0, rotated the receptacle 45 degrees, then exploded the block and changed the color to 40 and the linetype to hidden.  This gives a visual reference for the starting conditions.  I then inserted another copy of the block at 0,0,0 and rotated it 45 degrees.  This block is not exploded and is cyan.  I loaded one drawing in Bricscad and one in Autocad 2010.  In both programs I ran the code I posted before.  I put the output of the two programs in one drawing to make them easy to compare.  With Bricscad the rectangles before and after (vle-entmod 50 a 0.0) are identical.  With Autocad the rectangles are not the same.  I'm not sure that the rectangle for the symbol rotated 45 degrees is correctly sized, but the smaller rectangle around the cyan block is exactly what I would expect it to be.

    Roy,

    Good catch on the entlast.  Too many hours trying to make this work I guess.  I verified that OSMODE is set to 0 and that the OSMODE stetting does not affect this.


    For what it's worth this code works as I expect in Bricscad.
    [code]    (vle-entmod 50 entity 0.0)                                                                      ; set rotation to 0.0
        (vla-GetBoundingBox (vlax-ename->vla-object entity) 'minpoint 'maxpoint)
        (setq LL    (vlax-safearray->list minpoint)
              UR    (vlax-safearray->list maxpoint)
        )
    [/code]


    AC.dwg

  • Not sure whether it is of help, but Lee Mac has some functions for this type of thing. May provide a counterpoint for testing. In my case vle-GetGeomExtents met my needs to provide a bounding box of multiple selected entities.

    Regards,

    Jason Bourhill

    CAD Concepts


  • Thanks, Jason.

    As I look into this more it looks like vle-GetGeomExtents works properly when I make modifications to rotation and other parameters manually.  The problem only seems to appear when I change rotation of an entity using vle-entmod before calling vle-GetGeomExtents in a lisp routine.  I'll do more testing later today.

  • I've found a work-around, but it makes no sense to me.  This works with the blocks in the dwg file I posted earlier.
    [code](defun c:geo2 ( / a b c d)
      (setvar "osmode" 0)
      (setq a (entlast))
      (setq b (vle-getgeomextents a))
      (setq c (car b))
      (setq d (cadr b))
      (command "rectangle" c d)
      (vle-entmod 50 a 0.0)
      (print)
      (setq b (vle-getgeomextents a))
      (setq c (car b))
      (setq d (cadr b))
      (command "rectangle" c d)
    )
    [/code]
    I have no idea why adding (print) after the vle-entmod in c:geo2 changes the operation.  (princ) does not work.  ENTUPD does not work.

  • Haver you tried swapping out vle-entmod with entmod? If you're testing in AutoCAD, then vle-extension.lsp will be using entmod. I guess you could also try vle-entmod-m, but I assume it would be utilising the same underlying methodology. My guess is that BricsCAD doesn't see the vle-entmod transaction until something triggers a refresh. I assume a REGEN would also work?

    You could try wrapping the vle-entmod call with vle-start-transaction & vle-end-transaction. Perhaps this would force BricsCAD to refresh.

    Regards,

    Jason Bourhill

    CAD Concepts


  • If I test with AC.dwg and BricsCAD V14 I get the same result as the drawing indicates comes from AutoCAD. To avoid confusion I have changed (entlast) to (car (entsel)). But I am surprised by the bounding box for the block that is rotated 45 degrees. It is too big. I think it is the boudingbox around a boundingbox under 45 degrees.

    If you are interested in the boundingbox of an 'unrotated' block reference, you can also check the boundingbox of all the elements in the block definition and then translate and scale the points to match the reference. An approach I would prefer.


  • Dear All,

    it might be possible, that an extra (entupd) is necessary, if the entity is changed (rotation) wtihin same Lisp code flow, before (vle-getgeomextents) ?
    As the extents calculation is often (in Acad + Bcad, depending on entity type) depending on the entity's display representation (GS nodes store the 2 min+max points), the visual representation needs to be up-to-date;
    but the update process is often delayed till idle time (or other events - like the (print) function) ...

    Hence, (entupd) or (vla-update) might help ... usually, (vla-update) is slower, but "intensively" updates entity graphics (i.e. for BlockReferences, when BlockDefinition was changed).

    I hope this can explain some behaviour ?
    many greetings !
  • Roy, 
    I agree that the "rotated" box appears to be too big, but it appears to be too big in Autocad 2010, too. 
    At this point my intention is to try to get then anomaly in vle-getgeomextents/vl-getgeomextents fixed.  I have working code that uses vla-getboundingbox.

    Torsten,
    I tried (entupd) in the latest version of Bricscad and it did not help.  (vla-update (vlax-ename->vla-object a)) does work, but I do not consider it an acceptable solution.  Autocad does not need the (vla-update), so code that is written for Autocad using vl-getgeomextents will run in Bricscad but will not give the same result as in Autocad. 
  • Hi, Martin,

    thanks for the feedback ... I will check with your posted code, and try to get the different behaviour fixed.
    I will keep you updated here.
    many greetings !
  • Hi, Martin,
    I tried to reproduce - but it works perfectly fine ...

    I only noticed, that your AC.dwg contains the exploded block (at "BricsCAD" side) , while the "AutoCAD" mode has 2 blocks.

    Please find attached the "AC-test.dwg", created from your original dwg, and the "test.lsp", using your c:geo2 code, with deactivated (print) statements -
    the created rectangles exactly match the geometric extents, before + after applying (vle-entmod) ...

    If you can create a reproducabel case, please open a support request for this - I will be glad to investigate + fix, what needs to be fixed.
    many greetings !

    test.lspAC-test.dwg

  • Torsten,

    Are you testing in V15?  V15 works fine here.  I was using something newer than V15 that I'm not supposed to talk about when I was testing this.  I still get the incorrect result with the beta.  I probably should have been clear on that.
  • aaah - yes, now I can reproduce ... and just fixed;
    was caused by an intended performance optimisation, using the GS extents;
    but as this case shows, this approach is not reliable in some circumstances.

    Just fixed, works as expected again.
    many greetings !
This discussion has been closed.

Howdy, Stranger!

It looks like you're new here. Click one of the buttons on the top bar to get involved!