Author Topic: Explode Inside Block  (Read 1670 times)

0 Members and 1 Guest are viewing this topic.

mailmaverick

  • Bull Frog
  • Posts: 494
Explode Inside Block
« on: June 22, 2020, 09:30:28 PM »
Hi,

I want to explode all objects inside a block (not the block itself). I created following program :-
Code: [Select]
(defun c:ExplodeInsideBlocks ()
  (defun get-block-entities (blk / ent lst)
    (if (and (setq blk (vla-get-effectivename (vlax-ename->vla-object blk)))
     (setq ent (tblobjname "block" blk))
)
      (while (setq ent (entnext ent)) (setq lst (cons ent lst)))
    )
    (reverse lst)
  )
  ;;
  (defun explodefunction (entnm / obj xx blkentlst)
    (if (setq enx (entget entnm))
      (progn (setq typ (strcase (cdr (assoc 0 enx))))
     (if (and (eq typ "INSERT") (setq blkentlst (get-block-entities entnm)))
       (progn ;;
      (mapcar (function (lambda (xx)
  (if (not (eq entnm xx))
    (explodefunction xx)
  )
)
      )
      blkentlst
      )
       )
       (progn ;;
      (command "_.explode" entnm)
       )
     )
      )
    )
  )
  (if (setq sset (ssget "_:L" (list (cons 0 "INSERT"))))
    (repeat (setq n (sslength sset)) (setq ent (ssname sset (setq n (1- n)))) (explodefunction ent))
  )
  (princ)
)


When I use this function, I get following error :-
_.explode <Bad Entity name: DA71E400>
_.explode <Bad Entity name: DA71E410>
_.explode <Bad Entity name: DA71E420>
_.explode <Bad Entity name: DA71E430>
_.explode <Bad Entity name: DA71E440>
_.explode <Bad Entity name: DA71E450>


The reason I can think of is that the entity is inside block, hence could not be exploded.
But instead of
Code: [Select]
"(command "_.explode" entnm)" when I use
Code: [Select]
"(vla-put-color (vlax-ename->vla-object entnm) 3)" it works. I also tried
Code: [Select]
"(vla-explode (vlax-ename->vla-object entnm))" but it also does not work. When I am able to change the color of all entities within a block (without exploding the block), what is the problem in exploding those entities ?

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Explode Inside Block
« Reply #1 on: June 22, 2020, 11:04:47 PM »
On iPad ... so untested ... thinking aloud ...
  • Iterate the host block, collecting nested block inserts.
  • Iterate the collected inserts, making an instance of each in model space (or a temp odds doc).
  • Will need to be mindful of layering, scales, rotations, normals etc.
  • Explode each of these new instances.
  • Collect shrapnel.
  • Use shrapnel to add elements to the host block def.
  • Delete the block inserts collected in step 1.
  • Have a cookie.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

kpblc

  • Bull Frog
  • Posts: 396
Re: Explode Inside Block
« Reply #2 on: June 23, 2020, 01:02:21 AM »
I didn't check the code:
Code - Auto/Visual Lisp: [Select]
  1.  
  2. (defun c:explinside (/ adoc ent err)
  3.   (cond ((/= (type
  4.                (setq ent (vl-catch-all-apply (function (lambda () (ssname (ssget "_+.:S:E" '((0 . "INSERT"))) 0)))))
  5.              ) ;_ end of type
  6.              'ename
  7.          ) ;_ end of /=
  8.          (princ "\nNothing selected")
  9.         )
  10.         ((vl-catch-all-error-p
  11.            (setq ent (vl-catch-all-apply
  12.                        (function
  13.                          (lambda () (vla-item (vla-get-blocks adoc) (vla-get-effectivename (vlax-ename->vla-object ent))))
  14.                        ) ;_ end of function
  15.                      ) ;_ end of vl-catch-all-apply
  16.            ) ;_ end of setq
  17.          ) ;_ end of vl-catch-all-error-p
  18.          (princ "\nCan't recognize block definition")
  19.         )
  20.         (t
  21.          (vla-startundomark adoc)
  22.          (vlax-for sub ent
  23.            (if (= (vla-get-objectname sub) "AcDbBlockReference")
  24.              (if (not (vl-catch-all-error-p (setq err (vl-catch-all-apply (function (lambda () (vla-explode sub))))))
  25.                  ) ;_ end of not
  26.                (vla-erase sub)
  27.                (princ (strcat "\nCan't explode nested block named "
  28.                               (vla-get-effectivename sub)
  29.                               " : "
  30.                               (vl-catch-all-error-message err)
  31.                       ) ;_ end of strcat
  32.                ) ;_ end of princ
  33.              ) ;_ end of if
  34.            ) ;_ end of if
  35.          ) ;_ end of vlax-for
  36.          (vla-endundomark adoc)
  37.         )
  38.   ) ;_ end of cond
  39.   (princ)
  40. ) ;_ end of defun
Sorry for my English.

mailmaverick

  • Bull Frog
  • Posts: 494
Re: Explode Inside Block
« Reply #3 on: June 23, 2020, 03:01:10 AM »
Thanks for your effort but still not working my friend. Please see attached drawing.

kpblc

  • Bull Frog
  • Posts: 396
Re: Explode Inside Block
« Reply #4 on: June 23, 2020, 06:58:01 AM »
I'm sorry but there are no blocks (I mean block references) inside. Try to open it in block editor and use _.qselect
Sorry for my English.

mailmaverick

  • Bull Frog
  • Posts: 494
Re: Explode Inside Block
« Reply #5 on: June 23, 2020, 07:51:21 AM »
I understand that there are no block references inside. But I still want to explode all objects that are inside, especially dimensions. Any way to do that ?

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: Explode Inside Block
« Reply #6 on: June 23, 2020, 09:43:58 AM »
Dimensions, mtext etc. do not sport an explode (activex) method.

Explode-able objects within a block def should be blast-able by this quick and dirty (i.e. not production ready) code:

Code: [Select]
(vlax-for x def
    (if (vlax-method-applicable-p x 'explode)
        (if (listp (setq spawn (vl-catch-all-apply 'vlax-invoke (list x 'explode))))
            (progn
                (princ (strcat "\n" (vla-get-objectname x) " <" (vla-get-handle x) "> exploded."))
                (vl-catch-all-apply 'vlax-invoke (list x 'delete))
            )
            (princ (strcat "\n" (vla-get-objectname x) " <" (vla-get-handle x) "> could not be exploded "))
        )
    )
)

If you want to explode dimensions, mtext etc. via command you could:

1. Capture the last entity in the drawing.
2. Create all entities that reside within the def in modelspace (could explode an instance created at normal scale etc).
3. Explode everything you wish by command.
4. Collect all entities that exist after the entity captured in item (1) in a selection set.
5. Use this selection set to redefine the target block def.

Edit: Added ipso-facto.dwg
« Last Edit: June 23, 2020, 10:33:04 AM by MP »
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

ronjonp

  • Needs a day job
  • Posts: 7526

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

kpblc

  • Bull Frog
  • Posts: 396
Re: Explode Inside Block
« Reply #8 on: June 23, 2020, 01:02:31 PM »
Just come back home...
Code - Auto/Visual Lisp: [Select]
  1.  
  2. (defun c:explinside (/ _kpblc-conv-vla-to-list adoc ent dim err)
  3.   (defun _kpblc-conv-vla-to-list (value / res)
  4.     (cond ((listp value) (mapcar (function _kpblc-conv-vla-to-list) value))
  5.           ((= (type value) 'variant) (_kpblc-conv-vla-to-list (vlax-variant-value value)))
  6.           ((= (type value) 'safearray)
  7.            (if (>= (vlax-safearray-get-u-bound value 1) 0)
  8.              (_kpblc-conv-vla-to-list (vlax-safearray->list value))
  9.            ) ;_ end of if
  10.           )
  11.           ((and (= (type value) 'vla-object) (vlax-property-available-p value 'count))
  12.            (vlax-for sub value (setq res (cons sub res)))
  13.           )
  14.           (t value)
  15.     ) ;_ end of cond
  16.   ) ;_ end of defun
  17.   (defun fun_explode (ent / res def)
  18.     (cond ((vlax-method-applicable-p ent 'explode)
  19.            (foreach sub (vla-explode ent) (fun_explode sub))
  20.            (vla-erase ent)
  21.           )
  22.           ((wcmatch (strcase (vla-get-objectname ent)) "ACDB*DIM*")
  23.            (setq def (vla-item (vla-get-blocks adoc) (cdr (assoc 2 (entget (vlax-vla-object->ename ent)))))
  24.                  def (_kpblc-conv-vla-to-list def)
  25.            ) ;_ end of setq
  26.            (vla-copyobjects
  27.              adoc
  28.              (vlax-make-variant
  29.                (vlax-safearray-fill (vlax-make-safearray vlax-vbobject (cons 0 (1- (length def)))) def)
  30.              ) ;_ end of vlax-make-variant
  31.              (vla-objectidtoobject adoc (vla-get-ownerid ent))
  32.            ) ;_ end of vla-CopyObjects
  33.            (vla-erase ent)
  34.           )
  35.     ) ;_ end of cond
  36.   ) ;_ end of defun
  37.   (cond ((/= (type
  38.                (setq ent (vl-catch-all-apply (function (lambda () (ssname (ssget "_+.:S:E" '((0 . "INSERT"))) 0)))))
  39.              ) ;_ end of type
  40.              'ename
  41.          ) ;_ end of /=
  42.          (princ "\nNothing selected")
  43.         )
  44.         ((vl-catch-all-error-p
  45.            (setq ent (vl-catch-all-apply
  46.                        (function
  47.                          (lambda () (vla-item (vla-get-blocks adoc) (vla-get-effectivename (vlax-ename->vla-object ent))))
  48.                        ) ;_ end of function
  49.                      ) ;_ end of vl-catch-all-apply
  50.            ) ;_ end of setq
  51.          ) ;_ end of vl-catch-all-error-p
  52.          (princ "\nCan't recognize block definition")
  53.         )
  54.         (t
  55.          (vla-startundomark adoc)
  56.          (vlax-for sub ent (vl-catch-all-apply (function (lambda () (fun_explode sub)))))
  57.          (vla-endundomark adoc)
  58.         )
  59.   ) ;_ end of cond
  60.   (princ)
  61. ) ;_ end of defun
Sorry for my English.