From 47cf2ea29ed417b1d8d2b2802bd6570ad7f46c43 Mon Sep 17 00:00:00 2001 From: Laurens Oostwegel Date: Tue, 26 Oct 2021 00:04:49 +0200 Subject: [PATCH] BlenderBIM: import IFC PointCloud Representation (#1804) * Implemented export of point cloud representation * Do representation geometry data no-edge check before no-polygon check * Initial implementation import of point clouds in BlenderBIM * create point cloud elements on the appropriate place * Updated import_ifc.py based on review PR * delete is_pointcloud() because it is replaced by get_pointcloud_representation() --- src/blenderbim/blenderbim/bim/import_ifc.py | 61 +++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/src/blenderbim/blenderbim/bim/import_ifc.py b/src/blenderbim/blenderbim/bim/import_ifc.py index 2ae36395b8..c9e2a1fde9 100644 --- a/src/blenderbim/blenderbim/bim/import_ifc.py +++ b/src/blenderbim/blenderbim/bim/import_ifc.py @@ -590,6 +590,8 @@ class IfcImporter: self.create_generic_elements(self.elements) def create_generic_elements(self, elements): + products = self.create_pointclouds(elements) + elements -= products products = self.create_products(elements) elements -= products products = self.create_curve_products(elements) @@ -685,6 +687,65 @@ class IfcImporter: obj.matrix_world = self.apply_blender_offset_to_matrix_world(obj, placement_matrix) self.link_element(product, obj) + def get_pointcloud_representation(self, product): + if hasattr(product, 'Representation') and hasattr(product.Representation, 'Representations'): + representations = product.Representation.Representations + elif hasattr(product, "RepresentationMaps") and hasattr(product.RepresentationMaps, 'RepresentationMaps'): + representations = product.RepresentationMaps + else: + return None + + for representation in representations: + if representation.RepresentationType == 'PointCloud': + return representation + + elif self.file.schema == "IFC2X3" and representation.RepresentationType == 'GeometricSet': + for item in representation.Items: + if not (item.is_a("IfcCartesianPointList") or item.is_a("IfcCartesianPoint")): + break + else: + return representation + + elif representation.RepresentationType == 'MappedRepresentation': + for item in representation.Items: + mapped_representation = self.get_pointcloud_representation(item) + if mapped_representation is not None: + return mapped_representation + return None + + def create_pointclouds(self, products): + result = set() + for product in products: + representation = self.get_pointcloud_representation(product) + if representation is not None: + pointcloud = self.create_pointcloud(product, representation) + if pointcloud is not None: + result.add(pointcloud) + + return result + + def create_pointcloud(self, product, representation): + placement_matrix = ifcopenshell.util.placement.get_local_placement(product.ObjectPlacement) + vertex_list = [] + for item in representation.Items: + if item.is_a("IfcCartesianPointList"): + vertex_list.extend(mathutils.Vector(list(coordinates)) * self.unit_scale + for coordinates in item.CoordList) + elif item.is_a("IfcCartesianPoint"): + vertex_list.append(mathutils.Vector(list(item.Coordinates)) * self.unit_scale) + + if len(vertex_list) == 0: + return None + + mesh_name = f"{representation.ContextOfItems.id()}/{representation.id()}" + mesh = bpy.data.meshes.new(mesh_name) + mesh.from_pydata(vertex_list, [], []) + + obj = bpy.data.objects.new("{}/{}".format(product.is_a(), product.Name), mesh) + obj.matrix_world = self.apply_blender_offset_to_matrix_world(obj, placement_matrix) + self.link_element(product, obj) + return product + def create_curve_products(self, products): results = set() if not products: