How to know a point is inside which faces in a model?

I tried to find all faces that one point is inside them and write the following code for it.

#finding all faces in the model
defs = Sketchup.active_model.definitions
          list =[]
          defs.each { |d|
            next if d.image?
            ins=[]
            d.instances.each{ |i| ins << i }
            list << d.instances unless ins.empty?
          }
          f_list = []
          list.each { |c| c[0].definition.entities.grep(Sketchup::Face).find_all { |e| f_list << e } }
#finding faces that pt0 is inside
          f_list.each do |f|
            if f.parent.is_a? (Sketchup::ComponentDefinition)
              pt0_tr = [pt0.x, pt0.y, pt0.z]
              grp = f.parent.instances[0] 
              tr = grp.transformation
              pt0_tr.transform! tr.inverse
              if grp.parent.is_a? (Sketchup::ComponentDefinition)
# How can I find grp.parent.transformation and ....
              end
              pt0_faces << f if (f.classify_point(pt0_tr) == 1) || (f.classify_point(pt0_tr) == 4)
            end
          end

if the face has one group in its instance path it works well but I don’t know what should I do if the face has more than one group or component in its instance path. Your help will be highly appreciated.

Please correct the indentation of your code snippet.


  ins = []
  d.instances.each { |i| ins << i }

… serves no purpose as ins is the same as d.instances or even ins = d.instances.


Instance and Group objects do not respond to #empty? method calls.


c[0].definition.entities.grep(Sketchup::Face)

… gives you the instance’s definition’s faces array. There is no need to add on …
.find_all { |e| f_list << e } }

Just do …

face_list << c[0].definition.entities.grep(Sketchup::Face)
1 Like

Is the point given in world or local coordinates ? I am going to guess world (model) coordinate’s since you speak of instance path and applying instance transforms.

So, you cannot do it the way you are trying to do it. In order to build instance paths, you must walk the entire model tree and build an instance path for each instance you are going to test. (Ie, you cannot just go through a definition list iteration.)

This usually means a recursive method call.

But as you walk the model’s instance tree, you can cut down on the number of instances to check by testing if the pt0 is within the bounding box of the instance. In order for the point to be “on an instance’s face” it must also be within the instance’s bounds.

REF:

1 Like