Author Topic: Explode anonymous blocks  (Read 1339 times)

0 Members and 1 Guest are viewing this topic.

Dennis1

  • Mosquito
  • Posts: 4
Explode anonymous blocks
« on: August 26, 2020, 09:17:20 AM »
I have been using the lisp made by Lee Mac for a while to explode only the anonymous blocks.
While it is working amazing i have the problem that it also explodes all of the dynamic blocks wich i dont want to happen, i have tried to edit it myself but this exceeds my knowledge.



https://www.theswamp.org/index.php?topic=37245.0

Code: [Select]
(defun c:explanon ( / *error* _StartUndo _EndUndo _UnlockLayers _RelockLayers _isExplodable _GetBlockName acblk acdoc locked name ss )
  (vl-load-com)

  (defun *error* ( msg )
    (if locked (_RelockLayers locked))
    (if acdoc  (_EndUndo acdoc))
    (or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
        (princ (strcat "\n** Error: " msg " **")))
    (princ)
  )

  (defun _StartUndo ( doc ) (_EndUndo doc)
    (vla-StartUndoMark doc)
  )

  (defun _EndUndo ( doc )
    (if (= 8 (logand 8 (getvar 'UNDOCTL)))
      (vla-EndUndoMark doc)
    )
  )

  (defun _UnlockLayers ( doc / l )
    (vlax-for layer (vla-get-layers doc)
      (if (eq :vlax-true (vla-get-lock layer))
        (vla-put-lock (car (setq l (cons layer l))) :vlax-false)
      )
    )
    l
  )

  (defun _RelockLayers ( lst )
    (mapcar '(lambda ( l ) (vla-put-lock l :vlax-true)) lst)
  )

  (defun _isExplodable ( blockdef )
    (or
      (not (vlax-property-available-p blockdef 'explodable))
      (eq :vlax-true (vla-get-explodable blockdef))
    )
  )

  (defun _GetBlockName ( obj )
    (if (vlax-property-available-p obj 'effectivename)
      (vla-get-effectivename obj)
      (vla-get-name obj)
    )
  )

  (setq acdoc (vla-get-ActiveDocument (vlax-get-acad-object))
        acblk (vla-get-blocks acdoc)
  )       

  (if (ssget "_X" '((0 . "INSERT") (2 . "`*U*")))
    (progn
      (_StartUndo acdoc) (setq locked (_UnlockLayers acdoc))
     
      (vlax-for obj (setq ss (vla-get-ActiveSelectionSet acdoc))
       
        (if (_isExplodable (vla-item acblk (setq name (_GetBlockName obj))))
          (progn
            (vla-explode obj) (vla-delete obj)
          )
          (princ (strcat "\nBlock: " name " is not explodable."))
        )
      )
      (vla-delete ss) (_RelockLayers locked) (_EndUndo acdoc)
    )
  )

  (princ)
)



ribarm

  • Gator
  • Posts: 3274
  • Marko Ribar, architect
Re: Explode anonymous blocks
« Reply #1 on: August 26, 2020, 10:25:27 AM »
Replace main portion of routine with this (only - if expression is changed...)

Code: [Select]
...
  (if (ssget "_X" '((0 . "INSERT") (2 . "`*U*")))
    (progn
      (_StartUndo acdoc) (setq locked (_UnlockLayers acdoc))
     
      (vlax-for obj (setq ss (vla-get-ActiveSelectionSet acdoc))
       
        (if
          (and
            (_isExplodable (vla-item acblk (setq name (_GetBlockName obj))))
            (= (vla-get-IsDynamicBlock obj) :vlax-false)
          )
          (progn
            (vla-explode obj) (vla-delete obj)
          )
          (princ (strcat "\nBlock: " name " is not explodable, or block with this name is dynamic..."))
        )
      )
      (vla-delete ss) (_RelockLayers locked) (_EndUndo acdoc)
    )
  )
...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

Dennis1

  • Mosquito
  • Posts: 4
Re: Explode anonymous blocks
« Reply #2 on: August 27, 2020, 05:31:34 AM »
Thanks for your reply, this does not seem work for me.
The lisp still functions as the old one did and does not explode the blocks that are Dynamic. But only if the dynamic block is in it's basic state.
if any of the dynamic functions are used (like rotation or flip) your extra code will still explode it. you know a way to fix that 





ribarm

  • Gator
  • Posts: 3274
  • Marko Ribar, architect
Re: Explode anonymous blocks
« Reply #3 on: August 27, 2020, 09:12:50 AM »
What you think is a Dynamic block may and probably is subjective opinion... You may be right, but also wrong... I offered free revision that in general satisfies your request... If you think you are right and adress this as a bug in AutoCAD, then you should adress AutoDesk - not me... And as they are bussy and probably don't want to fix all bugs related to products they released, they may charge you extra to satisfy your specific needs. I thnik that my reply was fairly correct and if you wish you can carry on to try fix on your own... I'd in that manner suggest you to write down additional sub function (IsDynamic-p) and inside it check for any parameter you think is related to Dynamic blocks and if there exist even single, you adress return of sub as T... Then in main routine you should replace this line (= (vla-get-IsDynamicBlock obj) :vlax-false) with (not (IsDynamic-p obj)) and I suppose that now this time it should work as expected... If you wish and find appropriate you can post your discovery at this topic and maybe someone that has the same issue in the future may benefit from your findings and your generosity.
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Explode anonymous blocks
« Reply #4 on: August 27, 2020, 03:27:19 PM »
@Dennis1: Can you post an example DWG?

Dennis1

  • Mosquito
  • Posts: 4
Re: Explode anonymous blocks
« Reply #5 on: August 28, 2020, 02:55:36 AM »
Thanks for your time, here is a small example of the situation

I found this piece of code made by CAB https://www.theswamp.org/index.php?topic=10054.0
this will select all dynamic blocks that have a modified state, these should be filtered out of the selection made by the c:explanon



Code: [Select]
;;  CAB 05/11/06
;;  returns a ss of user selected dynamic blocks or nil
(defun c:ssgetDynamicBlock (/ ename ss ssnew)
  (vl-load-com)
  (setq ss   (ssget '((0 . "INSERT"))))
  (while (setq ename (ssname ss 0))
    (if (eq (vla-get-IsDynamicBlock (vlax-ename->vla-object ename)) :vlax-true)
      (if (null ssnew) (setq ssnew (ssadd ename))(ssadd ename ssnew))
    )
    (ssdel ename ss)
  )
  (sssetfirst nil) ; un-highlight all
  (and ssnew (sssetfirst nil ssnew)) ; highlite remaining
  ssnew
)

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Explode anonymous blocks
« Reply #6 on: August 28, 2020, 04:01:30 AM »
@Dennis1:
Ribarm's modification and the code in your last post rely on the same IsDynamicBlock property. There is nothing wrong with ribarm's code. When used the blocks indicated as having a 'flipped' state are not exploded.

So probably you are misinterpreting the results.

The DWG is a bit strange though:
Anon blocks are nested in anon blocks.
Dynamic blocks are nested in non-dynamic anon blocks.

Dennis1

  • Mosquito
  • Posts: 4
Re: Explode anonymous blocks
« Reply #7 on: August 28, 2020, 04:58:37 AM »
I tried it on a other pc with civil and there it indeed worked, wich is weird, dont know what caused this. but it indeed works. Thank you @Roy and Ribarm

the cause of this anon in anon thing this comes from survey data in civil 3d wich used to be cogopoints, but to be usable in regular Cad they need to be exploded to be used as regular blocks.
some elements of the survey points then have multiple different blocks nested in them so need to be exploded multiple times to get to final non anon block