mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-12 02:23:34 +00:00
New hierarchical classification navigator, reading class data from IFCs. Thanks to Lucyon Oak (Teck-Freak)
This commit is contained in:
@@ -72,9 +72,12 @@ if bpy is not None:
|
||||
operator.EditAggregate,
|
||||
operator.SaveAggregate,
|
||||
operator.ExplodeAggregate,
|
||||
operator.LoadClassification,
|
||||
operator.AddClassification,
|
||||
operator.RemoveClassification,
|
||||
operator.AssignClassification,
|
||||
operator.UnassignClassification,
|
||||
operator.RemoveClassification,
|
||||
operator.RemoveClassificationReference,
|
||||
operator.FetchLibraryInformation,
|
||||
operator.FetchExternalMaterial,
|
||||
operator.FetchObjectPassport,
|
||||
@@ -95,6 +98,11 @@ if bpy is not None:
|
||||
operator.SetViewPreset1,
|
||||
operator.OpenUpstream,
|
||||
operator.BIM_OT_CopyAttributesToSelection,
|
||||
operator.BIM_OT_ChangeClassificationLevel,
|
||||
prop.StrProperty,
|
||||
prop.Classification,
|
||||
prop.ClassificationReference,
|
||||
prop.ClassificationView,
|
||||
prop.BcfTopic,
|
||||
prop.BcfTopicLabel,
|
||||
prop.BcfTopicFile,
|
||||
@@ -112,7 +120,6 @@ if bpy is not None:
|
||||
prop.BoundaryCondition,
|
||||
prop.PsetQto,
|
||||
prop.Document,
|
||||
prop.Classification,
|
||||
prop.GlobalId,
|
||||
prop.BIMObjectProperties,
|
||||
prop.BIMMaterialProperties,
|
||||
@@ -121,6 +128,7 @@ if bpy is not None:
|
||||
prop.BIMCameraProperties,
|
||||
ui.BIM_PT_documentation,
|
||||
ui.BIM_PT_bim,
|
||||
ui.BIM_PT_classifications,
|
||||
ui.BIM_PT_search,
|
||||
ui.BIM_PT_bcf,
|
||||
ui.BIM_PT_owner,
|
||||
@@ -133,8 +141,10 @@ if bpy is not None:
|
||||
ui.BIM_PT_material,
|
||||
ui.BIM_PT_mesh,
|
||||
ui.BIM_PT_object,
|
||||
ui.BIM_PT_classification_references,
|
||||
ui.BIM_PT_camera,
|
||||
ui.BIM_UL_topics,
|
||||
ui.BIM_UL_classifications,
|
||||
ui.BIM_ADDON_preferences,
|
||||
)
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
Source,Edition,EditionDate,Name,Description,Location,ReferenceTokens
|
||||
RIBA Enterprises Ltd,2015,Aug-19,Uniclass 2015,Uniclass2015 is a unified classification for the UK industry covering all construction sectors.,https://www.thenbs.com/our-tools/uniclass-2015,"[""_""]"
|
||||
OmniClass,2.1,May-12,OmniClass,The OmniClass Construction Classification System is a classification system for the construction industry.,https://www.csiresources.org/standards/omniclass,"[""-"","" ""]"
|
||||
|
@@ -1,2 +0,0 @@
|
||||
Identification,Name,ReferencedSource
|
||||
Pr_20_85_14_16,Concrete solid slabs,0
|
||||
|
@@ -463,7 +463,7 @@ class IfcParser():
|
||||
|
||||
for classification in obj.BIMObjectProperties.classifications:
|
||||
self.rel_associates_classification_object.setdefault(
|
||||
classification.identification, []).append(product)
|
||||
classification.name, []).append(product)
|
||||
|
||||
for key in obj.keys():
|
||||
if key[0:9] == 'Objective':
|
||||
@@ -634,32 +634,39 @@ class IfcParser():
|
||||
return results
|
||||
|
||||
def get_classifications(self):
|
||||
results = []
|
||||
class_path = self.data_dir + 'class/'
|
||||
with open(class_path + 'classifications.csv', 'r') as f:
|
||||
data = list(csv.reader(f))
|
||||
keys = data.pop(0)
|
||||
for row in data:
|
||||
row[-1] = json.loads(row[-1])
|
||||
results.append({
|
||||
'ifc': None,
|
||||
'raw': row,
|
||||
'attributes': dict(zip(keys, row))
|
||||
})
|
||||
classifications = bpy.context.scene.BIMProperties.classifications
|
||||
results = {}
|
||||
for classification in classifications:
|
||||
results[classification.name] = {
|
||||
'ifc': None,
|
||||
'raw': classification,
|
||||
'attributes': {
|
||||
'Name': classification.name,
|
||||
'Source': classification.source,
|
||||
'Edition': classification.edition,
|
||||
'EditionDate': classification.edition_date,
|
||||
'Description': classification.description,
|
||||
'Location': classification.location,
|
||||
'ReferenceTokens': json.loads(
|
||||
'[{}]'.format(classification.reference_tokens[1:-1].replace('\'', '"').strip(',')))
|
||||
}
|
||||
}
|
||||
return results
|
||||
|
||||
def get_classification_references(self):
|
||||
results = {}
|
||||
class_path = self.data_dir + 'class/'
|
||||
with open(class_path + 'references.csv', 'r') as f:
|
||||
data = list(csv.reader(f))
|
||||
keys = data.pop(0)
|
||||
for row in data:
|
||||
results[row[0]] = {
|
||||
for product in self.selected_products:
|
||||
for reference in product['raw'].BIMObjectProperties.classifications:
|
||||
results[reference.name] = {
|
||||
'ifc': None,
|
||||
'raw': row,
|
||||
'referenced_source': int(row.pop()),
|
||||
'attributes': dict(zip(keys, row))
|
||||
'raw': reference,
|
||||
'referenced_source': reference.referenced_source,
|
||||
'attributes': {
|
||||
'Location': reference.location,
|
||||
'Identification': reference.name,
|
||||
'Name': reference.human_name,
|
||||
'Description': reference.description
|
||||
}
|
||||
}
|
||||
return results
|
||||
|
||||
@@ -1323,7 +1330,7 @@ class IfcExporter():
|
||||
[self.ifc_parser.project['ifc']], document['ifc'])
|
||||
|
||||
def create_classifications(self):
|
||||
for classification in self.ifc_parser.classifications:
|
||||
for classification in self.ifc_parser.classifications.values():
|
||||
classification['ifc'] = self.file.create_entity(
|
||||
'IfcClassification',
|
||||
**classification['attributes']
|
||||
|
||||
@@ -1198,14 +1198,64 @@ class ExplodeAggregate(bpy.types.Operator):
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class LoadClassification(bpy.types.Operator):
|
||||
bl_idname = 'bim.load_classification'
|
||||
bl_label = 'Load Classification'
|
||||
|
||||
def execute(self, context):
|
||||
from . import prop
|
||||
prop.ClassificationView.raw_data = schema.ifc.load_classification(
|
||||
context.scene.BIMProperties.classification)
|
||||
context.scene.BIMProperties.classification_references.root = ''
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class AddClassification(bpy.types.Operator):
|
||||
bl_idname = 'bim.add_classification'
|
||||
bl_label = 'Add Classification'
|
||||
|
||||
def execute(self, context):
|
||||
if context.scene.BIMProperties.classification in schema.ifc.classifications:
|
||||
data = schema.ifc.classifications[context.scene.BIMProperties.classification]
|
||||
classification = context.scene.BIMProperties.classifications.add()
|
||||
classification.source = data.Source
|
||||
classification.edition = data.Edition
|
||||
classification.edition_date = data.EditionDate
|
||||
classification.name = data.Name
|
||||
classification.description = data.Description
|
||||
classification.location = data.Location
|
||||
classification.reference_tokens = str(data.ReferenceTokens)
|
||||
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.scene.BIMProperties.classifications.remove(self.classification_index)
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class AssignClassification(bpy.types.Operator):
|
||||
bl_idname = 'bim.assign_classification'
|
||||
bl_label = 'Assign Classification'
|
||||
|
||||
def execute(self, context):
|
||||
referenced_source = schema.ifc.classifications[bpy.context.scene.BIMProperties.classification].Name
|
||||
for obj in bpy.context.selected_objects:
|
||||
classification = obj.BIMObjectProperties.classifications.add()
|
||||
classification.identification = bpy.context.scene.BIMProperties.reference
|
||||
refs = bpy.context.scene.BIMProperties.classification_references
|
||||
data = refs.root['children'][refs.children[refs.active_index].name]
|
||||
if data['identification']:
|
||||
classification.name = data['identification']
|
||||
if data['name']:
|
||||
classification.human_name = data['name']
|
||||
for key in ['location', 'description']:
|
||||
if data[key]:
|
||||
setattr(classification, key, data[key])
|
||||
classification.referenced_source = referenced_source
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
@@ -1214,18 +1264,20 @@ class UnassignClassification(bpy.types.Operator):
|
||||
bl_label = 'Unassign Classification'
|
||||
|
||||
def execute(self, context):
|
||||
refs = bpy.context.scene.BIMProperties.classification_references
|
||||
key = refs.children[refs.active_index].name
|
||||
for obj in bpy.context.selected_objects:
|
||||
index = object.BIMObjectProperties.classifications.find(bpy.context.scene.BIMProperties.classification)
|
||||
index = obj.BIMObjectProperties.classifications.find(key)
|
||||
if index != -1:
|
||||
object.BIMObjectProperties.classifications.remove(index)
|
||||
obj.BIMObjectProperties.classifications.remove(index)
|
||||
|
||||
obj.BIMObjectProperties.classification = ''
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class RemoveClassification(bpy.types.Operator):
|
||||
bl_idname = 'bim.remove_classification'
|
||||
bl_label = 'Remove Classification'
|
||||
class RemoveClassificationReference(bpy.types.Operator):
|
||||
bl_idname = 'bim.remove_classification_reference'
|
||||
bl_label = 'Remove Classification Reference'
|
||||
classification_index: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
@@ -1662,3 +1714,24 @@ class BIM_OT_CopyAttributesToSelection(bpy.types.Operator):
|
||||
try:
|
||||
setattr(new_prop_base, p, getattr(prop, p))
|
||||
except: pass
|
||||
|
||||
|
||||
class BIM_OT_ChangeClassificationLevel(bpy.types.Operator):
|
||||
bl_idname = "bim.change_classification_level"
|
||||
bl_label = "Change Classification Level"
|
||||
|
||||
# string representing the id-data (e.g. the scene).
|
||||
path_sid: bpy.props.StringProperty()
|
||||
# path from the id-data to the classification view object
|
||||
path_lst: bpy.props.StringProperty()
|
||||
# name of child entity to enter (empty = go up one level)
|
||||
path_itm: bpy.props.StringProperty()
|
||||
|
||||
def invoke(self, context, event):
|
||||
id_data = eval(self.path_sid)
|
||||
lst = id_data.path_resolve(self.path_lst)
|
||||
if self.path_itm:
|
||||
lst.root = self.path_itm
|
||||
else:
|
||||
lst.root = ''
|
||||
return {'FINISHED'}
|
||||
|
||||
@@ -32,7 +32,6 @@ scenarios_enum = []
|
||||
psetnames_enum = []
|
||||
psetfiles_enum = []
|
||||
classification_enum = []
|
||||
reference_enum = []
|
||||
attributes_enum = []
|
||||
overridepsetnames_enum = []
|
||||
qtonames_enum = []
|
||||
@@ -236,31 +235,15 @@ def getClassifications(self, context):
|
||||
global classification_enum
|
||||
if len(classification_enum) < 1:
|
||||
classification_enum.clear()
|
||||
with open(os.path.join(self.data_dir, 'class', 'classifications.csv'), 'r') as f:
|
||||
data = list(csv.reader(f))
|
||||
keys = data.pop(0)
|
||||
index = keys.index('Name')
|
||||
classification_enum.extend([(str(i), d[index], '') for i, d in enumerate(data)])
|
||||
files = os.listdir(os.path.join(self.schema_dir, 'classifications'))
|
||||
classification_enum.extend([(f.replace('.ifc', ''), f.replace('.ifc', ''), '') for f in files])
|
||||
return classification_enum
|
||||
|
||||
|
||||
def refreshReferences(self, context):
|
||||
global reference_enum
|
||||
reference_enum.clear()
|
||||
getReferences(self, context)
|
||||
|
||||
|
||||
def getReferences(self, context):
|
||||
global reference_enum
|
||||
if len(reference_enum) < 1:
|
||||
if not self.classification.strip():
|
||||
return reference_enum
|
||||
with open(os.path.join(self.data_dir, 'class', 'references.csv'), 'r') as f:
|
||||
data = list(csv.reader(f))
|
||||
keys = data.pop(0)
|
||||
reference_enum.extend([(d[0], '{} - {}'.format(d[0], d[1]), '') for d in data if
|
||||
d[2] == self.classification.strip()])
|
||||
return reference_enum
|
||||
context.scene.BIMProperties.classification_references.root = None
|
||||
ClassificationView.raw_data = schema.ifc.load_classification(context.scene.BIMProperties.classification)
|
||||
context.scene.BIMProperties.classification_references.root = ''
|
||||
|
||||
|
||||
def getOverridePsetNames(self, context):
|
||||
@@ -390,6 +373,10 @@ def getSheets(self, context):
|
||||
return sheets_enum
|
||||
|
||||
|
||||
class StrProperty(PropertyGroup):
|
||||
pass
|
||||
|
||||
|
||||
class Subcontext(PropertyGroup):
|
||||
name: StringProperty(name='Name')
|
||||
target_view: StringProperty(name='Target View')
|
||||
@@ -587,6 +574,78 @@ def getBcfViewpoints(self, context):
|
||||
return bcfviewpoints_enum
|
||||
|
||||
|
||||
class Classification(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
source: StringProperty(name="Source")
|
||||
edition: StringProperty(name="Edition")
|
||||
edition_date: StringProperty(name="Edition Date")
|
||||
description: StringProperty(name="Description")
|
||||
location: StringProperty(name="Location")
|
||||
reference_tokens: StringProperty(name="Reference Tokens")
|
||||
|
||||
|
||||
class ClassificationReference(PropertyGroup):
|
||||
name: StringProperty(name="Identification")
|
||||
location: StringProperty(name="Location")
|
||||
human_name: StringProperty(name="Name")
|
||||
referenced_source: StringProperty(name="Source")
|
||||
description: StringProperty(name="Description")
|
||||
sort: StringProperty(name="Sort")
|
||||
|
||||
|
||||
class ClassificationView(PropertyGroup):
|
||||
crumbs: None
|
||||
children: None
|
||||
active_index: bpy.props.IntProperty()
|
||||
raw_data = {}
|
||||
|
||||
@property
|
||||
def root(self):
|
||||
data = self.raw_data
|
||||
for crumb in self.crumbs:
|
||||
data = data['children'].get(crumb.name)
|
||||
if not data:
|
||||
raise TypeError('Cannot resolve crumb path')
|
||||
return data
|
||||
|
||||
@root.setter
|
||||
def root(self, rt):
|
||||
if rt == None:
|
||||
self.crumbs.clear()
|
||||
self.children.clear()
|
||||
elif rt == '':
|
||||
if self.crumbs:
|
||||
self.crumbs.remove(len(self.crumbs)-1)
|
||||
self.children.clear()
|
||||
for child in self.root['children'].keys():
|
||||
self.children.add().name = child
|
||||
else:
|
||||
data = self.root
|
||||
if rt in data['children'].keys():
|
||||
self.crumbs.add().name = rt
|
||||
self.children.clear()
|
||||
for child in data['children'][rt]['children'].keys():
|
||||
self.children.add().name = child
|
||||
|
||||
def draw_stub(self, context, layout):
|
||||
if not self.children:
|
||||
op = layout.operator('bim.change_classification_level', text="@Toplevel")
|
||||
else:
|
||||
op = layout.operator('bim.change_classification_level', text=self.root['name'])
|
||||
op.path_sid = "%r"%self.id_data
|
||||
op.path_lst = self.path_from_id()
|
||||
op.path_itm = ''
|
||||
layout.template_list('BIM_UL_classifications',
|
||||
self.path_from_id(), self, 'children', self, 'active_index')
|
||||
|
||||
|
||||
# Monkey-patched, just to keep registration in one block
|
||||
ClassificationView.__annotations__['crumbs'] = \
|
||||
bpy.props.CollectionProperty(type=StrProperty)
|
||||
ClassificationView.__annotations__['children'] = \
|
||||
bpy.props.CollectionProperty(type=StrProperty)
|
||||
|
||||
|
||||
class BIMProperties(PropertyGroup):
|
||||
schema_dir: StringProperty(default=os.path.join(cwd ,'schema') + os.path.sep, name="Schema Directory")
|
||||
data_dir: StringProperty(default=os.path.join(cwd, 'data') + os.path.sep, name="Data Directory")
|
||||
@@ -639,7 +698,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)
|
||||
reference: EnumProperty(items=getReferences, name="Reference")
|
||||
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=False)
|
||||
model_subcontexts: CollectionProperty(name='Model Subcontexts', type=Subcontext)
|
||||
@@ -647,6 +706,7 @@ class BIMProperties(PropertyGroup):
|
||||
available_contexts: EnumProperty(items=[('Model', 'Model', ''), ('Plan', 'Plan', '')], name="Available Contexts")
|
||||
available_subcontexts: EnumProperty(items=getSubcontexts, name="Available Subcontexts")
|
||||
available_target_views: EnumProperty(items=getTargetViews, name="Available Target Views")
|
||||
classification_references: PointerProperty(type=ClassificationView)
|
||||
|
||||
|
||||
class BCFProperties(PropertyGroup):
|
||||
@@ -720,10 +780,6 @@ class PsetQto(PropertyGroup):
|
||||
class Document(PropertyGroup):
|
||||
file: StringProperty(name="File")
|
||||
|
||||
class Classification(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
identification: StringProperty(name="Identification")
|
||||
|
||||
|
||||
class GlobalId(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
@@ -744,7 +800,7 @@ class BIMObjectProperties(PropertyGroup):
|
||||
applicable_attributes: EnumProperty(items=getApplicableAttributes, name="Attribute Names")
|
||||
documents: CollectionProperty(name="Documents", type=Document)
|
||||
applicable_documents: EnumProperty(items=getApplicableDocuments, name="Available Documents")
|
||||
classifications: CollectionProperty(name="Classifications", type=Classification)
|
||||
classifications: CollectionProperty(name="Classifications", type=ClassificationReference)
|
||||
material_type: EnumProperty(items=getMaterialTypes, name="Material Type")
|
||||
override_psets: CollectionProperty(name="Override Psets", type=PsetQto)
|
||||
override_pset_name: EnumProperty(items=getOverridePsetNames, name='Override Pset Name')
|
||||
|
||||
@@ -21,14 +21,22 @@ class IfcSchema():
|
||||
'IfcElementType'
|
||||
]
|
||||
self.elements = {}
|
||||
|
||||
self.property_files = []
|
||||
property_paths = Path(self.schema_dir).glob('Pset_*.ifc')
|
||||
for path in property_paths:
|
||||
self.property_files.append(ifcopenshell.open(path))
|
||||
|
||||
self.classification_files = {}
|
||||
classification_paths = Path(self.schema_dir).glob('classifications/*.ifc')
|
||||
for path in classification_paths:
|
||||
self.classification_files[os.path.basename(path).split('.')[0]] = ifcopenshell.open(path)
|
||||
|
||||
self.psets = {}
|
||||
self.qtos = {}
|
||||
self.applicable_psets = {}
|
||||
self.applicable_qtos = {}
|
||||
self.classifications = {}
|
||||
self.load()
|
||||
|
||||
def load(self):
|
||||
@@ -53,4 +61,31 @@ class IfcSchema():
|
||||
entity = prop.ApplicableEntity if prop.ApplicableEntity else 'IfcRoot'
|
||||
self.applicable_psets.setdefault(entity, []).append(prop.Name)
|
||||
|
||||
for filename, classification_file in self.classification_files.items():
|
||||
classification = classification_file.by_type('IfcClassification')[0]
|
||||
self.classifications[filename] = classification
|
||||
|
||||
def load_classification(self, filename):
|
||||
classification = self.classifications[filename]
|
||||
return {
|
||||
'name': '',
|
||||
'description': '',
|
||||
'children': self.get_classification_references(classification)
|
||||
}
|
||||
|
||||
def get_classification_references(self, classification):
|
||||
references = {}
|
||||
if not classification.HasReferences:
|
||||
return references
|
||||
for reference in classification.HasReferences:
|
||||
references[reference.Identification] = {
|
||||
'location': reference.Location,
|
||||
'identification': reference.Identification,
|
||||
'name': reference.Name,
|
||||
'description': reference.Description,
|
||||
'children': self.get_classification_references(reference)
|
||||
}
|
||||
return references
|
||||
|
||||
|
||||
ifc = IfcSchema()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+12474
File diff suppressed because it is too large
Load Diff
@@ -111,17 +111,6 @@ class BIM_PT_object(Panel):
|
||||
row = layout.row()
|
||||
row.prop(props, 'documents')
|
||||
|
||||
layout.label(text="Classification:")
|
||||
|
||||
for index, classification in enumerate(props.classifications):
|
||||
row = layout.row(align=True)
|
||||
row.prop(classification, 'identification', text='')
|
||||
row.prop(classification, 'name', text='')
|
||||
row.operator('bim.remove_classification', icon='X', text='').classification_index = index
|
||||
|
||||
row = layout.row()
|
||||
row.prop(props, 'classifications')
|
||||
|
||||
row = layout.row()
|
||||
row.prop(props, 'material_type')
|
||||
|
||||
@@ -142,6 +131,87 @@ class BIM_PT_object(Panel):
|
||||
row.prop(props, 'structural_member_connection')
|
||||
|
||||
|
||||
class BIM_PT_classification_references(Panel):
|
||||
bl_label = 'Classification References'
|
||||
bl_idname = 'BIM_PT_classification_references'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = 'object'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
props = context.active_object.BIMObjectProperties
|
||||
|
||||
layout.label(text="Classification:")
|
||||
|
||||
for index, classification in enumerate(props.classifications):
|
||||
row = layout.row(align=True)
|
||||
row.prop(classification, 'name')
|
||||
row.operator('bim.remove_classification_reference', icon='X', text='').classification_index = index
|
||||
row = layout.row(align=True)
|
||||
row.prop(classification, 'human_name')
|
||||
row = layout.row(align=True)
|
||||
row.prop(classification, 'location')
|
||||
row = layout.row(align=True)
|
||||
row.prop(classification, 'description')
|
||||
row = layout.row(align=True)
|
||||
row.prop(classification, 'referenced_source')
|
||||
|
||||
row = layout.row()
|
||||
row.prop(props, 'classifications')
|
||||
|
||||
|
||||
class BIM_PT_classifications(Panel):
|
||||
bl_label = 'Classifications'
|
||||
bl_idname = 'BIM_PT_classifications'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
bl_context = 'scene'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
props = context.scene.BIMProperties
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(props, "classification", text='')
|
||||
row.operator("bim.add_classification", text='', icon='ADD')
|
||||
|
||||
if context.scene.BIMProperties.classification_references.raw_data:
|
||||
context.scene.BIMProperties.classification_references.draw_stub(context, layout)
|
||||
row = layout.row(align=True)
|
||||
row.operator("bim.assign_classification")
|
||||
row.operator("bim.unassign_classification")
|
||||
else:
|
||||
row = layout.row(align=True)
|
||||
row.operator('bim.load_classification')
|
||||
|
||||
if not props.classifications:
|
||||
return
|
||||
|
||||
layout.label(text="Classifications:")
|
||||
|
||||
for index, classification in enumerate(props.classifications):
|
||||
row = layout.row(align=True)
|
||||
row.prop(classification, 'name')
|
||||
row.operator('bim.remove_classification', icon='X', text='').classification_index = index
|
||||
row = layout.row(align=True)
|
||||
row.prop(classification, 'source')
|
||||
row = layout.row(align=True)
|
||||
row.prop(classification, 'edition')
|
||||
row = layout.row(align=True)
|
||||
row.prop(classification, 'edition_date')
|
||||
row = layout.row(align=True)
|
||||
row.prop(classification, 'description')
|
||||
row = layout.row(align=True)
|
||||
row.prop(classification, 'location')
|
||||
row = layout.row(align=True)
|
||||
row.prop(classification, 'reference_tokens')
|
||||
|
||||
row = layout.row()
|
||||
row.prop(props, 'classifications')
|
||||
|
||||
class BIM_PT_mesh(Panel):
|
||||
bl_label = 'IFC Representations'
|
||||
bl_idname = 'BIM_PT_mesh'
|
||||
@@ -499,16 +569,6 @@ class BIM_PT_bim(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 BIM_PT_search(Panel):
|
||||
bl_label = "BIM Search"
|
||||
@@ -852,6 +912,24 @@ class BIM_UL_topics(bpy.types.UIList):
|
||||
layout.label(text="", translate=False)
|
||||
|
||||
|
||||
class BIM_UL_classifications(bpy.types.UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||
if self.layout_type in {'DEFAULT', 'COMPACT'}:
|
||||
rt = data.root
|
||||
ch = rt['children']
|
||||
itemdata = ch[item.name]
|
||||
if itemdata.get('children', {}):
|
||||
op = layout.operator("bim.change_classification_level", text="",
|
||||
emboss=False, icon="DISCLOSURE_TRI_RIGHT")
|
||||
op.path_sid = "%r"%active_data.id_data # get id-data
|
||||
op.path_lst = active_data.path_from_id() # path to view
|
||||
op.path_itm = item.name # name of child. empty = go up
|
||||
else:
|
||||
layout.label(text='', icon='BLANK1')
|
||||
layout.prop(item, "name", text="", emboss=False)
|
||||
layout.label(text=itemdata['name'])
|
||||
|
||||
|
||||
class BIM_ADDON_preferences(bpy.types.AddonPreferences):
|
||||
bl_idname = 'blenderbim'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user