diff --git a/src/blenderbim/blenderbim/bim/import_ifc.py b/src/blenderbim/blenderbim/bim/import_ifc.py index d58a97108b..7af955b97d 100644 --- a/src/blenderbim/blenderbim/bim/import_ifc.py +++ b/src/blenderbim/blenderbim/bim/import_ifc.py @@ -1929,6 +1929,7 @@ class IfcImporter: offset_point = np.linalg.inv(mat) @ offset_point verts = [None] * len(geometry.verts) for i in range(0, len(geometry.verts), 3): + # Note: this enh2xyz call is crazy slow. verts[i], verts[i + 1], verts[i + 2] = ifcopenshell.util.geolocation.enh2xyz( geometry.verts[i], geometry.verts[i + 1], diff --git a/src/blenderbim/blenderbim/bim/module/pset_template/operator.py b/src/blenderbim/blenderbim/bim/module/pset_template/operator.py index 895b512b65..e33f6d6c05 100644 --- a/src/blenderbim/blenderbim/bim/module/pset_template/operator.py +++ b/src/blenderbim/blenderbim/bim/module/pset_template/operator.py @@ -268,7 +268,6 @@ class RemovePropTemplate(bpy.types.Operator, Operator): prop_template: bpy.props.IntProperty() def _execute(self, context): - props = context.scene.BIMPsetTemplateProperties ifcopenshell.api.run( "pset_template.remove_prop_template", IfcStore.pset_template_file, @@ -287,21 +286,21 @@ class EditPropTemplate(bpy.types.Operator, Operator): def _execute(self, context): props = context.scene.BIMPsetTemplateProperties if props.active_prop_template.template_type == "P_ENUMERATEDVALUE": - enumerator = self.generate_prop_enum(props) + data_type = props.active_prop_template.get_value_name() + prop = props.active_prop_template + enumerators = [getattr(ev, data_type) for ev in prop.enum_values] else: - enumerator = None + enumerators = None ifcopenshell.api.run( "pset_template.edit_prop_template", IfcStore.pset_template_file, - **{ - "prop_template": IfcStore.pset_template_file.by_id(props.active_prop_template_id), - "attributes": { - "Name": props.active_prop_template.name, - "Description": props.active_prop_template.description, - "PrimaryMeasureType": props.active_prop_template.primary_measure_type, - "TemplateType": props.active_prop_template.template_type, - "Enumerators": enumerator, - }, + prop_template=IfcStore.pset_template_file.by_id(props.active_prop_template_id), + attributes={ + "Name": props.active_prop_template.name, + "Description": props.active_prop_template.description, + "PrimaryMeasureType": props.active_prop_template.primary_measure_type, + "TemplateType": props.active_prop_template.template_type, + "Enumerators": enumerators, } ) bpy.ops.bim.disable_editing_prop_template() @@ -309,18 +308,3 @@ class EditPropTemplate(bpy.types.Operator, Operator): blenderbim.bim.handler.refresh_ui_data() if tool.Ifc.get(): blenderbim.bim.schema.reload(tool.Ifc.get().schema) - - # TODO -This will need to go into the - # api code at some point - vulevukusej - def generate_prop_enum(self, props): - self.file = IfcStore.pset_template_file - data_type = props.active_prop_template.get_value_name() - prop = props.active_prop_template - prop_enum = self.file.create_entity( - "IFCPROPERTYENUMERATION", - Name=prop.name, - EnumerationValues=tuple( - self.file.create_entity(prop.primary_measure_type, getattr(ev, data_type)) for ev in prop.enum_values - ), - ) - return prop_enum diff --git a/src/ifcopenshell-python/ifcopenshell/api/pset_template/edit_prop_template.py b/src/ifcopenshell-python/ifcopenshell/api/pset_template/edit_prop_template.py index 7a6d33990b..5c738bf8e0 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/pset_template/edit_prop_template.py +++ b/src/ifcopenshell-python/ifcopenshell/api/pset_template/edit_prop_template.py @@ -47,7 +47,20 @@ def edit_prop_template( ifcopenshell.api.run("pset_template.edit_prop_template", model, prop_template=prop, attributes={"Name": "DemoA", "PrimaryMeasureType": "IfcLengthMeasure"}) """ - settings = {"prop_template": prop_template, "attributes": attributes} + if enum_values := attributes.get("Enumerators", None): + prop_name = attributes.get("Name", None) or getattr(prop_template, "Name", None) or "Unnamed" + primary_measure_type = ( + attributes.get("PrimaryMeasureType", None) or getattr(prop_template, "PrimaryMeasureType", None) or "IfcLabel" + ) + enum_values = [file.create_entity(primary_measure_type, v) for v in enum_values] + if enumerators := prop_template.Enumerators: + enumerators.Name = prop_name + enumerators.EnumerationValues = enum_values + else: + prop_template.Enumerators = file.create_entity("IfcPropertyEnumeration", prop_name, enum_values) - for name, value in settings["attributes"].items(): - setattr(settings["prop_template"], name, value) + if "Enumerators" in attributes: + del attributes["Enumerators"] + + for name, value in attributes.items(): + setattr(prop_template, name, value) diff --git a/src/ifcopenshell-python/test/api/pset_template/__init__.py b/src/ifcopenshell-python/test/api/pset_template/__init__.py new file mode 100644 index 0000000000..8bed51a56f --- /dev/null +++ b/src/ifcopenshell-python/test/api/pset_template/__init__.py @@ -0,0 +1,17 @@ +# IfcOpenShell - IFC toolkit and geometry engine +# Copyright (C) 2021 Dion Moult +# +# This file is part of IfcOpenShell. +# +# IfcOpenShell is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# IfcOpenShell 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with IfcOpenShell. If not, see . diff --git a/src/ifcopenshell-python/test/api/pset_template/test_edit_prop_template.py b/src/ifcopenshell-python/test/api/pset_template/test_edit_prop_template.py new file mode 100644 index 0000000000..18522189fc --- /dev/null +++ b/src/ifcopenshell-python/test/api/pset_template/test_edit_prop_template.py @@ -0,0 +1,62 @@ +# IfcOpenShell - IFC toolkit and geometry engine +# Copyright (C) 2021 Dion Moult +# +# This file is part of IfcOpenShell. +# +# IfcOpenShell is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# IfcOpenShell 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with IfcOpenShell. If not, see . + +import test.bootstrap +import ifcopenshell.api + + +class TestEditPropTemplate(test.bootstrap.IFC4): + def test_editing_a_simple_template(self): + template = ifcopenshell.api.run("pset_template.add_pset_template", self.file, name="ABC_RiskFactors") + prop = ifcopenshell.api.run("pset_template.add_prop_template", self.file, pset_template=template) + ifcopenshell.api.run( + "pset_template.edit_prop_template", + self.file, + prop_template=prop, + attributes={"Name": "DemoA", "PrimaryMeasureType": "IfcLabel"}, + ) + ifcopenshell.api.run( + "pset_template.edit_prop_template", self.file, prop_template=prop, attributes={"Name": "DemoB"} + ) + assert prop.Name == "DemoB" + + def test_editing_an_enumeration(self): + template = ifcopenshell.api.run("pset_template.add_pset_template", self.file, name="ABC_RiskFactors") + prop = ifcopenshell.api.run("pset_template.add_prop_template", self.file, pset_template=template) + ifcopenshell.api.run( + "pset_template.edit_prop_template", + self.file, + prop_template=prop, + attributes={"Name": "DemoA", "PrimaryMeasureType": "IfcLabel"}, + ) + ifcopenshell.api.run( + "pset_template.edit_prop_template", + self.file, + prop_template=prop, + attributes={"Enumerators": ["FOO", "BAR"]}, + ) + assert prop.Enumerators.EnumerationValues == tuple(self.file.createIfcLabel(v) for v in ("FOO", "BAR")) + ifcopenshell.api.run( + "pset_template.edit_prop_template", + self.file, + prop_template=prop, + attributes={"Name": "DemoC", "Enumerators": ["BAZ", "BAR"]}, + ) + assert prop.Enumerators.Name == "DemoC" + assert prop.Enumerators.EnumerationValues == tuple(self.file.createIfcLabel(v) for v in ("BAZ", "BAR")) + assert len(self.file.by_type("IfcPropertyEnumeration")) == 1