Selecting Dynamic Blocks
Hi,
Having played around with Dynamic Blocks I have discovered (along with many others) that you can no longer simply rely on (ssget "X" '((cons 2. "blockname"))) in Lisp to find all the blocks of a particular name on your drawing.
Dynamic blocks use anonymous blocks *U* to replace the default instance of the block with the modified version. This stops (ssget "X" '((cons 2. "blockname"))) from working, as you need to know the anonymous block name, not the original block name.
This raises a number of problems for LISP users (not sure about other environments) as functions that look for blocks using ssget won't necessarily find them, and there doesn't appear to be any way with standard LISP to determine whether a block is Dynamic or not.
I have created the function below to return a selection set of blocks of the same name in a drawing. Works in two passes.
- uses ssget "x" to select standard blocks & dynamic blocks that haven't been modified.
- selects all anonymous blocks, then iterates through adding any blocks with the same Effective name to the selection set.
; Function to create a selection set of standard & dynamic blocks
; That have the same Effective name
(defun BlockSSET (blname / sset ss-dyn num ent effname)
(vl-load-com) ; ensure that ActiveX is loaded.
(if (not (setq sset (ssget "X" (list (cons 2 blname))))) ; Select block with standard method. This will also capture dynamic blocks in their default state.
(setq sset (ssadd)) ; if nothing is found then create and empty selection set
)
(if (setq ss-dyn (ssget "X" (list (cons 2 "`*U*")))) ; select all anonymous blocks. this will also capture any dynamic blocks that have been worked with
(progn ; If anonymous blocks found, check for the given effective name
(setq num 0) ; zero counter
(repeat (sslength ss-dyn) ; repeat for the number of objects in the selection set
(setq ent (ssname ss-dyn num)) ; find the entity name
(setq effname (vla-get-EffectiveName (vlax-ename->vla-object ent))) ; Find the EffectiveName of the block
(if (= blname effname) ; if the blockname matches the effective name
(ssadd ent sset) ; then add it to the original selection set
); end if
(setq num (1+ num)) ; Increment the counter by one
)
)
)
; return the gathered selection set
sset
)
Seems to work ok. Would be interested in seeing how others have approached this problem. Dynamic blocks are a useful feature to have, but you need to be able to work with them easily.
Note also in Bricscad that Quickselect will not work with Dynamic blocks, assume for the same reason. Also when you list a Dynamic Block it returns the anonymous name, but doesn't give the effective name.
Jason Bourhill
Comments
-
Thanks Jason for the very useful Lisp.
Yes, indeed, selecting dynamic blocks have been a pain and I have been thinking about updating my code to handle dynamic blocks. I will now test your program and see how it works.
I will keep you posted here
Regards
www.coordsys.com0 -
Hi Rakesh,
that's what bought it to my attention. I have a number of routines that I use with blocks. Found that they no longer worked on some drawings due to dynamic block use.
Users aren't necessarily going to know that creating a dynamic block is going to make them hard to work with. Therefore your routines must be able to accomodate both forms.
It would appear that you may have to develop a number of functions to ensure that you can work with blocks no matter the form. The biggest suprise to me is the lack of any additional tooling in LISP to work with these objects.
Regards,
Jason
0 -
Hi Jason,
Indeed, it would be good if ssget simply tool care of it internally and handled it. I think I should file a support request and my friend Torsten to tweak Lisp to handle this.
Regards
Rakesh Rao
http://rakeshrao.typepad.com0