regarding the Explode method

Joe Burke

Usenet Archive
Joined
May 28, 2000
Messages
653
Reaction score
0
A couple questions about the Explode method.

First, I find when used on a block or pline, the source vla object itself is not exploded. Rather it's like making a copy, and exploding the copy. I guess that's just how it works. But it seems strange there's no reference to this in help on the Explode method. It says, "refer to the Explode command topic..." hmm.

Second question is somewhat related to the first. It seems the new objects created by the Explode method are not immediately accessible. The following Test function demonstrates. With the line (command "point" 0,0) commented out, (if ss... test returns "... out-to-lunch". With (command "point" 0,0) included, (if ss... test returns the correct entity list, i.e., what you'd expect. It *seems* the database has to be altered in some way before the exploded vla objects are recognized.

(defun c:Test ( / ent ename pt vobj vlst ss )
(setq ent (entsel "\nSelect block or pline: "))
(setq ename (car ent))
(setq pt (cadr ent))
(setq vobj (vlax-ename->vla-object ename))
(setq vlst (vlax-invoke vobj 'Explode)) ;list of exploded vla objects (vla-delete vobj) ;delete source object ;(foreach x vlst (vlax-release-object x)) ;error: unable to get ObjectID (print (mapcar 'vlax-write-enabled-p vlst)) ;(T T) no hint, seems right (command "point" 0,0) ;** compare with this line commented out ** (setq ss (ssget pt)) ;selection set at point pt (if ss (print (entget (ssname ss 0))) ;if something, what is it? (print "Object is out-to-lunch") ;else - command "point" is commented out ) (princ)
) ;end

I'd appreciate any thoughts on this. Just want to understand what's going on.

Thanks
Joe Burke
 
Interesting that the original object remains.
Try this one, but watch out for locked layers
(defun c:Test2 ( / ent ename vobj vlst ss)
(and
(setq ent (entsel "\nSelect block or pline: "))
(setq ename (car ent))
(setq vobj (vlax-ename->vla-object ename))
(or
(vlax-method-applicable-p vobj 'Explode)
(prompt " Object can not be exploded.")
)
(or
(setq vlst (vlax-invoke vobj 'Explode)) ;list of exploded vla objects (prompt " Hey... Where'd they go!?") ) (not (vla-delete vobj)) (princ (strcat "\n" (itoa (length vlst)) " objects in return list.")) (setq ss (ssadd)) (foreach item vlst (ssadd (vlax-vla-object->ename item) ss) ) (if ss (princ (strcat "\n" (itoa (sslength ss)) " objects created.")) (print "Object is out-to-lunch") ;else - command "point" is commented out ) (sssetfirst nil ss) (sssetfirst) ) (princ)
)
 
Hi John,

Thanks for your reply. At first glance, I'm not sure it gets to the heart of the question. Of course, I might be wrong, or maybe I didn't explain the issue clearly. Or maybe I just need study what you posted. :-)

As I see it, there's no question about the vla-object list returned by (vlax-invoke vobj 'Explode). The problem seems to be trying to pick one of those new objects within the program using (ssget <original pick point>). It should return the new exploded object at pick point, right? But it doesn't unless I alter the drawing somehow first, and then ask for (ssget <original pick point>).

Yes, it's interesting the original object remains. I thought it was strange until I looked at Juerg's VxGetBlockInters function. It vla-explodes a block, looks for intersections using vla-IntersectWith, then discards the copied vla-objects. The original block remains, by virtue of the nature of the Expode method.

Joe
 
Joe,
What you posted assumed that the return value from the (vla-explode...) was a collection. It is not. Instead it is a variant containing a safe-array. To use the group of objects directly, you need to use something like (vlax-safearray->list(variant-value(vla-explode obj)))

A more direct approach (less code) is to do what John demonstrated, which is to use (vlax-invoke obj 'explode) to give you a direct return value of a list of objects (not a collection). Since it is a list, you can use foreach rather than vlax-for.

There are major advantages to the explode method working on a copy. You might find explanations in this newsgroup on this issue if you search for "explode method".

Hope that helps.

If you need more code, let me know.

Regards,
Doug
 
Hi Doug,

Experience tells me something important isn't getting through my thick skull.
:-)

Take another look at the Test function I posted:

(setq vlst (vlax-invoke vobj 'Explode))

Agreed regarding the explode method working on a copy. In fact, it was a pleasant surprise.

Thanks
Joe
 
You're right Joe. Maybe I'm the thickheaded one.
I can't understand your code though(at vlax-release).
Why do you feel that you need to release objects that
haven't been bound to a variable? The foreach argument is strictly local and normal cleanup will take care of things.

AFAIK, the vlax-release-object only works when you
feed it a symbol, not a value. But there is no point at all in doing so. If you try to move the objects instead of releasing them, you will see all is well.

Does that help. Sorry about the other babble.
 
Doug,

I'm on my way out, so this is only a partial reply. The commented out, foreach vlax-release-object line was just a test. I'm not sure what the error means. Either as you said, I've misused the function, or it's an indication AutoCAD (A2k2) thinks the new exploded objects don't exist yet.

That's my main question. Why does ssget <point> think there's no object at <point> after explode and delete the source object? It only works if I do that dumb thing... place a point at 0,0, and then ssget.

Thanks
Joe
 
Joe,

try this after the explode...

(vla-update (vlax-get-acad-object))

then use the (ssget pt) ...

luis.
 
Joe:
Strikes me you might be using the ol' "end around" on NCOPY, eh? Think about it... Ask for an (entsel), not a messy (nentsel). Explode the parent like a fish releasing its offspring. Discard all the progeny except for "the chosen one" and Voila!

No translation required and with EXPLMODE set to 1 you can even stretch those elliptical arcs.

Unfortunately smacks of Nazi tactics, but then again cloning is philosophically questionable as well. :/ Anyway, don't want to steal any thunder, so with what Luis suggested, how about your wrapping this one up for us?
 
Luis,

That fixed it. :-)

Thank you
Joe

Luis Esquivel said:
Joe,

try this after the explode...

(vla-update (vlax-get-acad-object))

then use the (ssget pt) ...

luis.
 
John,

You're absolutely right. Exploding a block in this case is a cheap trick. It's something I'm doing while I work on other issues within the code. The "case" is I want to use the IntersectWith method, and one of the objects may be inside a block.

Whether I'll ever find something better that the cheap trick is another question. I tried the Copy method, but that copied the object inside the block.

Consider it wrapped. Luis' suggestion did the trick.

Joe
 

Latest threads

Back
Top