Author Topic: Convert annotative blocks to normal blocks  (Read 18201 times)

0 Members and 1 Guest are viewing this topic.

vnanhvu

  • Guest
Convert annotative blocks to normal blocks
« on: June 29, 2011, 01:38:29 AM »
I use layout, I take annonative 100 (in properties )for in viewport scale 100 Only see. Same text, dim with annonative.
Can you help me, convert annotative blocks to normal blocks.
Thank you very much.

alanjt

  • Needs a day job
  • Posts: 5352
  • Standby for witty remark...
Re: Convert annotative blocks to normal blocks
« Reply #1 on: June 29, 2011, 08:49:59 AM »
Code: [Select]
Command:
CHANGE
Select objects: Specify opposite corner: 10 found

Select objects:
Specify change point or [Properties]: p

Enter property to change
[Color/Elev/LAyer/LType/ltScale/LWeight/Thickness/TRansparency/Material/Annotati
ve]: a

Make Annotative? [Yes/No] <No>:

Enter property to change
[Color/Elev/LAyer/LType/ltScale/LWeight/Thickness/TRansparency/Material/Annotati
ve]:
Civil 3D 2019 ~ Windohz 7 64bit
Dropbox

ribarm

  • Gator
  • Posts: 3225
  • Marko Ribar, architect
Re: Convert annotative blocks to normal blocks
« Reply #2 on: June 29, 2011, 09:19:16 AM »
Alan, neither of variations in this code won't work neither in Acad 2012 nor Acad 2011 nor Acad 2008...

Code: [Select]
(defun c:t ( / ss ssent Block BlockName blocks ch)
  (vl-load-com)
  (prompt "\nSelect block")
  (setq ss (ssget ":S"))
  (setq ssent (ssname ss 0))
  (setq Block (vlax-ename->vla-object ssent))
  (setq BlockName (vla-get-effectivename Block))
  (setq blocks (vla-get-blocks
(vla-get-activedocument (vlax-get-acad-object))
       )
  )
  (initget 1 "Annotative a Non-annotative n")
  (setq ch
(getkword
   "\nDo you want to make block Annotative or Non-annotative (A/N) : "
)
  )
  (vlax-for bl blocks
    (cond ((and (= (vla-get-name bl) BlockName) (= ch "Annotative"))
   ;(vla-put-Annotative bl :vlax-true)
           (command "change" ssent "" "P" "A" "Yes" "")
   )
  ((and (= (vla-get-name bl) BlockName) (= ch "Non-annotative"))
   ;(vla-put-Annotative bl :vlax-false)
   (command "change" ssent "" "P" "A" "No" "")
   )
    )
  )
  (princ)
)

M.R. :-(
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

vnanhvu

  • Guest
Re: Convert annotative blocks to normal blocks
« Reply #3 on: June 29, 2011, 01:31:27 PM »
 Thanks Rebarm& Alanjt, but no result. Hix :cry:

ribarm

  • Gator
  • Posts: 3225
  • Marko Ribar, architect
Re: Convert annotative blocks to normal blocks
« Reply #4 on: June 29, 2011, 02:06:31 PM »
Even worse... I tried to trick CAD (to explode block, delete, redefine it and if necessary insert with new Annotation value)... No success, for after explode, all subentities changed their entity names... Nothing gets selected from new selection set after explode...

Code: [Select]
(defun listsubent (bname / data datalst)
(setq data (tblobjname "BLOCK" bname))
(setq data (entget data '("*")))
(setq data (acet-dxf -2 data))
(setq datalst (cons data datalst))
(setq data (entget data '("*")))
(while data
(setq data (entnext (acet-dxf -1 data)))
(if (/= data nil)
(progn
(setq datalst (cons data datalst))
(setq data (entget data '("*")))
))
)
(setq datalst (reverse datalst))
)

;(defun c:t ( / ss ssent blocks Block BlockName inspt rotang Xeffscf Yeffscf Zeffscf subentlst sssubents ch)
(defun c:t nil
  (vl-load-com)
  (prompt "\nSelect block")
  (setq ss (ssget ":S"))
  (setq ssent (ssname ss 0))
  (setq blocks (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))))
  (setq Block (vlax-ename->vla-object ssent))
  (setq BlockName (vla-get-effectivename Block))
  (setq inspt (vlax-safearray->list (vlax-variant-value (vla-get-insertionpoint Block))))
  (setq rotang (vla-get-rotation Block))
  (setq Xeffscf (vla-get-Xeffectivescalefactor Block))
  (setq Yeffscf (vla-get-Yeffectivescalefactor Block))
  (setq Zeffscf (vla-get-Zeffectivescalefactor Block))
  (setq subentlst (listsubent BlockName)) 
  (setq sssubents (ssadd))
  (foreach sub subentlst
  (ssadd sub sssubents)
  )
  (vlax-for bl blocks
  (if (= (vla-get-name bl) BlockName)
  (vla-put-explodable bl :vlax-true)
  )
  )
;  (command "group" "" BlockName "" ssent "")
  (vla-explode Block)
  (vla-delete Block)
  (initget 1 "Annotative a Non-annotative n")
  (setq ch
(getkword
   "\nDo you want to make block Annotative or Non-annotative (A/N) : "
)
  )
  (if (= ch "Annotative") (setq ch "Yes"))
  (if (= ch "Non-annotative") (setq ch "No"))
;  (command "select" "g" BlockName "")
;  (setq sssubents (ssget "P"))
  (sssetfirst nil sssubents)
;  (command "block" BlockName "Y" "A" ch "" inspt sssubents "")
;  (command "insert" BlockName inspt Xeffscf rotang)
  (princ)
)

M.R. Shit... :realmad:
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

vnanhvu

  • Guest
Re: Convert annotative blocks to normal blocks
« Reply #5 on: June 29, 2011, 02:14:39 PM »
i can use command X ( explode ), easy and quick, but i must block all again. :lmao:

ribarm

  • Gator
  • Posts: 3225
  • Marko Ribar, architect
Re: Convert annotative blocks to normal blocks
« Reply #6 on: June 29, 2011, 03:14:18 PM »
I did it... Try this:

Code: [Select]
(defun c:t ( / ss ssent blocks Block BlockName inspt rotang rotangd Xeffscf Yeffscf Zeffscf sssubents ch)
  (vl-load-com)
  (prompt "\nSelect block")
  (setq ss (ssget ":S"))
  (setq ssent (ssname ss 0))
  (setq blocks (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))))
  (setq Block (vlax-ename->vla-object ssent))
  (setq BlockName (vla-get-effectivename Block))
  (setq inspt (vlax-safearray->list (vlax-variant-value (vla-get-insertionpoint Block))))
  (setq rotang (vla-get-rotation Block))
  (setq rotangd (* (/ 180 PI) rotang))
  (setq Xeffscf (vla-get-Xeffectivescalefactor Block))
  (setq Yeffscf (vla-get-Yeffectivescalefactor Block))
  (setq Zeffscf (vla-get-Zeffectivescalefactor Block))
  (vlax-for bl blocks
  (if (= (vla-get-name bl) BlockName)
  (vla-put-explodable bl :vlax-true)
  )
  )
  (command "EXPLODE" ssent "")
  (initget 1 "Annotative a Non-annotative n")
  (setq ch
(getkword
   "\nDo you want to make block Annotative or Non-annotative (A/N) : "
)
  )
  (setq sssubents (ssget "P"))
  (if (= ch "Annotative")
  (progn
  (setq ch "Yes")
  (command "block" BlockName "Y" "A" ch "Y" inspt sssubents "")
  (command "insert" BlockName inspt Xeffscf Yeffscf rotangd)
  ))
  (if (= ch "Non-annotative")
  (progn
  (setq ch "No")
  (command "block" BlockName "Y" "A" ch "Y" inspt sssubents "")
  (command "insert" BlockName inspt Xeffscf rotangd)
  ))
  (princ)
)

M.R. - Explode did the trick and selection was possible... :lol:
« Last Edit: June 30, 2011, 06:41:49 AM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

vnanhvu

  • Guest
Re: Convert annotative blocks to normal blocks
« Reply #7 on: June 29, 2011, 03:43:56 PM »
My drawing have some object same name block.When i use your code, old blocks is replaced by new some blocks. Display error location with that blocks. How you can try! You can copy this block into 10 blocks, and....bummmm.... error location block ... :-o

ribarm

  • Gator
  • Posts: 3225
  • Marko Ribar, architect
Re: Convert annotative blocks to normal blocks
« Reply #8 on: June 30, 2011, 04:44:17 AM »
You have to insert firstly your block with X,Y,Z scale factor 1... Then you should add to annoscales of block scale 1:1 and delete 1:100... Then you have to set CANNOSCALE to 1:1 (active scale of active document)... Anyway, I'll post your modified *.dwg, where routine should work...

M.R.

P.S. Last lines in my code with insert command were changed (you have to insert attribute values during insert)
« Last Edit: June 30, 2011, 06:42:26 AM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

vnanhvu

  • Guest
Re: Convert annotative blocks to normal blocks
« Reply #9 on: June 30, 2011, 10:44:14 AM »
Thank for helping me. But there is a problem, when i change annotative 1:1, block is minimized, and request rename blocks. If i have multiple blocks, i take the time to rename & scale blocks.
Maybe i have to do this manually, i do not set annonative from the beginning.
Thank you again.

hc9818

  • Guest
Re: Convert annotative blocks to normal blocks
« Reply #10 on: November 06, 2015, 03:04:01 PM »
Hi ribarm,
I have tried your code above. My dwg file contians multiple blocks with Annotative set to Yes. My problem is that only the last block from the selection will be changed No. Can you please help?

ribarm

  • Gator
  • Posts: 3225
  • Marko Ribar, architect
Re: Convert annotative blocks to normal blocks
« Reply #11 on: November 06, 2015, 03:40:20 PM »
I can't guarantee, but have you tried to iterate through selection set without singe option...

Code: [Select]
(defun c:t ( / ucsf ch blocks bllst ss i ssent Block BlockName inspt rotang rotangd Xeffscf Yeffscf Zeffscf sssubents ans )

  (vl-load-com)

  (if (eq (getvar 'worlducs) 0)
    (progn
      (command "_.UCS" "_W")
      (setq ucsf t)
    )
  )
  (initget 1 "Annotative Non-annotative")
  (setq ch
    (getkword
      "\nDo you want to make selected blocks Annotative or Non-annotative [A/N] : "
    )
  )
  (setq blocks (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))))
  (vlax-for bl blocks
    (setq bllst (cons (list (vla-get-name bl) bl (vla-get-isxref bl)) bllst))
  )
  (prompt "\nSelect blocks with or without attributes that reside on unlocked layer(s)...")
  (setq ss (ssget "_:L" '((0 . "INSERT"))))
  (if ss
    (repeat (setq i (sslength ss))
      (setq ssent (ssname ss (setq i (1- i))))
      (setq Block (vlax-ename->vla-object ssent))
      (setq BlockName (vla-get-effectivename Block))
      (setq inspt (vlax-safearray->list (vlax-variant-value (vla-get-insertionpoint Block))))
      (setq rotang (vla-get-rotation Block))
      (setq rotangd (* (/ 180 PI) rotang))
      (setq Xeffscf (vla-get-Xeffectivescalefactor Block))
      (setq Yeffscf (vla-get-Yeffectivescalefactor Block))
      (setq Zeffscf (vla-get-Zeffectivescalefactor Block))
      (if (and (assoc BlockName bllst) (eq (last (assoc BlockName bllst)) :vlax-false))
        (vla-put-explodable (cadr (assoc BlockName bllst)) :vlax-true)
      )
      (command "_.EXPLODE" ssent)
      (while (< 0 (getvar 'cmdactive))
        (command "")
      )
      (setq sssubents (ssget "_P"))
      (if (= ch "Annotative")
        (progn
          (setq ans "Yes")
          (command "_.ROTATE" sssubents "" "_non" inspt (- rotangd))
          (command "_.BLOCK" BlockName "_Y" "_A" ans "_N" "_non" inspt sssubents "")
          (command "_.INSERT" BlockName "_non" inspt Xeffscf Yeffscf rotangd)
        )
        (progn
          (setq ans "No")
          (command "_.ROTATE" sssubents "" "_non" inspt (- rotangd))
          (command "_.BLOCK" BlockName "_Y" "_A" ans "_N" "_non" inspt sssubents "")
          (command "_.INSERT" BlockName "_non" inspt Xeffscf rotangd)
        )
      )
    )
    (prompt "\nEmpty sel.set... Retry routine with some blocks selected next time...")
  )
  (if ucsf
    (command "_.UCS" "_P")
  )
  (princ)
)

If you have attributed blocks, then you'll have to do it in another way... You have to try without me as I am not sure how to quickly write it...

[EDIT : Code changed to accept attributed blocks...]
« Last Edit: December 07, 2015, 02:07:18 AM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Convert annotative blocks to normal blocks
« Reply #12 on: November 07, 2015, 08:09:31 AM »
Here is my suggestion (without redefining blocks).
Note: Limited testing on BricsCAD V14. Seems to work OK though.
Code - Auto/Visual Lisp: [Select]
  1. (defun _Conv_Pickset_To_EnameList (ss / i ret)
  2.   (if ss
  3.     (repeat (setq i (sslength ss))
  4.       (setq ret (cons (ssname ss (setq i (1- i))) ret))
  5.     )
  6.   )
  7. )
  8.  
  9. (defun _Data_XdataGet (ename app)
  10.   (cdadr (assoc -3 (entget ename (list app))))
  11. )
  12.  
  13. (defun _Data_XdataSet (ename app dataLst)
  14.   (regapp app)
  15.   (entmod
  16.     (append
  17.       (entget ename)
  18.       (list (list -3 (cons app dataLst)))
  19.     )
  20.   )
  21. )
  22.  
  23. (defun _Sys_Apply (expr varLst / ret)
  24.   (if (not (vl-catch-all-error-p (setq ret (vl-catch-all-apply expr varLst))))
  25.     ret
  26.   )
  27. )
  28.  
  29. (defun BlkDefNonAnnotative (obj)
  30.   (if
  31.     (and
  32.       (= :vlax-false (vla-get-isxref obj))
  33.       (_Data_XdataGet (vlax-vla-object->ename obj) "AcadAnnotative")
  34.     )
  35.     (_Data_XdataSet
  36.       (vlax-vla-object->ename obj)
  37.       "AcadAnnotative"
  38.       '(
  39.         (1000 . "AnnotativeData")
  40.         (1002 . "{")
  41.         (1070 . 1)
  42.         (1070 . 0)
  43.         (1002 . "}")
  44.       )
  45.     )
  46.   )
  47. )
  48.  
  49. (defun BlkRefNonAnnotative (obj / dic ext)
  50.   (if
  51.     (and
  52.       (= :vlax-true (vla-get-hasextensiondictionary obj))
  53.       (setq ext (vla-getextensiondictionary obj))
  54.     )
  55.     (progn
  56.       (if (setq dic (_Sys_Apply 'vla-item (list ext "AcDbContextDataManager")))
  57.         (vla-delete dic)
  58.       )
  59.       (if (zerop (vla-get-count ext))
  60.         (vla-delete ext)
  61.       )
  62.     )
  63.   )
  64. )
  65.  
  66. (defun c:test ( / blks ss nmeLst)
  67.   (if (setq ss (ssget '((0 . "INSERT"))))
  68.     (mapcar
  69.       '(lambda (enme / nme obj)
  70.         (setq obj (vlax-ename->vla-object enme))
  71.         (if (not (vl-position (setq nme (strcase (vla-get-name obj))) nmeLst))
  72.           (progn
  73.             (setq nmeLst (cons nme nmeLst))
  74.             (BlkDefNonAnnotative (vla-item blks nme))
  75.           )
  76.         )
  77.         (BlkRefNonAnnotative obj)
  78.       )
  79.       (_Conv_Pickset_To_EnameList ss)
  80.     )
  81.   )
  82.   (princ)
  83. )

hc9818

  • Guest
Re: Convert annotative blocks to normal blocks
« Reply #13 on: November 10, 2015, 01:15:38 PM »
ribarm, Thanks so much for your quick response! Your code works for me. I will try roy's code when I have a chance. 

ribarm

  • Gator
  • Posts: 3225
  • Marko Ribar, architect
Re: Convert annotative blocks to normal blocks
« Reply #14 on: December 07, 2015, 12:03:11 AM »
Hi, I have some request research... I've updated my code from here :
http://www.theswamp.org/index.php?topic=38757.msg555312#msg555312

But now I am not aware and unable to replicate behavior when and why I have to use burst command to explode attributed blocks, when now this code works with just ordinary EXPLODE command leaving attribute definitions that are to be consequently be used in process of redefining block with them...

If you have an info I overlooked inform me or shed some light ab burst...

Thanks, M.R.
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3225
  • Marko Ribar, architect
Re: Convert annotative blocks to normal blocks
« Reply #15 on: December 07, 2015, 02:47:45 AM »
Ok, I've found this link :
http://www.cad-notes.com/use-burst-for-block-with-attributes-instead-of-explode/
explaining for what burst command is useful in comparison to EXPLODE... And there is also this link :
http://autocadtips1.com/2011/07/21/using-burst-to-explode-a-block/
explaining usage of BURST over EXPLODE to explode Dynamic Blocks...

But have you seen examples where you can't do EXPLODE on block that is explodable and instead you must use BURST to explode block with attributes (block behaves like unexplodable) - I have report that in some cases this is an issue?
Please any opinion?
Thanks...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

boycemin

  • Guest
Re: Convert annotative blocks to normal blocks
« Reply #16 on: July 18, 2019, 02:17:06 PM »
I can't guarantee, but have you tried to iterate through selection set without singe option...

Code: [Select]
(defun c:t ( / ucsf ch blocks bllst ss i ssent Block BlockName inspt rotang rotangd Xeffscf Yeffscf Zeffscf sssubents ans )

  (vl-load-com)

  (if (eq (getvar 'worlducs) 0)
    (progn
      (command "_.UCS" "_W")
      (setq ucsf t)
    )
  )
  (initget 1 "Annotative Non-annotative")
  (setq ch
    (getkword
      "\nDo you want to make selected blocks Annotative or Non-annotative [A/N] : "
    )
  )
  (setq blocks (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))))
  (vlax-for bl blocks
    (setq bllst (cons (list (vla-get-name bl) bl (vla-get-isxref bl)) bllst))
  )
  (prompt "\nSelect blocks with or without attributes that reside on unlocked layer(s)...")
  (setq ss (ssget "_:L" '((0 . "INSERT"))))
  (if ss
    (repeat (setq i (sslength ss))
      (setq ssent (ssname ss (setq i (1- i))))
      (setq Block (vlax-ename->vla-object ssent))
      (setq BlockName (vla-get-effectivename Block))
      (setq inspt (vlax-safearray->list (vlax-variant-value (vla-get-insertionpoint Block))))
      (setq rotang (vla-get-rotation Block))
      (setq rotangd (* (/ 180 PI) rotang))
      (setq Xeffscf (vla-get-Xeffectivescalefactor Block))
      (setq Yeffscf (vla-get-Yeffectivescalefactor Block))
      (setq Zeffscf (vla-get-Zeffectivescalefactor Block))
      (if (and (assoc BlockName bllst) (eq (last (assoc BlockName bllst)) :vlax-false))
        (vla-put-explodable (cadr (assoc BlockName bllst)) :vlax-true)
      )
      (command "_.EXPLODE" ssent)
      (while (< 0 (getvar 'cmdactive))
        (command "")
      )
      (setq sssubents (ssget "_P"))
      (if (= ch "Annotative")
        (progn
          (setq ans "Yes")
          (command "_.ROTATE" sssubents "" "_non" inspt (- rotangd))
          (command "_.BLOCK" BlockName "_Y" "_A" ans "_N" "_non" inspt sssubents "")
          (command "_.INSERT" BlockName "_non" inspt Xeffscf Yeffscf rotangd)
        )
        (progn
          (setq ans "No")
          (command "_.ROTATE" sssubents "" "_non" inspt (- rotangd))
          (command "_.BLOCK" BlockName "_Y" "_A" ans "_N" "_non" inspt sssubents "")
          (command "_.INSERT" BlockName "_non" inspt Xeffscf rotangd)
        )
      )
    )
    (prompt "\nEmpty sel.set... Retry routine with some blocks selected next time...")
  )
  (if ucsf
    (command "_.UCS" "_P")
  )
  (princ)
)

If you have attributed blocks, then you'll have to do it in another way... You have to try without me as I am not sure how to quickly write it...

[EDIT : Code changed to accept attributed blocks...]

- Hi Ribarm! thanks for your code! it worked on my Cad2019
it have a litle trouble:
i tried with an AnnoBlock (Az) (has list scale 1:1 / 1:50 / 1:100) in a normal block (Nx),
its means Nx= [(Ny)+(Az)]
-
after convert [Az] to Non-annoBlock => [Nz],
in my cur view (1:100) have [Nz] = Az(1:1)scale1.5
and inside Block Nx:
with block curview 1:100,result Nx = [(Ny) + [Nz]scale 150]
with block curview 1:50,  result Nx = [(Ny) + [Nz]scale 75]
with block curview 1:1 ,   result Nx = [(Ny) + [Nz]scale 1.5]
may you fix result is alway scale 1 for curview and same scale for all in normal block not dependd on block view?
i think it will be pretty cool if we could custom scale for New[N] for all (but not change anything inside)
-
by the way, i would like to share with you guys, lisp i get from vietnam
this have AAS function to make Normal block become to annotative block in you Cur View with setting of list scale, ANC help you check available scale of AnnoBlock
but this lisp appears vietnamese language, i have no idea how to translate to English. its no extension by .lsp
hope it is useful for everyone
-
« Last Edit: July 18, 2019, 02:30:50 PM by boycemin »