Change the color of only one instance
-
Hello all,
They referred me to the ruby section to find a answer for my question. See also: http://www.sketchucation.com/forums/scf/viewtopic.php?f=15&t=13891
In short:
We are looking for a method to temporary change the clor/material of one or more instances without influencing the other instances of the same component.
When the component elements have no color/material defined there is no problem. The color/material can be set on component level.
But when the elements of the component have a color defined before they were turned into a component the color cannot be changed. (at least not on the component level)Now, based upon the result of a script an instance should be temporary colored in a different then original color/material BUT without losing the link with the original component.
Is there a way to do this? We were thinking about creating (duplicating) a stand-in component with the color red and make all the instances that need to be red, instances of this stand-in component. With a hit on a button (or another script result) they should become instances of the original component again.
Easiest way would be if an instance has an attribute that defines the source component and we just temporarily change that.
is there such an editable attribute? Or are there better methods to accomplish this?Thx!
-
i'm just thinking of another question:
Is there a way to edit, with ruby the colors of the contents of a component (the geometry) So a loop through the geometry of the component and change all the materials/colors of them. -
i'm posting my progress.
To change the component definition from an instance i have found.
Leaves me with 2 questions:
- Can i copy the 'in model' components in the library
- Secondly: how do i set all those copied components to be red? (also the internal geometry of the component)
thx
-
Assuming you are not going to edit the component definition...
Pick the component instance [let's callits definition Y].
Use make unique on it [let's call this new version's definition X].
Chnage the definition of X to make all of its materials the <default> (nil).
Make the instance's colour say 'Red' - or whatever.
At the end you simply swap the instances of X with the original definition Y and it looks the same.
You will have a spare definition hanging around unused - could purge it or empty it's entity list and give it a 'scrap' name....
-
Thank you Tig,
Sounds like the setup we thought about yesterday.
This is the processflow we were thinking about:
Change color depending on script result
- Get the component definition of the instance
- Write this component definition as an attribute in the instance attribute dictionary
- Make the instance unique (this results in a new component definition)and give it a name (can we use the auto-component name generator from SU itself?)
- Loop through all the entities in the component and set color as red
Reset color
- Check to see if the current instance component definition equals the component definition that is available in the attribute dict of the instance
- If there is a difference: give the instance the component definition it has set in it's attribute dictionary.
- Delete the 'current' component definition from the component library
Is this a good way? Thx again
-
And you were asking for help in the SU discussions
-
lol Gaieus
Well i thought i asked it in the component section
The thread we had going on there was very helpfull to see the posibilities and clear my mind of what exactly i wanted it to do.
I now have the basics of it but still there are some major issues.Here is the code:
def cinchange ######################## #--Change the instance-- ######################## #--initialize-- model=Sketchup.active_model ss=model.selection.first #--Get component definition name of instance-- compdefname=ss.definition.name #--Write component def. to instance dictionary ss.set_attribute 'xdid_dict', 'compdefname', compdefname #--Make instance unique (creates new comp. definition)-- ss.make_unique #--Edit the instance (make all entities red)-- compdef=ss.definition ent=compdef.entities ent.each {|i| if i.typename=="Face" i.material="red" i.back_material="red" end } end def cinrestore ######################### #--Restore the instance-- ######################### #--initialize-- model=Sketchup.active_model ss=model.selection.first #--Get current component definition of instance-- current_compdefname=ss.definition.name #--Get the component definition defined in the attrib. dict.-- orig_compdefname=ss.get_attribute 'xdid_dict', 'compdefname' #--If comp. def. set in attrib. dict. does not equal current comp. def., set the component definition from the attrib. dict. back-- if orig_compdefname if orig_compdefname!= current_compdefname definitionlist=model.definitions ss.definition=definitionlist[orig_compdefname] #--Delete the current component definition from the library-- #--Delete the attrib. dict. entry from the instance end end end
The issues are:
- what to do when there is only one instance of a component present in the model. make unique does not work then. (any thoughts on this?)
- now for each instance of the same component it creates a new component definition while it could reuse the first one. (dito)
- get the attribute information out of the instances dictionary
I don't know if anyone could use the above script and if i need to put it in a plugin or something.
-
ok i have my script (almost working)
def cinchange #--initialize-- model=Sketchup.active_model ss=model.selection.first UI.messagebox('selection OK') ######################## #--Change the instance-- ######################## #--Get component definition of instance-- compdef=ss.definition.name UI.messagebox('definition OK') #--Write component def. to instance dictionary ss.set_attribute 'xdid_dict', 'compdef', compdef UI.messagebox('attribute OK') #--Make instance unique (creates new comp. definition)-- ss.make_unique UI.messagebox('unique OK') #--Edit the instance (make all entities red)-- compdef2=ss.definition ent=compdef2.entities ent.each {|i| if i.typename=="Face" i.material="red" i.back_material="red" end } UI.messagebox('rood OK') UI.messagebox('total succes') end def cinrestore
######################### #--Restore the instance-- ######################### #--Get current component definition of instance-- model=Sketchup.active_model ss=model.selection.first UI.messagebox('selection OK') #--Get the component definition defined in the attrib. dict.-- orig_compdef=ss.get_attribute 'xdid_dict', 'compdef' UI.messagebox(orig_compdef) #--If no comp. definition set in the attrib. dict., do nothing-- #--If comp. def. set in attrib. dict. does not equal current comp. def., set the component definition from the attrib. dict. back-- current_compdef=ss.definition.name UI.messagebox(current_compdef) if orig_compdef!= current_compdef UI.messagebox('niet gelijk') ss.definition=orig_compdef end
The only problem left is how to set the definition of the instance back to the original one based upon the variable orig_compdef which is the name of the definition.
I have saved the original 'name' of the component definition in the attrib. dictionary cause appaerently it is not possible to save the definition itself.
Can someone help me on this? --> SOLVEDAlso, could you check if it is possible to make this script 'better'?
Thx
-
@pout said:
what to do when there is only one instance of a component present in the model. make unique does not work then. (any thoughts on this?)
True this works that way but how to solve it with ruby, I don't know. Maybe make a temporary copy of it, make it unique then and delete the copy.
-
Does anyone know how i can give a component definition a certain name?
When making an instance unique it automatically adds #1 behind the current component definition name. -
You can always rename the component (and yes, there have been several feature requests for the Create Component window to pop up when making a component unique).
Now how you would do it in ruby, that's a different question
-
Ok i have found that (jeez, i should stop posting when something pops up in my mind)
Almost finished.
I'll post my code soon. -
Advertisement