Author Topic: Can't change color for dynamic block  (Read 6835 times)

0 Members and 1 Guest are viewing this topic.

Coder

  • Swamp Rat
  • Posts: 827
Can't change color for dynamic block
« on: December 22, 2013, 02:41:44 AM »
Hello

I have a dynamic block and I want to change the color of all inside objects to red but my code change the color in the main block and not in the drawing .

Also if there is other dynamic blocks it would be changed and not only my block name "Rect"  :-o

I attached the dynamic block .

thanks in advance .  :-)

Code: [Select]
(defun c:color-rect (/)
  (setq mydoct (vla-get-ActiveDocument (vlax-get-acad-object)))
 
 (setq mySel (ssget "_X" (list '(0 . "INSERT")
                                    (cons 2 (strcat "`*U*," "Rect"))))
            )
    (repeat (setq no (sslength mySel))
      (setq sname   (ssname s (setq no (1- no)))
            Blkname (vla-get-effectivename (vlax-ename->vla-object sname)
                      )
      )
      (vlax-for objs (vla-item (vla-get-blocks mydoct) Blkname)
        (vla-put-color objs Acred))
    )
  (command "regen")
)

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Can't change color for dynamic block
« Reply #1 on: December 22, 2013, 06:53:02 AM »
A few points:
  • You are correctly retrieving the effectivename property of the dynamic block, however, will need to test whether the value of this property matches the name of the dynamic block you are looking to change, otherwise other anonymous or dynamic blocks could be modified.
  • Since you are processing block references, there could be multiple references of the same block definition being processed; since a block definition only need be processed once, it would be more efficient to check whether a block definition has been processed before iterating over the objects contained therein.
  • Since your ssget filter list contains only constant data (literal strings), the entire filter list may be quoted and the group 2 pair does not need to be constructed using cons/strcat. See this article for more information.

Consider the following example:

Code - Auto/Visual Lisp: [Select]
  1. (defun c:redblock ( / ano blc bln doc idx lst obj sel )
  2.     (while
  3.         (not
  4.             (or (= "" (setq blk (strcase (getstring t "\nSpecify block name: "))))
  5.                 (tblsearch "block" blk)
  6.             )
  7.         )
  8.         (princ (strcat "\nBlock \"" blk "\" not found."))
  9.     )
  10.     (if (and (/= "" blk) (setq sel (ssget "_X" (list '(0 . "INSERT") (cons 2 (strcat "`*U*," blk))))))
  11.         (progn
  12.                   blc (vla-get-blocks doc)
  13.             )
  14.             (repeat (setq idx (sslength sel))
  15.                 (setq obj (vlax-ename->vla-object (ssname sel (setq idx (1- idx))))
  16.                       ano (strcase (vla-get-name obj))
  17.                       bln (strcase (LM:blockname obj))
  18.                 )
  19.                 (if (and (= blk bln) (not (member ano lst)))
  20.                     (progn
  21.                         (vlax-for obj (vla-item blc ano)
  22.                             (if (vlax-write-enabled-p obj)
  23.                                 (vla-put-color obj acred)
  24.                             )
  25.                         )
  26.                         (setq lst (cons ano lst))
  27.                     )
  28.                 )
  29.             )
  30.             (vla-regen doc acallviewports)
  31.         )
  32.     )
  33.     (princ)
  34. )
  35.  
  36. ;; Block Name  -  Lee Mac
  37. ;; Returns the true (effective) name of a supplied block reference
  38.                        
  39. (defun LM:blockname ( obj )
  40.     (if (vlax-property-available-p obj 'effectivename)
  41.         (defun LM:blockname ( obj ) (vla-get-effectivename obj))
  42.         (defun LM:blockname ( obj ) (vla-get-name obj))
  43.     )
  44.     (LM:blockname obj)
  45. )
« Last Edit: December 22, 2013, 07:00:00 AM by Lee Mac »

Coder

  • Swamp Rat
  • Posts: 827
Re: Can't change color for dynamic block
« Reply #2 on: December 22, 2013, 07:32:54 AM »
Thank you for your help but I have one question please .

why did you add the name of the block (ano) to the list and not the effective name (bln) ?
is is the same result in this case or another thing I can not see ?  :-(

Many thanks .

Coder

  • Swamp Rat
  • Posts: 827
Re: Can't change color for dynamic block
« Reply #3 on: December 22, 2013, 08:32:22 AM »
  • Since your ssget filter list contains only constant data (literal strings), the entire filter list may be quoted and the group 2 pair does not need to be constructed using cons/strcat. See this article for more information.

That's also a very good point ( I got it ) , thanks a lot .  :-)

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Can't change color for dynamic block
« Reply #4 on: December 22, 2013, 11:14:27 AM »
why did you add the name of the block (ano) to the list and not the effective name (bln) ?
is is the same result in this case or another thing I can not see ?  :-(

Because the effective name will be the same for all references of the dynamic block, whereas the block name (usually anonymous) will be different for each set of references of the dynamic block holding different values for the dynamic block parameters.

If the effective name was added to the list, the program would only process references of the first anonymous block encountered, or only non-anonymous references.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Can't change color for dynamic block
« Reply #5 on: December 22, 2013, 11:15:01 AM »
  • Since your ssget filter list contains only constant data (literal strings), the entire filter list may be quoted and the group 2 pair does not need to be constructed using cons/strcat. See this article for more information.

That's also a very good point ( I got it ) , thanks a lot .  :-)

Excellent - you're welcome!  :-)

Coder

  • Swamp Rat
  • Posts: 827
Re: Can't change color for dynamic block
« Reply #6 on: December 22, 2013, 11:36:09 AM »
why did you add the name of the block (ano) to the list and not the effective name (bln) ?
is is the same result in this case or another thing I can not see ?  :-(

Because the effective name will be the same for all references of the dynamic block, whereas the block name (usually anonymous) will be different for each set of references of the dynamic block holding different values for the dynamic block parameters.

If the effective name was added to the list, the program would only process references of the first anonymous block encountered, or only non-anonymous references.

Great , I have been struggling for almost two days now because of the effective name that I added to the lst variable and not the block name  :ugly:

now it is running as i need it because of your great help .  :-)

Many many thanks .

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Can't change color for dynamic block
« Reply #7 on: December 22, 2013, 12:56:01 PM »
You're most welcome Coder - I'm delighted that you understand  :-)

Coder

  • Swamp Rat
  • Posts: 827
Re: Can't change color for dynamic block
« Reply #8 on: January 06, 2014, 12:03:48 AM »
Hello Lee .

One small question please .  :embarrassed:

If I change the ssget function to (ssget "_:L") this will change ONLY the color of the same block name in the drawing but if I keep it (ssget "_X") , it is changing all blocks and the Block definition
of the same name of the block .

is that normal  ? :-o

Many thanks

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Can't change color for dynamic block
« Reply #9 on: January 06, 2014, 06:09:58 PM »
If I change the ssget function to (ssget "_:L") this will change ONLY the color of the same block name in the drawing but if I keep it (ssget "_X") , it is changing all blocks and the Block definition
of the same name of the block .

is that normal  ? :-o

Yes, because not all of the anonymous block references are being processed, only those that the user has selected.

Coder

  • Swamp Rat
  • Posts: 827
Re: Can't change color for dynamic block
« Reply #10 on: January 06, 2014, 11:29:10 PM »
If I change the ssget function to (ssget "_:L") this will change ONLY the color of the same block name in the drawing but if I keep it (ssget "_X") , it is changing all blocks and the Block definition
of the same name of the block .

is that normal  ? :-o

Yes, because not all of the anonymous block references are being processed, only those that the user has selected.

Thank you so much .  :-)

Can I say that dynamic blocks definitions are similar to attributed blocks definitions somehow ? I am talking about  ( attributes ) in blocks .

Thanks .

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Can't change color for dynamic block
« Reply #11 on: January 07, 2014, 03:19:52 PM »
Thank you so much .  :-)

 :-)

Can I say that dynamic blocks definitions are similar to attributed blocks definitions somehow ? I am talking about  ( attributes ) in blocks .

I suppose they are similar on some levels in that the properties of the attribute references for a block reference can be modified independently of the block definition, though, note that where the attribute references are separate from the block definition for every reference of the block, the anonymous block definition generated when the dynamic block properties of a block reference are altered may reference multiple blocks - namely, all references of the dynamic block sharing the same dynamic block properties.

It may be better to think about it as each dynamic block reference which possesses a different set of dynamic block properties being a different block entirely, referencing its own [anonymous] block definition; all of these separate anonymous blocks are then tied to the main dynamic block using the effective name and identifiers stored in xdata.

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Can't change color for dynamic block
« Reply #12 on: January 08, 2014, 06:08:40 AM »
Nothing new as Lee already gave a nice explanation,
but a BlockReference
  • Pushes transformation matrixes on a stack in the graphics pipeline
  • Draws the entities in the Block Definition
  • Pops the transformations off.

So a BlockReference is nothing but a set of transformations to be applied to its definition as in scale, position, rotation, and other properties common to all entities like color, linetype, etc....
When it encounters a non-constant AttributeDefinition it creates a AttributeReference that is attached to the BlockReference.

A block definition can not have different states or vary between blockreferences that reference it since they just transform it as mentioned above.

A dynamic block just has parameters and the arguments passed in by a stretch or rotation grip or directly entered in properties palette, etc... are used to create another BlockDefinition(I think it searches first if one is already created with same values).

I and not familiar with AutoLisp but,  I do know how to steal it.
Did a quick search and first thing I found that was 4 lines or less was from Lee.
I made a minor adjustment which removes a "*" from the beginning of blocks name.
Now anonymous blocks will show up in the block editor.

If you want to see them insert some dynamic blocks and change some of the properties for each BlockReference.
Also add some tables and dimensions if you want to see that they are really just anonymous blocks.
Then run the code below. Would use only on a test drawing and not on any drawing you would want for future use.

Link to original code stolen from Lee.
Code - Auto/Visual Lisp: [Select]
  1. (defun c:test ( / name ) (vl-load-com)
  2.         (if (wcmatch (setq name (vla-get-name block)) "`**")
  3.             (vl-catch-all-apply 'vla-put-name (list block (substr name 2))))
  4.         )
  5.     )
  6.     (princ)
  7.  
Tables are named T1, T2, T3
Dimensions are D1, D2, etc..
Dynamic Blocks create names U1, U2, U3, etc....

In case you were wondering
BlockReferences contain the properties BlockTableRecord , DynamicBlockTableRecord & AnonymousBlockTableRecord.

Quote
BlockTableRecord
Accesses the object ID of the BlockTableRecord referenced by the block reference.

Quote
DynamicBlockTableRecord
Returns the object ID of the dynamic block definition (a BlockTableRecord) if the block reference is a dynamic block.

Quote
AnonymousBlockTableRecord
Returns the anonymous block definition used to draw the dynamic block.

BlockTableRecord always points to its definition.

If it is not dynamic or no properties have been change to a dynamic block then
  • DynamicBlockTableRecord & BlockTableRecord are the same
  • AnonymousBlockTableRecord is null(nill)

If properties have been change to a dynamic block then
  • DynamicBlockTableRecord  points to the dynamic block definition
  • AnonymousBlockTableRecord & BlockTableRecord are the same


Coder

  • Swamp Rat
  • Posts: 827
Re: Can't change color for dynamic block
« Reply #13 on: January 08, 2014, 11:31:54 PM »
Thank you Jeff so much .

It is very kind of you to write all that for me to understand the differences between blocks , that is great .

Many thanks again .  :-)

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Can't change color for dynamic block
« Reply #14 on: January 09, 2014, 06:32:24 PM »
Great supplement Jeff, thanks for your input  :-)