mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-12 02:23:34 +00:00
Allow manually specified qto values to be exported
This commit is contained in:
@@ -66,6 +66,7 @@ if bpy is not None:
|
||||
operator.RemovePset,
|
||||
operator.AddOverridePset,
|
||||
operator.RemoveOverridePset,
|
||||
operator.AddQto,
|
||||
operator.RemoveQto,
|
||||
operator.AddMaterialPset,
|
||||
operator.RemoveMaterialPset,
|
||||
|
||||
@@ -141,7 +141,6 @@ class IfcParser():
|
||||
self.load_representations()
|
||||
self.materials = self.get_materials()
|
||||
self.styled_items = self.get_styled_items()
|
||||
self.qtos = self.get_qtos()
|
||||
self.spatial_structure_elements = self.get_spatial_structure_elements()
|
||||
self.structural_analysis_models = self.get_structural_analysis_models()
|
||||
|
||||
@@ -448,17 +447,8 @@ class IfcParser():
|
||||
self.rel_defines_by_pset.setdefault(
|
||||
'{}/{}'.format(pset.name, pset.file), []).append(product)
|
||||
|
||||
for pset in obj.BIMObjectProperties.override_psets:
|
||||
pset_key = '{}/{}'.format(pset.name, obj.name)
|
||||
raw = {p.name: p.string_value for p in pset.properties if p.string_value}
|
||||
if not raw:
|
||||
continue
|
||||
self.psets[pset_key] = {
|
||||
'ifc': None,
|
||||
'raw': raw,
|
||||
'attributes': { 'Name': pset.name }
|
||||
}
|
||||
self.rel_defines_by_pset.setdefault(pset_key, []).append(product)
|
||||
self.get_product_psets_qtos(product, obj, is_pset=True)
|
||||
self.get_product_psets_qtos(product, obj, is_qto=True)
|
||||
|
||||
for document in obj.BIMObjectProperties.documents:
|
||||
self.rel_associates_document_object.setdefault(
|
||||
@@ -490,6 +480,27 @@ class IfcParser():
|
||||
|
||||
return product
|
||||
|
||||
def get_product_psets_qtos(self, product, obj, is_pset=False, is_qto=False):
|
||||
if is_pset:
|
||||
psets_qtos = obj.BIMObjectProperties.override_psets
|
||||
results = self.psets
|
||||
relationships = self.rel_defines_by_pset
|
||||
if is_qto:
|
||||
psets_qtos = obj.BIMObjectProperties.qtos
|
||||
results = self.qtos
|
||||
relationships = self.rel_defines_by_qto
|
||||
for item in psets_qtos:
|
||||
item_key = '{}/{}'.format(item.name, obj.name)
|
||||
raw = {p.name: p.string_value for p in item.properties if p.string_value}
|
||||
if not raw:
|
||||
continue
|
||||
results[item_key] = {
|
||||
'ifc': None,
|
||||
'raw': raw,
|
||||
'attributes': { 'Name': item.name }
|
||||
}
|
||||
relationships.setdefault(item_key, []).append(product)
|
||||
|
||||
def get_product_relating_structure(self, product, obj):
|
||||
relating_structure = obj.BIMObjectProperties.relating_structure
|
||||
if relating_structure:
|
||||
@@ -918,28 +929,6 @@ class IfcParser():
|
||||
})
|
||||
return results
|
||||
|
||||
def get_qtos(self):
|
||||
if not self.ifc_export_settings.has_quantities:
|
||||
return {}
|
||||
results = {}
|
||||
for product in self.selected_products + self.type_products:
|
||||
obj = product['raw']
|
||||
if not obj.data:
|
||||
continue
|
||||
for property in obj.keys():
|
||||
if property[0:4] != 'Qto_':
|
||||
continue
|
||||
results[obj.name] = {
|
||||
'ifc': None,
|
||||
'raw': obj,
|
||||
'class': property,
|
||||
'attributes': {
|
||||
'Name': property,
|
||||
'MethodOfMeasurement': obj[property]
|
||||
}
|
||||
}
|
||||
return results
|
||||
|
||||
def get_type_products(self):
|
||||
results = []
|
||||
index = 0
|
||||
@@ -1316,10 +1305,6 @@ class IfcExporter():
|
||||
for pset in self.ifc_parser.psets.values():
|
||||
properties = self.create_pset_properties(pset)
|
||||
if not properties:
|
||||
self.ifc_export_settings.logger.error(
|
||||
'No properties could be detected for the pset {}/{}'.format(
|
||||
pset['attributes']['Name'],
|
||||
pset['attributes']['Description']))
|
||||
continue
|
||||
pset['attributes'].update({
|
||||
'GlobalId': ifcopenshell.guid.new(),
|
||||
@@ -1338,6 +1323,10 @@ class IfcExporter():
|
||||
'Material': material['ifc']
|
||||
})
|
||||
|
||||
def create_qto_properties(self, qto):
|
||||
if qto['attributes']['Name'] in schema.ifc.qtos:
|
||||
return self.create_templated_qto_properties(qto)
|
||||
|
||||
def create_pset_properties(self, pset):
|
||||
if pset['attributes']['Name'] in schema.ifc.psets:
|
||||
return self.create_templated_pset_properties(pset)
|
||||
@@ -1382,6 +1371,30 @@ class IfcExporter():
|
||||
invalid_pset_keys))
|
||||
return properties
|
||||
|
||||
def create_templated_qto_properties(self, qto):
|
||||
properties = []
|
||||
templates = schema.ifc.qtos[qto['attributes']['Name']]['HasPropertyTemplates']
|
||||
for name, data in templates.items():
|
||||
if name not in qto['raw']:
|
||||
continue
|
||||
if data.TemplateType[0:2] == 'Q_':
|
||||
value_basename = data.TemplateType[2:].title()
|
||||
value_name = f'{value_basename}Value'
|
||||
class_name = f'IfcQuantity{value_basename}'
|
||||
properties.append(
|
||||
self.file.create_entity(class_name, **{
|
||||
'Name': name,
|
||||
value_name: float(qto['raw'][name])
|
||||
}))
|
||||
invalid_qto_keys = [k for k in qto['raw'].keys() if k not in templates.keys()]
|
||||
if invalid_qto_keys:
|
||||
self.ifc_export_settings.logger.error(
|
||||
'One or more properties were invalid in the qto {}/{}: {}'.format(
|
||||
qto['attributes']['Name'],
|
||||
qto['attributes']['Description'],
|
||||
invalid_qto_keys))
|
||||
return properties
|
||||
|
||||
def cast_to_base_type(self, var_type, value):
|
||||
if var_type not in schema.ifc.type_map:
|
||||
return value
|
||||
@@ -1676,12 +1689,15 @@ class IfcExporter():
|
||||
self.create_product(product)
|
||||
|
||||
def create_qtos(self):
|
||||
for object_name, qto in self.ifc_parser.qtos.items():
|
||||
quantities = self.calculate_quantities(qto['class'], qto['raw'])
|
||||
# TODO: re-introduce calculated quantities
|
||||
for qto in self.ifc_parser.qtos.values():
|
||||
properties = self.create_qto_properties(qto)
|
||||
if not properties:
|
||||
continue
|
||||
qto['attributes'].update({
|
||||
'GlobalId': ifcopenshell.guid.new(),
|
||||
'OwnerHistory': self.owner_history,
|
||||
'Quantities': quantities
|
||||
'Quantities': properties
|
||||
})
|
||||
qto['ifc'] = self.file.create_entity('IfcElementQuantity', **qto['attributes'])
|
||||
|
||||
|
||||
@@ -480,6 +480,22 @@ class RemovePset(bpy.types.Operator):
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class AddQto(bpy.types.Operator):
|
||||
bl_idname = 'bim.add_qto'
|
||||
bl_label = 'Add Qto'
|
||||
|
||||
def execute(self, context):
|
||||
name = bpy.context.active_object.BIMObjectProperties.qto_name
|
||||
if name not in schema.ifc.qtos:
|
||||
return {'FINISHED'}
|
||||
qto = bpy.context.active_object.BIMObjectProperties.qtos.add()
|
||||
qto.name = name
|
||||
for prop_name in schema.ifc.qtos[name]['HasPropertyTemplates'].keys():
|
||||
prop = qto.properties.add()
|
||||
prop.name = prop_name
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class AddOverridePset(bpy.types.Operator):
|
||||
bl_idname = 'bim.add_override_pset'
|
||||
bl_label = 'Add Override Pset'
|
||||
|
||||
@@ -490,6 +490,7 @@ class BIMObjectProperties(PropertyGroup):
|
||||
material_type: EnumProperty(items=getMaterialTypes, name="Material Type")
|
||||
override_psets: CollectionProperty(name="Override Psets", type=PsetQto)
|
||||
override_pset_name: StringProperty(name="Override Pset Name")
|
||||
qto_name: StringProperty(name="Qto Name")
|
||||
has_boundary_condition: BoolProperty(name='Has Boundary Condition')
|
||||
boundary_condition: PointerProperty(name='Boundary Condition', type=BoundaryCondition)
|
||||
structural_member_connection: PointerProperty(name='Structural Member Connection', type=bpy.types.Object)
|
||||
|
||||
@@ -74,6 +74,10 @@ class BIM_PT_object(Panel):
|
||||
|
||||
layout.label(text="Quantities:")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(props, 'qto_name', text='')
|
||||
row.operator('bim.add_qto')
|
||||
|
||||
for index, qto in enumerate(props.qtos):
|
||||
row = layout.row(align=True)
|
||||
row.prop(qto, 'name', text='')
|
||||
|
||||
Reference in New Issue
Block a user