From 2d0d0ed7862b2224b4b21b42c583b58ec636062f Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Fri, 1 Nov 2019 17:44:10 +1100 Subject: [PATCH] New UI to add and remove classifications --- .../io_export_ifc/__init__.py | 7 +++ .../io_export_ifc/export_ifc.py | 9 ++-- .../io_export_ifc/operator.py | 32 +++++++++++++ src/ifcblenderexport/io_export_ifc/ui.py | 46 +++++++++++++++++++ 4 files changed, 90 insertions(+), 4 deletions(-) diff --git a/src/ifcblenderexport/io_export_ifc/__init__.py b/src/ifcblenderexport/io_export_ifc/__init__.py index bd47d3bcba..c5b971cdc1 100644 --- a/src/ifcblenderexport/io_export_ifc/__init__.py +++ b/src/ifcblenderexport/io_export_ifc/__init__.py @@ -44,12 +44,19 @@ classes = ( operator.RemoveAttribute, operator.QuickProjectSetup, operator.SelectGlobalId, + operator.CreateAggregate, + operator.EditAggregate, + operator.SaveAggregate, + operator.AssignClassification, + operator.UnassignClassification, + operator.RemoveClassification, ui.BIMProperties, ui.MapConversion, ui.TargetCRS, ui.Attribute, ui.Pset, ui.Document, + ui.Classification, ui.BIMObjectProperties, ui.BIMMaterialProperties, ui.BIMMeshProperties, diff --git a/src/ifcblenderexport/io_export_ifc/export_ifc.py b/src/ifcblenderexport/io_export_ifc/export_ifc.py index 7743f8320f..8c6c6deadb 100644 --- a/src/ifcblenderexport/io_export_ifc/export_ifc.py +++ b/src/ifcblenderexport/io_export_ifc/export_ifc.py @@ -279,11 +279,12 @@ class IfcParser(): self.rel_associates_document_object.setdefault( document.file, []).append(product) + for classification in object.BIMObjectProperties.classifications: + self.rel_associates_classification_object.setdefault( + classification.identification, []).append(product) + for key in object.keys(): - if key[0:5] == 'Class': - self.rel_associates_classification_object.setdefault( - object[key], []).append(product) - elif key[0:9] == 'Objective': + if key[0:9] == 'Objective': self.rel_associates_constraint_objective_object.setdefault( object[key], []).append(product) diff --git a/src/ifcblenderexport/io_export_ifc/operator.py b/src/ifcblenderexport/io_export_ifc/operator.py index ea19159ca3..73c0036ff6 100644 --- a/src/ifcblenderexport/io_export_ifc/operator.py +++ b/src/ifcblenderexport/io_export_ifc/operator.py @@ -503,3 +503,35 @@ class SaveAggregate(bpy.types.Operator): if obj.instance_collection == aggregate: obj.hide_viewport = False return {'FINISHED'} + +class AssignClassification(bpy.types.Operator): + bl_idname = 'bim.assign_classification' + bl_label = 'Assign Classification' + + def execute(self, context): + for obj in bpy.context.selected_objects: + classification = obj.BIMObjectProperties.classifications.add() + classification.identification = bpy.context.scene.BIMProperties.reference + return {'FINISHED'} + +class UnassignClassification(bpy.types.Operator): + bl_idname = 'bim.unassign_classification' + bl_label = 'Unassign Classification' + + def execute(self, context): + for obj in bpy.context.selected_objects: + index = object.BIMObjectProperties.classifications.find(bpy.context.scene.BIMProperties.classification) + if index != -1: + object.BIMObjectProperties.classifications.remove(index) + + obj.BIMObjectProperties.classification = '' + return {'FINISHED'} + +class RemoveClassification(bpy.types.Operator): + bl_idname = 'bim.remove_classification' + bl_label = 'Remove Classification' + classification_index: bpy.props.IntProperty() + + def execute(self, context): + bpy.context.active_object.BIMObjectProperties.classifications.remove(self.classification_index) + return {'FINISHED'} diff --git a/src/ifcblenderexport/io_export_ifc/ui.py b/src/ifcblenderexport/io_export_ifc/ui.py index 52566ea949..ad1f4353a9 100644 --- a/src/ifcblenderexport/io_export_ifc/ui.py +++ b/src/ifcblenderexport/io_export_ifc/ui.py @@ -1,6 +1,7 @@ import bpy import json import os +import csv from pathlib import Path cwd = os.path.dirname(os.path.realpath(__file__)) + os.path.sep @@ -36,6 +37,22 @@ class BIMProperties(bpy.types.PropertyGroup): files = os.listdir(bpy.context.scene.BIMProperties.data_dir + 'pset/{}/'.format(bpy.context.scene.BIMProperties.pset_name)) return [(f.replace('.csv', ''), f.replace('.csv', ''), '') for f in files] + def getClassifications(self, context): + with open(bpy.context.scene.BIMProperties.data_dir + 'class/classifications.csv', 'r') as f: + data = list(csv.reader(f)) + keys = data.pop(0) + index = keys.index('Name') + return [(str(i), d[index], '') for i, d in enumerate(data)] + + def getReferences(self, context): + if not bpy.context.scene.BIMProperties.classification: + return [] + with open(bpy.context.scene.BIMProperties.data_dir + 'class/references.csv', 'r') as f: + data = list(csv.reader(f)) + keys = data.pop(0) + return [(d[0], '{} - {}'.format(d[0], d[1]), '') for d in data if + d[2] == bpy.context.scene.BIMProperties.classification] + schema_dir: bpy.props.StringProperty(default=cwd + 'schema/', name="Schema Directory") data_dir: bpy.props.StringProperty(default=cwd + 'data/', name="Data Directory") ifc_class: bpy.props.EnumProperty(items = getIfcClasses, name="Class") @@ -53,6 +70,8 @@ class BIMProperties(bpy.types.PropertyGroup): diff_json_file: bpy.props.StringProperty(default='', name="Diff JSON File") aggregate_class: bpy.props.EnumProperty(items = getIfcClasses, name="Aggregate Class") aggregate_name: bpy.props.StringProperty(name="Aggregate Name") + classification: bpy.props.EnumProperty(items = getClassifications, name="Classification") + reference: bpy.props.EnumProperty(items = getReferences, name="Reference") class MapConversion(bpy.types.PropertyGroup): eastings: bpy.props.StringProperty(name="Eastings") @@ -86,6 +105,10 @@ class Pset(bpy.types.PropertyGroup): class Document(bpy.types.PropertyGroup): file: bpy.props.StringProperty(name="File") +class Classification(bpy.types.PropertyGroup): + name: bpy.props.StringProperty(name="Name") + identification: bpy.props.StringProperty(name="Identification") + class BIMObjectProperties(bpy.types.PropertyGroup): def getApplicableAttributes(self, context): if '/' in bpy.context.active_object.name \ @@ -108,6 +131,7 @@ class BIMObjectProperties(bpy.types.PropertyGroup): applicable_attributes: bpy.props.EnumProperty(items=getApplicableAttributes, name="Attribute Names") documents: bpy.props.CollectionProperty(name="Documents", type=Document) applicable_documents: bpy.props.EnumProperty(items=getApplicableDocuments, name="Available Documents") + classifications: bpy.props.CollectionProperty(name="Classifications", type=Classification) class BIMMaterialProperties(bpy.types.PropertyGroup): is_external: bpy.props.BoolProperty(name="Has External Definition") @@ -174,6 +198,18 @@ class ObjectPanel(bpy.types.Panel): row = layout.row() row.prop(bpy.context.active_object.BIMObjectProperties, 'documents') + layout.label(text="Classification:") + + for index, classification in enumerate(bpy.context.active_object.BIMObjectProperties.classifications): + row = layout.row(align=True) + row.prop(classification, 'identification', text='') + row.prop(classification, 'name', text='') + row.operator('bim.remove_classification', icon='CANCEL', text='').classification_index = index + + row = layout.row() + row.prop(bpy.context.active_object.BIMObjectProperties, 'classifications') + + class MeshPanel(bpy.types.Panel): bl_label = 'IFC Representations' bl_idname = 'BIM_PT_mesh' @@ -317,6 +353,16 @@ class BIMPanel(bpy.types.Panel): row.operator("bim.edit_aggregate") row.operator("bim.save_aggregate") + layout.label(text="Classifications:") + row = layout.row() + row.prop(bim_properties, "classification") + row = layout.row() + row.prop(bim_properties, "reference") + + row = layout.row(align=True) + row.operator("bim.assign_classification") + row.operator("bim.unassign_classification") + class QAPanel(bpy.types.Panel): bl_label = "BIMTester Quality Auditing" bl_idname = "BIM_PT_qa"