From afd5a5b23e87d2b189fe6b3ff57b0d9b6f52d1c9 Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Thu, 29 Aug 2024 18:42:43 +0500 Subject: [PATCH] Fix get_info_2 #5248 after d80bcd1 --- .../test/test_entity_instance.py | 60 +++++++++++++++++++ src/ifcwrap/IfcParseWrapper.i | 19 ++++++ 2 files changed, 79 insertions(+) create mode 100644 src/ifcopenshell-python/test/test_entity_instance.py diff --git a/src/ifcopenshell-python/test/test_entity_instance.py b/src/ifcopenshell-python/test/test_entity_instance.py new file mode 100644 index 0000000000..a07c9cdade --- /dev/null +++ b/src/ifcopenshell-python/test/test_entity_instance.py @@ -0,0 +1,60 @@ +# IfcOpenShell - IFC toolkit and geometry engine +# Copyright (C) 2021 Thomas Krijnen +# +# 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 pytest +import test.bootstrap +import ifcopenshell +import ifcopenshell.api +import ifcopenshell.util.element + + +class TestGetInfo2(test.bootstrap.IFC4): + def test_instance_attribute(self): + brep = self.file.create_entity("IfcFacetedBrep") + shell = self.file.create_entity("IfcClosedShell") + brep.Outer = shell + assert brep.get_info_2(recursive=True) == { + "Outer": {"CfsFaces": None, "id": 2, "type": "IfcClosedShell"}, + "id": 1, + "type": "IfcFacetedBrep", + } + + def test_aggregate_of_instance_attribute(self): + shell = self.file.create_entity("IfcClosedShell") + faces = [self.file.create_entity("IfcFace") for i in range(3)] + shell.CfsFaces = faces + assert shell.get_info_2(recursive=True)["CfsFaces"] == ( + {"Bounds": None, "id": 2, "type": "IfcFace"}, + {"Bounds": None, "id": 3, "type": "IfcFace"}, + {"Bounds": None, "id": 4, "type": "IfcFace"}, + ) + + def test_aggregate_of_aggregate_of_instance_attribute(self): + surface = self.file.create_entity("IfcBSplineSurfaceWithKnots") + pp = [self.file.create_entity("IfcCartesianPoint", [float(i)]) for i in range(4)] + surface.ControlPointsList = [pp[:2], pp[2:]] + assert surface.get_info_2(recursive=True)["ControlPointsList"] == ( + ( + {"Coordinates": (0.0,), "id": 2, "type": "IfcCartesianPoint"}, + {"Coordinates": (1.0,), "id": 3, "type": "IfcCartesianPoint"}, + ), + ( + {"Coordinates": (2.0,), "id": 4, "type": "IfcCartesianPoint"}, + {"Coordinates": (3.0,), "id": 5, "type": "IfcCartesianPoint"}, + ), + ) diff --git a/src/ifcwrap/IfcParseWrapper.i b/src/ifcwrap/IfcParseWrapper.i index cff9922693..3a30620670 100644 --- a/src/ifcwrap/IfcParseWrapper.i +++ b/src/ifcwrap/IfcParseWrapper.i @@ -773,6 +773,25 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas Py_INCREF(Py_None); return static_cast(Py_None); } + } else if constexpr (std::is_same_v) { + return get_info_cpp(v); + } else if constexpr (std::is_same_v) { + auto r = PyTuple_New(v->size()); + for (unsigned i = 0; i < v->size(); ++i) { + PyTuple_SetItem(r, i, get_info_cpp((*v)[i])); + } + return r; + } else if constexpr (std::is_same_v) { + auto rs = PyTuple_New(v->size()); + for (auto it = v->begin(); it != v->end(); ++it) { + auto v_i = it; + auto r = PyTuple_New(v_i->size()); + for (unsigned i = 0; i < v_i->size(); ++i) { + PyTuple_SetItem(r, i, get_info_cpp((*v_i)[i])); + } + PyTuple_SetItem(rs, std::distance(v->begin(), it), r); + } + return rs; } else if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) { Py_INCREF(Py_None); return static_cast(Py_None);