LISP to explode block and make block again with the same name

LISP to explode block and make block again with the same name

karpki
Advocate Advocate
7,805 Views
38 Replies
Message 1 of 39

LISP to explode block and make block again with the same name

karpki
Advocate
Advocate

Hi,

Need LISP to automate such action: explode selected (by clicking) block and make block again with the same name and from same primitives.

The aim is to lose all the attributes and dynamic parameters from the block.

Of caurse any other ideas without exploding welcome! 

All I have found - Undynamic.lsp few versions and multitasker bgtools.lsp aren't doing it the way I need. 

Thanks in advance! 

 

0 Likes
Accepted solutions (3)
7,806 Views
38 Replies
Replies (38)
Message 21 of 39

karpki
Advocate
Advocate
Accepted solution

WOW! Great! But adds number to the name or give name like this *U51 ! 🤔

 

Finally I have writen Macro which do exactly what i mean - kills all in block accept the geometry:

^C^C_bedit;ai_selall;_copybase;0;0;delete;_pasteclip;0;_bclose;;

 

 

0 Likes
Message 22 of 39

marko_ribar
Advisor
Advisor

@karpkiCan you please attach DWG with some of those dynamic blocks like *U51...

I'll try to investigate, but then I am afraid that I can't promise anything...

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 23 of 39

karpki
Advocate
Advocate

karpki_0-1609444735475.png

 

0 Likes
Message 24 of 39

karpki
Advocate
Advocate

I know, macro I posted above could turn blocks. It is OK for my aim. It's quite fast to turn them back manually afterall 

0 Likes
Message 25 of 39

marko_ribar
Advisor
Advisor

DWG you attached contains block named "1"... Can you attach the one with "*U???" ?

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 26 of 39

karpki
Advocate
Advocate

Sorry! Correct file is attached 

0 Likes
Message 27 of 39

marko_ribar
Advisor
Advisor

You have only one "*U15" block and that one is not dynamic - others are, but they have different normal name - not "*U??"

 

Command: (setq e (vla-item (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) "*U15"))
#<VLA-OBJECT IAcadBlock 000001c1b3dab738>

Command: (vla-get-isdynamicblock e)
:vlax-false

 

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 28 of 39

karpki
Advocate
Advocate

All of them are copies of original block to make tests.

One with the name "*U" is result of your programm action 

 

0 Likes
Message 29 of 39

marko_ribar
Advisor
Advisor

Oh, now I see...

Try this mod...

It should find not valid names and create valid "STATIC_number"...

 

(defun c:undynamic-MR ( / addzeros adoc blnlst ss i bl bln blnlstassoc blnlstassoccounter k nstr )

  (vl-load-com)

  (defun addzeros ( l k )
    (if (< k l)
      (strcat "0" (addzeros (1- l) k))
      ""
    )
  )

  (alert "When asked to select blocks, you have to select all only once to make names counter renaming dynamic to static blocks correct... You can't select partially (firstly one sel. set and then with another starting of routine next sel. set...")
  (vlax-for b (vla-get-blocks (setq adoc (vla-get-activedocument (vlax-get-acad-object))))
    (if (= (vla-get-isdynamicblock b) :vlax-true)
      (setq blnlst (cons (vla-get-name b) blnlst))
    )
  )
  (if (setq ss (ssget "_:L" '((0 . "INSERT"))))
    (repeat (setq i (sslength ss))
      (setq bl (ssname ss (setq i (1- i))))
      (cond
        ( (and (snvalid (setq bln (vla-get-effectivename (vlax-ename->vla-object bl)))) (member bln blnlst))
          (if (assoc bln blnlstassoc)
            (setq blnlstassoc (subst (cons bln (1+ (cdr (assoc bln blnlstassoc)))) (assoc bln blnlstassoc) blnlstassoc))
            (setq blnlstassoc (cons (cons bln 1) blnlstassoc))
          )
        )
        ( (not (snvalid bln))
          (setq bln "STATIC")
          (if (assoc bln blnlstassoc)
            (setq blnlstassoc (subst (cons bln (1+ (cdr (assoc bln blnlstassoc)))) (assoc bln blnlstassoc) blnlstassoc))
            (setq blnlstassoc (cons (cons bln 1) blnlstassoc))
          )
        )
      )
    )
  )
  (repeat (setq i (sslength ss))
    (setq bl (ssname ss (setq i (1- i))))
    (setq bln (vla-get-effectivename (vlax-ename->vla-object bl)))
    (if (not (snvalid bln))
      (setq bln "STATIC")
    )
    (if (assoc bln blnlstassoccounter)
      (progn
        (setq blnlstassoccounter (subst (cons bln (1+ (cdr (assoc bln blnlstassoccounter)))) (assoc bln blnlstassoccounter) blnlstassoccounter))
        (setq k (cdr (assoc bln blnlstassoccounter)))
        (setq nstr (strcat (addzeros (strlen (itoa (cdr (assoc bln blnlstassoc)))) (strlen (itoa k))) (itoa k)))
        (vla-converttostaticblock (vlax-ename->vla-object bl) (strcat bln "_" nstr))
      )
      (progn
        (setq blnlstassoccounter (cons (cons bln 1) blnlstassoccounter))
        (setq nstr (strcat (addzeros (strlen (itoa (cdr (assoc bln blnlstassoc)))) 1) (itoa 1)))
        (vla-converttostaticblock (vlax-ename->vla-object bl) (strcat bln "_" nstr))
      )
    )
  )
  (princ)
)

 

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 30 of 39

marko_ribar
Advisor
Advisor

Sorry, the code had lacks... This is now all checked and fine...

 

 

(defun c:undynamic-MR ( / addzeros ss i bl bln blnlstassoc blnlstassoccounter k nstr )

  (vl-load-com)

  (defun addzeros ( l k )
    (if (< k l)
      (strcat "0" (addzeros (1- l) k))
      ""
    )
  )

  (alert "When asked to select blocks, you have to select all only once to make names counter renaming dynamic to static blocks correct... You can't select partially (firstly one sel. set and then with another starting of routine next sel. set...")
  (if (setq ss (ssget "_:L" '((0 . "INSERT"))))
    (repeat (setq i (sslength ss))
      (setq bl (ssname ss (setq i (1- i))))
      (if (= (vla-get-isdynamicblock (vlax-ename->vla-object bl)) :vlax-true)
        (cond
          ( (snvalid (setq bln (vla-get-effectivename (vlax-ename->vla-object bl))))
            (if (assoc bln blnlstassoc)
              (setq blnlstassoc (subst (cons bln (1+ (cdr (assoc bln blnlstassoc)))) (assoc bln blnlstassoc) blnlstassoc))
              (setq blnlstassoc (cons (cons bln 1) blnlstassoc))
            )
          )
          ( (not (snvalid bln))
            (setq bln "STATIC")
            (if (assoc bln blnlstassoc)
              (setq blnlstassoc (subst (cons bln (1+ (cdr (assoc bln blnlstassoc)))) (assoc bln blnlstassoc) blnlstassoc))
              (setq blnlstassoc (cons (cons bln 1) blnlstassoc))
            )
          )
        )
      )
    )
  )
  (repeat (setq i (sslength ss))
    (setq bl (ssname ss (setq i (1- i))))
    (setq bln (vla-get-effectivename (vlax-ename->vla-object bl)))
    (if (not (snvalid bln))
      (setq bln "STATIC")
    )
    (if (= (vla-get-isdynamicblock (vlax-ename->vla-object bl)) :vlax-true)
      (if (assoc bln blnlstassoccounter)
        (progn
          (setq blnlstassoccounter (subst (cons bln (1+ (cdr (assoc bln blnlstassoccounter)))) (assoc bln blnlstassoccounter) blnlstassoccounter))
          (setq k (cdr (assoc bln blnlstassoccounter)))
          (setq nstr (strcat (addzeros (strlen (itoa (cdr (assoc bln blnlstassoc)))) (strlen (itoa k))) (itoa k)))
          (vla-converttostaticblock (vlax-ename->vla-object bl) (strcat bln "_" nstr))
        )
        (progn
          (setq blnlstassoccounter (cons (cons bln 1) blnlstassoccounter))
          (setq nstr (strcat (addzeros (strlen (itoa (cdr (assoc bln blnlstassoc)))) 1) (itoa 1)))
          (vla-converttostaticblock (vlax-ename->vla-object bl) (strcat bln "_" nstr))
        )
      )
    )
  )
  (princ)
)
Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 31 of 39

marko_ribar
Advisor
Advisor

One more revision...

 

 

(defun c:undynamic-MR ( / addzeros ss i bl bln blnlstassoc blnlstassoccounter k nstr )

  (vl-load-com)

  (defun addzeros ( l k )
    (if (< k l)
      (strcat "0" (addzeros (1- l) k))
      ""
    )
  )

  (alert "When asked to select blocks, you have to select all only once to make names counter renaming dynamic to static blocks correct... You can't select partially (firstly one sel. set and then with another starting of routine next sel. set...")
  (if (setq ss (ssget "_:L" '((0 . "INSERT"))))
    (repeat (setq i (sslength ss))
      (setq bl (ssname ss (setq i (1- i))))
      (if (= (vla-get-isdynamicblock (vlax-ename->vla-object bl)) :vlax-true)
        (progn
          (if (not (snvalid (setq bln (vla-get-effectivename (vlax-ename->vla-object bl)))))
            (setq bln (cdr (assoc 2 (entget bl))))
          )
          (cond
            ( (snvalid bln)
              (if (assoc bln blnlstassoc)
                (setq blnlstassoc (subst (cons bln (1+ (cdr (assoc bln blnlstassoc)))) (assoc bln blnlstassoc) blnlstassoc))
                (setq blnlstassoc (cons (cons bln 1) blnlstassoc))
              )
            )
            ( t
              (setq bln "STATIC")
              (if (assoc bln blnlstassoc)
                (setq blnlstassoc (subst (cons bln (1+ (cdr (assoc bln blnlstassoc)))) (assoc bln blnlstassoc) blnlstassoc))
                (setq blnlstassoc (cons (cons bln 1) blnlstassoc))
              )
            )
          )
        )
      )
    )
  )
  (repeat (setq i (sslength ss))
    (setq bl (ssname ss (setq i (1- i))))
    (if (not (snvalid (setq bln (vla-get-effectivename (vlax-ename->vla-object bl)))))
      (setq bln (cdr (assoc 2 (entget bl))))
    )
    (if (not (snvalid bln))
      (setq bln "STATIC")
    )
    (if (= (vla-get-isdynamicblock (vlax-ename->vla-object bl)) :vlax-true)
      (if (assoc bln blnlstassoccounter)
        (progn
          (setq blnlstassoccounter (subst (cons bln (1+ (cdr (assoc bln blnlstassoccounter)))) (assoc bln blnlstassoccounter) blnlstassoccounter))
          (setq k (cdr (assoc bln blnlstassoccounter)))
          (setq nstr (strcat (addzeros (strlen (itoa (cdr (assoc bln blnlstassoc)))) (strlen (itoa k))) (itoa k)))
          (vla-converttostaticblock (vlax-ename->vla-object bl) (strcat bln "_" nstr))
        )
        (progn
          (setq blnlstassoccounter (cons (cons bln 1) blnlstassoccounter))
          (setq nstr (strcat (addzeros (strlen (itoa (cdr (assoc bln blnlstassoc)))) 1) (itoa 1)))
          (vla-converttostaticblock (vlax-ename->vla-object bl) (strcat bln "_" nstr))
        )
      )
    )
  )
  (princ)
)
Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 32 of 39

karpki
Advocate
Advocate

No difference in results.

After two tries situation like this.

The drawing with 4 same blocks named block1. 

Blocks which weren't choosen stay as they are:

karpki_0-1609515442753.png

First try, block name bacame with the 1 extra number:

karpki_1-1609515523096.png

Second try, block name bacame *UX:

karpki_2-1609515584805.png

Resulting dwg is attached. I have renamed blocks from ru to eng lang, thinking that it could be a reason, also took away one of the dynamic parameter.

I' d like to offer you to stop this research. I guess there is something wrong in the idea to use LISP method.

The Macro I gave before works great and I will use that Macro.

The Great Respect for your fantastic knowledge of the issue. Unfortunatelly I don't understand this at all and dream to learn it bit by bit.  

0 Likes
Message 33 of 39

karpki
Advocate
Advocate

It was about first version, now will try latest

0 Likes
Message 34 of 39

karpki
Advocate
Advocate

No difference, same behaviour. LISP reloaded, ACad reloaded.

 

0 Likes
Message 35 of 39

marko_ribar
Advisor
Advisor

Look, routine will never make "*UX" blocks - X number...

Second - you have to erase block named "block1_1" and purge DWG after which you have to copy dynamic block on place where was "block1_1"... Like I stated in alert prompt, you can't apply routine twice and partially - you have to do it once and with all selection of blocks... The problem is that CAD can't recognize lastly created "name_number" and continue from there to build "name_number+1", "name_number+2", ... Simply CAD don't know from where to begin if such block exist "name_number"... You have to remove it, purge DWG and place a copy in stead of that odd block... Then you should apply routine once for all... That's all story, it'll never create "*UX", if name isn't valid - it'll create named block "STATIC_number"...

Marko Ribar, d.i.a. (graduated engineer of architecture)
0 Likes
Message 36 of 39

thomas_schluesselberger
Advocate
Advocate

@marko_ribar  schrieb:

Here is what I have in my library that may be helpful for dynamic blocks...

 

;;
;; Convert dynamic blocks (in current visibility state) to static
;;
;; Routine: UnDynamic by MP Seagull - March 26, 2010
;; 
;; MODIFIED BY Lanny Schiele (aka 'HatchMaker Maker') - 10/27/2017
;;

(defun c:UnDynamic
    (   /
        _DefGetString
        _get_item
        _right
        _make_key
        _dynamic->static_block
        _get_locked
        _get_dynamic_inserts
        _main
    )

    (vl-load-com)

	;;;* GET STRING WITH DEFAULT
	(defun _DefGetString (prmpt default allowspace / d2)
	  (if allowspace
	    (setq
	      ans
	       (cond
	         ((not
	            (= (setq
	                 d2 (getstring T (strcat prmpt " <" default ">: "))
	               ) ;_ end of setq
	               ""
	            ) ;_ end of =
	          ) ;_ end of not
	          d2
	         )
	         (default)
	       ) ;_ end of cond
	    ) ;_ end of setq
	    (setq
	      ans
	       (cond
	         ((not
	            (= (setq d2 (getstring (strcat prmpt " <" default ">: ")))
	               ""
	            ) ;_ end of =
	          ) ;_ end of not
	          d2
	         )
	         (default)
	       ) ;_ end of cond
	    ) ;_ end of setq
	  ) ;_ end of if
	  ans
	) ;_ end of defun
  

    (defun _get_item ( collection key / item )
        (vl-catch-all-apply
           '(lambda ( ) (setq item (vla-item collection key)))
        )
        item
    )

    (defun _right ( str n / len )
        (if (< n (setq len (strlen str)))
            (substr str (1+ (- len n)))
            str
        )
    )

    (defun _make_key ( collection prefix len / key )
        (   (lambda ( i pad )
                (while
                    (_get_item collection
                        (setq key
                            (strcat prefix
                                (_right
                                    (strcat pad (itoa (setq i (1+ i))))
                                    len
                                )
                            )
                        )
                    )
                )
                key
            )
         ;;;0
            99999
            (   (lambda ( pad )
                    (while (< (strlen pad) len)
                        (setq pad (strcat "0" pad))
                    )
                    pad
                )
                ""
            )
        )
    )


    (defun _dynamic->static_block ( blocks insert len )
        (vla-ConvertToStaticBlock
            insert
            (_make_key blocks *UnDynamic:Prefix* len)
        )
    )


    (defun _get_locked ( layers / locked )
        (vlax-for layer layers
            (if (eq :vlax-true (vla-get-lock layer))
                (setq locked (cons layer locked))
            )
        )
        locked
    )


    (defun _get_dynamic_inserts ( blocks / block object inserts )
        (vlax-for block blocks
            (vlax-for object block
                (if (eq "AcDbBlockReference" (vla-get-objectname object))
                    (if (eq :vlax-true (vla-get-isdynamicblock object))
                        (setq inserts (cons object inserts))
                    )
                )
            )
        )
        inserts
    )
  

    (defun _get_dynamic_inserts_from_pickset ( ss / i object inserts )
        (setq i 0)
        (while (< i (sslength ss))
                (setq object (vlax-ename->vla-object (ssname ss i)))
                (if (eq "AcDbBlockReference" (vla-get-objectname object))
                    (if (eq :vlax-true (vla-get-isdynamicblock object))
                        (setq inserts (cons object inserts))
                    )
                )
                (setq i (1+ i))
        )
        inserts
    )


    (defun _main ( document / ss blocks inserts locked len )
        (if (not *UnDynamic:Prefix*)
          (setq *UnDynamic:Prefix* "STATIC_")
        )
        (if (and
              (setq blocks (vla-get-blocks document))
              (setq ss (ssget ":L" (list (cons 0 "INSERT"))))
              (setq inserts (_get_dynamic_inserts_from_pickset ss))
              (setq *UnDynamic:Prefix* (_DefGetString "\nPrefix for static block names" *UnDynamic:Prefix* T))
            )
;;;            (setq inserts
;;;                (_get_dynamic_inserts
;;;                    (setq blocks (vla-get-blocks document))
;;;                )
;;;            )
            
            (progn
;;;                (foreach layer (setq locked (_get_locked (vla-get-layers document)))
;;;                    (vla-put-lock layer :vlax-false)
;;;                )
;;;                (setq len (strlen (itoa (length inserts))))
                (setq len 6)
                (foreach insert inserts
                    (_dynamic->static_block blocks insert len)
                )
;;;                (foreach layer locked
;;;                    (vla-put-lock layer :vlax-true)
;;;                )
                (princ "\n...done.")
            )
            (princ "\nNo dynamic blocks found - no block inserts were changed.")
        )
        (princ)
    )

    (_main (vla-get-activedocument (vlax-get-acad-object)))

)

 

Hey!

 

I really like this code and it works really nice.

 

Is there a way to edit the code, that i can write my blocknames inside the code and when i execute the code i don't need to pick the blocks i want to get static?

My problem is, that i have multible layouts with dynamic blocks for the plan frame and when i want to make them static i need to go in each layout and select them individually (which takes some time).

 

It would be really nice, if you could change the code, that i just need to add my blocknames.

 

Thank's in advance! 🙂

0 Likes
Message 37 of 39

syan2_D
Community Visitor
Community Visitor

Hi I have read your posts twice - and I have encountered same issue. 

I have a lot of dynamic blocks with Rotation only, and hope to convert to static block and keep them all as the same name! (*then they will be imported to Rhino).

My question is which code you used at the end, and what is the Macro you mentioned, and how to use it? sorry I don't understand too much about coding/script..

0 Likes
Message 38 of 39

sbaines
Explorer
Explorer

Hay @syan2_D Did you ever find that LISP rotuine?

0 Likes
Message 39 of 39

karpki
Advocate
Advocate

Hi, Sorry for a late answer

The fact that I don't use it anymore cause have found how to manage with all those dynamic blocks 🙂

 

Macro was: ^C^C_bedit;ai_selall;_copybase;0;0;delete;_pasteclip;0;_bclose;;

 

Best regards

Kirill

0 Likes