Searching for a group (by name) within a group

What is the quickest and most inexpensive way to search for a group or groups within an existing group given only the sub- groups unique name?

My first crack at it would be, based on some of my recent code:

@maingroup = Sketchup.active_model.selection
group_list = @maingroup.entities.grep(Sketchup::Group)
specific_group_list = group_list.find_all { |e| e.name =~ /UNIQUE_NAME_GOES_HERE/ }
1 Like

This seems to work reasonably well:

ss = Sketchup.active_model.selection
@maingroup = ss[0]
group_list = @maingroup.entities.grep(Sketchup::Group)
custom_group_list = group_list.find_all { |e| e.name =~ /CUSTOM/i }

for groupi in custom_group_list do
	puts "#{groupi.name}"
end

What I am ultimately trying to accomplish with this piece of code is to somehow maintain certain sub-groups within my main group when I clear out the contents of the main group (for a rebuild from scratch).

My code to clear the main group of all its nested geometry is:

@maingroup.entities.clear!

It would be nice if there was a way to issue a clear command that cleared everything except the specified list of sub-entities but I don’t know how to do that.

The problem I’m having is how to pull out the sub-groups and then put them back in the group.

This code written by TIG a few years ago is probably the key:

grp ### the reference to the original group
newgrp = cdef.entities.add_instance( grp.entities.parent, grp.transformation )
newgrp.material = grp.material
newgrp.layer = grp.layer
newgrp.name = grp.name
attds = grp.attribute_dictionaries
attds.each{|d|
  n = d.name
  d.each_pair{|k, v|
    newgrp.set_attribute(n, k, v)
  }
} if attds
### you can also transfer any other properties like hidden?, locked? etc
grp.erase!

Maybe it would just be easier to grep for all the entities within the main group and then loop through and erase all of these except for the CUSTOM groups.

I wouldn’t think this would be much more computationally expensive than the clear! method.

This seems to work, not very compact but performance doesn’t seem to suffer too much:

if 1 == 2
	# Old method 06.18.2018
	@maingroup.entities.clear!
else
	group_list = @maingroup.entities.grep(Sketchup::Group)
	comp_list = @maingroup.entities.grep(Sketchup::ComponentInstance)
	grouperase_list = group_list.find_all { |e| e.name !~ /CUSTOM/i }
	comperase_list = comp_list.find_all { |e| e.name !~ /CUSTOM/i }
	erase_list = grouperase_list + comperase_list
	@maingroup.entities.erase_entities erase_list
end

Given the previous …

group_list = @maingroup.entities.grep(Sketchup::Group)
custom_group_list = group_list.find_all { |e| e.name =~ /CUSTOM/i }

… you can use the multi-erase method of the Entities class and pass it an array …
which is easily gotten by subtracting the custom_group_list array from the group_list array:

@maingroup.entities.erase_entities( group_list - custom_group_list )
2 Likes

I didn’t know you could subtract lists like this, interesting.

Well, … firstly remember from math classes about set operations ? Arrays are a kind of set that is non-unique.
Look at the first 7 instance methods of the Array class. These are basic.

I have two displays and I use the secondary (notebook’s) display for reference. There is always a SketchUp API doc page, a Ruby core doc page and usually some Ruby library page open on it that I’m referring to.

The secret to doing good work is having immediate access to good references. So when you know you are going to work with Arrays or Hashes, open up the class documentation page for that class and scan it’s method list before you start. It also helps to open up the Enumerable module that is mixed in and scan through it’s methods that are added to most collection classes.