Change material

Hello.
I have this piece of code.


      model.start_operation("Material change", true)
      component_definition.set_attribute("dynamic_attributes", "material","red")
      component_definition.material = "red"
      model.commit_operation("Material change")
      model.active_view.invalidate
      model.active_view.refresh

After running the code, I don’t see any changes to the material.
But if I press Ctrl+S, the changes become visible.

You must have more code than the one you write.
model and component_definition are not declared as variables.

def selector(my_guid)
  model = Sketchup.active_model
  view = model.active_view
  component_definition = model.definitions.find { |e|  e.guid == my_guid }

  if component_definition
      model.start_operation("Material change", true)
      component_definition.set_attribute("dynamic_attributes", "material","red")
      component_definition.material = "red"
      model.commit_operation

      model.active_view.invalidate
      model.active_view.refresh
  end
end

What is your main purpose? Do you want to change the color of one selected component?

Can this code help you?

Sketchup.active_model.selection.each do |e| 
  e.material = "red" if e.respond_to?(:material)
  e.back_material = "red" if e.respond_to?(:back_material)
end
1 Like

Thank you, but your code didn’t help. (
I think my problem is that the View is not refreshing.
Although I am trying to do this manually in my code.

:bulb: perhaps…

...
component_definition.material = "red"
component_definition.set_attribute("dynamic_attributes", "material","red")
component_definition.instances.each{|inst|
  $dc_observers.get_latest_class.redraw_with_undo(inst)
}
...
1 Like

The script runs without errors.
However, I can only see the changes after pressing the Ctrl+S keys or after the document is autosaved.

def selector(my_guid)
  model = Sketchup.active_model
  view = model.active_view
  component_definition = model.definitions.find { |e|  e.guid == my_guid }
  if component_definition
      #model.start_operation("Material change", true)
      component_definition.set_attribute("dynamic_attributes", "material","red")
      component_definition.material = "red"
      component_definition.instances.each{|inst|
      puts "redrawing model"
          $dc_observers.get_latest_class.redraw_with_undo(inst)
        }
      #model.commit_operation("Material change")
      #model.redraw_with_undo("Material change")
      #view.redraw_with_undo("Material change")
      #$dc_observers.get_latest_class.redraw_with_undo(component_definition)

      #model.active_view.invalidate
      #model.active_view.refresh

      #model.selection.add(component_definition)
      #model.active_view.zoom(component_definition)
      puts "Material changed: #{component_definition.name} "
    else
      puts "Error: #{component_definition.class} "
  end
end
component_definition.material = "red"

Do not set material property upon a component definition object.
It has weird behavior that is undocumented. For more see …

2 Likes

This implies then that you should set the material upon instance objects.

SketchUp comes with sample Dynamic Components that can change color.

With a DC, the default color is set in the definition’s dynamic dictionary, but if instances differ from the default, then the material attribute will be added to the instance’s dynamic dictionary.

Can you give me an example of code? I’ve been trying to figure out my problem for several days, but I can’t seem to get it right. ((

#comment out:
#component_definition.material = "red"
#component_definition.set_attribute("dynamic_attributes", "material","red")
####

component_definition.instances.each{|inst|
  #perhaps you need to add a condition if you do not want to paint all instances..
  inst.set_attribute("dynamic_attributes", "material","red")
  inst.material = "red"
}
1 Like

Hooray, it works! Thank you very much!

1 Like

Of course, it works because the snippet is directly setting the instance’s material property.

This is not really hooking into the DC functionality where the dynamic “material” attribute is controlling the instance’s material property.

Again, use an Attribute Inspector extension to interrogate one of the DC samples that comes with SketchUp.


P.S. - Please remove the solution for the topic as the discussion is continuing.
(It will get rid of the nag screen that the topic has been solved, which it really hasn’t.)

Also, there are numerous discussions on Ruby coding DCs in the forum’s Dynamic Components subcategory.

3 Likes