Float.lsp

Jesús Padilla

Usenet Archive
Joined
Aug 18, 2003
Messages
29
Reaction score
0
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
 
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
 
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
 
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,

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
 
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>.
 
(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.
 
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
 
(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.
 
John Uhden said:
(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.

That was 12 years ago.

Today, it's actually much worse than that.

See my other note in this thread.
 
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.

The newsreader server searches around here are useless

Since when?
http://groups.google.com/groups?q=float.lsp
 
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.
 
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,
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)
)
 
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)
)
 
I see plenty of problems with vla-copy over just plain
(command "copy"....) especially with regard to leaders.
Would copyobjects be better?
 
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 said:
Tony,
Do you see any problems with this approach?

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".
 
Doug Broad said:
Yes. Copyobjects preserves the links between copied objects.

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.
 

Latest threads

Back
Top