Trying to use the make_unique method

I am trying to get my script to make a component and all of the child components unique. the rest of my script works fine but nit making them unique. any advice?

require 'sketchup.rb'

module MR_Instance_Updater
  def self.make_selected_instances_unique(selection)
    selection.each do |entity|
      if entity.is_a?(Sketchup::ComponentInstance) || entity.is_a?(Sketchup::Group)
        make_entities_unique(entity.definition.entities)
      end
    end
  end

  # Recursive method to make all nested instances unique
  def self.make_entities_unique(entities)
    entities.each do |entity|
      if entity.is_a?(Sketchup::ComponentInstance) || entity.is_a?(Sketchup::Group)
        begin
          entity.make_unique
          UI.messagebox("Component instance #{entity.name} made unique.")
          make_entities_unique(entity.definition.entities)
        rescue => e
          puts "Error making entity unique: #{e.message}"
        end
      end
    end
  end

  def self.prefix_instance_names(entity, prefix)
    if entity.is_a?(Sketchup::ComponentInstance)
      new_name = "#{prefix}_#{entity.definition.name}"
      entity.name = new_name
    end

    if entity.respond_to?(:definition) && entity.definition
      entity.definition.entities.each do |sub_entity|
        prefix_instance_names(sub_entity, prefix)
      end
    end
  end

  def self.extract_prefix(selection)
    selection.find do |entity|
      if entity.is_a?(Sketchup::ComponentInstance)
        return entity.name.split('_').first
      end
    end
    return ''
  end

  def self.prompt_for_prefix
    model = Sketchup.active_model
    selection = model.selection

    if selection.empty?
      UI.messagebox('No component selected. Please select a component and try again.')
      return
    end

    make_selected_instances_unique(selection)
    current_prefix = extract_prefix(selection)
    
    prompts = ["Enter new prefix:", "Current prefix:"]
    defaults = ["", current_prefix]
    titles = "Enter New Prefix for Instance Names (Current prefix: #{current_prefix})"
    input = UI.inputbox(prompts, defaults, titles)

    if input
      new_prefix = input[0]
      selection.each do |entity|
        prefix_instance_names(entity, new_prefix)
      end

      UI.messagebox("Instance names updated successfully.")
      continue = UI.messagebox('Do you want to update another component?', MB_YESNO)
      
      if continue == 6 # User clicked 'Yes'
        UI.messagebox("Please select another component and run the script again.")
        model.select_tool(nil) # Clear any active tool to allow component selection
        model.selection.clear # Clear previous selection
      else
        UI.messagebox("Prefix input canceled.")
      end
    end
  end

  unless file_loaded?(__FILE__)
    # Add item to the Plugins menu
    menu = UI.menu('Plugins').add_submenu('BoxStudy')
    menu.add_item('Update Instance Names') { self.prompt_for_prefix }

    # Create a toolbar
    toolbar = UI::Toolbar.new "MR Instance Updater"

    # Create a command for the toolbar button
    cmd = UI::Command.new("Update Instance Names") { self.prompt_for_prefix }
    cmd.small_icon = "icons/update_small.png" # Path to your 16x16 pixels icon
    cmd.large_icon = "icons/update_large.png" # Path to your 24x24 pixels icon
    cmd.tooltip = "Update Instance Names"
    cmd.status_bar_text = "Updates the names of selected component instances by applying a prefix."
    cmd.menu_text = "Update Instance Names"

    # Add the command to the toolbar
    toolbar.add_item cmd

    # Show the toolbar
    toolbar.show

    file_loaded(__FILE__)
  end
end

Maybe the problem are groups. Could it be possible?
Child entities in Components are inside definition but Child entities in group doesn’t.
Supossing an entity…
Component:
entity.definition.entities
Group:
entity.entities

def self.make_selected_instances_unique(selection)
  selection.each do |entity|
    if entity.is_a?(Sketchup::ComponentInstance)
      make_entities_unique(entity.definition.entities)
    elsif entity.is_a?(Sketchup::Group)
      make_entities_unique(entity.entities)
    end
  end
end

I recently had a similar problem. Are you sure you’re collecting nested components here:

  def self.make_selected_instances_unique(selection)
    selection.each do |entity|
      if entity.is_a?(Sketchup::ComponentInstance) || entity.is_a?(Sketchup::Group)
        make_entities_unique(entity.definition.entities)
      end
    end
  end

Code I found over here can at least gathers entities:

When you adjust that as follows it should collect nested components:

    def collect_components( ents )
      a = []
      ents.each { |e|
        if e.is_a?( Sketchup::ComponentInstance )
          a.concat( collect_components( e.definition.entities ))
          a << e
        elsif e.is_a?( Sketchup::Group )
            a.concat( collect_components( e.definition.entities ))
        end
      }
      a
    end

Eneroth’s extension “deep make unique” does just that.
She might be of great help.

I think you may be correct here. I will modify my script and try it again tonight when I get home.

Not correct. Groups are just “special” component instances that also have a component definition.

Group definitions do not appear in the Component inspector browser pane, and if manually opened they are automatically made unique if the definition has more than 1 instance.

Note:

1 Like