From fda508e3f861c7db5f1ae40366c28153fc56e25f Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Mon, 6 Jul 2020 17:26:38 +1000 Subject: [PATCH] New UI to manage IFC constraints in the file --- .../blenderbim/bim/__init__.py | 5 ++ .../blenderbim/bim/operator.py | 20 ++++++++ src/ifcblenderexport/blenderbim/bim/prop.py | 32 ++++++++++++ src/ifcblenderexport/blenderbim/bim/ui.py | 49 +++++++++++++++++++ 4 files changed, 106 insertions(+) diff --git a/src/ifcblenderexport/blenderbim/bim/__init__.py b/src/ifcblenderexport/blenderbim/bim/__init__.py index 6cc07c067b..60e39b716f 100644 --- a/src/ifcblenderexport/blenderbim/bim/__init__.py +++ b/src/ifcblenderexport/blenderbim/bim/__init__.py @@ -58,6 +58,8 @@ if bpy is not None: operator.RemoveQto, operator.AddMaterialPset, operator.RemoveMaterialPset, + operator.AddConstraint, + operator.RemoveConstraint, operator.AddDocumentInformation, operator.RemoveDocumentInformation, operator.AssignDocumentInformation, @@ -154,6 +156,7 @@ if bpy is not None: prop.DocumentReference, prop.ClashSource, prop.ClashSet, + prop.Constraint, prop.BcfTopic, prop.BcfTopicLabel, prop.BcfTopicFile, @@ -184,6 +187,7 @@ if bpy is not None: ui.BIM_PT_psets, ui.BIM_PT_classifications, ui.BIM_PT_document_information, + ui.BIM_PT_constraints, ui.BIM_PT_search, ui.BIM_PT_ifccsv, ui.BIM_PT_ifcclash, @@ -204,6 +208,7 @@ if bpy is not None: ui.BIM_PT_camera, ui.BIM_PT_text, ui.BIM_UL_clash_sets, + ui.BIM_UL_constraints, ui.BIM_UL_document_information, ui.BIM_UL_document_references, ui.BIM_UL_topics, diff --git a/src/ifcblenderexport/blenderbim/bim/operator.py b/src/ifcblenderexport/blenderbim/bim/operator.py index 49e1497acb..065754b9ac 100644 --- a/src/ifcblenderexport/blenderbim/bim/operator.py +++ b/src/ifcblenderexport/blenderbim/bim/operator.py @@ -820,6 +820,26 @@ class RemoveMaterialPset(bpy.types.Operator): return {'FINISHED'} +class AddConstraint(bpy.types.Operator): + bl_idname = 'bim.add_constraint' + bl_label = 'Add Constraint' + + def execute(self, context): + constraint = bpy.context.scene.BIMProperties.constraints.add() + constraint.name = 'New Constraint' + return {'FINISHED'} + + +class RemoveConstraint(bpy.types.Operator): + bl_idname = 'bim.remove_constraint' + bl_label = 'Remove Constraint' + index: bpy.props.IntProperty() + + def execute(self, context): + bpy.context.scene.BIMProperties.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 bacd160eb2..656f9e3ab8 100644 --- a/src/ifcblenderexport/blenderbim/bim/prop.py +++ b/src/ifcblenderexport/blenderbim/bim/prop.py @@ -483,6 +483,36 @@ class ClashSet(PropertyGroup): b: CollectionProperty(name='Group B', type=ClashSource) +class Constraint(PropertyGroup): + name: StringProperty(name='Name') + description: StringProperty(name='Description') + constraint_grade: EnumProperty(items=[ + ('HARD', 'HARD', 'Qualifies a constraint such that it must be followed rigidly within or at the values set.'), + ('SOFT', 'SOFT', 'Qualifies a constraint such that it should be followed within or at the values set.'), + ('ADVISORY', 'ADVISORY', 'Qualifies a constraint such that it is advised that it is followed within or at the values set.'), + ('USERDEFINED', 'USERDEFINED', 'A user-defined grade indicated by a separate attribute at the referencing entity.'), + ('NOTDEFINED', 'NOTDEFINED', 'Grade has not been specified.'), + ], name='Grade') + constraint_source: StringProperty(name='Source') + user_defined_grade: StringProperty(name='Custom Grade') + objective_qualifier: EnumProperty(items=[ + ('CODECOMPLIANCE', 'CODECOMPLIANCE', 'A constraint whose objective is to ensure satisfaction of a code compliance provision.'), + ('CODEWAIVER', 'CODEWAIVER', 'A constraint whose objective is to identify an agreement that code compliance requirements (the waiver) will not be enforced.'), + ('DESIGNINTENT', 'DESIGNINTENT', 'A constraint whose objective is to ensure satisfaction of a design intent provision.'), + ('EXTERNAL', 'EXTERNAL', 'A constraint whose objective is to synchronize data with an external source such as a file'), + ('HEALTHANDSAFETY', 'HEALTHANDSAFETY', 'A constraint whose objective is to ensure satisfaction of a health and safety provision.'), + ('MERGECONFLICT', 'MERGECONFLICT', 'A constraint whose objective is to resolve a conflict such as merging data from multiple sources.'), + ('MODELVIEW', 'MODELVIEW', 'A constraint whose objective is to ensure data conforms to a model view definition.'), + ('PARAMETER', 'PARAMETER', 'A constraint whose objective is to calculate a value based on other referenced values.'), + ('REQUIREMENT', 'REQUIREMENT', 'A constraint whose objective is to ensure satisfaction of a project requirement provision.'), + ('SPECIFICATION', 'SPECIFICATION', 'A constraint whose objective is to ensure satisfaction of a specification provision.'), + ('TRIGGERCONDITION', 'TRIGGERCONDITION', 'A constraint whose objective is to indicate a limiting value beyond which the condition of an object requires a particular form of attention.'), + ('USERDEFINED', 'USERDEFINED', ''), + ('NOTDEFINED', 'NOTDEFINED', '') + ], name='Qualifier') + user_defined_qualifier: StringProperty(name='Custom Qualifier') + + class BcfTopic(PropertyGroup): name: StringProperty(name='Name') @@ -956,6 +986,8 @@ class BIMProperties(PropertyGroup): active_document_reference_index: IntProperty(name='Active Document Reference Index') clash_sets: CollectionProperty(name='Clash Sets', type=ClashSet) active_clash_set_index: IntProperty(name='Active Clash Set Index') + constraints: CollectionProperty(name='Constraints', type=Constraint) + active_constraint_index: IntProperty(name='Active Constraint Index') class BCFProperties(PropertyGroup): diff --git a/src/ifcblenderexport/blenderbim/bim/ui.py b/src/ifcblenderexport/blenderbim/bim/ui.py index 2638c9a195..4e7b5bcad0 100644 --- a/src/ifcblenderexport/blenderbim/bim/ui.py +++ b/src/ifcblenderexport/blenderbim/bim/ui.py @@ -203,6 +203,46 @@ class BIM_PT_document_information(Panel): row.operator('bim.unassign_document_reference', text='Unassign Reference') +class BIM_PT_constraints(Panel): + bl_label = 'IFC Constraints' + bl_idname = 'BIM_PT_constraints' + bl_options = {'DEFAULT_CLOSED'} + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = 'scene' + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + props = context.scene.BIMProperties + + row = layout.row() + row.operator('bim.add_constraint') + + 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') + row.operator('bim.remove_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') + + class BIM_PT_documents(Panel): bl_label = 'IFC Documents' bl_idname = 'BIM_PT_documents' @@ -1283,6 +1323,15 @@ class BIM_UL_clash_sets(bpy.types.UIList): layout.label(text="", translate=False) +class BIM_UL_constraints(bpy.types.UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_propname): + ob = data + if item: + layout.prop(item, 'name', text='', emboss=False) + else: + layout.label(text="", translate=False) + + class BIM_UL_document_information(bpy.types.UIList): def draw_item(self, context, layout, data, item, icon, active_data, active_propname): ob = data