From 0625e4153c32fabd05beb1f0dfea64ff99a70ee0 Mon Sep 17 00:00:00 2001 From: Vukas Pajic <83825269+vulevukusej@users.noreply.github.com> Date: Tue, 4 Jan 2022 02:59:55 +0100 Subject: [PATCH] bulk property editor (#1896) * first revision * update incorporating review comments * added a new feature - remove psets * type dropdown now references ifc data types * adopt new solution for enumerations and umlauts * Revert "adopt new solution for enumerations and umlauts" This reverts commit 203a31a2bf88dc4bc5477b3ad6bce7ec03a142d5. --- .../blenderbim/bim/module/pset/__init__.py | 20 ++- .../blenderbim/bim/module/pset/operator.py | 157 +++++++++++++++++- .../blenderbim/bim/module/pset/prop.py | 42 ++++- .../blenderbim/bim/module/pset/ui.py | 114 +++++++++++++ .../bim/module/pset_template/prop.py | 113 +------------ src/blenderbim/blenderbim/bim/prop.py | 111 +++++++++++++ 6 files changed, 443 insertions(+), 114 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/pset/__init__.py b/src/blenderbim/blenderbim/bim/module/pset/__init__.py index b1dcfa4ec2..dc5e2092ee 100644 --- a/src/blenderbim/blenderbim/bim/module/pset/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/pset/__init__.py @@ -29,12 +29,21 @@ classes = ( operator.GuessQuantity, operator.RemovePset, operator.TogglePsetExpansion, + operator.BIM_OT_add_property_to_edit, + operator.BIM_OT_remove_property_to_edit, + operator.BIM_OT_clear_list, + operator.BIM_OT_rename_parameters, + operator.BIM_OT_add_edit_custom_property, + operator.BIM_OT_bulk_remove_psets, prop.PsetProperties, prop.MaterialPsetProperties, prop.TaskPsetProperties, prop.ResourcePsetProperties, prop.ProfilePsetProperties, prop.WorkSchedulePsetProperties, + prop.RenameProperties, + prop.AddEditProperties, + prop.DeletePsets, ui.BIM_PT_object_psets, ui.BIM_PT_object_qtos, ui.BIM_PT_material_psets, @@ -43,6 +52,10 @@ classes = ( ui.BIM_PT_resource_psets, ui.BIM_PT_profile_psets, ui.BIM_PT_work_schedule_psets, + ui.BIM_PT_bulk_property_editor, + ui.BIM_PT_rename_parameters, + ui.BIM_PT_add_edit_custom_properties, + ui.BIM_PT_delete_psets ) @@ -53,7 +66,9 @@ def register(): bpy.types.Scene.ResourcePsetProperties = bpy.props.PointerProperty(type=prop.ResourcePsetProperties) bpy.types.Scene.ProfilePsetProperties = bpy.props.PointerProperty(type=prop.ProfilePsetProperties) bpy.types.Scene.WorkSchedulePsetProperties = bpy.props.PointerProperty(type=prop.WorkSchedulePsetProperties) - + bpy.types.Scene.RenameProperties = bpy.props.CollectionProperty(type=prop.RenameProperties) + bpy.types.Scene.AddEditProperties = bpy.props.CollectionProperty(type=prop.AddEditProperties) + bpy.types.Scene.DeletePsets = bpy.props.CollectionProperty(type=prop.DeletePsets) def unregister(): del bpy.types.Object.PsetProperties @@ -62,3 +77,6 @@ def unregister(): del bpy.types.Scene.ResourcePsetProperties del bpy.types.Scene.ProfilePsetProperties del bpy.types.Scene.WorkSchedulePsetProperties + del bpy.types.Scene.RenameProperties + del bpy.types.Scene.AddEditProperties + del bpy.types.Scene.DeletePsets diff --git a/src/blenderbim/blenderbim/bim/module/pset/operator.py b/src/blenderbim/blenderbim/bim/module/pset/operator.py index b306ebba76..0813a32739 100644 --- a/src/blenderbim/blenderbim/bim/module/pset/operator.py +++ b/src/blenderbim/blenderbim/bim/module/pset/operator.py @@ -101,7 +101,6 @@ class EnablePsetEditing(bpy.types.Operator): def execute(self, context): self.props = get_pset_props(context, self.obj, self.obj_type) - self.props.properties.clear() data = Data.psets if self.pset_id in Data.psets else Data.qtos @@ -374,3 +373,159 @@ class CopyPropertyToSelection(bpy.types.Operator, Operator): prop_name=self.name, prop_value=prop_value, ) + + +class BIM_OT_add_property_to_edit(bpy.types.Operator): + bl_label = "Add new row" + bl_idname = "bim.add_property_to_edit" + bl_options = {"REGISTER", "UNDO"} + option: bpy.props.StringProperty() + + def execute(self, context): + getattr(context.scene, self.option).add() + return {"FINISHED"} + + +class BIM_OT_remove_property_to_edit(bpy.types.Operator): + bl_label = "Remove property to be renamed" + bl_idname = "bim.remove_property_to_edit" + bl_options = {"REGISTER", "UNDO"} + index: bpy.props.IntProperty() + option: bpy.props.StringProperty() + + def execute(self, context): + getattr(context.scene, self.option).remove(self.index) + return {"FINISHED"} + + +class BIM_OT_clear_list(bpy.types.Operator): + bl_label = "Clear list of properties" + bl_idname = "bim.clear_list" + bl_options = {"REGISTER", "UNDO"} + option: bpy.props.StringProperty() + + def execute(self, context): + getattr(context.scene, self.option).clear() + return {"FINISHED"} + + +class BIM_OT_rename_parameters(bpy.types.Operator): + bl_label = "Rename Parameters" + bl_idname = "bim.rename_parameters" + bl_options = {"REGISTER", "UNDO"} + bl_description = "Rename parameters that are subclasses of IfcElement" + + def execute(self, context): + return IfcStore.execute_ifc_operator(self, context) + + def _execute(self, context): + props_to_map = context.scene.RenameProperties + ifc_file = IfcStore.get_file() + all_ifc_elements = ifc_file.by_type("IfcElement") + + for ifc_element in all_ifc_elements: + for definition in ifc_element.IsDefinedBy: + if definition.is_a('IfcRelDefinesByProperties'): + prop_set = definition.RelatingPropertyDefinition + self.rename_property(prop_set, props_to_map, ifc_element) + + self.report({'INFO'}, 'Finished applying changes') + return {"FINISHED"} + + def rename_property(self, property_set, properties_to_map, ifc_element): + if property_set.is_a() == "IfcPropertySet": + property_container = property_set.HasProperties + elif property_set.is_a() == "IfcElementQuantity": + property_container = property_set.Quantities + + for obj_prop in property_container: + for prop2map in properties_to_map: + if prop2map.pset_name != property_set.Name: + continue + if prop2map.existing_property_name == obj_prop.Name: + obj_prop.Name = prop2map.new_property_name + Data.load(IfcStore.get_file(), ifc_element.id()) + + +class BIM_OT_add_edit_custom_property(bpy.types.Operator): + bl_label = "Add or edit a custom property" + bl_idname = "bim.add_edit_custom_property" + bl_options = {"REGISTER", "UNDO"} + index: bpy.props.IntProperty() + + def execute(self, context): + return IfcStore.execute_ifc_operator(self, context) + + def _execute(self, context): + self.file = IfcStore.get_file() + selected_objects = context.selected_objects + props = context.scene.AddEditProperties + + for obj in selected_objects: + ifc_definition_id = obj.BIMObjectProperties.ifc_definition_id + if not ifc_definition_id: + continue + ifc_element = tool.Ifc.get().by_id(ifc_definition_id) + + for prop in props: + value = getattr(prop, prop.get_value_name()) + primary_measure_type = prop.primary_measure_type + value_ifc_entity = getattr(self.file, f"create{primary_measure_type}")(value) + + new_pset = ifcopenshell.api.run( + "pset.add_pset", + self.file, + product=ifc_element, + name=prop.pset_name + ) + ifcopenshell.api.run( + "pset.edit_pset", + self.file, + pset=new_pset, + properties={prop.property_name:value_ifc_entity} + ) + + self.report({'INFO'}, 'Finished applying changes') + return {"FINISHED"} + + +class BIM_OT_bulk_remove_psets(bpy.types.Operator): + bl_label = "Bulk remove psets from selected objects" + bl_idname = "bim.bulk_remove_psets" + bl_options = {"REGISTER", "UNDO"} + bl_description = "Bulk remove psets from selected objects" + index: bpy.props.IntProperty() + + def execute(self, context): + return IfcStore.execute_ifc_operator(self, context) + + def _execute(self, context): + self.file = IfcStore.get_file() + selected_objects = context.selected_objects + props = context.scene.DeletePsets + + for obj in selected_objects: + ifc_definition_id = obj.BIMObjectProperties.ifc_definition_id + if not ifc_definition_id: + continue + ifc_element = tool.Ifc.get().by_id(ifc_definition_id) + psets = ifcopenshell.util.element.get_psets(ifc_element) + + for prop in props: + pset = prop.pset_name + if pset in psets: + try: + ifcopenshell.api.run( + "pset.remove_pset", + self.file, + **{ + "product": self.file.by_id(ifc_definition_id), + "pset": self.file.by_id(psets[pset]["id"]), + }, + ) + except KeyError: + pass #Sometimes the pset id is not found, I'm not sure why this happens though. - vulevukusej + Data.load(IfcStore.get_file(), ifc_definition_id) + + self.report({'INFO'}, 'Finished applying changes') + return {"FINISHED"} \ No newline at end of file diff --git a/src/blenderbim/blenderbim/bim/module/pset/prop.py b/src/blenderbim/blenderbim/bim/module/pset/prop.py index ba96a34555..153b89c4aa 100644 --- a/src/blenderbim/blenderbim/bim/module/pset/prop.py +++ b/src/blenderbim/blenderbim/bim/module/pset/prop.py @@ -18,7 +18,8 @@ import bpy import blenderbim.bim.schema -from blenderbim.bim.prop import Attribute +from blenderbim.bim.prop import Attribute, PRIMARY_MEASURE_TYPE +import ifcopenshell from ifcopenshell.api.pset.data import Data from blenderbim.bim.ifc import IfcStore from bpy.types import PropertyGroup @@ -173,3 +174,42 @@ class WorkSchedulePsetProperties(PropertyGroup): active_pset_name: StringProperty(name="Pset Name") properties: CollectionProperty(name="Properties", type=Attribute) pset_name: EnumProperty(items=getWorkSchedulePsetNames, name="Pset Name") + + +class RenameProperties(PropertyGroup): + pset_name: StringProperty(name="Pset") + existing_property_name: StringProperty(name="Existing Property Name") + new_property_name: StringProperty(name="New Property Name") + + +class AddEditProperties(PropertyGroup): + pset_name: StringProperty(name="Pset") + property_name: StringProperty(name="Property") + string_value: StringProperty(name="Value") + bool_value: BoolProperty(name="Value") + int_value: IntProperty(name="Value") + float_value: FloatProperty(name="Value") + primary_measure_type: EnumProperty( + items=[ + (x, x, "") + for x in PRIMARY_MEASURE_TYPE + ], + default="IfcLabel", + name="Primary Measure Type" + ) + + def get_value_name(self): + ifc_data_type = IfcStore.get_schema().declaration_by_name(self.primary_measure_type) + data_type = ifcopenshell.util.attribute.get_primitive_type(ifc_data_type) + if data_type == "string": + return "string_value" + elif data_type == "boolean": + return "bool_value" + elif data_type == "integer": + return "int_value" + elif data_type == "float": + return "float_value" + + +class DeletePsets(PropertyGroup): + pset_name: StringProperty(name="Pset") diff --git a/src/blenderbim/blenderbim/bim/module/pset/ui.py b/src/blenderbim/blenderbim/bim/module/pset/ui.py index a7247daf0f..0beb3882f3 100644 --- a/src/blenderbim/blenderbim/bim/module/pset/ui.py +++ b/src/blenderbim/blenderbim/bim/module/pset/ui.py @@ -375,3 +375,117 @@ class BIM_PT_work_schedule_psets(Panel): for pset in WorkSchedulePsetsData.data["psets"]: draw_psetqto_ui(context, pset["id"], pset, props, self.layout, "WorkSchedule") + + +class BIM_PT_bulk_property_editor(Panel): + bl_label = "IFC Bulk Property Editor" + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "object" + + def draw(self, context): + pass + + +class BIM_PT_rename_parameters(Panel): + bl_label = "Rename all building elements" + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "object" + bl_parent_id = "BIM_PT_bulk_property_editor" + bl_options = {"DEFAULT_CLOSED"} + bl_order = 0 + + def draw(self, context): + layout = self.layout + props = context.scene.RenameProperties + + if props: + for index, prop in enumerate(props): + row = layout.row() + row.prop(prop, "pset_name", text="") + row.prop(prop, "existing_property_name", text="") + row.prop(prop, "new_property_name", text="") + op = row.operator("bim.remove_property_to_edit",icon="PANEL_CLOSE", text="") + op.index = index + op.option = "RenameProperties" + + row = layout.row() + row.label() + op = row.operator("bim.add_property_to_edit", icon="ADD",text="") + op.option = "RenameProperties" + + if props: + row = layout.row() + clear = row.operator("bim.clear_list") + clear.option = "RenameProperties" + row.operator("bim.rename_parameters") + + +class BIM_PT_add_edit_custom_properties(Panel): + bl_label = "Add/Edit Custom Properties and Values (to selected objects)" + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "object" + bl_parent_id = "BIM_PT_bulk_property_editor" + bl_options = {"DEFAULT_CLOSED"} + bl_order = 1 + + def draw(self, context): + layout = self.layout + props = context.scene.AddEditProperties + + if props: + for index, prop in enumerate(props): + row = layout.row() + row.prop(prop, "pset_name", text="") + row.prop(prop, "property_name", text="") + row.prop(prop, prop.get_value_name(), text="") + row.prop(prop, "primary_measure_type", text="") + op = row.operator("bim.remove_property_to_edit",icon="PANEL_CLOSE", text="") + op.index = index + op.option = "AddEditProperties" + + row = layout.row() + row.label() + op = row.operator("bim.add_property_to_edit", icon="ADD",text="") + op.option = "AddEditProperties" + + if props: + row = layout.row() + clear = row.operator("bim.clear_list") + clear.option = "AddEditProperties" + op = row.operator("bim.add_edit_custom_property",icon="ADD", text="Apply Changes") + + +class BIM_PT_delete_psets(Panel): + bl_label = "Bulk remove psets from selected objects" + bl_space_type = 'PROPERTIES' + bl_region_type = 'WINDOW' + bl_context = "object" + bl_parent_id = "BIM_PT_bulk_property_editor" + bl_options = {"DEFAULT_CLOSED"} + bl_order = 2 + + def draw(self, context): + layout = self.layout + props = context.scene.DeletePsets + + if props: + for index, prop in enumerate(props): + row = layout.row() + row.prop(prop, "pset_name", text="Pset") + op = row.operator("bim.remove_property_to_edit",icon="PANEL_CLOSE", text="") + op.index = index + op.option = "DeletePsets" + + row = layout.row(align=True) + row.label() + op = row.operator("bim.add_property_to_edit", icon="ADD",text="") + op.option = "DeletePsets" + + if props: + row = layout.row() + clear = row.operator("bim.clear_list") + clear.option = "DeletePsets" + op = row.operator("bim.bulk_remove_psets", text="Apply Changes") diff --git a/src/blenderbim/blenderbim/bim/module/pset_template/prop.py b/src/blenderbim/blenderbim/bim/module/pset_template/prop.py index 6f41a98a23..9ec6925cb5 100644 --- a/src/blenderbim/blenderbim/bim/module/pset_template/prop.py +++ b/src/blenderbim/blenderbim/bim/module/pset_template/prop.py @@ -19,7 +19,7 @@ import os import bpy import ifcopenshell -from blenderbim.bim.prop import StrProperty, Attribute +from blenderbim.bim.prop import StrProperty, Attribute, PRIMARY_MEASURE_TYPE from blenderbim.bim.ifc import IfcStore from bpy.types import PropertyGroup from bpy.props import ( @@ -146,116 +146,7 @@ class PropTemplate(PropertyGroup): primary_measure_type: EnumProperty( items=[ (x, x, "") - for x in [ - "IfcInteger", - "IfcReal", - "IfcBoolean", - "IfcIdentifier", - "IfcText", - "IfcLabel", - "IfcLogical", - "IfcDateTime", - "IfcDate", - "IfcTime", - "IfcDuration", - "IfcTimeStamp", - "IfcPositiveInteger", - "IfcBinary", - "IfcVolumeMeasure", - "IfcTimeMeasure", - "IfcThermodynamicTemperatureMeasure", - "IfcSolidAngleMeasure", - "IfcPositiveRatioMeasure", - "IfcRatioMeasure", - "IfcPositivePlaneAngleMeasure", - "IfcPlaneAngleMeasure", - "IfcParameterValue", - "IfcNumericMeasure", - "IfcMassMeasure", - "IfcPositiveLengthMeasure", - "IfcLengthMeasure", - "IfcElectricCurrentMeasure", - "IfcDescriptiveMeasure", - "IfcCountMeasure", - "IfcContextDependentMeasure", - "IfcAreaMeasure", - "IfcAmountOfSubstanceMeasure", - "IfcLuminousIntensityMeasure", - "IfcNormalisedRatioMeasure", - "IfcComplexNumber", - "IfcNonNegativeLengthMeasure", - "IfcAbsorbedDoseMeasure", - "IfcAccelerationMeasure", - "IfcAngularVelocityMeasure", - "IfcAreaDensityMeasure", - "IfcCompoundPlaneAngleMeasure", - "IfcCurvatureMeasure", - "IfcDoseEquivalentMeasure", - "IfcDynamicViscosityMeasure", - "IfcElectricCapacitanceMeasure", - "IfcElectricChargeMeasure", - "IfcElectricConductanceMeasure", - "IfcElectricResistanceMeasure", - "IfcElectricVoltageMeasure", - "IfcEnergyMeasure", - "IfcForceMeasure", - "IfcFrequencyMeasure", - "IfcHeatFluxDensityMeasure", - "IfcHeatingValueMeasure", - "IfcIlluminanceMeasure", - "IfcInductanceMeasure", - "IfcIntegerCountRateMeasure", - "IfcIonConcentrationMeasure", - "IfcIsothermalMoistureCapacityMeasure", - "IfcKinematicViscosityMeasure", - "IfcLinearForceMeasure", - "IfcLinearMomentMeasure", - "IfcLinearStiffnessMeasure", - "IfcLinearVelocityMeasure", - "IfcLuminousFluxMeasure", - "IfcLuminousIntensityDistributionMeasure", - "IfcMagneticFluxDensityMeasure", - "IfcMagneticFluxMeasure", - "IfcMassDensityMeasure", - "IfcMassFlowRateMeasure", - "IfcMassPerLengthMeasure", - "IfcModulusOfElasticityMeasure", - "IfcModulusOfLinearSubgradeReactionMeasure", - "IfcModulusOfRotationalSubgradeReactionMeasure", - "IfcModulusOfSubgradeReactionMeasure", - "IfcMoistureDiffusivityMeasure", - "IfcMolecularWeightMeasure", - "IfcMomentOfInertiaMeasure", - "IfcMonetaryMeasure", - "IfcPHMeasure", - "IfcPlanarForceMeasure", - "IfcPowerMeasure", - "IfcPressureMeasure", - "IfcRadioActivityMeasure", - "IfcRotationalFrequencyMeasure", - "IfcRotationalMassMeasure", - "IfcRotationalStiffnessMeasure", - "IfcSectionModulusMeasure", - "IfcSectionalAreaIntegralMeasure", - "IfcShearModulusMeasure", - "IfcSoundPowerLevelMeasure", - "IfcSoundPowerMeasure", - "IfcSoundPressureLevelMeasure", - "IfcSoundPressureMeasure", - "IfcSpecificHeatCapacityMeasure", - "IfcTemperatureGradientMeasure", - "IfcTemperatureRateOfChangeMeasure", - "IfcThermalAdmittanceMeasure", - "IfcThermalConductivityMeasure", - "IfcThermalExpansionCoefficientMeasure", - "IfcThermalResistanceMeasure", - "IfcThermalTransmittanceMeasure", - "IfcTorqueMeasure", - "IfcVaporPermeabilityMeasure", - "IfcVolumetricFlowRateMeasure", - "IfcWarpingConstantMeasure", - "IfcWarpingMomentMeasure", - ] + for x in PRIMARY_MEASURE_TYPE ], name="Primary Measure Type", ) diff --git a/src/blenderbim/blenderbim/bim/prop.py b/src/blenderbim/blenderbim/bim/prop.py index 4fbb62f62b..ba3d983c0a 100644 --- a/src/blenderbim/blenderbim/bim/prop.py +++ b/src/blenderbim/blenderbim/bim/prop.py @@ -40,6 +40,117 @@ cwd = os.path.dirname(os.path.realpath(__file__)) materialpsetnames_enum = [] +PRIMARY_MEASURE_TYPE = [ + "IfcInteger", + "IfcReal", + "IfcBoolean", + "IfcIdentifier", + "IfcText", + "IfcLabel", + "IfcLogical", + "IfcDateTime", + "IfcDate", + "IfcTime", + "IfcDuration", + "IfcTimeStamp", + "IfcPositiveInteger", + "IfcBinary", + "IfcVolumeMeasure", + "IfcTimeMeasure", + "IfcThermodynamicTemperatureMeasure", + "IfcSolidAngleMeasure", + "IfcPositiveRatioMeasure", + "IfcRatioMeasure", + "IfcPositivePlaneAngleMeasure", + "IfcPlaneAngleMeasure", + "IfcParameterValue", + "IfcNumericMeasure", + "IfcMassMeasure", + "IfcPositiveLengthMeasure", + "IfcLengthMeasure", + "IfcElectricCurrentMeasure", + "IfcDescriptiveMeasure", + "IfcCountMeasure", + "IfcContextDependentMeasure", + "IfcAreaMeasure", + "IfcAmountOfSubstanceMeasure", + "IfcLuminousIntensityMeasure", + "IfcNormalisedRatioMeasure", + "IfcComplexNumber", + "IfcNonNegativeLengthMeasure", + "IfcAbsorbedDoseMeasure", + "IfcAccelerationMeasure", + "IfcAngularVelocityMeasure", + "IfcAreaDensityMeasure", + "IfcCompoundPlaneAngleMeasure", + "IfcCurvatureMeasure", + "IfcDoseEquivalentMeasure", + "IfcDynamicViscosityMeasure", + "IfcElectricCapacitanceMeasure", + "IfcElectricChargeMeasure", + "IfcElectricConductanceMeasure", + "IfcElectricResistanceMeasure", + "IfcElectricVoltageMeasure", + "IfcEnergyMeasure", + "IfcForceMeasure", + "IfcFrequencyMeasure", + "IfcHeatFluxDensityMeasure", + "IfcHeatingValueMeasure", + "IfcIlluminanceMeasure", + "IfcInductanceMeasure", + "IfcIntegerCountRateMeasure", + "IfcIonConcentrationMeasure", + "IfcIsothermalMoistureCapacityMeasure", + "IfcKinematicViscosityMeasure", + "IfcLinearForceMeasure", + "IfcLinearMomentMeasure", + "IfcLinearStiffnessMeasure", + "IfcLinearVelocityMeasure", + "IfcLuminousFluxMeasure", + "IfcLuminousIntensityDistributionMeasure", + "IfcMagneticFluxDensityMeasure", + "IfcMagneticFluxMeasure", + "IfcMassDensityMeasure", + "IfcMassFlowRateMeasure", + "IfcMassPerLengthMeasure", + "IfcModulusOfElasticityMeasure", + "IfcModulusOfLinearSubgradeReactionMeasure", + "IfcModulusOfRotationalSubgradeReactionMeasure", + "IfcModulusOfSubgradeReactionMeasure", + "IfcMoistureDiffusivityMeasure", + "IfcMolecularWeightMeasure", + "IfcMomentOfInertiaMeasure", + "IfcMonetaryMeasure", + "IfcPHMeasure", + "IfcPlanarForceMeasure", + "IfcPowerMeasure", + "IfcPressureMeasure", + "IfcRadioActivityMeasure", + "IfcRotationalFrequencyMeasure", + "IfcRotationalMassMeasure", + "IfcRotationalStiffnessMeasure", + "IfcSectionModulusMeasure", + "IfcSectionalAreaIntegralMeasure", + "IfcShearModulusMeasure", + "IfcSoundPowerLevelMeasure", + "IfcSoundPowerMeasure", + "IfcSoundPressureLevelMeasure", + "IfcSoundPressureMeasure", + "IfcSpecificHeatCapacityMeasure", + "IfcTemperatureGradientMeasure", + "IfcTemperatureRateOfChangeMeasure", + "IfcThermalAdmittanceMeasure", + "IfcThermalConductivityMeasure", + "IfcThermalExpansionCoefficientMeasure", + "IfcThermalResistanceMeasure", + "IfcThermalTransmittanceMeasure", + "IfcTorqueMeasure", + "IfcVaporPermeabilityMeasure", + "IfcVolumetricFlowRateMeasure", + "IfcWarpingConstantMeasure", + "IfcWarpingMomentMeasure", + ] + def update_preset(self, context): from blenderbim.bim.data.ui.presets import presets