From 84096529e12c098a6fe308a328a3ec64f114bd27 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Fri, 7 Jan 2022 14:55:37 +1100 Subject: [PATCH] Primary measure type lists are now dynamically generated based on the schema. --- src/blenderbim/blenderbim/bim/ifc.py | 4 +- .../blenderbim/bim/module/pset/__init__.py | 3 +- .../blenderbim/bim/module/pset/data.py | 16 +++ .../blenderbim/bim/module/pset/operator.py | 44 +++---- .../blenderbim/bim/module/pset/prop.py | 18 +-- .../bim/module/pset_template/data.py | 39 ++++++ .../bim/module/pset_template/prop.py | 17 +-- src/blenderbim/blenderbim/bim/prop.py | 113 +----------------- src/blenderbim/blenderbim/core/structural.py | 2 +- src/blenderbim/blenderbim/tool/ifc.py | 4 + 10 files changed, 102 insertions(+), 158 deletions(-) create mode 100644 src/blenderbim/blenderbim/bim/module/pset_template/data.py diff --git a/src/blenderbim/blenderbim/bim/ifc.py b/src/blenderbim/blenderbim/bim/ifc.py index be613099b9..f8a3f978ff 100644 --- a/src/blenderbim/blenderbim/bim/ifc.py +++ b/src/blenderbim/blenderbim/bim/ifc.py @@ -119,7 +119,9 @@ class IfcStore: @staticmethod def get_schema(): if IfcStore.file is None: - return + IfcStore.schema = ifcopenshell.ifcopenshell_wrapper.schema_by_name( + bpy.context.scene.BIMProjectProperties.export_schema + ) elif IfcStore.schema is None: IfcStore.schema = ifcopenshell.ifcopenshell_wrapper.schema_by_name(IfcStore.file.schema) return IfcStore.schema diff --git a/src/blenderbim/blenderbim/bim/module/pset/__init__.py b/src/blenderbim/blenderbim/bim/module/pset/__init__.py index dc5e2092ee..f86950c3b2 100644 --- a/src/blenderbim/blenderbim/bim/module/pset/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/pset/__init__.py @@ -55,7 +55,7 @@ classes = ( ui.BIM_PT_bulk_property_editor, ui.BIM_PT_rename_parameters, ui.BIM_PT_add_edit_custom_properties, - ui.BIM_PT_delete_psets + ui.BIM_PT_delete_psets, ) @@ -70,6 +70,7 @@ def register(): 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 del bpy.types.Material.PsetProperties diff --git a/src/blenderbim/blenderbim/bim/module/pset/data.py b/src/blenderbim/blenderbim/bim/module/pset/data.py index 6e041bf29c..06ce5d638a 100644 --- a/src/blenderbim/blenderbim/bim/module/pset/data.py +++ b/src/blenderbim/blenderbim/bim/module/pset/data.py @@ -34,6 +34,7 @@ def refresh(): ResourcePsetsData.is_loaded = False ProfilePsetsData.is_loaded = False WorkSchedulePsetsData.is_loaded = False + AddEditCustomPropertiesData.is_loaded = False class Data: @@ -156,3 +157,18 @@ class WorkSchedulePsetsData(Data): ifc_definition_id = bpy.context.scene.BIMWorkScheduleProperties.active_work_schedule_id cls.data = {"psets": cls.psetqtos(tool.Ifc.get().by_id(ifc_definition_id), psets_only=True)} cls.is_loaded = True + + +class AddEditCustomPropertiesData: + data = {} + is_loaded = False + + @classmethod + def load(cls): + cls.data = {"primary_measure_type": cls.primary_measure_type()} + cls.is_loaded = True + + @classmethod + def primary_measure_type(cls): + schema = tool.Ifc.schema() + return [(t, t, "") for t in sorted([d.name() for d in schema.declarations() if hasattr(d, "declared_type")])] diff --git a/src/blenderbim/blenderbim/bim/module/pset/operator.py b/src/blenderbim/blenderbim/bim/module/pset/operator.py index 8bc6949d70..63caea9eff 100644 --- a/src/blenderbim/blenderbim/bim/module/pset/operator.py +++ b/src/blenderbim/blenderbim/bim/module/pset/operator.py @@ -426,11 +426,11 @@ class BIM_OT_rename_parameters(bpy.types.Operator): for ifc_element in all_ifc_elements: for definition in ifc_element.IsDefinedBy: - if definition.is_a('IfcRelDefinesByProperties'): + 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') + self.report({"INFO"}, "Finished applying changes") return {"FINISHED"} def rename_property(self, property_set, properties_to_map, ifc_element): @@ -472,21 +472,13 @@ class BIM_OT_add_edit_custom_property(bpy.types.Operator): 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') + 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"} @@ -509,7 +501,7 @@ class BIM_OT_bulk_remove_psets(bpy.types.Operator): ifc_definition_id = obj.BIMObjectProperties.ifc_definition_id if not ifc_definition_id: continue - ifc_element = tool.Ifc.get().by_id(ifc_definition_id) + ifc_element = tool.Ifc.get().by_id(ifc_definition_id) psets = ifcopenshell.util.element.get_psets(ifc_element) for prop in props: @@ -517,16 +509,16 @@ class BIM_OT_bulk_remove_psets(bpy.types.Operator): 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"]), - }, + "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 + 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 + self.report({"INFO"}, "Finished applying changes") + return {"FINISHED"} diff --git a/src/blenderbim/blenderbim/bim/module/pset/prop.py b/src/blenderbim/blenderbim/bim/module/pset/prop.py index 153b89c4aa..0ba32460b9 100644 --- a/src/blenderbim/blenderbim/bim/module/pset/prop.py +++ b/src/blenderbim/blenderbim/bim/module/pset/prop.py @@ -18,9 +18,10 @@ import bpy import blenderbim.bim.schema -from blenderbim.bim.prop import Attribute, PRIMARY_MEASURE_TYPE +from blenderbim.bim.prop import Attribute import ifcopenshell from ifcopenshell.api.pset.data import Data +from blenderbim.bim.module.pset.data import AddEditCustomPropertiesData from blenderbim.bim.ifc import IfcStore from bpy.types import PropertyGroup from bpy.props import ( @@ -132,6 +133,12 @@ def getQtoNames(self, context): return [] +def get_primary_measure_type(self, context): + if not AddEditCustomPropertiesData.is_loaded: + AddEditCustomPropertiesData.load() + return AddEditCustomPropertiesData.data["primary_measure_type"] + + class PsetProperties(PropertyGroup): active_pset_id: IntProperty(name="Active Pset ID") active_pset_name: StringProperty(name="Pset Name") @@ -189,14 +196,7 @@ class AddEditProperties(PropertyGroup): 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" - ) + primary_measure_type: EnumProperty(items=get_primary_measure_type, name="Primary Measure Type") def get_value_name(self): ifc_data_type = IfcStore.get_schema().declaration_by_name(self.primary_measure_type) diff --git a/src/blenderbim/blenderbim/bim/module/pset_template/data.py b/src/blenderbim/blenderbim/bim/module/pset_template/data.py new file mode 100644 index 0000000000..66d40530d0 --- /dev/null +++ b/src/blenderbim/blenderbim/bim/module/pset_template/data.py @@ -0,0 +1,39 @@ +# BlenderBIM Add-on - OpenBIM Blender Add-on +# Copyright (C) 2022 Dion Moult +# +# This file is part of BlenderBIM Add-on. +# +# BlenderBIM Add-on is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# BlenderBIM Add-on is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with BlenderBIM Add-on. If not, see . + +import bpy +import blenderbim.tool as tool + + +def refresh(): + PsetTemplatesData.is_loaded = False + + +class PsetTemplatesData: + data = {} + is_loaded = False + + @classmethod + def load(cls): + cls.data = {"primary_measure_type": cls.primary_measure_type()} + cls.is_loaded = True + + @classmethod + def primary_measure_type(cls): + schema = tool.Ifc.schema() + return [(t, t, "") for t in sorted([d.name() for d in schema.declarations() if hasattr(d, "declared_type")])] diff --git a/src/blenderbim/blenderbim/bim/module/pset_template/prop.py b/src/blenderbim/blenderbim/bim/module/pset_template/prop.py index 9ec6925cb5..0d6a46a94e 100644 --- a/src/blenderbim/blenderbim/bim/module/pset_template/prop.py +++ b/src/blenderbim/blenderbim/bim/module/pset_template/prop.py @@ -19,7 +19,8 @@ import os import bpy import ifcopenshell -from blenderbim.bim.prop import StrProperty, Attribute, PRIMARY_MEASURE_TYPE +from blenderbim.bim.module.pset_template.data import PsetTemplatesData +from blenderbim.bim.prop import StrProperty, Attribute from blenderbim.bim.ifc import IfcStore from bpy.types import PropertyGroup from bpy.props import ( @@ -87,6 +88,12 @@ def getPsetTemplates(self, context): return psettemplates_enum +def get_primary_measure_type(self, context): + if not PsetTemplatesData.is_loaded: + PsetTemplatesData.load() + return PsetTemplatesData.data["primary_measure_type"] + + class PsetTemplate(PropertyGroup): global_id: StringProperty(name="Global ID") name: StringProperty(name="Name") @@ -143,13 +150,7 @@ class PropTemplate(PropertyGroup): global_id: StringProperty(name="Global ID") name: StringProperty(name="Name") description: StringProperty(name="Description") - primary_measure_type: EnumProperty( - items=[ - (x, x, "") - for x in PRIMARY_MEASURE_TYPE - ], - name="Primary Measure Type", - ) + primary_measure_type: EnumProperty(items=get_primary_measure_type, name="Primary Measure Type") class BIMPsetTemplateProperties(PropertyGroup): diff --git a/src/blenderbim/blenderbim/bim/prop.py b/src/blenderbim/blenderbim/bim/prop.py index 9fa8ff8e2a..c69170704d 100644 --- a/src/blenderbim/blenderbim/bim/prop.py +++ b/src/blenderbim/blenderbim/bim/prop.py @@ -1,5 +1,5 @@ # BlenderBIM Add-on - OpenBIM Blender Add-on -# Copyright (C) 2020, 2021 Dion Moult +# Copyright (C) 2020, 2021, 2022 Dion Moult # # This file is part of BlenderBIM Add-on. # @@ -42,117 +42,6 @@ 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 diff --git a/src/blenderbim/blenderbim/core/structural.py b/src/blenderbim/blenderbim/core/structural.py index d2b55f8263..06367c039c 100644 --- a/src/blenderbim/blenderbim/core/structural.py +++ b/src/blenderbim/blenderbim/core/structural.py @@ -51,7 +51,7 @@ def edit_structural_analysis_model(ifc, structural): **{ "structural_analysis_model": structural.get_active_structural_analysis_model(), "attributes": attributes, - } + }, ) structural.load_structural_analysis_models() structural.disable_editing_structural_analysis_model() diff --git a/src/blenderbim/blenderbim/tool/ifc.py b/src/blenderbim/blenderbim/tool/ifc.py index 7ead3b3502..198700a6b6 100644 --- a/src/blenderbim/blenderbim/tool/ifc.py +++ b/src/blenderbim/blenderbim/tool/ifc.py @@ -40,6 +40,10 @@ class Ifc(blenderbim.core.tool.Ifc): if IfcStore.get_file(): return IfcStore.get_file().schema + @classmethod + def schema(cls): + return IfcStore.get_schema() + @classmethod def get_entity(cls, obj): ifc = IfcStore.get_file()