Get instances using a loop

When I transform the component, I usually set one to run one, just like the following code,but when I need a large number of components, I need to use a loop. How can I use a loop to achieve the following code,and the instances also have their own name. I would appreciate it if you could help me

path=Sketchup.find_support_file "panel.skp","components"
def_list=mod.definitions
test_panel= def_list.load path
move1 =Geom::Transformation.translation [10*1,0,0]
move2 =Geom::Transformation.translation [10*2,0,0]
move3 =Geom::Transformation.translation [10*3,0,0]
move4 =Geom::Transformation.translation [10*4,0,0]
inst1=ent.add_instance test_panel,move1
inst1=ent.add_instance test_panel,move2
inst1=ent.add_instance test_panel,move3
inst1=ent.add_instance test_panel,move4

The first thing you need to do different is always check is the definition list already has the component loaded before loading from disk.

def get_comp(name, filename, dirpath = "Components")
  mod = Sketchup.active_model
  def_list = mod.definitions
  cdef = def_list[name]
  if !cdef
    path = Sketchup.find_support_file(filename, dirpath)
    cdef = def_list.load(path)
  end
  return cdef
rescue RuntimError # Component file is corrupt
  return nil
end

Then you’ll need a method to handle a loop.

This example will copy an existing group or component instance …

def copy_array(instance, copies, spacing, axis)
  base_transform = instance.transformation
  model = instance.model
  ents = model.active_entities
  type = instance.is_a?(Sketchup::Group) ? 'Groups' : 'Instances'
  added = []
  model.start_operation("Copy #{copies} #{type}",true)
    for i in 1..copies do
      translation = (spacing * i).to_l
      translate = case axis
      when X_AXIS
        [translation, 0, 0]
      when Y_AXIS
        [0, translation, 0]
      when Z_AXIS
        [0, 0, translation]
      else
        vector = Geom::Vector3d.new(axis)
        vector.length= translation
        vector
      end
      transform = base_transform * Geom::Transformation.translation(translate)
      inst = ents.add_instance(instance.definition, transform)
      inst.name = instance.name << " #{i}" unless instance.name.empty?
      added << inst
    end
  model.commit_operation
  return added # the array of newly added instance copies
end

So, we can modify the above method for an array of new component instances …

def comp_array(definition, initial_transform, copies, spacing, axis)
  model = definition.model
  ents = model.active_entities
  added = []
  model.start_operation("Component Array (#{copies})",true)
    inst = ents.add_instance(definition, initial_transform)
    inst.name = definition.name << " 1"
    added << inst
    for i in 2..copies do
      translation = (spacing * i).to_l
      translate = case axis
      when X_AXIS
        [translation, 0, 0]
      when Y_AXIS
        [0, translation, 0]
      when Z_AXIS
        [0, 0, translation]
      else
        vector = Geom::Vector3d.new(axis)
        vector.length= translation
        vector
      end
      transform = initial_transform * Geom::Transformation.translation(translate)
      inst = ents.add_instance(instance.definition, transform)
      inst.name = definition.name << " #{i}"
      added << inst
    end
  model.commit_operation
  return added # the array of newly added instances
end

Where:

  • initial_transform can be a transformation, point, vector or array
  • axis can be: a vector, an array, or one of the global preset constants (X_AXIS, Y_AXIS, Z_AXIS)
  • copies is an Integer
  • spacing should be a Length object