diff --git a/src/bonsai/bonsai/bim/import_ifc.py b/src/bonsai/bonsai/bim/import_ifc.py index 87cebbb7f0..57d8a1b6b8 100644 --- a/src/bonsai/bonsai/bim/import_ifc.py +++ b/src/bonsai/bonsai/bim/import_ifc.py @@ -691,24 +691,15 @@ class IfcImporter: def create_structural_point_connections(self): for product in self.file.by_type("IfcStructuralPointConnection"): # TODO: make this based off ifcopenshell. See #1409 + representation: ifcopenshell.entity_instance = next( + rep for rep in product.Representation.Representations if rep.RepresentationType == "Vertex" + ) + mesh = tool.Loader.create_structural_point_connection_mesh(representation) + if mesh is None: + continue + tool.Ifc.link(representation, mesh) + placement_matrix = ifcopenshell.util.placement.get_local_placement(product.ObjectPlacement) - vertex = None - context = None - representation = None - for subelement in self.file.traverse(product.Representation): - if subelement.is_a("IfcVertex") and subelement.VertexGeometry.is_a("IfcCartesianPoint"): - vertex = list(subelement.VertexGeometry.Coordinates) - elif subelement.is_a("IfcGeometricRepresentationContext"): - context = subelement - elif subelement.is_a("IfcTopologyRepresentation"): - representation = subelement - if not vertex or not context or not representation: - continue # TODO implement non cartesian point vertexes - - mesh_name = tool.Geometry.get_representation_name(representation) - mesh = bpy.data.meshes.new(mesh_name) - mesh.from_pydata([mathutils.Vector(vertex) * self.unit_scale], [], []) - obj = bpy.data.objects.new(tool.Loader.get_name(product), mesh) self.set_matrix_world(obj, tool.Loader.apply_blender_offset_to_matrix_world(obj, placement_matrix)) self.link_element(product, obj) diff --git a/src/bonsai/bonsai/bim/module/geometry/operator.py b/src/bonsai/bonsai/bim/module/geometry/operator.py index 2c2427c08b..32f7616bbb 100644 --- a/src/bonsai/bonsai/bim/module/geometry/operator.py +++ b/src/bonsai/bonsai/bim/module/geometry/operator.py @@ -2754,7 +2754,15 @@ class ImportRepresentationItems(bpy.types.Operator, tool.Ifc.Operator): data = obj.data assert data - item_ids = data["ios_item_ids"] if "ios_item_ids" in data else data["ios_edges_item_ids"] + if "ios_item_ids" in data: # Has faces. + item_ids = data["ios_item_ids"] + elif "ios_edges_item_ids" in data: # Has edges. + item_ids = data["ios_edges_item_ids"] + elif "ios_verts_item_ids" in data: # Has only verts. + item_ids = data["ios_verts_item_ids"] + else: + assert False, "Unexpected mesh type." + queue = list(set(item_ids)) processed_ids = set() boolean_ids = set() diff --git a/src/bonsai/bonsai/tool/loader.py b/src/bonsai/bonsai/tool/loader.py index bd699c4d5d..f209b54bc4 100644 --- a/src/bonsai/bonsai/tool/loader.py +++ b/src/bonsai/bonsai/tool/loader.py @@ -763,6 +763,25 @@ class Loader(bonsai.core.tool.Loader): mesh.from_pydata(vertex_list, [], []) return mesh + @classmethod + def create_structural_point_connection_mesh( + cls, representation: ifcopenshell.entity_instance + ) -> Union[bpy.types.Mesh, None]: + item = representation.Items[0] + point = item.VertexGeometry + + # TODO implement non cartesian point vertices. + if not point.is_a("IfcCartesianPoint"): + return + + ifc_file = tool.Ifc.get() + co = np.array(point.Coordinates) * ifcopenshell.util.unit.calculate_unit_scale(ifc_file) + mesh_name = tool.Geometry.get_representation_name(representation) + mesh = bpy.data.meshes.new(mesh_name) + mesh.from_pydata([co], [], []) + mesh["ios_verts_item_ids"] = [item.id()] + return mesh + @classmethod def create_camera( cls,