diff --git a/src/bonsai/bonsai/bim/module/drawing/decoration.py b/src/bonsai/bonsai/bim/module/drawing/decoration.py index f2346f61f1..cd778099c2 100644 --- a/src/bonsai/bonsai/bim/module/drawing/decoration.py +++ b/src/bonsai/bonsai/bim/module/drawing/decoration.py @@ -1724,16 +1724,14 @@ class CutDecorator: bm_original.from_mesh(mesh) if not (material := ifcopenshell.util.element.get_material(element)): - geom = bm_original.verts[:] + bm_original.edges[:] + bm_original.faces[:] - verts, tris = self.bisect_mesh_tris(obj, bm_original, geom, context.scene.camera) + verts, tris = self.bisect_mesh_tris(obj, bm_original, context.scene.camera) DecoratorData.fill_cache[element_id].setdefault(self.fallback_colour, []).append((verts, tris)) return if material.is_a() not in ("IfcMaterialLayerSet", "IfcMaterialLayerSetUsage"): # Constituents, lists, and item styles not supported yet material = ifcopenshell.util.element.get_materials(element)[0] - geom = bm_original.verts[:] + bm_original.edges[:] + bm_original.faces[:] - verts, tris = self.bisect_mesh_tris(obj, bm_original, geom, context.scene.camera) + verts, tris = self.bisect_mesh_tris(obj, bm_original, context.scene.camera) colour = self.get_material_colour(material) DecoratorData.fill_cache[element_id].setdefault(colour, []).append((verts, tris)) return @@ -1753,8 +1751,7 @@ class CutDecorator: if len(layer_set.MaterialLayers) == 1: material = layer_set.MaterialLayers[0].Material - geom = bm_original.verts[:] + bm_original.edges[:] + bm_original.faces[:] - verts, tris = self.bisect_mesh_tris(obj, bm_original, geom, context.scene.camera) + verts, tris = self.bisect_mesh_tris(obj, bm_original, context.scene.camera) colour = self.get_material_colour(material) DecoratorData.fill_cache[element_id].setdefault(colour, []).append((verts, tris)) return @@ -1809,8 +1806,7 @@ class CutDecorator: edges = [g for g in bisect["geom_cut"] if isinstance(g, bmesh.types.BMEdge)] fill = bmesh.ops.edgenet_fill(bm_fill, edges=edges) - geom = bm_fill.verts[:] + bm_fill.edges[:] + bm_fill.faces[:] - verts, tris = self.bisect_mesh_tris(obj, bm_fill, geom, context.scene.camera) + verts, tris = self.bisect_mesh_tris(obj, bm_fill, context.scene.camera) DecoratorData.fill_cache[element_id].setdefault(colour, []).append((verts, tris)) verts, edges = self.bisect_mesh(obj, bm, slice_plane_geom, context.scene.camera) @@ -1861,18 +1857,19 @@ class CutDecorator: return verts, edges - def bisect_mesh_tris(self, obj, bm, geom, camera): + def bisect_mesh_tris(self, obj, bm, camera): camera_matrix = obj.matrix_world.inverted() @ camera.matrix_world plane_co = camera_matrix.translation plane_no = camera_matrix.col[2].xyz global_offset = camera.matrix_world.col[2].xyz * -camera.data.clip_start + geom = bm.verts[:] + bm.edges[:] + bm.faces[:] bmesh.ops.bisect_plane( bm, geom=geom, dist=0.0001, plane_co=plane_co, plane_no=plane_no, clear_inner=True, clear_outer=True ) - bmesh.ops.remove_doubles(bm, verts=bm.verts[:]) - fill = bmesh.ops.edgenet_fill(bm, edges=bm.edges[:]) + bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=1e-6) + fill = bmesh.ops.edgenet_fill(bm, edges=bm.edges) triangulate = bmesh.ops.triangulate(bm, faces=fill["faces"]) vert_map = {} diff --git a/src/bonsai/bonsai/tool/loader.py b/src/bonsai/bonsai/tool/loader.py index 0b8c4f321e..91cfbc4629 100644 --- a/src/bonsai/bonsai/tool/loader.py +++ b/src/bonsai/bonsai/tool/loader.py @@ -1062,17 +1062,26 @@ class Loader(bonsai.core.tool.Loader): styles[style] = i last_i = len(layer_set.MaterialLayers) - 1 for i, layer in enumerate(layer_set.MaterialLayers): - prev_co = co.copy() - co += no * layer.LayerThickness * cls.unit_scale if i != last_i: + prev_co = co.copy() + co += no * layer.LayerThickness * cls.unit_scale bisect_geom = bmesh.ops.bisect_plane( bm, geom=bm.verts[:] + bm.edges[:] + bm.faces[:], dist=0.0001, plane_co=co, plane_no=no ) bmesh.ops.duplicate(bm, geom=bisect_geom["geom_cut"]) - if style := ifcopenshell.util.representation.get_material_style(layer.Material, body): - if (material_index := styles.get(style, None)) is None: - material_index = len(mesh.materials) - mesh.materials.append(tool.Ifc.get_object(style)) + if not (style := ifcopenshell.util.representation.get_material_style(layer.Material, body)): + continue + if (material_index := styles.get(style, None)) is None: + material_index = len(mesh.materials) + mesh.materials.append(tool.Ifc.get_object(style)) + if i == last_i: + for face in bisect_geom["geom"]: + if isinstance(face, bmesh.types.BMFace): + center = face.calc_center_median() + if (center - co).dot(no) >= 0: + face.material_index = material_index + has_layer_styles = True + else: for face in bisect_geom["geom"]: if isinstance(face, bmesh.types.BMFace): center = face.calc_center_median()