Does $dc_observers.get_latest_class.redraw_with_undo(instance) only work with Sketchup::ComponentInstance?

I have a group with a LenX attribute, where I am setting any value with
instance.set_attribute(DYDICT, key, value)

Then with the code $dc_observers.get_latest_class.redraw_with_undo(instance) I try to redraw it but it doesn’t work.

Is there a way to redraw an instance of Sketchup::Group?
I notice that in the ‘Component Options’ this works.

Thanks… :slightly_smiling_face:

Redraw should work on groups or components. Can you post your code?

EDIT: Group attributes are kept in the definition instance, where components have attributes at the instance and definition level, this is likely probably not your issue… :man_shrugging: You have to set the group attribute at the definition instance.

EDIT2: I had it backwards, corrected above. Thanks @DanRathbun!

DYDICT ||= 'dynamic_attributes'
model = Sketchup.active_model
sel = model.selection

def self.set_instance_or_definition_attributes(instance, key, value)
  val = instance.get_attribute(DYDICT, key, nil)
  instance.set_attribute(DYDICT, key, value) unless val.nil?
  puts "val: #{val}"
  puts "#{key}, #{value}"

  val = instance.definition.get_attribute(DYDICT, key, nil)
  instance.definition.set_attribute(DYDICT, key, value) unless val.nil?
  puts "val: #{val}"
  puts "#{key}, #{value}"
end

def self.set_instance_attributes(entities)
  entities.grep(Sketchup::ComponentInstance).concat(entities.grep(Sketchup::Group)).each do |instance|
    key = 'lenx'
    value = (800 / 25.4).to_s

    set_instance_or_definition_attributes(instance, key, value)
    $dc_observers.get_latest_class.redraw_with_undo(instance)
  end
rescue StandardError => error
  puts error.backtrace
  raise
end

set_instance_attributes(sel)


Redraw Test.skp (853.4 KB)

See the code example. I also attached the test model and now not only the group but the component instance doesn’t seem to work.

It is possible to see with ‘Attribute Inspector’ that the value was set correctly, but it is not redrawn.

1 Like

However you set it as string:

Try this:

    key = 'lenx'
    value = 800 / 25.4
2 Likes

Dynamic groups must be nested within a dynamic component. I.e., the dynamic group cannot be the progenitor dynamic object.

Secondly, … if there is only one instance of a dynamic component, then all dynamic attributes will be on the definition and the instance will use it’s definition’s attributes.

1 Like

I tried this way, but I was not successful either.

The only way I was able to do this was to add a formula attribute to the component instance and definition, and then remove it from the attribute dictionary.
I also had to do a redraw before removing it from the dictionary.

DYDICT ||= 'dynamic_attributes'
model = Sketchup.active_model
sel = model.selection

# Removes an attribute from a dictionary.
# @param [AttributeDictionary] dictionary - The dictionary to remove attribute.
# @param [Array<String>] attributes - Array of attributes to remove.
def self.remove_dynamic_attribute(dict, attributes = [])
  return if attributes.empty?

  attributes.each do |attribute|
    dict&.delete_key(attribute)
  end
end

def self.set_instance_or_definition_attributes(instance, key, value)
  definition = instance.definition
  formula = "_#{key}_formula"

  instance.set_attribute(DYDICT, formula, value)
  definition.set_attribute(DYDICT, formula, value)
  $dc_observers.get_latest_class.redraw_with_undo(instance)

  dict = instance.attribute_dictionary(DYDICT) # instance dictionary
  definition_dict = definition.attribute_dictionary(DYDICT) # definition dictionary

  remove_dynamic_attribute(dict, [formula, "_#{key}_error"])
  remove_dynamic_attribute(definition_dict, [formula, "_#{key}_error"])
end

def self.set_instance_attributes(entities)
  entities.grep(Sketchup::ComponentInstance).concat(entities.grep(Sketchup::Group)).each do |instance|
    key = 'lenx'
    value = (800 / 10).to_s

    set_instance_or_definition_attributes(instance, key, value)
  end
rescue StandardError => error
  puts error.backtrace
  raise
end

set_instance_attributes(sel)