From 97d34a706141e3903913bcc171b909fd22ac4060 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Fri, 29 Jan 2021 17:44:52 +1100 Subject: [PATCH] WIP unbreak drawing generation and support box context generation. See #1222. --- .../blenderbim/bim/import_ifc.py | 8 ++ .../bim/module/geometry/add_representation.py | 15 +++ .../bim/module/geometry/operator.py | 94 ++++++++++++++----- .../blenderbim/bim/operator.py | 10 +- 4 files changed, 98 insertions(+), 29 deletions(-) diff --git a/src/ifcblenderexport/blenderbim/bim/import_ifc.py b/src/ifcblenderexport/blenderbim/bim/import_ifc.py index f30847f97b..f7c67a801b 100644 --- a/src/ifcblenderexport/blenderbim/bim/import_ifc.py +++ b/src/ifcblenderexport/blenderbim/bim/import_ifc.py @@ -377,6 +377,8 @@ class IfcImporter: if self.ifc_import_settings.should_clean_mesh and len(self.file.by_type("IfcElement")) < 1000: self.clean_mesh() self.profile_code("Mesh cleaning") + self.set_default_context() + self.profile_code("Setting default context") def auto_set_workarounds(self): applications = self.file.by_type("IfcApplication") @@ -1539,6 +1541,12 @@ class IfcImporter: parent = self.get_local_placement(plc.PlacementRelTo) return parent @ self.get_axis2placement(plc.RelativePlacement) + def set_default_context(self): + for subcontext in self.file.by_type("IfcGeometricRepresentationSubContext"): + if subcontext.ContextIdentifier == "Body": + bpy.context.scene.BIMProperties.contexts = str(subcontext.id()) + break + class IfcImportSettings: def __init__(self): diff --git a/src/ifcblenderexport/blenderbim/bim/module/geometry/add_representation.py b/src/ifcblenderexport/blenderbim/bim/module/geometry/add_representation.py index 3e7c336658..7a3a195326 100644 --- a/src/ifcblenderexport/blenderbim/bim/module/geometry/add_representation.py +++ b/src/ifcblenderexport/blenderbim/bim/module/geometry/add_representation.py @@ -300,3 +300,18 @@ class Usecase: "GeometricCurveSet", [geometric_curve_set], ) + + def create_box_representation(self): + obj = self.settings["blender_object"] + bounding_box = self.file.createIfcBoundingBox( + self.create_cartesian_point(obj.bound_box[0][0], obj.bound_box[0][1], obj.bound_box[0][2]), + self.convert_si_to_unit(obj.dimensions[0]), + self.convert_si_to_unit(obj.dimensions[1]), + self.convert_si_to_unit(obj.dimensions[2]), + ) + return self.file.createIfcShapeRepresentation( + self.settings["context"], + self.settings["context"].ContextIdentifier, + "BoundingBox", + [bounding_box], + ) diff --git a/src/ifcblenderexport/blenderbim/bim/module/geometry/operator.py b/src/ifcblenderexport/blenderbim/bim/module/geometry/operator.py index acba9268f9..df71af77bd 100644 --- a/src/ifcblenderexport/blenderbim/bim/module/geometry/operator.py +++ b/src/ifcblenderexport/blenderbim/bim/module/geometry/operator.py @@ -1,6 +1,7 @@ import bpy import numpy as np import ifcopenshell +import ifcopenshell.util.element import logging import blenderbim.bim.module.geometry.edit_object_placement as edit_object_placement import blenderbim.bim.module.geometry.add_representation as add_representation @@ -11,6 +12,15 @@ import blenderbim.bim.module.geometry.remove_representation as remove_representa from blenderbim.bim.ifc import IfcStore from blenderbim.bim import import_ifc from blenderbim.bim.module.geometry.data import Data +from blenderbim.bim.module.context.data import Data as ContextData + + +def get_box_context_id(): + for context in ContextData.contexts.values(): + if context["ContextType"] == "Model": + for i, subcontext in context["HasSubContexts"].items(): + if subcontext["ContextIdentifier"] == "Box" and subcontext["TargetView"] == "MODEL_VIEW": + return i class EditObjectPlacement(bpy.types.Operator): @@ -76,20 +86,35 @@ class AddRepresentation(bpy.types.Operator): bpy.ops.bim.edit_object_placement(obj=obj.name) if obj.data: - result = add_representation.Usecase( - self.file, - { - "context": self.file.by_id(context_id), - "blender_object": obj, - "geometry": obj.data, - "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, - }, - ).execute() + product = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id) + context_of_items = self.file.by_id(context_id) + + representation_data = { + "context": context_of_items, + "blender_object": obj, + "geometry": obj.data, + "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 = add_representation.Usecase(self.file, representation_data).execute() + if not result: print("Failed to write shape representation") return {"FINISHED"} + + box_context_id = get_box_context_id() + if ( + box_context_id + and context_of_items.ContextType == "Model" + and context_of_items.ContextIdentifier + and context_of_items.ContextIdentifier == "Body" + ): + representation_data["context"] = self.file.by_id(box_context_id) + new_box = add_representation.Usecase(self.file, representation_data).execute() + assign_representation.Usecase(self.file, {"product": product, "representation": new_box}).execute() + assign_styles.Usecase( self.file, { @@ -102,10 +127,7 @@ class AddRepresentation(bpy.types.Operator): "should_use_presentation_style_assignment": context.scene.BIMGeometryProperties.should_use_presentation_style_assignment, }, ).execute() - assign_representation.Usecase( - self.file, - {"product": self.file.by_id(obj.BIMObjectProperties.ifc_definition_id), "representation": result}, - ).execute() + assign_representation.Usecase(self.file, {"product": product, "representation": result}).execute() existing_mesh = obj.data mesh = obj.data.copy() @@ -216,28 +238,48 @@ class UpdateMeshRepresentation(bpy.types.Operator): obj: bpy.props.StringProperty() def execute(self, context): + if not ContextData.is_loaded: + ContextData.load() + objs = [bpy.data.objects.get(self.obj)] if self.obj else bpy.context.selected_objects self.file = IfcStore.get_file() for obj in objs: bpy.ops.bim.edit_object_placement(obj=obj.name) + product = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id) old_representation = self.file.by_id(obj.data.BIMMeshProperties.ifc_definition_id) - new_representation = add_representation.Usecase( - self.file, - { - "context": old_representation.ContextOfItems, - "blender_object": obj, - "geometry": obj.data, - "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, - }, - ).execute() + context_of_items = old_representation.ContextOfItems + + representation_data = { + "context": context_of_items, + "blender_object": obj, + "geometry": obj.data, + "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, + } + + new_representation = add_representation.Usecase(self.file, representation_data).execute() + if not new_representation: print("Failed to write shape representation") return {"FINISHED"} + box_context_id = get_box_context_id() + old_box = ifcopenshell.util.element.get_representation(product, "Model", "Box", "MODEL_VIEW") + if ( + box_context_id + and old_box + and context_of_items.ContextType == "Model" + and context_of_items.ContextIdentifier + and context_of_items.ContextIdentifier == "Body" + ): + representation_data["context"] = self.file.by_id(box_context_id) + new_box = add_representation.Usecase(self.file, representation_data).execute() + for inverse in self.file.get_inverse(old_box): + ifcopenshell.util.element.replace_attribute(inverse, old_box, new_box) + assign_styles.Usecase( self.file, { diff --git a/src/ifcblenderexport/blenderbim/bim/operator.py b/src/ifcblenderexport/blenderbim/bim/operator.py index 9f3e4404c1..6f30063977 100644 --- a/src/ifcblenderexport/blenderbim/bim/operator.py +++ b/src/ifcblenderexport/blenderbim/bim/operator.py @@ -614,10 +614,14 @@ class CutSection(bpy.types.Operator): bpy.data.objects[name].hide_set(value) def does_obj_have_target_view_representation(self, obj, camera): - for representation in obj.BIMObjectProperties.representations: - element = self.file.by_id(representation.ifc_definition_id) + if not obj.BIMObjectProperties.ifc_definition_id: + return False + element = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id) + if not element.Representation: + return False + for representation in element.Representation.Representations: if ifcopenshell.util.element.is_representation_of_context( - element, "Plan", "Annotation", camera.data.BIMCameraProperties.target_view + representation, "Plan", "Annotation", camera.data.BIMCameraProperties.target_view ): return True