Copy Group and Rename Layers

Is there a way to Copy a group and then rename all the layers that that group has artwork on?

Example File:
Copy Group and Rename Layers - Example 01.skp (122.6 KB)

As an example, I have a model of a house where I’ve put different parts of the house onto different layers so that I can show/hide them easily. We’ll call this House 1. So I wind up with multiple layers:

  • House 1
  • House 1 - Building
  • House 1 - Furniture
  • House 1 - Land
  • House 1 - Roof

In order to make multi-house configurations I often copy House 1 and then edit it. So now I have 2 houses but all the groups are still on their respective House 1 layers so I can’t control the visibility of groups in House 2 independently. In the past I manually went through the groups in House 2 and moved them each to new layers named for House 2:

  • House 2
  • House 2 - Building
  • House 2 - Furniture
  • House 2 - Land
  • House 2 - Roof

This accomplished the right end result but it’s very slow.

Recently I found a script that can successfully change the names of the layers but it doesn’t work completely as expected. Here is the script:

Sketchup.active_model.layers.each {|layer| 
  # do a pattern match of layer.name and revise the required names
  if layer.name.start_with?('House 1')
  # Replace starting House 1 with House 2:
  layer.name= layer.name.gsub(/\A(House 1)/,'House 2')
end
}

Here’s what I’ve been doing with the script:

  1. I copy House 1 and past it into a new document, so all the House 1 layers get copied over
  2. I open the Ruby Console and paste in the script so all the ‘House 1…’ layers end up being changed to ‘House 2…’
  3. At this point the group works as expected, turning off a House 2 layer hides the expected groups
  4. Then I copy the house group and paste it back into the first document, all the new House 2 layers now show up in the first document along with the House 1 layers
  5. After pasting back into the original document the problem is that only the outer-most group seems to be on the House 2 layer. All the other layers seem to revert back to the way they were before—being on the House 1 layers. I’m really confused as to why this happens.

Here’s a video of me doing this whole process.

Doing it without any scripts, I would select the components/groups that you are interested in and copy them to the clipboard. Then change the layer associations for the visible components/groups to the appropriate House 2 layers. Then turn off those layers and paste the copied groups in place.

@DaveR you’re the fastest gun slinger in the west!

I just tried out your suggestion but the interior layers still seem to stay on the House 1 layers.

Also, I made this file as a simplified version just to explain the problem. So in this example each house only has 5 layers associated with it but in my regular use each house has more like 10 layers associated with it and I’m often copying many houses so I really do need some kind of scripted solution. Up until now I’ve been doing it manually but it’s getting really long.

You would need to edit each group that has a different layer association. The process I outlined wouldn’t do that for you. But maybe you don’t need such a complicated layering scheme either and maybe you don’t need such a complicated nesting scheme, either.

I don’t know if there’d be a way for a script to automatically create new layers with new names for selected nested groups.

I’m starting to think you may be right. That layering/nesting scheme grew slowly out of different things that I always need to do with the file. If it were possible it would be really amazing. Changing the layer names seems to work really well, I just have no idea about how to get the internally nested groups to change layers too.

You’d need to select the groups and change their layer association. I would use Outliner to select them and Entity Info to reassign the layer. It would be helpful to give the groups useful names.

If you want to make the layers unique for one of the houses you can copy it to a separate file, rename all layers and copy back in.

However I’m not sure why. The power in layers is much that they are global; you can e.g. hide all furniture at once regardless of what building it is in. Maybe using groups and hide at entity level is simpler in this case.

1 Like

That’s what I thought would work too, after I change the layer names in the new document they seem to be all named ‘House 2…’, but then when I paste the group back in to the original document all the nested groups somehow magically switch back to being on House 1 layers. The only group that stays on a House 2 layer like it was renamed is the outermost group.

Do nested groups have some kind of memory of what layer they were in?

I thought you wanted to have one set of the groups on layers appended with number one and another set of groups on layers appended with number two. If that’s the case, there’s no need to copy the groups into a separate file. You can do it all in the same SketchUp file.

Your problem is not layers, nor layer names. As I tried to explain in the private thread, instances are “display copies”. Ie, instances do not have a geometric collection.

Groups are a special kind of component instance that does not appear in the “In Model” component browser. Also, when you manually open a group for edit, and there are more than one group instance of that definition, the SketchUp engine automatically makes the group unique. This means it creates a clone of the group’s shared definition and it’s geometric collection, and converts the entered instance to an instance of the clone definition. (This means the former definition has one of it’s instances replaced.)

The most important thing to understand is that instances (component or group) do not have a geometry collection. It is their definition that has the geometry collection. When you enter a group or component instance manually in the GUI, you are actually transparently editing the definition’s geometry.
This means for components, that you edit ALL component instances of that definition. But for groups, SketchUp clones the definition so that you only edit that particular instance’s definition’s geometry.

So, without manually entering the edit context of a group instance, or any component instance, you will see what you show in the above image in the Outliner. Both top level groups shared the same definition, and therefore the same geometric collection … ie, the same geometry entities.
In that collection are 2 nested group instances, whose definitions have a geometric collection. The first has 3 nested group instances in it’s own geometry collection, each having their layer properties set to use their respective “House” layers.

Since each of the top level house group instances share the same definition, and therefore it’s geometry, the nested groups instances are one and the same nested group instance, and so on. The nested group is the same, and it’s nested groups are the same.

5 Likes

Maybe you have to go through all groups, open them for editing and then close them. It appears renaming the layer alone doesn’t generate new GUIDs for all definitions referencing said layer, causing SketchUp to think the groups are still identical to those in the old model and use those instead once you try to paste. I’ve had similar problems with materials.

1 Like

If you are going to write yourself up a Ruby “macro” then you’ll need to traverse the entity hierarchy for the second house, and cause them to be unique depending upon whether using groups or component instances.

I think that calling this upon an sole instance (ie, single instance of a definition,) has no effect. So it should only work if the definition has 2 or more instances.

I also think that you may need to “uniquify” from top down.

2 Likes

Okay I think I understand, the concept at least. So if this only works when the definition has 2 or more instances then I guess I would need to do everything from within the same file where there would be a second instance instead of the way I’ve been trying to do it so far (copying it into another file, changing the layer names, and then pasting it back in).

Copying into another file is working too hard for this anyway.

This is what I’m going to try to make:

User makes a copy of a certain group
Take the selected group
	Make groups unique
		Open top-most group
		Make the top-most group unique
		Open nested group
		Make nested group unique
		Repeat with all nested groups
	Rename layers
		Look at layer name of top level group
			Prompt user to enter text that is to be replaced (X)
			Prompt user to enter text that is to replace X text, this will be called Y text
			Look for X text in layer name
			Replace X text in layer name with Y text (a new layer is made) 
			Reassign top level group to newly renamed layer
		Look at layer name of nested group
			Look for X text in layer name
			Replace X text in layer name with Y (a new layer is made)
			Reassign nested group to newly created / renamed layer
        	Repeat with all nested groups

Sounds good, excpet for the “open group” part. Via Ruby you cannot open edit contexts (this is a manual user only function.) You can however close open edit contexts. One of the things that the API has a disparity with.

EDIT (2022-07-07) : Since the 2020.0 release the Ruby API implemented the Sketchup::Model#active_path= setter method to open editing contexts.

Do you think there’s any way around that then? Or really the only way to do it is to manually open each group?

Do you think if all the groups were components then I could use ‘Make unique’ to do it? But I guess even if they were components I would maybe have the same problem, right? (since ‘Make unique’ only acts on the top-level component and not nested components).

If the API allows you to close Edit Contents that are already open then maybe I could restructure the workflow so that the first thing the user does is use the Outliner to manually open the deepest-level group/component of the copied group, and then the user would activate the script which would then make the groups unique and change their layer names before closing it and moving on to the next one.

No. You likely misunderstood. The opening of a group (or component instance) for edit is a feature that is meant to visually enhance the manual use of SketchUp.

You can directly modify objects using SketchUp’s Ruby API regardless of whether of not they are the user’s active editing context. (There are situations where you do need to be careful however.)

So if you have a reference to a group instance, you simply call it’s #make_unique method.

  new_unique_group_instance = old_group_instance.make_unique

After calling the above then the following should return false

  new_unique_group_instance.definition == old_group_instance.definition

Meaning that each now unique group instance should each have it’s own unique definition object.


Another thing to keep in mind is that group.entities() is a shortcut (wrapper) method for group.definition.entities(). In the past they were trying to hide the fact that groups are a special kind of component instance.

TIG explains how to avoid BugSplat! crashes …