Explode the blocks inside the blocks

Explode the blocks inside the blocks

Anonymous
Not applicable
922 Views
6 Replies
Message 1 of 7

Explode the blocks inside the blocks

Anonymous
Not applicable

Dear all,

I am trying that to explode all the blocks inside blocks.

I written a code like below, but i have a doubt that how to repeat the process until end of the blocks ?

 

(defun c:GAD()
	(if
		(and
			(/= (setq blocks (ssget "_X" '((0 . "INSERT")))) nil)
			(setq ctr 0 len (sslength blocks))
		)
		(progn
			(while (< ctr len)
				(command "qaflags" 1)
				(setq blk (ssname blocks ctr))
				(command "EXPLODE" blk "")
				(command "qaflags" 0)
				(setq ctr (1+ ctr))
			)
		)
	)
	(command "_.PURGE" "_all" "NO" "")
	(princ)
)

 

Please teach me how to grow myself in this topics ?

0 Likes
923 Views
6 Replies
Replies (6)
Message 2 of 7

hak_vz
Advisor
Advisor

 

 

(defun c:GAD()	
	(setvar 'qaflags 1)
	(setvar 'cmdecho 0)
	(while (setq blocks (ssget "_x" '((0 . "INSERT"))))
		(setq ctr 0 len (sslength blocks))
	
		(while (< ctr len)
			(setq blk (ssname blocks ctr))
			(command "EXPLODE" blk "")
			(setq ctr (1+ ctr))
		)
	)
	(command "_.PURGE" "_all" "NO" "")
	(setvar 'qaflags 0)
	(setvar 'cmdecho 1)
	(princ)
)

 

 

 

Localize variables. Read the code and grasp the logic. If you need explanation ask.

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes
Message 3 of 7

pbejse
Mentor
Mentor

@Anonymous wrote:

Dear all,

I am trying that to explode all the blocks inside blocks.


Are you saying explode a block ONLY if it is inside a block?

Explode ALL blocks including inside blocks?

What you have posted is exploding blocks currently on the drawing layouts.

 

if its the former:

Here's a quick demo [ targeting block definition ]

(defun c:demoEx	(/ a)
  (while (setq a (tblnext "BLock" (null a)))
    (if	(/= 4 (logand 4 (cdr (assoc 70 a))))
      (vlax-for	obj
		    (vla-item
		      (vla-get-blocks
			(vla-get-ActiveDocument (vlax-get-acad-object))
		      )
		      (cdr (assoc 2 a))
		    )
	(if (and
	      (eq (vla-get-ObjectName obj) "AcDbBlockReference")
	      (vlax-write-enabled-p obj)
	    )
	  (progn
	    (vla-Explode obj)
	    (Vla-delete obj)
	  )
	)
      )
    )
  )
  (princ)
)

HTH

 

 

 

0 Likes
Message 4 of 7

Kent1Cooper
Consultant
Consultant

If you're Exploding one at a time, you don't need to mess with the QAFLAGS System Variable, but since it will only Explode one in a (command) function, you also don't need to complete the selection.  And you don't need to check whether the selection set is not nil, but merely whether anything is in it, that is, whether it exists.  Also, the (progn) function isn't doing anything for you.  I would simplify that code [not going after nested Blocks yet] this way:


(defun c:GAD()
	(if
		(and
			(setq blocks (ssget "_X" '((0 . "INSERT"))))
			(setq ctr 0 len (sslength blocks))
		)
		(while (< ctr len)
			(setq blk (ssname blocks ctr))
			(command "EXPLODE" blk)
			(setq ctr (1+ ctr))
		)
	)
	(command "_.PURGE" "_all" "NO" "")
	(princ)
)

But in addition, it's not necessary to put each Block into a variable -- they can Exploded right out of their position in the selection set.  For getting all the nested Blocks remaining, until there are none left, I think it can be as simple as this:

 

(defun c:GAD (/ blocks n)
  (while (setq blocks (ssget "_X" '((0 . "INSERT"))))
    (repeat (setq n (sslength blocks))
      (command "_.explode" (ssname blocks (setq n (1- n))))
    ); repeat
  ); while
  (command "_.PURGE" "_all" "NO" "")
  (princ)
)

 

BUT it is probably worth also adding a check on whether each Insert object is an Xref, before Exploding it.  That would  involve putting each one into a variable.

Kent Cooper, AIA
0 Likes
Message 5 of 7

Kent1Cooper
Consultant
Consultant

@Kent1Cooper wrote:

....

BUT it is probably worth also adding a check on whether each Insert object is an Xref, before Exploding it.  That would  involve putting each one into a variable.


In fact, if you will have any Xrefs, it's more complicated than to do just that check.  There will be an endless loop, since it will always find more Insert object(s).  There needs to be some way of marking that there was at least one non-Xref Block in each round, so it will stop once there are no more.  I'm thinking about that....

 

[I'd bet there are Explode-everything-all-the-way-down routines out there for the Searching.]

 

EDIT:  Here's one way [minimally tested]:

(defun C:GAD (/ go-on blocks n blk)
  (setq go-on T); initial value to enable first search
  (while
    (and
      go-on ; first time or previous round included Explodable Block(s)
      (setq blocks (ssget "_X" '((0 . "INSERT")))); still any Insert objects?
    ); and
    (setq go-on nil); will be set back to T if any Explodable Blocks included
    (repeat (setq n (sslength blocks))
      (setq blk (ssname blocks (setq n (1- n))))
      (if ; not an Xref?
        (= (logand 4 (cdr (assoc 70 (tblsearch "block" (cdr (assoc 2 (entget blk))))))) 0)
        (progn ; then
          (command "_.explode" blk)
          (setq go-on T); marker to search another round
        ); progn
      ); if
    ); repeat
  ); while
  (command "_.purge" "_all" "NO" "")
  (princ)
); defun

 

Kent Cooper, AIA
0 Likes
Message 6 of 7

pbejse
Mentor
Mentor

Also to consider attribute blocks, regular explode will set the value to tag names as attdef object. among other things. explodable, lock layers, layouts [ as the code is using command...]

 

[ Atributes will be converted to Attdef ]

(defun c:GAD (/ _explodeAndDelete aDoc b bn tl)  
(defun _explodeAndDelete (o) (vla-Explode o) (Vla-delete o))
(setq aDoc (vla-get-ActiveDocument (vlax-get-acad-object)))
  
(vlax-for ly (vla-get-layers aDoc)
  (vlax-put ly "Lock" 0)
) 
  (vlax-for b (vla-get-blocks aDoc
	      )
    (cond
      ((vl-every 'zerop
		 (mapcar '(lambda (v) (vlax-get b v))
			 '("islayout" "IsXRef")
		 )
       )
       (vla-put-explodable b :vlax-true)
       (Vlax-for c b
	 (if (eq (vla-get-ObjectName c) "AcDbBlockReference")
	   (_explodeAndDelete c)
	 )
       )
      )
      ((minusp (vlax-get b "islayout"))
       (vlax-for obj b
	 (if (And
	       (eq (vla-get-ObjectName obj) "AcDbBlockReference")
	       (not (vlax-property-available-p obj 'Path))
	     )
	   (_explodeAndDelete obj)
	 )
       )
      )
    )
  )
 (repeat 4
  (vla-purgeall aDoc)
 )
  (princ)
)

HTH

 

 

0 Likes
Message 7 of 7

pbejse
Mentor
Mentor
(Defun c:GAD (/ Xrefs a filter blocks n)

  (while (setq a (tblnext "BLock" (null a)))
    (if	(= 4 (logand 4 (cdr (assoc 70 a))))
      (setq Xrefs (cons
		    (cons 2 (cdr (assoc 2 a)))
		    Xrefs
		  )
      )
    )
  )
  (setq	filter
	 (if xrefs
	   (append '((0 . "INSERT") (410 . "Model") (-4 . "<NOT"))
		   Xrefs
		   '((-4 . "NOT>"))
	   )
	   '((0 . "INSERT") (410 . "Model"))
	 )
  )

  (while (setq blocks (ssget "_X" filter))
    (command "_.explode" blocks)
  )
  (command "_.PURGE" "_all" "NO" "")
  (princ)
)
0 Likes