Is it possible to implement Create Group from Slice without API?

Hi fellow seniors, I now want to implement the function of “generating a group from a section”, which is the function that appears when you right-click on a section in the scene. It perfectly meets the effect I need: the plane intersects with the object at the level of the plane, and the Groups are created as a result. And it runs very fast. I noticed a previous post on the forum, but there was no solution. The intersect_with method mentioned in it was not easy to use. So now I can only write my own sectioning function to achieve this function? Similar to S4U’s Slice? That will be a big project. .

The topic moved to [Developers] [Ruby API] section. (Again and again and again … :wink: )

I do not think you can avoid the intersect_with method.

I opened API requests 4 years ago …

1 Like

I wish there was a way to vote for new API methods, these both sound just dandy.

1 Like

First stab at writing the Section Create Group From Slice

slice from group all.rb (2.8 KB)

and a file to test with:
test slice.skp (104.8 KB)

The Code:

# In this implementation I have ignored any geometry in the top level entities collection
# and leave that to the reader to resolve.

# Slice every Component and Group in the model
#   saving the geometry in a new groups (under the group named 'Slice Group')
module SW
  def self.create_slice()
    model = Sketchup.active_model
    top_level_ents = model.active_entities
    model.start_operation('Create Slice', true)

    dest = top_level_ents.add_group = 'Slice Group'

    # find all of the visible groups and components
    cgs = dig(top_level_ents)
    # slice each component or group at height z
    z =
    cgs.each {| ent |
      slice(model, dest, ent, z)

    # unhide all of the components and groups

    # move the destinaiton group off to the side so that we can see it
    #tr = Geom::Transformation.translation([0, 400, 0])


  def self.hide_all(cgs)
    cgs.each {| cg | cg.hidden = true }

  def self.unhide_all(cgs)
    cgs.each {| cg | cg.hidden = false }

  # find all of the visible components and groups
  def self.dig(ents)
    cgs = []
    ents.each { | ent |
      next if 
      if ent.class == Sketchup::ComponentInstance
        cps << ent if !ent.hidden?

      elsif ent.class == Sketchup::Group
        cgs << ent if !ent.hidden?
    return cgs

  # create a slice of the entity at the height z
  # by unhiding the entity and applying intersect_with to the whole model
  def self.slice(top_level_ent, dest, ent, z)
    case top_level_ent
      when Sketchup::Group
        ents = top_level_ent.entities
      when  Sketchup::ComponentInstance
        ents = ent.definition.entities
      when Sketchup::Model
        ents = Sketchup.active_model.active_entities
    # create a face that is slightly larger than the current bound box
    bb = top_level_ent.bounds

    pt = bb.corner(4)
    p1 = [pt.x - 20, pt.y - 20, z]

    pt = bb.corner(5)
    p2 = [pt.x + 20, pt.y - 20, z]

    pt = bb.corner(7)
    p3 = [pt.x + 20, pt.y + 20, z]

    pt = bb.corner(6)
    p4 = [pt.x - 20, pt.y + 20, z]

    # add  the face to the current entities
    temp_face = ents.add_face(p1, p2, p3, p4)
    temp_edges = temp_face.edges

    # add a destination group to receive all of the intersection lines
    grp = dest.entities.add_group() =

    # Intersect the the current entities object with the temp_face,
    # placing the resulting lines in the destination group
    ent.hidden = false
    ents.intersect_with(true, IDENTITY, grp.entities, IDENTITY, false, temp_face)

    # remove the temp_face
    ent.hidden = true


The result of running the demo code should look like this:

What is the brute force hiding and unhiding for ?

If the user has some stuff hidden and other not, this would not restore things as they were.

The dig() method might have issues.

There is a statement line next if that has no conditional expression as the 1st line in the each loop.

Secondly, the results of the recursive call(s) are not returned. Ie, each recursive method call has it’s own cgs array that is not applied to the top level cgs array (from the first call to dig().

I did not test it, so if it works the way it is, then perhaps there is no need to reclusively dig down into nested objects?

The basic idea here is to draw a temporary face that is larger than the geometry we wish to section. Then we call upon Sketchup to intersect all of the geometry in the specified entities collection, the model.active_entities in this example, with the temporary face. Note the recurse flag is set to true. After making the intersect_with() call the destination group will contain a line at each location that a face in any group or component intersected our temporary face. Since we specified recurse, any visible geometry in the children containers of our top level entities will be included in the intersection.

  • To create separate slices for each child container, as the native Sketchup tool does, we must hide everything in the model and then unhide and perform the intersection on a single container at a time.

The ents.intersect_with method call is the workhorse of the whole algorithm which eliminates our needing to calculate any transformation matrices.

  # Intersect the the  entities object with the temp_face,
  # placing the resulting lines in the destination group
  ents.intersect_with(true, IDENTITY, grp.entities, IDENTITY, false, temp_face)

As you mentioned, the dig method does need to be revisited to return a tree of containers that may be traversed while making the slices. Not knowing the ultimate use of this code, I stopped refining the code once the basic example was working properly.

Thank you for the feedback!