SketchUp / api-issue-tracker

Public issue tracker for the SketchUp and LayOut's APIs
https://developer.sketchup.com/
38 stars 10 forks source link

Face insensitive to the intersect_with method #786

Open Wisext opened 2 years ago

Wisext commented 2 years ago

Bug Report

  1. SketchUp Pro 2022 (not tested on previous versions)
  2. OS Platform: Windows 10

Here is a SketchUp file containing 2 faces in the model and one face in a group: https://forums.sketchup.com/uploads/short-url/waas7ch2iaN5MkdMUCyTrFMerMB.skp

image

If you use the intersect_with method (https://ruby.sketchup.com/Sketchup/Entities.html#intersect_with-instance_method) to get the intersection between the group and the model, there is no intersection for the face in blue. Here is a code to use the method on the provided file:

  m = Sketchup.active_model
  # group containing a face that is a cutting plane of model entities
  section_group = m.find_entity_by_persistent_id(2719083) 
  # intersecting the model entities and the section group (the intersection entities are drawn in the section group)
  m.entities.intersect_with(false, Geom::Transformation.new, section_group, section_group.transformation, false, section_group)

image

The snippet is equivalent to opening the group for edit and then invoking Intersect Faces With…Model via the GUI and you get the same issue.

sketchup[bot] commented 2 years ago

Logged as: SKEXT-3433

LItterBoy-GB commented 2 years ago

I find another situation. test.skp

face_g, model_g = nil, nil
Sketchup.active_model.entities.grep(Sketchup::Group).each do |g|
  if g.entities.grep(Sketchup::Face).empty?
    model_g = g
  else
    face_g = g
  end
end
model_g.entities.intersect_with(true, model_g.transformation, Sketchup.active_model.entities, IDENTITY, false, face_g)

image

CAUL2000 commented 2 years ago

The reason for these bugs is that the faces are not planar enough. Something like the following snippet can be used to paint non-planar faces red - select a group and run the script:

module WonkyFacePaint

  def self.paint_wonky_faces(g)

    g.entities.grep(Sketchup::Face).each do |f|
      pts = f.outer_loop.vertices.map(&:position)
      scale = 100
      tr = Geom::Transformation.scaling(pts.first, scale, scale, scale)
      pts = pts.map { |pt| pt.transform(tr) }
      plane = Geom::fit_plane_to_points(pts)
      f.material = 'red' unless pts.all?{ |pt| pt.on_plane?(plane) }
    end

    g.entities.grep(Sketchup::Group).each { |g| paint_wonky_faces(g)}
  end

  Sketchup.active_model.start_operation("paint", true)
  paint_wonky_faces(Sketchup.active_model.selection.first)
  Sketchup.active_model.commit_operation

end

The faces have to be triangulated before intersect in order for intersect_with to work. Sketchup does this if intersect is performed from the UI and the geometry to be intersected is in the outer context.