Author Topic: How to find exploded blocks  (Read 6238 times)

0 Members and 1 Guest are viewing this topic.

HasanCAD

  • Swamp Rat
  • Posts: 1422
How to find exploded blocks
« on: January 12, 2011, 05:55:03 AM »
Is there a way to find and replace exploded blocks
Suppose I have a plan has 10 blocks each block inserted 10 times but all blocks are exploded.
How to find exploded block re block again

I know It is MAD idea but may be there is a solution somewhere

kruuger

  • Swamp Rat
  • Posts: 637
Re: How to find exploded blocks
« Reply #1 on: January 12, 2011, 06:44:45 AM »
That's really MAD  :-)

I think that only way to do this is to compare object layout/position to blocks layout (is it possible ?). If equal that block them.
I will be watching this tread. It is interesting.

Really MAD.

kruuger

pBe

  • Bull Frog
  • Posts: 402
Re: How to find exploded blocks
« Reply #2 on: January 12, 2011, 07:02:33 AM »

I think that only way to do this is to compare object layout/position to blocks layout (is it possible ?).

That would be something indeed 8-)

If a copy of the original block is still in the drawing, i guess you can use that for comparison  :| maybe... maybe not
It would be interesting to see if anyone would even try doing it this way..
 :-)

We shall see   :wink:

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: How to find exploded blocks
« Reply #3 on: January 12, 2011, 08:13:27 AM »
Maybe you can test for gunshot residue. :evil:
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Nibster

  • Guest
Re: How to find exploded blocks
« Reply #4 on: January 12, 2011, 08:29:42 AM »
Maybe you can test for gunshot residue. :evil:

i think that test is only good for dead links.   :-)


Tharwat

  • Swamp Rat
  • Posts: 710
  • Hypersensitive
Re: How to find exploded blocks
« Reply #5 on: January 12, 2011, 08:37:57 AM »
Woooooooo Iam sorry to hear that . :cry:  :cry:  :|

David Bethel

  • Swamp Rat
  • Posts: 656
Re: How to find exploded blocks
« Reply #6 on: January 13, 2011, 04:55:41 AM »
It could be probably be done with a high rate of accuracy.  But it would take a major amount of effort

Stumbling points would be INSERTs that were:
  • Rotated
  • Scaled
  • Unequally Scaled
  • Non WCS
prior to being exploded.

If any sub entities had been erased or modified, it would make the task almost impossible.  -David
R12 Dos - A2K

jvillarreal

  • Bull Frog
  • Posts: 332
Re: How to find exploded blocks
« Reply #7 on: July 26, 2011, 02:36:24 PM »
Using the simple idea of selecting the exploded block entities (1 block at a time) and comparing entity count along with min/max lengths of unpurged blocks...this could at least provide a starting point as it seems to work most of the time with limited testing.
I've provided a test drawing. I tried accounting for uniform scaling and rotation as well.
Please note that i haven't been lispin much in the past few months so expect the worst.
Code: [Select]
;;RB.lsp
(defun binfo (ob / sv msv cnt blengths)
 (setq sv (safearray-value (vlax-variant-value (vla-explode ob))) cnt (length sv)
       msv (vl-remove-if-not '(lambda (x)(vl-position (vla-get-objectname x) '("AcDbArc" "AcDbLine" "AcDbPolyline" "AcDbLWPolyline" "AcDb2dPolyline" "AcDb3dPolyline"))) sv))
(if msv (setq
       blengths (mapcar '(lambda (x)(olen x)) msv)
       minlen (apply 'min blengths) maxlen (apply 'max blengths)
       mino (nth (vl-position minlen blengths) msv)
       mins (vlax-curve-getpointatparam mino (vlax-curve-getstartparam mino))
       mine (vlax-curve-getpointatparam mino (vlax-curve-getendparam mino))))
 (mapcar '(lambda (x)(vla-delete x)) sv)
 cnt
)


(defun ssget->vla-list (ss / i ename allobj);(Charles Alan Butler)
 (if ss
  (progn
       (setq i -1)
       (while (setq  ename (ssname ss (setq i (1+ i))))
         (setq allobj (cons (vlax-ename->vla-object ename) allobj))
       )
       allobj))
)

(defun olen (ob / on)
(setq on (vla-get-objectname ob))
(cond
 ((vl-position on '("AcDbLine" "AcDbPolyline" "AcDbLWPolyline" "AcDb2dPolyline" "AcDb3dPolyline"))
   (vla-get-length ob))
 ((= on "AcDbArc")(vla-get-arclength ob))
)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun c:rb (/ ActDoc *Space* obcontents blk bname bcen ecen bfound tempobj mins mine mino minlen maxlen emins emine emino eminlen emaxlen ecnt)
(vl-load-com)
(setq ActDoc (vla-get-activedocument (vlax-get-acad-object))
      *Space* (vlax-get-property ActDoc (nth (vla-get-ActiveSpace ActDoc)'("PaperSpace" "ModelSpace")))
      obcontents (ssget) ecnt (sslength obcontents)
      vlaobcontents (ssget->vla-list obcontents)
      vlaobcontents (vl-remove-if-not
                     '(lambda (x)(vl-position (vla-get-objectname x) '("AcDbArc" "AcDbLine" "AcDbPolyline" "AcDbLWPolyline" "AcDb2dPolyline" "AcDb3dPolyline"))) vlaobcontents)
      elengths (mapcar '(lambda (x)(olen x)) vlaobcontents)
      eminlen (apply 'min elengths) emaxlen (apply 'max elengths)
      emino (nth (vl-position eminlen elengths) vlaobcontents)
      emins (vlax-curve-getpointatparam emino (vlax-curve-getstartparam emino))
      emine (vlax-curve-getpointatparam emino (vlax-curve-getendparam emino)))
(vlax-for blk (vla-get-blocks ActDoc)
   (and (not bfound) tempobj (not (vla-delete tempobj))(setq tempobj nil bname nil))
   (and
      (not bfound)
      (not (wcmatch (vla-get-name blk) "*Model_Space*,*Paper_Space*"))
      (eq (vlax-get-property blk 'explodable) :vlax-true)
      (setq tempobj
        (vla-insertblock *Space*
          (vlax-3d-point
            '(0 0 0)
          )
          (vla-get-name blk) 1.0 1.0 1.0 0.0
        )
      )
      (setq bname (vla-get-name blk))
   )

  (if (and bname tempobj
       (equal(binfo tempobj) ecnt 3)
       (equal (/ minlen eminlen)(/ maxlen emaxlen) -1.0e-6)
      )
      (setq bfound bname)
  )
)
  (if bfound
   (progn
    (vla-move tempobj (vlax-3d-point mins) (vlax-3d-point emins))
    (vla-rotate tempobj (vlax-3d-point emins)(- (angle emins emine)(angle mins mine)))
    (vla-scaleentity tempobj (vlax-3d-point emins)(/ eminlen minlen))
    (princ (strcat "\nBlock Found - " bname))
   )
  )

(and (not bfound) tempobj (vla-delete tempobj))
(if (not bfound)(princ "\nNo Match Found."))
(princ)
)

Andrea

  • Water Moccasin
  • Posts: 2372
Re: How to find exploded blocks
« Reply #8 on: July 26, 2011, 04:26:29 PM »
Well,...ther is my suggestion.

Create a tool who save block name and there propreties in a dictionary when closing the drawing.
so when the drawing will open the tool will check the block list data.

maybe i'm crasy... but this is what it come in mind.
Keep smile...

vnanhvu

  • Guest
Re: How to find exploded blocks
« Reply #9 on: July 26, 2011, 09:20:01 PM »
  Sorry i have a question, if someone broke all DIM, there is way to recover to its. Thanks for all help.

Andrea

  • Water Moccasin
  • Posts: 2372
Re: How to find exploded blocks
« Reply #10 on: July 27, 2011, 04:42:17 PM »
a little handy...but I think yes.
Keep smile...

SOFITO_SOFT

  • Guest
Re: How to find exploded blocks
« Reply #11 on: July 27, 2011, 06:55:49 PM »
Hellosss @llsssss:
The "Handle" may be a clue?
When does the INSERT is assigned a handle (DXF code 5).
When broken, this should go away right HANDLE?.
And the new entintys, daughters of the block, will have to take one.
Will they be consecutive?
The hole is free of disappear INSERT is completed or is it free?

Perhaps these are the remains of the powder of the shooting. :-P :-P :evil:

Greetings for Madrid.  :-) :-)

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: How to find exploded blocks
« Reply #12 on: July 29, 2011, 02:22:15 AM »
Unfortunately not necessarily. The handle isn't like an index, it's more of a hash code. There is probably a way to calculate it, but nothing documented. And there's probably also some objects made in between each of these "daughter' entities (e.g. the text in a Dim would probably also contain some XDictionaries & XRecords - each would also have handles)

I remember another thread about this - trying to get the "previous" entity by trying to calculate it's handle. I think the consensus there was that the ActiveX ObjectID was a better bet.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

Jeff H

  • Needs a day job
  • Posts: 6150
Re: How to find exploded blocks
« Reply #13 on: August 02, 2011, 02:42:30 AM »
For ObjectARX and .NET you can get the next handle using the Database's HandSeed property, the only thing that showed up in search was in DXF reference Headers Section for $HandSeed and not sure if that is helpful for Autolisp, but I do not really see how that helps much for this situation.

Getting the exploded blocks is easy if the drawing has not been closed using BlockTableRecord.GetErasedBlockReferenceIds and you are able to get the scale factor, rotation etc......
If the drawing has been closed then you need to add a event to store the info and using scale, rotation, insertion point etc..... you could find the exploded entites and replace with a BlockReference, but not sure if that is possible in AutoLisp

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: How to find exploded blocks
« Reply #14 on: August 02, 2011, 04:15:26 AM »
I think the idea with getting the handle would be to check for consecutiveness of entities in the Model/Paper space. Comparing them to what's in the block definition. Though you're correct, a simple entnext would do the same without needing to fiddle with Handle/ObjectID at all.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

curmudgeon

  • Newt
  • Posts: 194
Re: How to find exploded blocks
« Reply #15 on: August 02, 2011, 10:50:24 AM »
AH HA!

I think this will actually work. I will lay out my method. There are assumptions being made here.
I assume that the block is NOT a dimension for one.

When you explode a block, the data is written sequentially. Lee helped me with a hex converter not that long ago for a very similar purpose. I think, at least in my version of Autocad, and with what very little testing I did, that when a block is exploded the new handles WILL BE SEQUENTIAL. Handles are permanent, so the sequence should also be.

So, on the back of a napkin, do this.

Insert a new instance of the block you desire, and explode it OR go through the block definition table to get the "recipe" for the block you are interested in.

Do an ssget "X" for the exact entity of the first entity of the block, and make a list of the handles. Run the list and compare the sequential handles for the pattern formed by the block.

Since there is so much chance for stuff to go wrong, I think I would have the routine zoom in on the location when it thinks it finds an exploded block.

Cool?
Never express yourself more clearly than you are able to think.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: How to find exploded blocks
« Reply #16 on: August 02, 2011, 11:40:03 AM »
My point is you don't need to worry about the handle. The entnext function already does the sequencial bit for you. What I'm not sure about is does an explode work the same way round as (say) a select-and-copy? I.e. does it do these in reverse order? That may make for some "really" interesting coding!
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

Lee Mac

  • Seagull
  • Posts: 12915
  • London, England
Re: How to find exploded blocks
« Reply #17 on: August 02, 2011, 11:44:01 AM »
Do an ssget "X" for the exact entity of the first entity of the block...

But bear in mind that the first entity of the block definition is defined in WCS, at 1:1 scale and zero rotation.

The exploded blocks could have any insertion point, any normal, any scale (which could be non-uniform), and any rotation. All of such properties are lost when the block is exploded...

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: How to find exploded blocks
« Reply #18 on: August 02, 2011, 12:15:49 PM »
Yes, so the idea would be to first check for a set of consecutive entities matching the same entity types (perhaps in reverse order). Then the "real" hard part comes in: You'll need to account for such rotation, scaling (both uniform and non), ucs adjustment, etc. If all those check out, then you've probably got an "exploded" block.

The problem is how to convert to-and-from the block's internal WCS to what's in the DWG's WCS/UCS and account for rotations, mirrors, scaling and scale factor adjustments. It's difficult enought just to do that adjusting on a non-exploded block, never mind when you don't have stuff like an insertion point, normal, rotation & xyz scale factors!
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

curmudgeon

  • Newt
  • Posts: 194
Re: How to find exploded blocks
« Reply #19 on: August 02, 2011, 12:30:19 PM »
This is too much fun. entnext, yes. I can be such an idiot.

I am thinking that as the number of entities in the block increases, the chances of simply finding just the types in sequence approaches zed. How about if, for a single user and not the masses, you fix the exact matches and create a list of the those in sequence but with "problems" such as scale and UCS. Actually, maybe the scale would not be too hard to code if it were uniform.

My original application was with exploded blocks occurred when they were created or edited in Revit.
The translation back and forth to Autocad created inconsistencies. For example, so you have something to chew on, a smoke detector block would have an "S" in the middle of it, and sometimes the exploded block had the text entity - sometimes the "S" was broken down into several arc segment entities.

But that job "lost funding" and I never completed my routine to find the exploded blocks.
Which reminds me, I have to stop playing and get back to work.

cheers.

Never express yourself more clearly than you are able to think.

Jeff H

  • Needs a day job
  • Posts: 6150
Re: How to find exploded blocks
« Reply #20 on: August 02, 2011, 01:09:07 PM »
For that to work you need to know when it gets exploded so you might as well just call undo.

If you know the block,
 can you store the blockrefrences ObjectId's in a xrecord which will remap when drawing is open and store the insertion point rotaion and scale.

Then all you have to do is check if the objectId's were erased and if so use the insertion point, scale, and rotation info to find the where the exploded entites would be and insert a new block.

But seems that there must be a eaiser way by using a rector or whatever to watch for the explode command or the block being exploded and undoing it, or you trying to find a way to come back at a later point to un-explode them?   

Chris

  • Swamp Rat
  • Posts: 548
Re: How to find exploded blocks
« Reply #21 on: August 02, 2011, 01:26:50 PM »
well if you are going to go that far as to undo it just after it explodes, you might as well set up the block not to be able to be exploded.
Christopher T. Cowgill, P.E.
AEC Collection 2020 (C3D)
Win 10

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: How to find exploded blocks
« Reply #22 on: August 03, 2011, 02:07:07 AM »
Yep, AFAICT the idea is not to "stop" / "revert" / undo the explode command, but to get a DWG from somewhere (anywhere) which might already have these "exploded" blocks, without any "special" info about what was exploded where. So there's no way of using a reactor / redefining the explode command / making the block unexplodable. That would be like closing the gate after all your cattle's escaped. Though it would be the more "correct" and efficient way (i.e. prevention), it's rather useless in a scenario where the crime's already occurred  :pissed: .
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.