Problem with boundingbox intersections

I have a little problem with boundingbox intersections
As you can see in the image I have a test model with 2 spaces, 2 doors and 2 windows.


test.skp (1.3 MB)

I want to get a list of the windows and doors that intersect with each of the faces of the spaces (I must analyze the faces and not the boundingbox of the space because if it has an “L” shape it can give a wrong intersection).

My problem is that although there is intersection, only one of the doors seems to intersect with everything.

This is the console report:

conjunto salon cocina intersects with ...
puerta entrada_0#1
puerta entrada_0#1
aseo intersects with ...
puerta entrada_0#1
puerta entrada_0#1
puerta entrada_0#1
"[#<Sketchup::ComponentInstance:0x00000002d08ccb48>, #<Sketchup::ComponentInstance:0x00000002d08ccaf8>]"

Can anyone tell me what I can be doing wrong? This is my code (only for test)

mod = Sketchup.active_model
sel = mod.selection

espaces = []
doorsandwindows = []
sel.each do |md|
  if ifcComponent(md)
    ifcDict = md.definition.attribute_dictionary("AppliedSchemaTypes")
    if ifcDict["IFC 4"] == "IfcSpace"
     espaces.append(md)
    end
  end
end

sel.each do |md|
  if ifcComponent(md)
    ifcDict = md.definition.attribute_dictionary("AppliedSchemaTypes")
    if ifcDict["IFC 4"] == "IfcDoor" || ifcDict["IFC 4"] == "IfcWindow"
     doorsandwindows.append(md)
    end
  end
end

#puts espaces.count
#puts doorsandwindows.count

def ifcComponent(instance)
  isaComp = true if instance.is_a? Sketchup::ComponentInstance
  hasDict = true if instance.definition.attribute_dictionary("IFC 2x3") || instance.definition.attribute_dictionary("IFC 4")
  return  isaComp && hasDict
end

espaces.each do |e|
  puts e.definition.name + " intersects with ..."
  e.definition.entities.each do |mde|
     if mde.is_a? Sketchup::Face
       doorsandwindows.each do |dw|
         ii = dw.bounds.intersect(mde.bounds)
         puts dw.definition.name unless ii.empty?
       end
     end
  end
end

You need to calculate the bounds of each face according to the transformation of the object containing it.

  face_points = mde.vertices.map {|v| v.position.transform(e.transformation) }
  face_bb = Geom::BoundingBox.new.add(face_points)
  ii = dw.bounds.intersect(face_bb)
2 Likes

Thanks @curic4su, I hadn’t thought about the transformations.

On a related note, of determining the interaction of doors and windows with faces, if the component’s definitions are set as a gluing component (ie, door_comp.snapto= SnapTo_Vertical) then you can easily get the face that any of it’s instances are glued to via the door_inst.glued_to method.

Thanks @DanRathbun, the problem is that doors and windows (not always) are glued to walls but is not the case of spaces.
The IfcSpace components are generated from the interior perimeter of each room or space but they are solid without holes and usually serve in BIM quantification software to calculate the measures of the interior finishes from their areas and perimeters.
For example, if you want to measure the painting of a room, multiply the perimeter of the IfcSpace by the height and subtract the openings.
IfcSpaces represent 80% of the automatic measurement work in BIM Softwares.