From fbaa6cd2ed98390d2a5d977ab7b1c81bae0c5135 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Tue, 7 Jul 2020 12:33:41 +1000 Subject: [PATCH] New UI to assign constraints to objects and export --- .../blenderbim/bim/__init__.py | 4 ++ .../blenderbim/bim/export_ifc.py | 24 +++++----- .../blenderbim/bim/operator.py | 37 ++++++++++++++ src/ifcblenderexport/blenderbim/bim/prop.py | 2 + src/ifcblenderexport/blenderbim/bim/ui.py | 48 +++++++++++++++++++ 5 files changed, 102 insertions(+), 13 deletions(-) diff --git a/src/ifcblenderexport/blenderbim/bim/__init__.py b/src/ifcblenderexport/blenderbim/bim/__init__.py index 60e39b716f..efb70cbdbf 100644 --- a/src/ifcblenderexport/blenderbim/bim/__init__.py +++ b/src/ifcblenderexport/blenderbim/bim/__init__.py @@ -60,6 +60,9 @@ if bpy is not None: operator.RemoveMaterialPset, operator.AddConstraint, operator.RemoveConstraint, + operator.AssignConstraint, + operator.UnassignConstraint, + operator.RemoveObjectConstraint, operator.AddDocumentInformation, operator.RemoveDocumentInformation, operator.AssignDocumentInformation, @@ -205,6 +208,7 @@ if bpy is not None: ui.BIM_PT_representations, ui.BIM_PT_classification_references, ui.BIM_PT_documents, + ui.BIM_PT_constraint_relations, ui.BIM_PT_camera, ui.BIM_PT_text, ui.BIM_UL_clash_sets, diff --git a/src/ifcblenderexport/blenderbim/bim/export_ifc.py b/src/ifcblenderexport/blenderbim/bim/export_ifc.py index 7b828fcfc4..e29dea462c 100644 --- a/src/ifcblenderexport/blenderbim/bim/export_ifc.py +++ b/src/ifcblenderexport/blenderbim/bim/export_ifc.py @@ -115,8 +115,8 @@ class IfcParser(): self.rel_associates_material_layer_set = {} self.rel_associates_material_constituent_set = {} self.rel_associates_material_profile_set = {} - self.rel_associates_constraint_objective_object = {} - self.rel_associates_constraint_objective_type = {} + self.rel_associates_constraint_object = {} + self.rel_associates_constraint_type = {} self.rel_aggregates = {} self.rel_voids_elements = {} self.rel_fills_elements = {} @@ -472,10 +472,9 @@ class IfcParser(): self.rel_associates_classification_object.setdefault( classification.name, []).append(product) - for key in obj.keys(): - if key[0:9] == 'Objective': - self.rel_associates_constraint_objective_object.setdefault( - obj[key], []).append(product) + for constraint in obj.BIMObjectProperties.constraints: + self.rel_associates_constraint_object.setdefault( + constraint.name, []).append(product) for slot in obj.material_slots: if slot.material is None or slot.link == 'OBJECT': @@ -1203,8 +1202,7 @@ class IfcExporter(): self.relate_to_documents(self.ifc_parser.rel_associates_document_type) self.relate_to_classifications(self.ifc_parser.rel_associates_classification_object) self.relate_to_classifications(self.ifc_parser.rel_associates_classification_type) - self.relate_to_objectives(self.ifc_parser.rel_associates_constraint_objective_object) - self.relate_to_objectives(self.ifc_parser.rel_associates_constraint_objective_type) + self.relate_to_constraints(self.ifc_parser.rel_associates_constraint_object) self.relate_structural_members_to_connections() self.relate_objects_to_groups() self.write_ifc_file() @@ -1401,9 +1399,9 @@ class IfcExporter(): reference['ifc'] = self.file.add(reference['raw_element']) def create_constraints(self): - for objective in self.ifc_parser.constraints.values(): - objective['ifc'] = self.file.create_entity( - 'IfcObjective', **objective['attributes']) + for constraint in self.ifc_parser.constraints.values(): + constraint['ifc'] = self.file.create_entity( + 'IfcObjective', **constraint['attributes']) def create_psets(self): for pset in self.ifc_parser.psets.values(): @@ -2704,12 +2702,12 @@ class IfcExporter(): [o['ifc'] for o in related_objects], self.ifc_parser.classification_references[relating_key]['ifc']) - def relate_to_objectives(self, relationships): + def relate_to_constraints(self, relationships): for relating_key, related_objects in relationships.items(): self.file.createIfcRelAssociatesConstraint( ifcopenshell.guid.new(), self.owner_history, None, None, [o['ifc'] for o in related_objects], None, - self.ifc_parser.objectives[relating_key]['ifc']) + self.ifc_parser.constraints[relating_key]['ifc']) def relate_structural_members_to_connections(self): for relating_member, relating_connection in self.ifc_parser.rel_connects_structural_member.items(): diff --git a/src/ifcblenderexport/blenderbim/bim/operator.py b/src/ifcblenderexport/blenderbim/bim/operator.py index 065754b9ac..24f42720f0 100644 --- a/src/ifcblenderexport/blenderbim/bim/operator.py +++ b/src/ifcblenderexport/blenderbim/bim/operator.py @@ -840,6 +840,43 @@ class RemoveConstraint(bpy.types.Operator): return {'FINISHED'} +class AssignConstraint(bpy.types.Operator): + bl_idname = 'bim.assign_constraint' + bl_label = 'Assign Constraint' + + def execute(self, context): + identification = bpy.context.scene.BIMProperties.constraints[bpy.context.scene.BIMProperties.active_constraint_index].name + for obj in bpy.context.selected_objects: + if obj.BIMObjectProperties.constraints.get(identification): + continue + constraint = obj.BIMObjectProperties.constraints.add() + constraint.name = identification + return {'FINISHED'} + + +class UnassignConstraint(bpy.types.Operator): + bl_idname = 'bim.unassign_constraint' + bl_label = 'Unassign Constraint' + + def execute(self, context): + identification = bpy.context.scene.BIMProperties.constraints[bpy.context.scene.BIMProperties.active_constraint_index].name + for obj in bpy.context.selected_objects: + index = obj.BIMObjectProperties.constraints.find(identification) + if index >= 0: + obj.BIMObjectProperties.constraints.remove(index) + return {'FINISHED'} + + +class RemoveObjectConstraint(bpy.types.Operator): + bl_idname = 'bim.remove_object_constraint' + bl_label = 'Remove Object Constraint' + index: bpy.props.IntProperty() + + def execute(self, context): + bpy.context.active_object.BIMObjectProperties.constraints.remove(self.index) + return {'FINISHED'} + + class AddDocumentInformation(bpy.types.Operator): bl_idname = 'bim.add_document_information' bl_label = 'Add Document Information' diff --git a/src/ifcblenderexport/blenderbim/bim/prop.py b/src/ifcblenderexport/blenderbim/bim/prop.py index 656f9e3ab8..3d01a0b806 100644 --- a/src/ifcblenderexport/blenderbim/bim/prop.py +++ b/src/ifcblenderexport/blenderbim/bim/prop.py @@ -1077,6 +1077,8 @@ class BIMObjectProperties(PropertyGroup): applicable_attributes: EnumProperty(items=getApplicableAttributes, name="Attribute Names") document_references: CollectionProperty(name="Document References", type=DocumentReference) active_document_reference_index: IntProperty(name='Active Document Reference Index') + constraints: CollectionProperty(name='Constraints', type=Constraint) + active_constraint_index: IntProperty(name='Active Constraint Index') classifications: CollectionProperty(name="Classifications", type=ClassificationReference) material_type: EnumProperty(items=getMaterialTypes, name="Material Type") pset_name: EnumProperty(items=getPsetNames, name='Pset Name') diff --git a/src/ifcblenderexport/blenderbim/bim/ui.py b/src/ifcblenderexport/blenderbim/bim/ui.py index 4e7b5bcad0..24315f7d9d 100644 --- a/src/ifcblenderexport/blenderbim/bim/ui.py +++ b/src/ifcblenderexport/blenderbim/bim/ui.py @@ -242,6 +242,10 @@ class BIM_PT_constraints(Panel): row = layout.row() row.prop(constraint, 'user_defined_qualifier') + row = layout.row(align=True) + row.operator('bim.assign_constraint', text='Assign Constraint') + row.operator('bim.unassign_constraint', text='Unassign Constraint') + class BIM_PT_documents(Panel): bl_label = 'IFC Documents' @@ -284,6 +288,50 @@ class BIM_PT_documents(Panel): layout.label(text="Reference is invalid") +class BIM_PT_constraint_relations(Panel): + bl_label = 'IFC Constraints' + bl_idname = 'BIM_PT_constraint_relations' + bl_options = {'DEFAULT_CLOSED'} + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = 'object' + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + props = context.active_object.BIMObjectProperties + + if not props.constraints: + layout.label(text="No constraints found") + + if props.constraints: + layout.template_list('BIM_UL_constraints', '', props, 'constraints', props, 'active_constraint_index') + + if props.active_constraint_index < len(props.constraints): + constraint = props.constraints[props.active_constraint_index] + row = layout.row(align=True) + row.prop(constraint, 'name') + if constraint.name in bpy.context.scene.BIMProperties.constraints: + constraint = bpy.context.scene.BIMProperties.constraints[constraint.name] + row.operator('bim.remove_object_constraint', icon='X', text='').index = props.active_constraint_index + row = layout.row() + row.prop(constraint, 'description') + row = layout.row() + row.prop(constraint, 'constraint_grade') + if constraint.constraint_grade == 'USERDEFINED': + row = layout.row() + row.prop(constraint, 'user_defined_grade') + row = layout.row() + row.prop(constraint, 'constraint_source') + row = layout.row() + row.prop(constraint, 'objective_qualifier') + if constraint.objective_qualifier == 'USERDEFINED': + row = layout.row() + row.prop(constraint, 'user_defined_qualifier') + else: + layout.label(text="Constraint is invalid") + + class BIM_PT_representations(Panel): bl_label = 'IFC Representations' bl_idname = 'BIM_PT_representations'