Trimming group by multiple groups

How can I trim one group with multiple other groups? I figured trim would work best since it is supposed to be a nondestructive method but I can’t seem to get it to work.

group = group1
groups_to_trim = [group2,group3,group4]
groups_for_trim.map{|g| group=group.trim(g)}

You are not coding defensively. You need to ensure that the groups are manifold (watertight) and that each boolean operation returns a group and not nil.

Also the docs for the #trim method are not very clear. It is the argument group that gets trimmed.

  def trim_groups(group = Sketchup.active_model.selection[0])
    return unless group # nil if empty selection
    if group.manifold?
      model = Sketchup.active_model
      groups = model.active_entities.grep(Sketchup::Group) - [group]
      sel = model.selection
      sel.clear
      sel.add(group)
      UI.messagebox("This is the base group to Trim.",MB_OK)
      if groups.any? {|grp| grp.manifold? }
        model.start_operation("Trim Groups")
          # Iterate remaining groups
          groups.each do |trimmer|
            next puts "#{trimmer.inspect} is not manifold!" unless trimmer.manifold?
            sel.add(trimmer)
            UI.messagebox("Execute Trim Step?",MB_OK)
            result = trimmer.trim(group)
            if result
              # group is now an invalid reference
              group = result
              sel.add(group)
              puts "#{group} trimmed with #{trimmer}"
            else
              "Error trimming #{group} with #{trimmer}"
            end
          end
        model.commit_operation
        return group # The final trimmed group
      else
        puts "No manifold groups to trim with!"
      end
    else
      puts "First group is not manifold! - Trim operation cancelled."
    end
  end

Thanks!

How can I do the same but if the groups are nested?

Nested in what manner ?

Hello, thanks for answering, I am working on a small code that does something similar to what is explained here, but I work with components that are inside each other, that is, for example I have a model which is made up of 3 components, like this: component A is the main component, but it is made up of 3 components D5, D8 and D15, what I want is to make the clipping of component D5, until now I have only been able to make the clipping be done but I have to explode the main component and that is not what I need, I want to do it without having to explode the main component. Also when making the clipping it generates a group called Difference, what I want to know is if it is possible for the group to become a component that bears the name of the base component, that is, the component on which the clipping was made.

What is the “base component, that is, the component on which the clipping was made” ?

I would say that it should be either D8 or D15. Ie, … the two component (or group) instances in the Boolean operation need to be in the same geometric context.

Before the operation, make a reference to the string name for later assignment.

After the operation, convert it to a component with Group#to_component …

new_comp = diff_group.to_component

… then afterward change the name:

new_comp.name= prev_name

This is a quirk that has often been a point of complaint, where the result of the Boolean operation changes the class of the resultant object.

FYI … @eneroth3 has a Ruby library that does not do this:

No you do not need to explode the component’s geometry to work within it’s geometric context.

Just work in the component instance’s definition’s entities context …

ents = comp_A.definition.entities
comps = ents.grep(Sketchup::ComponentInstance)
d5 = ents.find { |inst| inst.name = "D5" }
d8 = ents.find { |inst| inst.name = "D8" }
d15 = ents.find { |inst| inst.name = "D15" }
# save the name for later use
prev_name = d8.name
# do the operation
# convert the group result to a component instance
# lastly rename the new component instance

I have a solid rectangle which I will call the base component or simply base, and I have cylinders which I want to cut out to make holes inside the rectangle, the cylinders are components that have three components inside that are part of the cylinder, one of those components that is part of the cylinder is the one I want to cut out, it is solid, but when I run the code it does not do the cutout, in order to be able to cut it it is necessary to explode the component, and I do not want to explode it, that’s all, when I explode it if it works if it does the cutout.

Again, the native Boolean tools require that the instances for the operation are in the same context.

Your only possible solution are:

  • combine the 3 subcomponents within the cutting “cylinder” into one solid component,
    OR
  • recreate the cutting subcylinder in the parent context where the “base” component resides,

… then use it to do the trim operation.