Swapping Component definition with instance

Hi all,

I’m new to Ruby and trying to figure something out and would greatly appreciate your help.

I’m trying to swap all model objects component instance with definition. so far i have used this but it renames both to read definition. is there anyway to swap this code around so that both fields can read the instance name?

m=Sketchup.active_model;m.start_operation(“inamer”,true);m.definitions.each{|d|next if d.group? || d.image?;d.instances.each{|i|i.name=d.name}};m.commit_operation;

many thanks for your help everyone. this image may help in showing what i trying to do…image

thank you.

Are you also a SketchUp user?

Hi yes

Ok, than you understand the difference between ComponentDefinition and ComponentInstance.
So you want to rename the definition by the instance name? But, what if a definition has multiple instances with different names?

Your right the definitions have multiple instances with different names. basically i was hoping that there might be a way to swap them around for all my modelled objects?..i just need all the definitions to be the same as the instances. many thanks

FYI, the fields in the Entity Info panel are name property fields.

It doesn’t make much sense to do this, as the reason they have separate name properties is so they can be different.

Often the definition name is a model / manufacturer identifier (part or stock number) and when instances are placed into the model, they get individual names based on their use.
(Ie, "Window - Master Bath", etc.)

Anyway … the main problem lies in that if there are multiple instances, as you iterate those instances, your code will be setting the definition’s name multiple times, and only the last setting (to the last instance name) will be persistent.

Ie, a common definition cannot carry the name of ALL of it’s instances. Ie, the definition’s name property is unique to it and can only hold one value.


The Ruby console can accept multiline code if you use Windows style line endings (CR+LF).

Basically your code should work.
I modified it a bit (wrapping it within a method and adding some customization arguments) …

def inamer(sep: ' ', prefix: '#', groups: false)
  m = Sketchup.active_model
  m.start_operation("inamer",true)
    m.definitions.each { |d|
      next if d.image? || (!groups && d.group?)
      next if d.name.empty?
      d.instances.each_with_index { |i,index|
        i.name= "#{d.name}#{sep}#{prefix}#{index+1}"
      }
    }
  m.commit_operation
end

Also, if you insert a model that is not set up to be a component, and has no name property, then SketchUp will set the definition name (after insertion) to be the basename of the filename (ie, minus the `".skp" extension.)


1 Like

Many thanks Dan for your help, I just ran it and had the same issue though.

Before:

After:

What im trying to get to:

Sorry to be a pain. i appreciate your help! Many thanks

Of course, because it names instances based upon the definition’s name. This is why it’s called “inamer”, right? (Ie, there is no call to reset the definition’s name property in your code example or mine.)

You haven’t yet answered the fundamental question that Ken and I both asked. What should happen if the definition has multiple instances ?

Your image labeled “What im trying to get to:” would not require any iteration of a definition’s instances if ALL the instances had the same name (which is contrary to best practice.)

So do we just go with the first instance in the definition’s instances collection ,… or the last ?

And would we take just the substring before the “- 0193” as the definition’s name ?

Do you apply this to ALL defintion’s … or only those who have instances whose names begin with “Ifc” ?

Hi Dan,

You haven’t yet answered the fundamental question that Ken and I both asked. What should happen if the definition has multiple instances ? sorry - the definition wont have multiple instances.

And would we take just the sub-string before the “- 0193” as the definition’s name ? no, the definitions name would need to include the -0193. this is why i’m finding it tricky. each modelled object has different numbers after “IFCBuildingElementProxy” i.e -0193, -0194 etc…which is what i am trying to show in the definition name.

Do you apply this to ALL defintion’s … or only those who have instances whose names begin with “Ifc” ? all definitions would need to be applied yes.

Thanks for your continued help.

To quote previous statements (yours or anyone’s), place the cursor in your new post or reply form where you will want the quote to appear, … then simply select the phrases you wish to quote and a quote button will appear. Click the quote button.
Add your reply outside (after) each quote. You can insert multiple quotes from multiple posts from multiple people in a single reply this way.


Is this renaming a task you need to do often for many models … or just fixing a single model ?

Thanks!

i will need to do it for a few models yes. i was thinking of batching it after.

Try this on for size. It can serve as a simple example …

module FoxyLeon
  module Renamer
  
    extend self

    def inamer(sep: ' ', prefix: '#', groups: false)
      m = Sketchup.active_model
      m.start_operation("inamer",true)
        m.definitions.each { |d|
          next if d.image? || (!groups && d.group?)
          next if d.name.empty?
          d.instances.each_with_index { |i,index|
            i.name= "#{d.name}#{sep}#{prefix}#{index+1}"
          }
        }
      m.commit_operation
    end

    def cdef_namer()
      m = Sketchup.active_model
      m.start_operation("Rename Definitions",true)
        m.definitions.each { |d|
          next if d.image? || d.group?
          inst = d.instances.first
          d.name= inst.name
        }
      m.commit_operation
    end

    if !@loaded
      menu = UI.menu('Extensions')
      submenu = menu.add_submenu('Foxy Renamer')
      submenu.add_item('Rename Definitions') { cdef_namer() }
      submenu.add_item('Rename Instances') { inamer() }
      @loaded = true
    end

  end
end
1 Like

You can add a method and menu item to choose a directory via UI.select_directory and iterate through the skp files and call the cdef_namer() method, then save the model, if it was modified.

1 Like

This is awesome! Thank you very much Dan! I love the new Extensions, great idea

1 Like