From 98a9550260f7480d983a074812e600a8dfecd43f Mon Sep 17 00:00:00 2001 From: Gorgious56 Date: Fri, 3 Jan 2025 14:12:16 +0100 Subject: [PATCH] Fix slowness when rendering dense meshes with the opening decorator It uses a custom boolean attribute on the mesh to decide whether an edge should be displayed or not. I think later on it can be used to get rid of the dictionary accessors which make the blend file size skyrocket. --- src/bonsai/bonsai/bim/module/model/opening.py | 12 +++++++----- src/bonsai/bonsai/tool/loader.py | 17 ++++++++++++++++- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/model/opening.py b/src/bonsai/bonsai/bim/module/model/opening.py index 6294acde96..93b7d10261 100644 --- a/src/bonsai/bonsai/bim/module/model/opening.py +++ b/src/bonsai/bonsai/bim/module/model/opening.py @@ -1184,12 +1184,14 @@ class DecorationsHandler: bm.from_mesh(obj.data) verts = [tuple(obj.matrix_world @ v.co) for v in bm.verts] - edges = [tuple([v.index for v in e.verts]) for e in bm.edges] - ios_edges = [(edge[0], edge[1]) for edge in obj.data.get("ios_edges", [])] - if ios_edges: - edges = [e for e in edges if (e[0], e[1]) in ios_edges or (e[1], e[0]) in ios_edges] + if ios_edges_attribute := obj.data.attributes.get("ios_edges"): + edges = [e for i, e in enumerate(bm.edges) if ios_edges_attribute.data[i].value] + else: + edges = bm.edges + edges_indices = [tuple([v.index for v in e.verts]) for e in edges] + color = selected_elements_color if obj in context.selected_objects else special_elements_color - self.draw_batch("LINES", verts, color, edges) + self.draw_batch("LINES", verts, color, edges_indices) obj.data.calc_loop_triangles() tris = [tuple(t.vertices) for t in obj.data.loop_triangles] diff --git a/src/bonsai/bonsai/tool/loader.py b/src/bonsai/bonsai/tool/loader.py index 0c6ee5c385..745322f059 100644 --- a/src/bonsai/bonsai/tool/loader.py +++ b/src/bonsai/bonsai/tool/loader.py @@ -937,7 +937,8 @@ class Loader(bonsai.core.tool.Loader): # ios_edges holds true edges that aren't triangulated. # # we do `.tolist()` because Blender can't assign `np.int32` to it's custom attributes - mesh["ios_edges"] = list(set(tuple(e) for e in ifcopenshell.util.shape.get_edges(geometry).tolist())) + ios_edges = list(set(tuple(e) for e in ifcopenshell.util.shape.get_edges(geometry).tolist())) + mesh["ios_edges"] = ios_edges mesh["ios_item_ids"] = ifcopenshell.util.shape.get_faces_representation_item_ids(geometry).tolist() mesh.vertices.add(num_vertices) @@ -979,6 +980,20 @@ class Loader(bonsai.core.tool.Loader): # For now, not necessary to load maps in Item mode if rep.is_a("IfcShapeRepresentation"): tool.Loader.load_indexed_colour_map(rep, mesh) + + ios_edges_indices = [(e[0], e[1]) for e in ios_edges] + attribute_ios_edges = mesh.attributes.get("ios_edges") + if not attribute_ios_edges: + attribute_ios_edges = mesh.attributes.new("ios_edges", domain="EDGE", type="BOOLEAN") + + attribute_ios_edges.data.foreach_set( + "value", + [ + (e.vertices[0], e.vertices[1]) in ios_edges_indices + or (e.vertices[1], e.vertices[0]) in ios_edges_indices + for e in mesh.edges + ], + ) else: e = geometry.edges v = verts