Classification trees are now stored in the blend instead of an external file for portability. See #1036.

This commit is contained in:
Dion Moult
2020-10-24 21:35:01 +11:00
parent ee6e96c226
commit 8872a13fd8
8 changed files with 37 additions and 52 deletions
@@ -185,7 +185,6 @@ if bpy is not None:
operator.SaveDrawingStyle,
operator.ActivateDrawingStyle,
operator.EditVectorStyle,
operator.PurgeProjectClassifications,
operator.RemoveSheet,
operator.AddSchedule,
operator.RemoveSchedule,
@@ -630,22 +630,23 @@ class IfcParser():
def get_classifications(self):
results = {}
for classification in bpy.context.scene.BIMProperties.classifications:
schema.ifc.load_classification(classification.filename)
results[classification.filename] = {
if classification.name not in schema.ifc.classification_files:
schema.ifc.classification_files[classification.name] = ifcopenshell.file.from_string(classification.data)
results[classification.name] = {
'ifc': None,
'raw': classification,
'raw_element': schema.ifc.classification_files[classification.filename].by_type('IfcClassification')[0]
'raw_element': schema.ifc.classification_files[classification.name].by_type('IfcClassification')[0]
}
return results
def get_classification_reference_maps(self):
results = {}
for filename, classification in self.classifications.items():
ifc_file = schema.ifc.classification_files[filename]
for name, classification in self.classifications.items():
ifc_file = schema.ifc.classification_files[name]
if ifc_file.schema == 'IFC2X3':
results[filename] = { e.ItemReference: e for e in ifc_file.by_type('IfcClassificationReference')}
results[name] = { e.ItemReference: e for e in ifc_file.by_type('IfcClassificationReference')}
else:
results[filename] = { e.Identification: e for e in ifc_file.by_type('IfcClassificationReference')}
results[name] = { e.Identification: e for e in ifc_file.by_type('IfcClassificationReference')}
return results
def get_classification_references(self):
@@ -1501,13 +1501,8 @@ class IfcImporter():
for entity in entities_to_add:
classification_file.add(entity)
classification_filename = '{}-{}'.format(
Path(os.path.basename(self.ifc_import_settings.input_file)).stem, element.Name)
classification_file.write(os.path.join(
bpy.context.scene.BIMProperties.schema_dir, 'project_classifications',
'{}.ifc'.format(classification_filename)))
classification.filename = classification_filename
self.classifications[classification.filename] = classification
classification.data = classification_file.to_string()
self.classifications[classification.name] = classification
self.schema_dir = bpy.context.scene.BIMProperties.schema_dir
from . import prop
@@ -1815,9 +1810,6 @@ class IfcImporter():
def get_referenced_source_name(self, element):
if not hasattr(element, 'ReferencedSource') or not element.ReferencedSource:
if element.is_a('IfcClassification'):
for filename, classification in self.classifications.items():
if classification.name == element.Name:
return filename
return element.Name
else:
return element.Identification
+11 -20
View File
@@ -1922,11 +1922,18 @@ class ExplodeAggregate(bpy.types.Operator):
class LoadClassification(bpy.types.Operator):
bl_idname = 'bim.load_classification'
bl_label = 'Load Classification'
is_file: bpy.props.BoolProperty()
classification_index: bpy.props.IntProperty()
def execute(self, context):
from . import prop
prop.ClassificationView.raw_data = schema.ifc.load_classification(
context.scene.BIMProperties.classification)
if self.is_file:
prop.ClassificationView.raw_data = schema.ifc.load_classification(
context.scene.BIMProperties.classification)
else:
prop.ClassificationView.raw_data = schema.ifc.load_classification(
context.scene.BIMProperties.classifications[self.classification_index].name,
self.classification_index)
context.scene.BIMProperties.classification_references.root = ''
return {'FINISHED'}
@@ -1949,7 +1956,7 @@ class AddClassification(bpy.types.Operator):
for key, value in data_map.items():
if hasattr(data, value) and getattr(data, value):
setattr(classification, key, str(getattr(data, value)))
classification.filename = context.scene.BIMProperties.classification
classification.data = schema.ifc.classification_files[context.scene.BIMProperties.classification].to_string()
return {'FINISHED'}
@@ -1979,7 +1986,7 @@ class AssignClassification(bpy.types.Operator):
for key in ['location', 'description']:
if data[key]:
setattr(classification, key, data[key])
classification.referenced_source = bpy.context.scene.BIMProperties.classification
classification.referenced_source = bpy.context.scene.BIMProperties.active_classification_name
return {'FINISHED'}
@@ -3872,22 +3879,6 @@ class EditVectorStyle(bpy.types.Operator):
return {'FINISHED'}
class PurgeProjectClassifications(bpy.types.Operator):
bl_idname = 'bim.purge_project_classifications'
bl_label = 'Purge Project Classifications'
def execute(self, context):
self.schema_dir = bpy.context.scene.BIMProperties.schema_dir
path = os.path.join(self.schema_dir, 'project_classifications')
files = os.listdir(path)
for f in files:
os.remove(os.path.join(path, f))
from . import prop
prop.classification_enum.clear()
prop.getClassifications(self, context)
return {'FINISHED'}
class RemoveSheet(bpy.types.Operator):
bl_idname = 'bim.remove_sheet'
bl_label = 'Remove Sheet'
+2 -3
View File
@@ -395,8 +395,6 @@ def getClassifications(self, context):
classification_enum.clear()
files = os.listdir(os.path.join(self.schema_dir, 'classifications'))
classification_enum.extend([(f.replace('.ifc', ''), f.replace('.ifc', ''), '') for f in files])
files = os.listdir(os.path.join(self.schema_dir, 'project_classifications'))
classification_enum.extend([(f.replace('.ifc', ''), f.replace('.ifc', ''), '') for f in files])
return classification_enum
@@ -1112,7 +1110,7 @@ class Classification(PropertyGroup):
description: StringProperty(name="Description")
location: StringProperty(name="Location")
reference_tokens: StringProperty(name="Reference Tokens")
filename: StringProperty(name="Filename")
data: StringProperty(name="Data")
class ClassificationReference(PropertyGroup):
@@ -1249,6 +1247,7 @@ class BIMProperties(PropertyGroup):
aggregate_class: EnumProperty(items=getIfcClasses, name="Aggregate Class")
aggregate_name: StringProperty(name="Aggregate Name")
classification: EnumProperty(items=getClassifications, name="Classification", update=refreshReferences)
active_classification_name: StringProperty(name="Active Classification Name")
classifications: CollectionProperty(name="Classifications", type=Classification)
has_model_context: BoolProperty(name="Has Model Context", default=True)
has_plan_context: BoolProperty(name="Has Plan Context", default=True)
+11 -8
View File
@@ -62,14 +62,17 @@ class IfcSchema():
entity = prop.ApplicableEntity if prop.ApplicableEntity else 'IfcRoot'
self.applicable_psets.setdefault(entity, []).append(prop.Name)
def load_classification(self, filename):
if filename not in self.classifications:
classification_path = os.path.join(self.schema_dir, 'classifications', '{}.ifc'.format(filename))
if not os.path.isfile(classification_path):
classification_path = os.path.join(self.schema_dir, 'project_classifications', '{}.ifc'.format(filename))
self.classification_files[filename] = ifcopenshell.open(classification_path)
self.classifications[filename] = self.classification_files[filename].by_type('IfcClassification')[0]
classification = self.classifications[filename]
def load_classification(self, name, classification_index=None):
if name not in self.classifications:
if classification_index is not None:
self.classification_files[name] = ifcopenshell.file.from_string(
bpy.context.scene.BIMProperties.classifications[classification_index].data)
else:
classification_path = os.path.join(self.schema_dir, 'classifications', '{}.ifc'.format(name))
self.classification_files[name] = ifcopenshell.open(classification_path)
self.classifications[name] = self.classification_files[name].by_type('IfcClassification')[0]
classification = self.classifications[name]
bpy.context.scene.BIMProperties.active_classification_name = self.classifications[name].Name
return {
'name': '',
'description': '',
+3 -3
View File
@@ -532,7 +532,7 @@ class BIM_PT_psets(Panel):
class BIM_PT_classifications(Panel):
bl_label = 'IFC Classifications References'
bl_label = 'IFC Classifications'
bl_idname = 'BIM_PT_classifications'
bl_options = {'DEFAULT_CLOSED'}
bl_space_type = 'PROPERTIES'
@@ -545,7 +545,6 @@ class BIM_PT_classifications(Panel):
row = layout.row(align=True)
row.prop(props, "classification", text='')
row.operator("bim.purge_project_classifications", text='', icon='TRASH')
row.operator("bim.add_classification", text='', icon='ADD')
if context.scene.BIMProperties.classification_references.raw_data:
@@ -555,7 +554,7 @@ class BIM_PT_classifications(Panel):
row.operator("bim.unassign_classification")
else:
row = layout.row(align=True)
row.operator('bim.load_classification')
row.operator('bim.load_classification').is_file = True
if not props.classifications:
return
@@ -565,6 +564,7 @@ class BIM_PT_classifications(Panel):
for index, classification in enumerate(props.classifications):
row = layout.row(align=True)
row.prop(classification, 'name')
row.operator('bim.load_classification', icon='IMPORT', text='').classification_index = index
row.operator('bim.remove_classification', icon='X', text='').classification_index = index
row = layout.row(align=True)
row.prop(classification, 'source')