From 0842df0bde34b2c23a247d97990cb5b4d6743f18 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Thu, 29 Feb 2024 16:08:54 +1100 Subject: [PATCH] Purge all Python test code --- cmake/CMakeLists.txt | 2 - .../blenderbim/bim/module/project/__init__.py | 7 - .../blenderbim/bim/module/project/operator.py | 903 ------------------ 3 files changed, 912 deletions(-) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 8c623ddc03..c44f9ddc77 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -909,8 +909,6 @@ if(BUILD_IFCGEOM) file(GLOB SCHEMA_AGNOSTIC_CPP_FILES ../src/ifcgeom_schema_agnostic/*.cpp) set(SCHEMA_AGNOSTIC_FILES ${SCHEMA_AGNOSTIC_H_FILES} ${SCHEMA_AGNOSTIC_CPP_FILES}) - include_directories(/home/dion/.config/blender/4.0/scripts/addons/blenderbim/libs/site/packages/numpy/core/include) - add_library(IfcGeom ${SCHEMA_AGNOSTIC_FILES}) set_target_properties(IfcGeom PROPERTIES COMPILE_FLAGS -DIFC_GEOM_EXPORTS VERSION "${PROJECT_VERSION}" SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") diff --git a/src/blenderbim/blenderbim/bim/module/project/__init__.py b/src/blenderbim/blenderbim/bim/module/project/__init__.py index 19664b3c3d..d90470218f 100644 --- a/src/blenderbim/blenderbim/bim/module/project/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/project/__init__.py @@ -49,13 +49,6 @@ classes = ( operator.UnloadLink, operator.UnloadProject, operator.ReloadLink, - operator.xxx, - operator.zzz, - operator.zxc, - operator.aaa, - operator.asdfasdf, - operator.qwerqwer, - operator.qwerqwer2, operator.LoadLinkedProject, operator.QueryLinkedElement, operator.EnableCulling, diff --git a/src/blenderbim/blenderbim/bim/module/project/operator.py b/src/blenderbim/blenderbim/bim/module/project/operator.py index 34c93beec4..2ec1c28444 100644 --- a/src/blenderbim/blenderbim/bim/module/project/operator.py +++ b/src/blenderbim/blenderbim/bim/module/project/operator.py @@ -1173,412 +1173,6 @@ class ImportIFC(bpy.types.Operator): return {"FINISHED"} -class xxx(bpy.types.Operator): - bl_idname = "bim.xxx" - bl_label = "Load IFC no chunking" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - import time - import multiprocessing - import ifcopenshell.geom - import numpy as np - from mathutils import Matrix - import resource - - mem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000 - start = time.time() - - collection = bpy.data.collections.new("Project") - # ifc_file = ifcopenshell.open('/home/dion/test.ifc') - # ifc_file = ifcopenshell.open('/home/dion/drive/ifcs/racbasicsampleproject.ifc') - ifc_file = ifcopenshell.open("/home/dion/drive/ifcs/TXG_sample_project-fixed-IFC4.ifc") - - settings = ifcopenshell.geom.settings() - iterator = ifcopenshell.geom.iterator(settings, ifc_file, multiprocessing.cpu_count()) - meshes = {} - blender_mats = {} - if iterator.initialize(): - while True: - shape = iterator.get() - element = ifc_file.by_id(shape.id) - matrix = shape.transformation.matrix.data - faces = shape.geometry.faces - verts = shape.geometry.verts - materials = shape.geometry.materials - material_ids = shape.geometry.material_ids - - m = shape.transformation.matrix.data - mat = np.array( - ([m[0], m[3], m[6], m[9]], [m[1], m[4], m[7], m[10]], [m[2], m[5], m[8], m[11]], [0, 0, 0, 1]) - ) - - mesh = meshes.get(shape.geometry.id, None) - if not mesh: - mesh = bpy.data.meshes.new("Mesh") - - material_to_slot = {} - max_slot_index = 0 - - for i, material in enumerate(materials): - alpha = 1.0 - if material.has_transparency and material.transparency > 0: - alpha = 1.0 - material.transparency - diffuse = material.diffuse + (alpha,) - material_name = f"{diffuse[0]}-{diffuse[1]}-{diffuse[2]}-{diffuse[3]}" - blender_mat = blender_mats.get(material_name, None) - if not blender_mat: - blender_mat = bpy.data.materials.new(material_name) - blender_mat.diffuse_color = diffuse - blender_mats[material_name] = blender_mat - slot_index = mesh.materials.find(material.name) - if slot_index == -1: - mesh.materials.append(blender_mat) - slot_index = max_slot_index - max_slot_index += 1 - material_to_slot[i] = slot_index - - material_index = [(material_to_slot[i] if i != -1 else 0) for i in material_ids] - - num_vertices = len(verts) // 3 - total_faces = len(faces) - loop_start = range(0, total_faces, 3) - num_loops = total_faces // 3 - loop_total = [3] * num_loops - num_vertex_indices = len(faces) - - mesh.vertices.add(num_vertices) - mesh.vertices.foreach_set("co", verts) - mesh.loops.add(num_vertex_indices) - mesh.loops.foreach_set("vertex_index", faces) - mesh.polygons.add(num_loops) - mesh.polygons.foreach_set("loop_start", loop_start) - mesh.polygons.foreach_set("loop_total", loop_total) - mesh.polygons.foreach_set("use_smooth", [0] * total_faces) - mesh.polygons.foreach_set("material_index", material_index) - mesh.update() - - meshes[shape.geometry.id] = mesh - - obj = bpy.data.objects.new(tool.Loader.get_name(element), mesh) - obj.matrix_world = Matrix(mat.tolist()) - collection.objects.link(obj) - - if not iterator.next(): - break - - bpy.context.scene.collection.children.link(collection) - print("Finished", time.time() - start) - newmem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000 - print("Mem", newmem - mem) - return {"FINISHED"} - - -class zzz(bpy.types.Operator): - bl_idname = "bim.zzz" - bl_label = "Load H5 no chunking" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - import uuid - import h5py - import multiprocessing - import ifcopenshell - import ifcopenshell.geom - import numpy as np - import time - from mathutils import Matrix - import resource - - mem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000 - start = time.time() - - collection = bpy.data.collections.new("Project") - model = h5py.File("/home/dion/test3.h5", "r") - # model = h5py.File('/home/dion/cpp.h5', 'r') - # model = h5py.File('/home/dion/test5.h5', 'r') - # model = h5py.File('/home/dion/test4.h5', 'r') - # model = h5py.File('/home/dion/filename.h5', 'r') - - materials = {} - for i, rgb in enumerate(model["materials"]): - blender_mat = bpy.data.materials.new(str(i)) - blender_mat.diffuse_color = rgb[()].tolist() - materials[i] = blender_mat - - meshes = {} - for shape_id, shape in model["shapes"].items(): - mesh = bpy.data.meshes.new(shape_id) - meshes[int(shape_id)] = mesh - - for material in shape["materials"]: - mesh.materials.append(materials[material]) - - verts = shape["verts"][()].tolist() - faces = shape["faces"][()].tolist() - - num_vertices = len(verts) // 3 - total_faces = len(faces) - loop_start = range(0, total_faces, 3) - num_loops = total_faces // 3 - loop_total = [3] * num_loops - num_vertex_indices = len(faces) - - mesh.vertices.add(num_vertices) - mesh.vertices.foreach_set("co", verts) - mesh.loops.add(num_vertex_indices) - mesh.loops.foreach_set("vertex_index", faces) - mesh.polygons.add(num_loops) - mesh.polygons.foreach_set("loop_start", loop_start) - mesh.polygons.foreach_set("loop_total", loop_total) - mesh.polygons.foreach_set("use_smooth", [0] * total_faces) - - if "material_ids" in shape: - mesh.polygons.foreach_set("material_index", shape["material_ids"][()].tolist()) - - mesh.update() - - for i, global_id in enumerate(model["element_global_ids"]): - global_id = str(uuid.UUID(bytes=bytes(global_id))) - obj = bpy.data.objects.new(global_id, meshes[model["element_shape_ids"][i]]) - m = model["element_matrices"][i] - mat = np.array( - ([m[0], m[3], m[6], m[9]], [m[1], m[4], m[7], m[10]], [m[2], m[5], m[8], m[11]], [0, 0, 0, 1]) - ) - obj.matrix_world = Matrix(mat.tolist()) - collection.objects.link(obj) - - bpy.context.scene.collection.children.link(collection) - print("Finished", time.time() - start) - newmem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000 - print("Mem", newmem - mem) - return {"FINISHED"} - - -class zxc(bpy.types.Operator): - bl_idname = "bim.zxc" - bl_label = "Load H5 Python chunking" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - import uuid - import h5py - import multiprocessing - import ifcopenshell - import ifcopenshell.geom - import time - from mathutils import Matrix - import resource - - mem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000 - start = time.time() - - self.collection = bpy.data.collections.new("Project") - model = h5py.File("/home/dion/test3.h5", "r") - # model = h5py.File('/home/dion/test5.h5', 'r') - print("Opened", time.time() - start) - - materials = {} - for i, rgb in enumerate(model["materials"]): - blender_mat = bpy.data.materials.new(str(i)) - blender_mat.diffuse_color = rgb[()].tolist() - materials[i] = blender_mat - - print("Materials", time.time() - start) - - shapes = {} - for shape_id, shape in model["shapes"].items(): - verts = np.array(shape["verts"][()].tolist()) - faces = shape["faces"][()].tolist() - - shapes[int(shape_id)] = { - "verts": verts, - "faces": faces, - "materials": [materials[m] for m in shape["materials"]], - "material_ids": shape["material_ids"][()].tolist() if "material_ids" in shape else None, - } - - print("Shapes", time.time() - start) - - chunk_size = 10000 - - offset = 0 - material_offset = 0 - chunked_verts = [] - chunked_faces = [] - chunked_materials = [] - chunked_material_ids = [] - - for i, global_id in enumerate(model["element_global_ids"]): - global_id = str(uuid.UUID(bytes=bytes(global_id))) - m = model["element_matrices"][i] - mat = np.array( - ([m[0], m[3], m[6], m[9]], [m[1], m[4], m[7], m[10]], [m[2], m[5], m[8], m[11]], [0, 0, 0, 1]) - ) - - shape = shapes[model["element_shape_ids"][i]] - verts = self.apply_matrix_to_flat_list(shape["verts"], mat) - faces = [f + offset for f in shape["faces"]] - - chunked_verts.extend(verts) - chunked_faces.extend(faces) - - material_map = {} - for material_index, material in enumerate(shape["materials"]): - try: - chunked_index = chunked_materials.index(material) - except: - chunked_index = len(chunked_materials) - chunked_materials.append(material) - material_map[material_index] = chunked_index - - if shape["material_ids"] is None: - chunked_material_ids.extend([list(material_map.values())[0]] * (len(faces) // 3)) - else: - chunked_material_ids.extend([material_map[m] for m in shape["material_ids"]]) - - offset += len(verts) // 3 - material_offset += len(shape["materials"]) - - if offset > chunk_size: - print("Chunk at", i) - self.create_object(chunked_verts, chunked_faces, chunked_materials, chunked_material_ids) - chunked_verts = [] - chunked_faces = [] - chunked_materials = [] - chunked_material_ids = [] - offset = 0 - material_offset = 0 - - if offset: - self.create_object(chunked_verts, chunked_faces, chunked_materials, chunked_material_ids) - - bpy.context.scene.collection.children.link(self.collection) - print("Finished", time.time() - start) - newmem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000 - print("Mem", newmem - mem) - return {"FINISHED"} - - def apply_matrix_to_flat_list(self, flat_list, matrix): - # Convert the flat list to a 2D array with 3 columns (x, y, z) - vertices = np.array(flat_list).reshape(-1, 3) - # Add a column of ones for homogeneous coordinates (x, y, z, 1) - vertices = np.hstack([vertices, np.ones((vertices.shape[0], 1))]) - # Apply the matrix transformation - transformed_vertices = np.dot(vertices, matrix.T) - # Discard the homogeneous coordinate and flatten the array - return transformed_vertices[:, :3].flatten() - - def create_object(self, verts, faces, materials, material_ids): - num_vertices = len(verts) // 3 - total_faces = len(faces) - loop_start = range(0, total_faces, 3) - num_loops = total_faces // 3 - loop_total = [3] * num_loops - num_vertex_indices = len(faces) - - mesh = bpy.data.meshes.new("Mesh") - - for material in materials: - mesh.materials.append(material) - - mesh.vertices.add(num_vertices) - mesh.vertices.foreach_set("co", verts) - mesh.loops.add(num_vertex_indices) - mesh.loops.foreach_set("vertex_index", faces) - mesh.polygons.add(num_loops) - mesh.polygons.foreach_set("loop_start", loop_start) - mesh.polygons.foreach_set("loop_total", loop_total) - mesh.polygons.foreach_set("use_smooth", [0] * total_faces) - - if material_ids: - mesh.polygons.foreach_set("material_index", material_ids) - - mesh.update() - - obj = bpy.data.objects.new("Blah", mesh) - self.collection.objects.link(obj) - - -class aaa(bpy.types.Operator): - bl_idname = "bim.aaa" - bl_label = "Load H5 C++ chunking" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - import uuid - import h5py - import multiprocessing - import ifcopenshell - import ifcopenshell.geom - import time - from mathutils import Matrix - import resource - - mem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000 - start = time.time() - - tree = ifcopenshell.geom.tree() - x = tree.load_h5() - self.materials = {} - for i, m in enumerate(x.materials): - blender_mat = bpy.data.materials.new(str(i)) - blender_mat.diffuse_color = m - self.materials[i] = blender_mat - - self.collection = bpy.data.collections.new("Project") - - for e in x.elements: - # *' at 0x7f0f871a8ff1> > - # - # e.get_verts() - # e.get_verts() - # e.get_faces() - # self.create_object(e.verts, e.faces, e.get_materials(), e.get_material_ids()) # 14.7 - # self.create_object(list(e.verts), list(e.faces), e.get_materials(), e.get_material_ids()) # 8.9 - o = self.create_object(e.get_verts(), e.get_faces(), e.get_materials(), e.get_material_ids()) # 6.5 - o["guids"] = [ifcopenshell.guid.compress(g) for g in list(e.guids)] - o["guid_ids"] = list(e.guid_ids) - - bpy.context.scene.collection.children.link(self.collection) - print("Finished", time.time() - start) - newmem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1000 - print("Mem", newmem - mem) - return {"FINISHED"} - - def create_object(self, verts, faces, materials, material_ids): - num_vertices = len(verts) // 3 - total_faces = len(faces) - loop_start = range(0, total_faces, 3) - num_loops = total_faces // 3 - loop_total = [3] * num_loops - num_vertex_indices = len(faces) - - mesh = bpy.data.meshes.new("Mesh") - - for material in materials: - mesh.materials.append(self.materials[material]) - - mesh.vertices.add(num_vertices) - mesh.vertices.foreach_set("co", verts) - mesh.loops.add(num_vertex_indices) - mesh.loops.foreach_set("vertex_index", faces) - mesh.polygons.add(num_loops) - mesh.polygons.foreach_set("loop_start", loop_start) - mesh.polygons.foreach_set("loop_total", loop_total) - mesh.polygons.foreach_set("use_smooth", [0] * total_faces) - - if material_ids.size > 0: - mesh.polygons.foreach_set("material_index", material_ids) - - mesh.update() - - obj = bpy.data.objects.new("Blah", mesh) - self.collection.objects.link(obj) - - return obj - - class LoadLinkedProject(bpy.types.Operator): bl_idname = "bim.load_linked_project" bl_label = "Load a project for viewing only." @@ -2247,8 +1841,6 @@ class CreateClippingPlane(bpy.types.Operator): self.report({"INFO"}, "No object found.") return {"FINISHED"} - print(hit, location, normal, face_index, obj, matrix) - vertices = [(-0.5, -0.5, 0), (0.5, -0.5, 0), (0.5, 0.5, 0), (-0.5, 0.5, 0)] faces = [(0, 1, 2, 3)] @@ -2284,498 +1876,3 @@ class CreateClippingPlane(bpy.types.Operator): self.mouse_x = event.mouse_region_x self.mouse_y = event.mouse_region_y return self.execute(context) - - -class asdfasdf(bpy.types.Operator): - bl_idname = "bim.asdfasdf" - bl_label = "Load IFC C++ chunking" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - import ifcpatch - import multiprocessing - import ifcopenshell.geom - - start = time.time() - - # self.filepath = "/home/dion/drive/ifcs/racbasicsampleproject.ifc" - self.filepath = "/home/dion/drive/ifcs/TXG_sample_project-fixed-IFC4.ifc" - # self.filepath = "/home/dion/tmp/petrubug/F-ELECT.ifc" - print("doing", self.filepath) - - self.collection = bpy.data.collections.new("IfcProject/" + os.path.basename(self.filepath)) - self.file = ifcopenshell.open(self.filepath) - # self.file = ifcopenshell.open('/home/dion/test.ifc') - # self.file = ifcopenshell.open('/home/dion/drive/ifcs/TXG_sample_project-fixed-IFC4.ifc') - # self.file = ifcopenshell.open("/home/dion/tmp/petrubug/F-ELECT.ifc") - print("Finished opening") - start = time.time() - - logger = logging.getLogger("ImportIFC") - ifc_import_settings = import_ifc.IfcImportSettings.factory(context, IfcStore.path, logger) - ifc_importer = import_ifc.IfcImporter(ifc_import_settings) - ifc_importer.file = self.file - ifc_importer.process_context_filter() - - self.elements = set(self.file.by_type("IfcElement")) - if self.file.schema in ("IFC2X3", "IFC4"): - self.elements |= set(self.file.by_type("IfcProxy")) - self.elements |= set(self.file.by_type("IfcSite")) - self.elements -= set(self.file.by_type("IfcFeatureElement")) - self.elements = list(self.elements) - - for settings in ifc_importer.context_settings: - iterator = ifcopenshell.geom.iterator( - settings, self.file, multiprocessing.cpu_count(), include=self.elements - ) - self.meshes = {} - self.blender_mats = {} - - total_materials = 0 - self.materials = [] - - ci = 0 - if iterator.initialize(): - while True: - shape = iterator.get() - if iterator.process_chunk(): - has_processed_chunk = True - ci += 1 - if ci % 50 == 0: - print("Doing chunk", ci) - chunk = iterator.get_chunk() - - for colour in chunk.colours: - blender_mat = bpy.data.materials.new(str(total_materials)) - blender_mat.diffuse_color = list(colour) - self.materials.append(blender_mat) - total_materials += 1 - self.create_object(chunk) - - if not iterator.next(): - if not has_processed_chunk: - # The left over chunk - chunk = iterator.get_chunk() - for colour in chunk.colours: - blender_mat = bpy.data.materials.new(str(total_materials)) - blender_mat.diffuse_color = list(colour) - self.materials.append(blender_mat) - total_materials += 1 - self.create_object(chunk) - break - - bpy.context.scene.collection.children.link(self.collection) - print("Finished", time.time() - start) - break - return {"FINISHED"} - - def create_object(self, chunk): - verts = chunk.get_verts() - faces = chunk.get_faces() - materials = chunk.get_materials() - material_ids = chunk.get_material_ids() - - num_vertices = len(verts) // 3 - if not num_vertices: - return - total_faces = len(faces) - loop_start = range(0, total_faces, 3) - num_loops = total_faces // 3 - loop_total = [3] * num_loops - num_vertex_indices = len(faces) - - mesh = bpy.data.meshes.new("Mesh") - - for material in materials: - mesh.materials.append(self.materials[material]) - - mesh.vertices.add(num_vertices) - mesh.vertices.foreach_set("co", verts) - mesh.loops.add(num_vertex_indices) - mesh.loops.foreach_set("vertex_index", faces) - mesh.polygons.add(num_loops) - mesh.polygons.foreach_set("loop_start", loop_start) - mesh.polygons.foreach_set("loop_total", loop_total) - mesh.polygons.foreach_set("use_smooth", [0] * total_faces) - - if material_ids.size > 0: - mesh.polygons.foreach_set("material_index", material_ids) - - mesh.update() - - obj = bpy.data.objects.new("Chunk", mesh) - obj["guids"] = list(chunk.guids) - obj["guid_ids"] = list(chunk.guid_ids) - - self.collection.objects.link(obj) - - -class qwerqwer(bpy.types.Operator): - bl_idname = "bim.qwerqwer" - bl_label = "Load IFC Numpy chunking" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - import ifcpatch - import multiprocessing - import ifcopenshell.geom - - start = time.time() - - # self.filepath = "/home/dion/drive/ifcs/racbasicsampleproject.ifc" - # self.filepath = '/home/dion/drive/ifcs/TXG_sample_project-fixed-IFC4.ifc' - self.filepath = "/home/dion/tmp/petrubug/F-ELECT.ifc" - print("doing", self.filepath) - - self.collection = bpy.data.collections.new("IfcProject/" + os.path.basename(self.filepath)) - self.file = ifcopenshell.open(self.filepath) - # self.file = ifcopenshell.open('/home/dion/test.ifc') - # self.file = ifcopenshell.open('/home/dion/drive/ifcs/TXG_sample_project-fixed-IFC4.ifc') - # self.file = ifcopenshell.open("/home/dion/tmp/petrubug/F-ELECT.ifc") - print("Finished opening") - start = time.time() - - logger = logging.getLogger("ImportIFC") - ifc_import_settings = import_ifc.IfcImportSettings.factory(context, IfcStore.path, logger) - ifc_importer = import_ifc.IfcImporter(ifc_import_settings) - ifc_importer.file = self.file - ifc_importer.process_context_filter() - - self.elements = set(self.file.by_type("IfcElement")) - if self.file.schema in ("IFC2X3", "IFC4"): - self.elements |= set(self.file.by_type("IfcProxy")) - self.elements |= set(self.file.by_type("IfcSite")) - self.elements -= set(self.file.by_type("IfcFeatureElement")) - self.elements = list(self.elements) - - for settings in ifc_importer.context_settings: - iterator = ifcopenshell.geom.iterator( - settings, self.file, multiprocessing.cpu_count(), include=self.elements - ) - - default_mat = np.array([[1, 1, 1, 1]], dtype=np.float32) - - self.meshes = {} - blender_mats = {} - - chunked_verts = [] - chunked_faces = [] - chunked_materials = [] - chunked_material_ids = [] - material_offset = 0 - max_slot_index = 0 - chunk_size = 10000 - r4 = np.array([[0, 0, 0, 1]]) - offset = 0 - - ci = 0 - if iterator.initialize(): - while True: - shape = iterator.get() - - has_processed_chunk = False - - ms = np.vstack([default_mat, np.frombuffer(shape.geometry.colors_buffer).reshape((-1, 4))]) - mi = np.frombuffer(shape.geometry.material_ids_buffer, dtype=np.int32) - chunked_materials.append(ms) - chunked_material_ids.append(mi + material_offset + 1) - material_offset += len(ms) - - M4 = np.frombuffer(shape.transformation_buffer).reshape((4, 3)) - M4 = np.concatenate((M4.T, r4)) - vs = np.frombuffer(shape.geometry.verts_buffer).reshape((-1, 3)) - vs = np.hstack((vs, np.ones((len(vs), 1)))) - vs = (np.asmatrix(M4) * np.asmatrix(vs).T).T.A - vs = vs[:, :3].flatten() - fs = np.frombuffer(shape.geometry.faces_buffer, dtype=np.int32) - chunked_verts.append(vs) - chunked_faces.append(fs + offset) - offset += len(vs) // 3 - - if offset > chunk_size: - has_processed_chunk = True - - mats = np.concatenate(chunked_materials) - midx = np.concatenate(chunked_material_ids) - mats, mapping = np.unique(mats, axis=0, return_inverse=True) - midx = mapping[midx] - - mat_results = [] - for mat in mats: - mat = tuple(mat) - blender_mat = blender_mats.get(mat, None) - if not blender_mat: - blender_mat = bpy.data.materials.new("Chunk") - blender_mat.diffuse_color = mat - blender_mats[mat] = blender_mat - mat_results.append(blender_mat) - - self.create_object( - np.concatenate(chunked_verts), np.concatenate(chunked_faces), mat_results, midx - ) - chunked_verts = [] - chunked_faces = [] - chunked_materials = [] - chunked_material_ids = [] - material_offset = 0 - max_slot_index = 0 - offset = 0 - pass - - if not iterator.next(): - if not has_processed_chunk: - mats = np.concatenate(chunked_materials) - midx = np.concatenate(chunked_material_ids) - mats, mapping = np.unique(mats, axis=0, return_inverse=True) - midx = mapping[midx] - - mat_results = [] - for mat in mats: - mat = tuple(mat) - blender_mat = blender_mats.get(mat, None) - if not blender_mat: - blender_mat = bpy.data.materials.new("Chunk") - blender_mat.diffuse_color = mat - blender_mats[mat] = blender_mat - mat_results.append(blender_mat) - - # The left over chunk - self.create_object( - np.concatenate(chunked_verts), np.concatenate(chunked_faces), mat_results, midx - ) - break - - bpy.context.scene.collection.children.link(self.collection) - print("Finished", time.time() - start) - break - return {"FINISHED"} - - def create_object(self, verts, faces, materials, material_ids): - num_vertices = len(verts) // 3 - if not num_vertices: - return - total_faces = len(faces) - loop_start = range(0, total_faces, 3) - num_loops = total_faces // 3 - loop_total = [3] * num_loops - num_vertex_indices = len(faces) - - mesh = bpy.data.meshes.new("Mesh") - - for material in materials: - mesh.materials.append(material) - - mesh.vertices.add(num_vertices) - mesh.vertices.foreach_set("co", verts) - mesh.loops.add(num_vertex_indices) - mesh.loops.foreach_set("vertex_index", faces) - mesh.polygons.add(num_loops) - mesh.polygons.foreach_set("loop_start", loop_start) - mesh.polygons.foreach_set("loop_total", loop_total) - mesh.polygons.foreach_set("use_smooth", [0] * total_faces) - - if materials: - mesh.polygons.foreach_set("material_index", material_ids) - - mesh.update() - - obj = bpy.data.objects.new("Chunk", mesh) - - self.collection.objects.link(obj) - - -class qwerqwer2(bpy.types.Operator): - bl_idname = "bim.qwerqwer2" - bl_label = "Load IFC Python chunking" - bl_options = {"REGISTER", "UNDO"} - - def execute(self, context): - import ifcpatch - import multiprocessing - import ifcopenshell.geom - - start = time.time() - - # self.filepath = "/home/dion/drive/ifcs/racbasicsampleproject.ifc" - self.filepath = "/home/dion/drive/ifcs/TXG_sample_project-fixed-IFC4.ifc" - # self.filepath = "/home/dion/tmp/petrubug/F-ELECT.ifc" - print("doing", self.filepath) - - self.collection = bpy.data.collections.new("IfcProject/" + os.path.basename(self.filepath)) - self.file = ifcopenshell.open(self.filepath) - # self.file = ifcopenshell.open('/home/dion/test.ifc') - # self.file = ifcopenshell.open('/home/dion/drive/ifcs/TXG_sample_project-fixed-IFC4.ifc') - # self.file = ifcopenshell.open("/home/dion/tmp/petrubug/F-ELECT.ifc") - print("Finished opening") - start = time.time() - - logger = logging.getLogger("ImportIFC") - ifc_import_settings = import_ifc.IfcImportSettings.factory(context, IfcStore.path, logger) - ifc_importer = import_ifc.IfcImporter(ifc_import_settings) - ifc_importer.file = self.file - ifc_importer.process_context_filter() - - self.elements = set(self.file.by_type("IfcElement")) - if self.file.schema in ("IFC2X3", "IFC4"): - self.elements |= set(self.file.by_type("IfcProxy")) - self.elements |= set(self.file.by_type("IfcSite")) - self.elements -= set(self.file.by_type("IfcFeatureElement")) - self.elements = list(self.elements) - - for settings in ifc_importer.context_settings: - iterator = ifcopenshell.geom.iterator( - settings, self.file, multiprocessing.cpu_count(), include=self.elements - ) - - default_mat = bpy.data.materials.new("Default") - default_mat.diffuse_color = (1, 1, 1, 1) - - self.meshes = {} - blender_mats = {} - - total_materials = 0 - self.materials = [] - - chunked_verts = [] - chunked_faces = [] - chunked_materials = [] - chunked_material_ids = [] - max_slot_index = 0 - chunk_size = 10000 - r4 = np.array([[0, 0, 0, 1]]) - offset = 0 - - ci = 0 - if iterator.initialize(): - while True: - shape = iterator.get() - - materials = shape.geometry.materials - material_ids = shape.geometry.material_ids - # material_ids = np.frombuffer(shape.geometry.material_ids_buffer) - - material_to_slot = {} - - for i, material in enumerate(materials): - alpha = 1.0 - if material.has_transparency and material.transparency > 0: - alpha = 1.0 - material.transparency - diffuse = material.diffuse + (alpha,) - material_name = f"{diffuse[0]}-{diffuse[1]}-{diffuse[2]}-{diffuse[3]}" - blender_mat = blender_mats.get(material_name, None) - if not blender_mat: - blender_mat = bpy.data.materials.new(material_name) - blender_mat.diffuse_color = diffuse - blender_mats[material_name] = blender_mat - try: - slot_index = chunked_materials.index(blender_mat) - except ValueError: - chunked_materials.append(blender_mat) - slot_index = max_slot_index - max_slot_index += 1 - material_to_slot[i] = slot_index - - if not materials: - try: - slot_index = chunked_materials.index(default_mat) - except ValueError: - chunked_materials.append(default_mat) - slot_index = max_slot_index - max_slot_index += 1 - material_to_slot[-1] = slot_index - - # Numpy alternative - """ - # Convert material_to_slot dictionary to a NumPy array - max_material_id = max(material_to_slot.keys()) - material_to_slot_array = np.zeros(max_material_id + 1, dtype=int) - for material_id, slot in material_to_slot.items(): - material_to_slot_array[material_id] = slot - - # Efficiently map material_ids to slots using NumPy - material_ids = np.frombuffer(shape.geometry.material_ids_buffer, dtype=np.int32) # Ensure the dtype matches - mapped_material_ids = material_to_slot_array[material_ids] - - # Extend the chunked_material_ids list - chunked_material_ids.extend(mapped_material_ids) - """ - - chunked_material_ids.extend([material_to_slot[i] for i in material_ids]) - - has_processed_chunk = False - - m = shape.transformation.matrix.data - mat = np.array( - ([m[0], m[3], m[6], m[9]], [m[1], m[4], m[7], m[10]], [m[2], m[5], m[8], m[11]], [0, 0, 0, 1]) - ) - verts = self.apply_matrix_to_flat_list(shape.geometry.verts, mat) - faces = [f + offset for f in shape.geometry.faces] - chunked_verts.extend(verts) - chunked_faces.extend(faces) - - offset += len(verts) // 3 - - if offset > chunk_size: - has_processed_chunk = True - self.create_object(chunked_verts, chunked_faces, chunked_materials, chunked_material_ids) - chunked_verts = [] - chunked_faces = [] - chunked_materials = [] - chunked_material_ids = [] - max_slot_index = 0 - offset = 0 - pass - - if not iterator.next(): - if not has_processed_chunk: - # The left over chunk - self.create_object(chunked_verts, chunked_faces, chunked_materials, chunked_material_ids) - break - - bpy.context.scene.collection.children.link(self.collection) - print("Finished", time.time() - start) - break - return {"FINISHED"} - - def apply_matrix_to_flat_list(self, flat_list, matrix): - # Convert the flat list to a 2D array with 3 columns (x, y, z) - vertices = np.array(flat_list).reshape(-1, 3) - # Add a column of ones for homogeneous coordinates (x, y, z, 1) - vertices = np.hstack([vertices, np.ones((vertices.shape[0], 1))]) - # Apply the matrix transformation - transformed_vertices = np.dot(vertices, matrix.T) - # Discard the homogeneous coordinate and flatten the array - return transformed_vertices[:, :3].flatten() - - def create_object(self, verts, faces, materials, material_ids): - num_vertices = len(verts) // 3 - if not num_vertices: - return - total_faces = len(faces) - loop_start = range(0, total_faces, 3) - num_loops = total_faces // 3 - loop_total = [3] * num_loops - num_vertex_indices = len(faces) - - mesh = bpy.data.meshes.new("Mesh") - - for material in materials: - mesh.materials.append(material) - - mesh.vertices.add(num_vertices) - mesh.vertices.foreach_set("co", verts) - mesh.loops.add(num_vertex_indices) - mesh.loops.foreach_set("vertex_index", faces) - mesh.polygons.add(num_loops) - mesh.polygons.foreach_set("loop_start", loop_start) - mesh.polygons.foreach_set("loop_total", loop_total) - mesh.polygons.foreach_set("use_smooth", [0] * total_faces) - - if materials: - mesh.polygons.foreach_set("material_index", material_ids) - - mesh.update() - - obj = bpy.data.objects.new("Chunk", mesh) - - self.collection.objects.link(obj)