Select correct face after intersection


#1

I have a function that performs a cut of a surface by using solids as tools.

module RG
  def self.cut_surfaces(tools, surface_group) #log
    orig_surfaces = surface_group.entities.grep(Sketchup::Face)

    tools.each do |t|
      arrays  = t.entities.intersect_with false, t.transformation, surface_group.entities, surface_group.transformation, false, surface_group
    end

    del = surface_group.entities.grep(Sketchup::Face).select{|e| !orig_surfaces.include?(e)}

      surface_group.entities.erase_entities del
    return true
  end
end
tools = Sketchup.active_model.entities.select{|e| e.layer.name == 'Layer0'}
aoi = Sketchup.active_model.entities.select{|e| e.layer.name == 'area_of_interest'}[0]
RG.cut_surfaces(tools, aoi)

Here tools is a collection of one or more groups (not necessarily solids) and surface_groups a group containing one or more faces. You can test it with the attached file.

This function works well as long as aoi does not intersect the tools. If the tools intersect the edges of the face then the ‘wrong’ area is actually generate. This is because I use the reference to the original face to decide which of the new faces needs to be deleted. When there is an intersection it seems that the API reassigns the same reference to one of the faces that I would actually like to cut-off.

This kinda make sense as the software cannot actually know in advance what I want to keep and what I want to discard.

The only solution that comes to mind is to abandon the use of the original face reference and perform a check on all the new surfaces generated from the cut. But it doesn’t seem very straightforward. For example I could check whether the centre of the face is inside the group, but as you can see from the attached file, ‘inside’ can be ambiguous when a group is composed by multiple elements that are visually solids, but are not solids from SU point of view.

Can you think to an alternative approach?

Thanks

forum_cut.skp (108.6 KB)


#2

My SectionCutFace tool adds a large face and intersects with it and then erases the original outer_loop, and then proceeds to erase the anticipated holes…

Here’s the original idea…

### sort out holes etc in sectioncut group
 faces=gents.grep(Sketchup::Face)
 (faces.length-1).times{
  faces.each{|face|
   next unless face.valid?
   face.outer_loop.edgeuses.each{|edgeuse|
    unless edgeuse.partners[0] ### outermost face
     faces = faces - [face]
     face.loops.each{|loop|
      faces.each{|fac|
       next unless fac.valid?
       if fac.outer_loop.edges - loop.edges == []
        faces = faces - [fac]
        fac.erase! if fac.valid?
        ### fac abutts kept face so it must be erased...
       end#if fac
      }#fac
     }#loop
    end#if outermost
   }#edgeuse
  }#face
 }#times

#3

Thanks TIG. Great idea using a larger surface!

Before using your approach I will try to modify mine based on your approach. The idea is to create a larger face that does not intersect the tools and perform the intersection with it. At this point the final surface will be the intersection between this (intersected) surface and the original (non intersected) surface. The only trick is to make these two surfaces solids by push-pull and then perform a solid intersection. It works manually, now I will see if I can make it work from the script.


#4

My code erases faces, yours needs to ‘collect’ them for later use ?


#5

Nope. No need for that.