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()
This commit is contained in:
Laurens Oostwegel
2021-10-26 00:04:49 +02:00
committed by GitHub
parent 9d8074f1fe
commit 47cf2ea29e
@@ -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: