From cbce3cbec07a9218a19c9626ab9bb2af3819ba52 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Tue, 18 May 2021 16:41:30 +1000 Subject: [PATCH] Assigning a representation to a product type now syncs mapped representations of all of its typed products. --- .../bim/module/geometry/operator.py | 155 ++++++++++-------- .../api/geometry/assign_representation.py | 14 ++ 2 files changed, 97 insertions(+), 72 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/geometry/operator.py b/src/blenderbim/blenderbim/bim/module/geometry/operator.py index 87129ef6b0..87c33b5e5f 100644 --- a/src/blenderbim/blenderbim/bim/module/geometry/operator.py +++ b/src/blenderbim/blenderbim/bim/module/geometry/operator.py @@ -72,84 +72,95 @@ class AddRepresentation(bpy.types.Operator): bpy.ops.bim.edit_object_placement(obj=obj.name) - if obj.data: - product = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id) + if not obj.data: + return {"FINISHED"} - context_id = self.context_id or int(bpy.context.scene.BIMProperties.contexts) - context_of_items = self.file.by_id(context_id) + product = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id) - gprop = context.scene.BIMGeoreferenceProperties - coordinate_offset = None - if gprop.has_blender_offset and gprop.blender_offset_type == "CARTESIAN_POINT": - coordinate_offset = Vector( - ( - float(gprop.blender_eastings), - float(gprop.blender_northings), - float(gprop.blender_orthogonal_height), - ) + context_id = self.context_id or int(bpy.context.scene.BIMProperties.contexts) + context_of_items = self.file.by_id(context_id) + + gprop = context.scene.BIMGeoreferenceProperties + coordinate_offset = None + if gprop.has_blender_offset and gprop.blender_offset_type == "CARTESIAN_POINT": + coordinate_offset = Vector( + ( + float(gprop.blender_eastings), + float(gprop.blender_northings), + float(gprop.blender_orthogonal_height), ) - - representation_data = { - "context": context_of_items, - "blender_object": obj, - "geometry": obj.data, - "coordinate_offset": coordinate_offset, - "total_items": max(1, len(obj.material_slots)), - "should_force_faceted_brep": context.scene.BIMGeometryProperties.should_force_faceted_brep, - "should_force_triangulation": context.scene.BIMGeometryProperties.should_force_triangulation, - } - - result = ifcopenshell.api.run("geometry.add_representation", self.file, **representation_data) - - if not result: - print("Failed to write shape representation") - return {"FINISHED"} - - box_context_id = get_context_id("Model", "Box", "MODEL_VIEW") - old_box = ifcopenshell.util.representation.get_representation(product, "Model", "Box", "MODEL_VIEW") - if ( - box_context_id - and context_of_items.ContextType == "Model" - and context_of_items.ContextIdentifier - and context_of_items.ContextIdentifier == "Body" - ): - if old_box: - bpy.ops.bim.remove_representation(representation_id=old_box.id(), obj=obj.name) - representation_data["context"] = self.file.by_id(box_context_id) - new_box = ifcopenshell.api.run("geometry.add_representation", self.file, **representation_data) - ifcopenshell.api.run( - "geometry.assign_representation", self.file, **{"product": product, "representation": new_box} - ) - - [ - bpy.ops.bim.add_style(material=s.material.name) - for s in obj.material_slots - if s.material and not s.material.BIMMaterialProperties.ifc_style_id - ] - - ifcopenshell.api.run( - "geometry.assign_styles", - self.file, - **{ - "shape_representation": result, - "styles": [ - self.file.by_id(s.material.BIMMaterialProperties.ifc_style_id) - for s in obj.material_slots - if s.material - ], - "should_use_presentation_style_assignment": context.scene.BIMGeometryProperties.should_use_presentation_style_assignment, - }, - ) - ifcopenshell.api.run( - "geometry.assign_representation", self.file, **{"product": product, "representation": result} ) - existing_mesh = obj.data - mesh = obj.data.copy() - mesh.name = "{}/{}".format(context_id, result.id()) - mesh.BIMMeshProperties.ifc_definition_id = int(result.id()) - obj.data = mesh + representation_data = { + "context": context_of_items, + "blender_object": obj, + "geometry": obj.data, + "coordinate_offset": coordinate_offset, + "total_items": max(1, len(obj.material_slots)), + "should_force_faceted_brep": context.scene.BIMGeometryProperties.should_force_faceted_brep, + "should_force_triangulation": context.scene.BIMGeometryProperties.should_force_triangulation, + } + + result = ifcopenshell.api.run("geometry.add_representation", self.file, **representation_data) + + if not result: + print("Failed to write shape representation") + return {"FINISHED"} + + # TODO: Migrate to parametric engine system + box_context_id = get_context_id("Model", "Box", "MODEL_VIEW") + old_box = ifcopenshell.util.representation.get_representation(product, "Model", "Box", "MODEL_VIEW") + if ( + box_context_id + and context_of_items.ContextType == "Model" + and context_of_items.ContextIdentifier + and context_of_items.ContextIdentifier == "Body" + ): + if old_box: + bpy.ops.bim.remove_representation(representation_id=old_box.id(), obj=obj.name) + representation_data["context"] = self.file.by_id(box_context_id) + new_box = ifcopenshell.api.run("geometry.add_representation", self.file, **representation_data) + ifcopenshell.api.run( + "geometry.assign_representation", self.file, **{"product": product, "representation": new_box} + ) + + [ + bpy.ops.bim.add_style(material=s.material.name) + for s in obj.material_slots + if s.material and not s.material.BIMMaterialProperties.ifc_style_id + ] + + ifcopenshell.api.run( + "geometry.assign_styles", + self.file, + **{ + "shape_representation": result, + "styles": [ + self.file.by_id(s.material.BIMMaterialProperties.ifc_style_id) + for s in obj.material_slots + if s.material + ], + "should_use_presentation_style_assignment": context.scene.BIMGeometryProperties.should_use_presentation_style_assignment, + }, + ) + ifcopenshell.api.run( + "geometry.assign_representation", self.file, **{"product": product, "representation": result} + ) + + existing_mesh = obj.data + mesh = obj.data.copy() + mesh.name = "{}/{}".format(context_id, result.id()) + mesh.BIMMeshProperties.ifc_definition_id = int(result.id()) + obj.data = mesh Data.load(IfcStore.get_file(), obj.BIMObjectProperties.ifc_definition_id) + + if self.file.schema == "IFC2X3": + types = product.ObjectTypeOf + else: + types = product.Types + if product.is_a("IfcTypeProduct") and types: + for element in types[0].RelatedObjects: + Data.load(IfcStore.get_file(), element.id()) return {"FINISHED"} diff --git a/src/ifcopenshell-python/ifcopenshell/api/geometry/assign_representation.py b/src/ifcopenshell-python/ifcopenshell/api/geometry/assign_representation.py index 1835bfbe39..2e09ed9586 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/geometry/assign_representation.py +++ b/src/ifcopenshell-python/ifcopenshell/api/geometry/assign_representation.py @@ -35,4 +35,18 @@ class Usecase: ) ) self.settings["product"].RepresentationMaps = maps + if self.file.schema == "IFC2X3": + types = self.settings["product"].ObjectTypeOf + else: + types = self.settings["product"].Types + if types: + for element in types[0].RelatedObjects: + mapped_representation = ifcopenshell.api.run( + "geometry.map_representation", self.file, **{"representation": self.settings["representation"]} + ) + ifcopenshell.api.run( + "geometry.assign_representation", + self.file, + **{"product": element, "representation": mapped_representation} + ) ifcopenshell.api.run("owner.update_owner_history", self.file, **{"element": self.settings["product"]})