Using Instance Path to open a nested group for editing?

Hello Everyone.

I want to move a group at the top level to within a nested group and have been attempting to use Instance Path to do so without success.

Here is the scenario…

  • Group_A and Group_X are at the top level
  • Inside Group_A is a nested group named Container_A
  • I need to get Container_A by iterating the model entities to find it by name.
  • I want to move Group_X into Container_A

My approach is to iterate the model to get the instance path for Container_A then later use the instance path to open it for editing and copy Group_X into it, thereby avoiding any cross-threading crashes.

Here is how I am getting the instance path…

Sketchup.active_model.entities.grep(Sketchup::Group){|this_group|
    if this_group.name == "Group_A"
        this_group.entities.grep(Sketchup::Group){|this_ent|
            if this_ent.name == "Container_A"
                # capture the instance path for later use
                @instance_path = Sketchup::InstancePath.new([this_ent])
            end
        }
    end
}

and this is how I am copying Group_X

# open the matched group for editing
Sketchup.active_model.active_path = @instance_path

# create a copy of Group_X in the active context, which should be Group A!!!
copy_of_Group_X = Sketchup.active_model.active_path[0].definition.entities.add_instance(Group_X.definition, Group_X.transformation)

# erase the original Group_X
Group_X.erase!

However the copy gets created at the top level!

I also tried…

copy_of_Group_X = @instance_path[0].definition.entities.add_instance(Group_X.definition, Group_X.transformation)

But then I get an error saying…

Error: #<TypeError: invalid instance path - deleted elements>

Any help would be greatly appreciated!

Happy Holidays y’all!

I think your issue is misunderstanding InstancePath. You must create it from an array of the entities in the nesting hierarchy leading from the model context to the leaf entity (this_ent). You only put in the leaf, so SketchUp thinks this ent is in the model. You need to put this_group in the Array before this_ent.

2 Likes

Thanks Dan,

So, if i understand correctly…

If I wanted to descend to an entity 27 levels deeper than the top level, I would have to record each entity along the way, resulting in an instance path array with 27 entries?

Yep (although my name isn’t Dan :shushing_face:)

I recommend you don’t start Variables with a capital letter as Ruby will think it’s a Constant, and when you change it a message will appear in the Console.
Also why not simply use the group’s definition entities directly without worrying about ‘active_path’ at all ?

### earlier on set 
this_group.entities.grep(Sketchup::Group){|this_ent|
  if this_ent.name == "Container_A"
    @defn = this_ent.definition
    break
  end
}
### later
copy_of_group_X = @defn.entities.add_instance(group_X.definition, group_X.transformation)
### etc

NB. I’ve de-capitalized your variables…
If you have several instances of the same group and only want to add into one of them then before that you need to use group.make_unique
So only that group is affected…

2 Likes

Haha! Sorry not sure where I got Dan!

Hi Tig. I did not know that about variable names… Thanks!

That was the approach I was using that caused a crash, which got me thinking I should use the instance_path approach.

I am able to confirm that I have captured the correct group before attempting the copy by checking the entityID but unfortunately Bugsplat nonetheless.