Author Topic: vla-explode changes drawing ?!?  (Read 12248 times)

0 Members and 1 Guest are viewing this topic.

BlackBox

  • King Gator
  • Posts: 3770
Re: vla-explode changes drawing ?!?
« Reply #15 on: August 28, 2014, 07:25:49 PM »
Here's a way to strip the constraints ( use with caution as it's a lobotomy ) :)

I tested and seemd to fix the vla-explode problem.
Code - Auto/Visual Lisp: [Select]
  1. (defun _stripconstraint ( / dic)
  2.   (and (setq dic (dictsearch (namedobjdict) "acad_assocnetwork")) (entdel (cdr (assoc -1 dic))))
  3. )
  4. (_stripconstraint)

That's the dictionary I couldn't remember for the life of me; thanks for the reminder.  :-)

I was reading a DevBLog article on adding geometric constraints in C#... Stephen was the author, or a contributor if memory serves.
"How we think determines what we do, and what we do determines what we get."

matthias312

  • Guest
Re: vla-explode changes drawing ?!?
« Reply #16 on: August 29, 2014, 02:25:01 AM »
Great both solution work perfectly :-D

Maybe this can work?
Is it right that you "redraw" the elements of the block and then delete it?.

As i'm realatively new to Lisp i would really like to know why the block behaved the way it did before ur help?

Here's a way to strip the constraints ( use with caution as it's a lobotomy ) :)

Lobotomy sounds a little bit dangerous  :-o, but it does the job.
Is there something special where its not good to use this methode?

Thank you all for your fast help!!!
« Last Edit: August 29, 2014, 02:33:23 AM by matthias312 »

matthias312

  • Guest
Re: vla-explode changes drawing ?!?
« Reply #17 on: August 29, 2014, 06:11:02 AM »
Maybe this can work?

Code - Auto/Visual Lisp: [Select]
  1. (defun c:test ( / s )
  2.     (if (setq s (ssget "_+.:E:S:L" '((0 . "INSERT"))))
  3.         (explodeblock (ssname s 0))
  4.     )
  5.     (princ)
  6. )
  7.  
  8. (defun explodeblock ( ent / enx lay mat obj )
  9.     (setq enx (entget ent)
  10.           obj (tblobjname "block" (cdr (assoc 2 enx)))
  11.           lay (assoc 410 enx)
  12.           mat
  13.         (vlax-tmatrix
  14.             (append
  15.                 (apply '(lambda ( m v ) (mapcar '(lambda ( r v ) (append r (list v))) m v)) (refgeom ent))
  16.                '((0.0 0.0 0.0 1.0))
  17.             )
  18.         )
  19.     )
  20.     (while (setq obj (entnext obj))
  21.         (setq enx (entget obj))
  22.         (if (/= 1 (cdr (assoc 60 enx)))
  23.             (vla-transformby (vlax-ename->vla-object (entmakex (subst lay (assoc 410 enx) enx))) mat)
  24.         )
  25.     )
  26.     (entdel ent)
  27. )
  28.  
  29. ;; RefGeom (gile)
  30. ;; Returns a list whose first item is a 3x3 transformation matrix and
  31. ;; second item the object insertion point in its parent (xref, block or space)
  32.  
  33. (defun refgeom ( ent / ang enx mat ocs )
  34.     (setq enx (entget ent)
  35.           ang (cdr (assoc 050 enx))
  36.           ocs (cdr (assoc 210 enx))
  37.     )
  38.     (list
  39.         (setq mat
  40.             (mxm
  41.                 (mapcar '(lambda ( v ) (trans v 0 ocs t))
  42.                    '(
  43.                         (1.0 0.0 0.0)
  44.                         (0.0 1.0 0.0)
  45.                         (0.0 0.0 1.0)
  46.                     )
  47.                 )
  48.                 (mxm
  49.                     (list
  50.                         (list (cos ang) (- (sin ang)) 0.0)
  51.                         (list (sin ang) (cos ang)     0.0)
  52.                        '(0.0 0.0 1.0)
  53.                     )
  54.                     (list
  55.                         (list (cdr (assoc 41 enx)) 0.0 0.0)
  56.                         (list 0.0 (cdr (assoc 42 enx)) 0.0)
  57.                         (list 0.0 0.0 (cdr (assoc 43 enx)))
  58.                     )
  59.                 )
  60.             )
  61.         )
  62.         (mapcar '- (trans (cdr (assoc 10 enx)) ocs 0)
  63.             (mxv mat (cdr (assoc 10 (tblsearch "block" (cdr (assoc 2 enx))))))
  64.         )
  65.     )
  66. )
  67.  
  68. ;; Matrix Transpose  -  Doug Wilson
  69. ;; Args: m - nxn matrix
  70.  
  71. (defun trp ( m )
  72.     (apply 'mapcar (cons 'list m))
  73. )
  74.  
  75. ;; Matrix x Matrix  -  Vladimir Nesterovsky
  76. ;; Args: m,n - nxn matrices
  77.  
  78. (defun mxm ( m n )
  79.     ((lambda ( a ) (mapcar '(lambda ( r ) (mxv a r)) m)) (trp n))
  80. )
  81.  
  82. ;; Matrix x Vector  -  Vladimir Nesterovsky
  83. ;; Args: m - nxn matrix, v - vector in R^n
  84.  
  85. (defun mxv ( m v )
  86.     (mapcar '(lambda ( r ) (apply '+ (mapcar '* r v))) m)
  87. )
  88.  
This code works fine for the block but running this program over all blocks in a drawing doesn't work.
I add dwg-file with thoose blocks. Block2 and Block3 make problems.

Using (entmake ....) instead of (entmakex ...) in the (explodeblock-methode) brought me this.
Quote
Fehler: Fehlerhafter Argumenttyp: lentityp ((-1 . <Objektname: 7ffffb07640>) (0 . "POINT") (330 . <Objektname: 7ffffb07620>) (5 . "31C") (100 . "AcDbEntity") (67 . 0) (8 . "Verband_wo") (62 . 7) (100 . "AcDbPoint") (10 0.0 -1961.0 0.0) (210 0.0 0.0 1.0) (50 . 0.0))

I think this has something to do with Acad 2015, as i only can explode this blocks using (command-s "_.explode" ...)
Don't know how to fix this.
« Last Edit: August 29, 2014, 06:26:17 AM by matthias312 »

ronjonp

  • Needs a day job
  • Posts: 7526
Re: vla-explode changes drawing ?!?
« Reply #18 on: August 29, 2014, 08:50:10 AM »
Here's a way to strip the constraints ( use with caution as it's a lobotomy ) :)

I tested and seemd to fix the vla-explode problem.
Code - Auto/Visual Lisp: [Select]
  1. (defun _stripconstraint ( / dic)
  2.   (and (setq dic (dictsearch (namedobjdict) "acad_assocnetwork")) (entdel (cdr (assoc -1 dic))))
  3. )
  4. (_stripconstraint)

That's the dictionary I couldn't remember for the life of me; thanks for the reminder.  :)

I was reading a DevBLog article on adding geometric constraints in C#... Stephen was the author, or a contributor if memory serves.


 :)  Had to do a little searching .. not sure what, if any side effects will happen when deleting.

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

BlackBox

  • King Gator
  • Posts: 3770
Re: vla-explode changes drawing ?!?
« Reply #19 on: August 29, 2014, 12:39:46 PM »
Here's a way to strip the constraints ( use with caution as it's a lobotomy ) :)

I tested and seemd to fix the vla-explode problem.
Code - Auto/Visual Lisp: [Select]
  1. (defun _stripconstraint ( / dic)
  2.   (and (setq dic (dictsearch (namedobjdict) "acad_assocnetwork")) (entdel (cdr (assoc -1 dic))))
  3. )
  4. (_stripconstraint)

That's the dictionary I couldn't remember for the life of me; thanks for the reminder.  :)

I was reading a DevBLog article on adding geometric constraints in C#... Stephen was the author, or a contributor if memory serves.


 :)  Had to do a little searching .. not sure what, if any side effects will happen when deleting.

I searched and couldn't find my bookmark - way too many of them now with the new server, etc. :-D

In any event, having not tested for myself, I was speculating that it would be similar to deleting all Object Data in kind... It's fast, and works well... But when I looked at my routine for that, it calls an ADE* function (which has .NET, ObjectARX, etc. behind the LispFunction Method). :|

Cheers
"How we think determines what we do, and what we do determines what we get."

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: vla-explode changes drawing ?!?
« Reply #20 on: August 29, 2014, 12:51:34 PM »
Maybe this can work?
Is it right that you "redraw" the elements of the block and then delete it?.

Correct, I copy the block components to the parent layout using entmakex (since the ActiveX copyobjects method would also copy the constraints), and then transform the resulting objects using an appropriate transformation matrix based on the position, scale, orientation & rotation of the block reference, before deleting the block reference.

As i'm realatively new to Lisp i would really like to know why the block behaved the way it did before ur help?

Because some (but perhaps not all) of the various constraints would still be present, causing the objects to be contorted as they are manipulated by AutoCAD to meet the remaining constraints.

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: vla-explode changes drawing ?!?
« Reply #21 on: August 29, 2014, 12:53:21 PM »
Maybe this can work?
Code - Auto/Visual Lisp: [Select]
  1. < ... >
This code works fine for the block but running this program over all blocks in a drawing doesn't work.
I add dwg-file with thoose blocks. Block2 and Block3 make problems.

Try the following code instead:
(I have also excluded attributes from being created - you may want to deal with these separately, converting them to text objects)

Code - Auto/Visual Lisp: [Select]
  1. (defun c:test ( / s )
  2.     (if (setq s (ssget "_+.:E:S:L" '((0 . "INSERT"))))
  3.         (explodeblock (ssname s 0))
  4.     )
  5.     (princ)
  6. )
  7.  
  8. (defun explodeblock ( ent / enx lay mat new obj )
  9.     (setq enx (entget ent)
  10.           obj (tblobjname "block" (cdr (assoc 2 enx)))
  11.           lay (assoc 410 enx)
  12.           mat
  13.         (vlax-tmatrix
  14.             (append
  15.                 (apply '(lambda ( m v ) (mapcar '(lambda ( r v ) (append r (list v))) m v)) (refgeom ent))
  16.                '((0.0 0.0 0.0 1.0))
  17.             )
  18.         )
  19.     )
  20.     (while (setq obj (entnext obj))
  21.         (if (and (/= 1 (cdr (assoc 60 (setq enx (entget obj)))))
  22.                  (/= "ATTDEF" (cdr (assoc 0 enx)))
  23.                  (setq new
  24.                      (entmakex
  25.                          (subst lay (assoc 410 enx)
  26.                              (vl-remove-if '(lambda ( x ) (member (car x) '(102 360))) enx)
  27.                          )
  28.                      )
  29.                  )
  30.             )
  31.             (vla-transformby (vlax-ename->vla-object new) mat)
  32.         )
  33.     )
  34.     (entdel ent)
  35. )
  36.  
  37. ;; RefGeom (gile)
  38. ;; Returns a list whose first item is a 3x3 transformation matrix and
  39. ;; second item the object insertion point in its parent (xref, block or space)
  40.  
  41. (defun refgeom ( ent / ang enx mat ocs )
  42.     (setq enx (entget ent)
  43.           ang (cdr (assoc 050 enx))
  44.           ocs (cdr (assoc 210 enx))
  45.     )
  46.     (list
  47.         (setq mat
  48.             (mxm
  49.                 (mapcar '(lambda ( v ) (trans v 0 ocs t))
  50.                    '(
  51.                         (1.0 0.0 0.0)
  52.                         (0.0 1.0 0.0)
  53.                         (0.0 0.0 1.0)
  54.                     )
  55.                 )
  56.                 (mxm
  57.                     (list
  58.                         (list (cos ang) (- (sin ang)) 0.0)
  59.                         (list (sin ang) (cos ang)     0.0)
  60.                        '(0.0 0.0 1.0)
  61.                     )
  62.                     (list
  63.                         (list (cdr (assoc 41 enx)) 0.0 0.0)
  64.                         (list 0.0 (cdr (assoc 42 enx)) 0.0)
  65.                         (list 0.0 0.0 (cdr (assoc 43 enx)))
  66.                     )
  67.                 )
  68.             )
  69.         )
  70.         (mapcar '- (trans (cdr (assoc 10 enx)) ocs 0)
  71.             (mxv mat (cdr (assoc 10 (tblsearch "block" (cdr (assoc 2 enx))))))
  72.         )
  73.     )
  74. )
  75.  
  76. ;; Matrix Transpose  -  Doug Wilson
  77. ;; Args: m - nxn matrix
  78.  
  79. (defun trp ( m )
  80.     (apply 'mapcar (cons 'list m))
  81. )
  82.  
  83. ;; Matrix x Matrix  -  Vladimir Nesterovsky
  84. ;; Args: m,n - nxn matrices
  85.  
  86. (defun mxm ( m n )
  87.     ((lambda ( a ) (mapcar '(lambda ( r ) (mxv a r)) m)) (trp n))
  88. )
  89.  
  90. ;; Matrix x Vector  -  Vladimir Nesterovsky
  91. ;; Args: m - nxn matrix, v - vector in R^n
  92.  
  93. (defun mxv ( m v )
  94.     (mapcar '(lambda ( r ) (apply '+ (mapcar '* r v))) m)
  95. )
  96.  

cmwade77

  • Swamp Rat
  • Posts: 1443
Re: vla-explode changes drawing ?!?
« Reply #22 on: August 29, 2014, 02:51:16 PM »
Quote
Off topic, but why are you exploding the block ?

I have to write a program to clean up dwg-files making them as small as possible.
My program allready works, but the part exploding blocks in drawing works only with (command-s "_.explode" ....).
As there are really big dwgs with many blocks this sometimes takes a while.

Quote
Here is some code to convert the block to static
Allready tried something like this. As long as the constraints stay in the block the problem stays.
When i manually delete the constraints in the Blockeditor and then use the vla-explode it works fine.

Someone knows a way how to delete theese out of the block before/while exploding?
In my experience, exploding blocks will generally make the files larger, not smaller.

ronjonp

  • Needs a day job
  • Posts: 7526
Re: vla-explode changes drawing ?!?
« Reply #23 on: August 29, 2014, 03:02:48 PM »
Quote
Off topic, but why are you exploding the block ?

I have to write a program to clean up dwg-files making them as small as possible.
My program allready works, but the part exploding blocks in drawing works only with (command-s "_.explode" ....).
As there are really big dwgs with many blocks this sometimes takes a while.

Quote
Here is some code to convert the block to static
Allready tried something like this. As long as the constraints stay in the block the problem stays.
When i manually delete the constraints in the Blockeditor and then use the vla-explode it works fine.

Someone knows a way how to delete theese out of the block before/while exploding?
In my experience, exploding blocks will generally make the files larger, not smaller.


http://www.theswamp.org/index.php?topic=47734.msg527428#msg527428
 :)

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

ronjonp

  • Needs a day job
  • Posts: 7526
Re: vla-explode changes drawing ?!?
« Reply #24 on: August 29, 2014, 03:03:45 PM »
This seems to work on your drawing:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:boom (/ d doc)
  2.   (and (setq d (dictsearch (namedobjdict) "acad_assocnetwork")) (entdel (cdr (assoc -1 d))))
  3.   (vlax-for l (vla-get-layers doc) (and (= -1 (vlax-get l 'lock)) (vlax-put l 'lock 0)))
  4.     (and (= 0 (+ (vlax-get bd 'islayout) (vlax-get bd 'isxref) (vlax-get bd 'explodable)))
  5.          (vlax-put bd 'explodable -1)
  6.     )
  7.     (vlax-for b bd
  8.       (if (= (vlax-get b 'objectname) "AcDbBlockReference")
  9.         (progn (vla-explode b) (vla-delete b))
  10.       )
  11.     )
  12.   )
  13.   (vla-purgeall doc)
  14.   (princ)
  15. )

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

matthias312

  • Guest
Re: vla-explode changes drawing ?!?
« Reply #25 on: August 29, 2014, 03:50:45 PM »
In my experience, exploding blocks will generally make the files larger, not smaller.
I think i explained a little bit wrong. Goal is to clean the drawing.
When i'm done i put the result together in one block.

Because some (but perhaps not all) of the various constraints would still be present, causing the objects to be contorted as they are manipulated by AutoCAD to meet the remaining constraints.
Thought something like this. Because the behaviour changes by moving or turning the block before exploding.
In a certain angle the locked point (0 0) works and the lines beginpoint jumps to (0 0)^^

As there is no Acad on my home desktop at the moment. I have to wait untill monday to test.
Have a nice weekend!

matthias312

  • Guest
Re: vla-explode changes drawing ?!?
« Reply #26 on: September 02, 2014, 08:37:03 AM »
Hallo,
all works perfectly now.
Thank u all for your great help!!

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: vla-explode changes drawing ?!?
« Reply #27 on: September 02, 2014, 09:22:54 AM »
In my experience, exploding blocks will generally make the files larger, not smaller.
I think i explained a little bit wrong. Goal is to clean the drawing.
When i'm done i put the result together in one block.
So actually your intent is NOT to ensure the file is as small as it possibly can be. It's rather to make it a flat file without any reused blocks.

Just so you know, that's not going to make the drawing smaller than it "could" have been. The last step (place everything into one block) will definitely increase the size by a small amount, while the first step (explode all blocks) would "most probably" increase the size by a huge amount (depending on how blocks were used to begin with).

Using a block can make the drawing multiple times smaller "if used correctly", but placing the entire drawing inside one single block would actually make it slightly LARGER. The only time a block makes a drawing smaller is when that same block is placed 2 or more times in the drawing.

Think about it ... the block defines the linework once. The inserts reference the linework into different places without actually making new copies of each line. Thus before exploding your drawing might look like this:
Code: [Select]
Block Definitions
   Block1
      Line1 X,Y,Z to X,Y,Z Layer Color etc.
      Line2 X,Y,Z to X,Y,Z Layer Color etc.
      Line3 X,Y,Z to X,Y,Z Layer Color etc.
Model Elements
   Block1-Insert1 @ X,Y,Z Rotate Scale Layer Color etc.
   Block1-Insert2 @ X,Y,Z Rotate Scale Layer Color etc.
   Block1-Insert3 @ X,Y,Z Rotate Scale Layer Color etc.
   Block1-Insert4 @ X,Y,Z Rotate Scale Layer Color etc.
After exploding that same file becomes something like this instead:
Code: [Select]
Model Elements
   Line1.1 X,Y,Z to X,Y,Z Layer Color etc.
   Line1.2 X,Y,Z to X,Y,Z Layer Color etc.
   Line1.3 X,Y,Z to X,Y,Z Layer Color etc.
   Line2.1 X,Y,Z to X,Y,Z Layer Color etc.
   Line2.2 X,Y,Z to X,Y,Z Layer Color etc.
   Line2.3 X,Y,Z to X,Y,Z Layer Color etc.
   Line3.1 X,Y,Z to X,Y,Z Layer Color etc.
   Line3.2 X,Y,Z to X,Y,Z Layer Color etc.
   Line3.3 X,Y,Z to X,Y,Z Layer Color etc.
   Line4.1 X,Y,Z to X,Y,Z Layer Color etc.
   Line4.2 X,Y,Z to X,Y,Z Layer Color etc.
   Line4.3 X,Y,Z to X,Y,Z Layer Color etc.
So the more copies of the same block you explode the more new lines you're actually placing in the drawing's model.

If you then go and make a new block of all of them you're simply going to end up with something like this
Code: [Select]
Block Definitions
   Block1
      Line1.1 X,Y,Z to X,Y,Z Layer Color etc.
      Line1.2 X,Y,Z to X,Y,Z Layer Color etc.
      Line1.3 X,Y,Z to X,Y,Z Layer Color etc.
      Line2.1 X,Y,Z to X,Y,Z Layer Color etc.
      Line2.2 X,Y,Z to X,Y,Z Layer Color etc.
      Line2.3 X,Y,Z to X,Y,Z Layer Color etc.
      Line3.1 X,Y,Z to X,Y,Z Layer Color etc.
      Line3.2 X,Y,Z to X,Y,Z Layer Color etc.
      Line3.3 X,Y,Z to X,Y,Z Layer Color etc.
      Line4.1 X,Y,Z to X,Y,Z Layer Color etc.
      Line4.2 X,Y,Z to X,Y,Z Layer Color etc.
      Line4.3 X,Y,Z to X,Y,Z Layer Color etc.
Model Elements
   Block1-Insert1 @ X,Y,Z Rotate Scale Layer Color etc.

Of course if no blocks in the drawing is inserted more than once, then exploding should reduce size by a slight bit as the definitions and the references would get removed. But each block which is inserted more than once would most probably cause an explode of it to increase the file's size.

The reason you see large file size in this case is due to the added stuff on top of those blocks, not because they're blocks - but because some extras are attached to them. These attachments usually gets attached to those Block-Inserts instead of the Block Definition - that's why they grow the file near exponentially (they're copied multiple times over). My guess would be if you can get rid of these attachments you'd be able to reduce the file's size tremendously, even much more so than simply exploding everything.

However, I'm talking "theoretically" - I'd need to see the original file to be sure.
« Last Edit: September 02, 2014, 09:28:12 AM by irneb »
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

matthias312

  • Guest
Re: vla-explode changes drawing ?!?
« Reply #28 on: September 02, 2014, 11:37:33 AM »
I know what you mean.
I make Acad Support in my work and there are more than 100 people using Acad. There are many don't really now what they are doing.
Sometimes many different blocks, sometimes imported somewhere perhaps made by them perhaps copied form other plans or ......
You never really know what's in a plan. And now my program has to clean this plans making working with this plans easier.

All whats left is put in one block because the things are fix and are some kind of blueprint for future work.
Most of the time the block is imported in a new drawing. Perhaps turned and scaled.
Making the hole drawing in one block is not for size, its for the users.

Sorry, but my english isn't good and i think i explained this wrong at the start.


This seems to work on your drawing:
Code - Auto/Visual Lisp: [Select]
  1. (defun c:boom (/ d doc)
  2.   (and (setq d (dictsearch (namedobjdict) "acad_assocnetwork")) (entdel (cdr (assoc -1 d))))
  3.   (vlax-for l (vla-get-layers doc) (and (= -1 (vlax-get l 'lock)) (vlax-put l 'lock 0)))
  4.     (and (= 0 (+ (vlax-get bd 'islayout) (vlax-get bd 'isxref) (vlax-get bd 'explodable)))
  5.          (vlax-put bd 'explodable -1)
  6.     )
  7.     (vlax-for b bd
  8.       (if (= (vlax-get b 'objectname) "AcDbBlockReference")
  9.         (progn (vla-explode b) (vla-delete b))
  10.       )
  11.     )
  12.   )
  13.   (vla-purgeall doc)
  14.   (princ)
  15. )

Made a version also working for nested blocks
Code - Auto/Visual Lisp: [Select]
  1. (defun c:boomNested (/ d doc)
  2.     (and (setq d (dictsearch (namedobjdict) "acad_assocnetwork")) (entdel (cdr (assoc -1 d))))
  3.     (vlax-for l (vla-get-layers doc) (and (= -1 (vlax-get l 'lock)) (vlax-put l 'lock 0)))
  4.     (vlax-for bd (vla-get-blocks doc)
  5.         (and (= 0 (+ (vlax-get bd 'islayout) (vlax-get bd 'isxref) (vlax-get bd 'explodable)))
  6.              (vlax-put bd 'explodable -1)
  7.              )
  8.         (vlax-for b bd
  9.             (and (= (vlax-get b 'objectname) "AcDbBlockReference")(explBlock b))
  10.             )
  11.         )
  12.     (vla-purgeall doc)
  13.     (princ)
  14. )
  15.  
  16. (defun explBlock (b / )
  17.     (mapcar '(lambda (x / )
  18.                  (and (= (vlax-get x 'objectname) "AcDbBlockReference")
  19.                       (explBlock x)))
  20.             (vlax-invoke b 'explode)
  21.             )
  22.     (vla-delete b)
  23. )
  24.