Float.lsp

Discussion in 'AutoCAD' started by Jesús Padilla, Jan 24, 2004.

  1. Last Friday, talking about "DrawOrder", Dean Saadallah wrote:

    "there is a lisp called FLOAT posted all over this NG if you want to try
    it."
    ---------------------------------------------------------------------

    I did´t find the program.
    Where should I search fot it.

    Jesús Padilla
     
    Jesús Padilla, Jan 24, 2004
    #1
  2. Hi Dean:

    I suposed Float was a "more developed" program.

    I use:

    (VL-CMDF
    "UNDO" "MARK"
    "COPYBASE" '(0 0 0) #SS-OR ""
    "PASTECLIP" '(0 0 0)
    "ERASE" #SS-OR ""
    );VL-CMDF

    But when the layer is locked, you can copy but you can´t delete them, so
    that, I get more entities.
    I will fix it.

    Thanks.

    JPadilla
     
    Jesús Padilla, Jan 24, 2004
    #2
  3. Jesús Padilla

    TCEBob Guest

    Dean,

    There's a hidden bomb in that procedure: leaders don't like being copied
    and lose their tails. Only fix that I can see is to search the sset for
    leaders and actually rebuild them. It's on my list of Things To Do Real
    Soon Now.

    rs
     
    TCEBob, Jan 24, 2004
    #3
  4. Jesús Padilla

    TCEBob Guest

    Okay, try this:

    (defun c:fup( / ) ;float objects without copy.
    (setq sset (ssget))
    (if sset
    (progn
    (setq x (sslength sset))
    (setq count -1)
    (while (< count x)
    (setq count (1+ count))
    (setq y (entget (ssname sset count)))
    (entdel (ssname sset count))
    (entmake y)
    )
    )
    )
    (princ))
     
    TCEBob, Jan 24, 2004
    #4
  5. Jesús Padilla

    Joe Burke Guest

    TCEBob,

    Your program errors with,"bad argument type: lentityp nil" because the while loop
    runs once too often.

    A simpler alternative:

    (defun c:float ( / ss idx ename )
    (setq ss (ssget))
    (setq idx 0)
    (if ss
    (repeat (sslength ss)
    (setq ename (ssname ss idx))
    (entmake (entget ename))
    (entdel ename)
    (setq idx (1+ idx))
    )
    )
    (princ)
    )

    Joe Burke
     
    Joe Burke, Jan 24, 2004
    #5
  6. Jesús Padilla

    John Uhden Guest

    Cadlantic's LORDER does it all with your choice of using draworder vs. recreate,
    grabbing associated objects, and a cute dialog to organize, save, and recall
    named layer order files.

    I see it needs an update to check for locked layers and better layout treatment
    <to-do list>.
     
    John Uhden, Jan 24, 2004
    #6
  7. Jesús Padilla

    John Uhden Guest

    (entmake) is not a good idea. I think Tony warned us of that recently because
    of things like optional 6 and 62 codes that may be missing. My warning is w/r/t
    complex entities like heavy polylines or blocks with attributes that would
    require digging into via (entnext), plus the references to associated entities
    would be broken. (command "_.copy" ...) should work just fine.
     
    John Uhden, Jan 24, 2004
    #7
  8. Jesús Padilla

    R.K. McSwain Guest

    R.K. McSwain, Jan 24, 2004
    #8
  9. Jesús Padilla

    Joe Burke Guest

    Hi John

    Thanks for the info. I wondered if there might be some pitfalls with entmake in this
    case.

    Similar caution using (vlax-invoke vobj 'Copy) rather than entmake? Help says, "you
    should not attempt to use this method (meaning Copy) on AttributeReference objects."

    Joe Burke
     
    Joe Burke, Jan 24, 2004
    #9
  10. (entmake (entget ename))

    This does not copy an entity.

    Not only does it not copy an entity, it can corrupt
    a drawing if the entity passed to entget has an
    extension dictionary.

    In that case, the resulting 'copy' of that entity
    that is produced by (entmake) will have the *same*
    extension dictionary, which effectively results in
    a "multiply-owned object" scenario, whereby a single
    object has more than one owner (a major no-no!).
    This can eventually lead to a corrupt, and possibly
    unrecoverable drawing.

    You need to use the ActiveX API to copy objects.

    Yet another reason why LISP is a dead end.
     
    Tony Tanzillo, Jan 24, 2004
    #10
  11. That was 12 years ago.

    Today, it's actually much worse than that.

    See my other note in this thread.
     
    Tony Tanzillo, Jan 24, 2004
    #11
  12. Jesús Padilla

    rdi Guest

    The WHOLE statement was <The newsreader server searches around here are
    useless, use the browser
    access instead>.

    The google search to which you pointed is a BROWSER search. An example of a
    newsreader server search is if I used Outlook Express to search.

    --

    RDI

    (remove the exclamation from the email address)

    Since when?
    http://groups.google.com/groups?q=float.lsp
     
    rdi, Jan 24, 2004
    #12
  13. Allow me to correct myself. (entmake) will fail if there
    is an extension dictionary in the entity data list, so
    (entmake (entget ...)) does not work at all in that case,
    which is not as bad as corrupting a drawing, but nonetheless
    makes (entmake (entget ...)) a conceptually invalid construct,
    since manipulation of the result of (entget) is mandatory.

    I would have expected (entmake) to ignore an extension
    dictionary in the input data list, but it just fails
    unconditionally instead.
     
    Tony Tanzillo, Jan 24, 2004
    #13
  14. Let me correct myself again.

    (entmake) appears to fail when the list contains
    an extension dictionary, but actually doesn't fail,
    it just returns NIL and creates the entity without
    an extension dictionary.

    Of course, that makes it even more obvious that
    (entmake (entget ...)) does not 'copy' entities.

    Try using (vla-copy) on an entity with an extension
    dictionary, and you'll see that the dictionary is
    copied as well.
     
    Tony Tanzillo, Jan 24, 2004
    #14
  15. Jesús Padilla

    Doug Broad Guest

    Tony,
    Do you see any problems with this approach? Is this brand of LISP dead? ;-)

    (defun c:float (/ lockedlayers relocklst *error* doc)
    ;;D. C. Broad, Jr. 1/23/2004
    ;;This routine will not float main entities on locked
    ;;layers.

    ;;Error routine ensures that any unlocked layers are re-locked.
    (defun *error* (msg)
    (foreach layer relocklst (vla-put-lock layer :vlax-true))
    (if msg
    (princ msg))
    (vla-endundomark doc)
    (princ))

    (setq doc (vla-get-activedocument(vlax-get-acad-object)))
    (vla-startundomark doc)

    (setq lockedlayers "")
    ;;make a list of locked layers. Unlock them temporarily
    ;;for this operation because nested objects on locked layers
    ;;can cause problems. Use the locked layer names as a filter
    ;;list for object selection.
    (vlax-for layer (vla-get-layers doc)
    (if (= :vlax-true (vla-get-lock layer))
    (progn
    (setq lockedlayers
    (strcat (vla-get-name layer) "," lockedlayers)
    )
    (vla-put-lock layer :vlax-false)
    (setq relocklst (cons layer relocklst)))))
    ;;Disallow selection of objects on locked layers
    (ssget (list (cons 8 (strcat "~" lockedlayers))))
    ;;Copy and delete
    (vlax-for obj (vla-get-activeselectionset doc)
    (vla-copy obj)
    (vla-delete obj))
    ;;Restore layer settings
    (*error* nil)
    )
     
    Doug Broad, Jan 24, 2004
    #15
  16. Jesús Padilla

    Doug Broad Guest

    Correction (if added)

    (defun c:float (/ lockedlayers relocklst *error* doc)
    ;;D. C. Broad, Jr. 1/23/2004
    ;;This routine will not float main entities on locked
    ;;layers.

    ;;Error routine ensures that any unlocked layers are re-locked.
    (defun *error* (msg)
    (foreach layer relocklst (vla-put-lock layer :vlax-true))
    (if msg
    (princ msg))
    (vla-endundomark doc)
    (princ))

    (setq doc (vla-get-activedocument(vlax-get-acad-object)))
    (vla-startundomark doc)

    (setq lockedlayers "")
    ;;make a list of locked layers. Unlock them temporarily
    ;;for this operation because nested objects on locked layers
    ;;can cause problems. Use the locked layer names as a filter
    ;;list for object selection.
    (vlax-for layer (vla-get-layers doc)
    (if (= :vlax-true (vla-get-lock layer))
    (progn
    (setq lockedlayers
    (strcat (vla-get-name layer) "," lockedlayers)
    )
    (vla-put-lock layer :vlax-false)
    (setq relocklst (cons layer relocklst)))))
    ;;Disallow selection of objects on locked layers
    (if
    (ssget (list (cons 8 (strcat "~" lockedlayers))))
    ;;Copy and delete
    (vlax-for obj (vla-get-activeselectionset doc)
    (vla-copy obj)
    (vla-delete obj)))
    ;;Restore layer settings
    (*error* nil)
    )
     
    Doug Broad, Jan 24, 2004
    #16
  17. Jesús Padilla

    Doug Broad Guest

    I see plenty of problems with vla-copy over just plain
    (command "copy"....) especially with regard to leaders.
    Would copyobjects be better?
     
    Doug Broad, Jan 24, 2004
    #17
  18. Jesús Padilla

    Doug Broad Guest

    Yes. Copyobjects preserves the links between copied objects.

    (defun c:float (/ lockedlayers relocklst *error* doc objlst)
    ;;D. C. Broad, Jr. 1/23/2004
    ;;This routine will not float main entities on locked
    ;;layers.

    ;;Error routine ensures that any unlocked layers are re-locked.
    (defun *error* (msg)
    (foreach layer relocklst (vla-put-lock layer :vlax-true))
    (if msg
    (princ msg))
    (vla-endundomark doc)
    (princ))

    (setq doc (vla-get-activedocument(vlax-get-acad-object)))
    (vla-startundomark doc)

    (setq lockedlayers "")
    ;;make a list of locked layers. Unlock them temporarily
    ;;for this operation because nested objects on locked layers
    ;;can cause problems. Use the locked layer names as a filter
    ;;list for object selection.
    (vlax-for layer (vla-get-layers doc)
    (if (= :vlax-true (vla-get-lock layer))
    (progn
    (setq lockedlayers
    (strcat (vla-get-name layer) "," lockedlayers)
    )
    (vla-put-lock layer :vlax-false)
    (setq relocklst (cons layer relocklst)))))
    ;;Disallow selection of objects on locked layers
    (if
    (ssget (list (cons 8 (strcat "~" lockedlayers))))
    ;;Copy and delete
    (progn
    (vlax-for obj (vla-get-activeselectionset doc)
    (setq objlst (cons obj objlst)))
    (vlax-invoke doc 'copyobjects objlst)
    (foreach obj objlst
    (vla-delete obj))))
    ;;Restore layer settings
    (*error* nil)
    )
     
    Doug Broad, Jan 24, 2004
    #18
  19. Yep!

    Is this brand of LISP dead? ;-)

    The (entxxxxx) style of LISP programming is dead.

    Even this approach is flawed, because it breaks inter-
    object references that may be stored in extension
    dictionaries, specifically in cases where both the
    referenced and the referencing objects are being
    "floated".
     
    Tony Tanzillo, Jan 24, 2004
    #19
  20. Actually, I'm afraid the answer is "Yes and No",
    or just a classic case of catch 22.

    You can deal with inter-object references using
    Copyobjects in cases where the referenced and the
    referencing objects are both involved in the same
    operation, but on the other hand, you would also
    be breaking any other reference to any object that
    is copied, if the referencing object(s) are not
    involved in the same deep clone operation.

    I'm afraid this is simply not an operation you can
    do in LISP or ActiveX, in a way that addresses all
    of the issues.

    For anyone that's interested, AcadX has a method that
    can solve the problem. The AcadXApplication object's
    SwapIds() method exchanges the objectid/handle and
    extension dictionaries of two database-resident objects,
    and provides a way to preserve inter-object references
    when copying objects for this kind of purpose. With it,
    you can use CopyObjects to clone a set of entities, then
    swap the objectids/handles and extension dictionaries
    of the original source objects with the copies, before
    deleting the source objects.

    IAcadXApplication.SwapIds(First as IAcadObject,
    Second as IAcadObject
    [, SwapXData as Boolean = False]
    [, SwapXDict as Boolean = False] )

    First and Second are two objects whose data is to be
    exchanged. If SwapXData is true, then the Xdata of
    the two objects is also exchanged. If SwapXDict is true,
    then the extension dictionaries of both objects are
    swapped.
     
    Tony Tanzillo, Jan 24, 2004
    #20
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.