get_info_2 to support excluding identifier

This commit is contained in:
Andrej730
2024-10-03 16:51:08 +05:00
parent 770e25dbc2
commit 8ae951d27a
3 changed files with 28 additions and 20 deletions
@@ -435,7 +435,7 @@ class entity_instance:
elif None in (self.wrapped_data.file, other.wrapped_data.file): elif None in (self.wrapped_data.file, other.wrapped_data.file):
# when not added to a file, we can only compare attribute values # when not added to a file, we can only compare attribute values
# and we need this for where rule evaluation # and we need this for where rule evaluation
return self.get_info(recursive=True, include_identifier=False) == other.get_info( return self.get_info_2(recursive=True, include_identifier=False) == other.get_info_2(
recursive=True, include_identifier=False recursive=True, include_identifier=False
) )
else: else:
@@ -632,14 +632,12 @@ class entity_instance:
Method has exactly the same signature as `.get_info()` but it doesn't support getting information non-recursively. Method has exactly the same signature as `.get_info()` but it doesn't support getting information non-recursively.
Currently supported arguments values: Currently supported arguments values:
* include_identifier: `True`
* recursive: `True` (will fail with default `False` value from `.get_info()`) * recursive: `True` (will fail with default `False` value from `.get_info()`)
* return_type: `dict` * return_type: `dict`
* ignore: `()` (empty tuple) * ignore: `()` (empty tuple)
""" """
assert include_identifier
assert recursive assert recursive
assert return_type is dict assert return_type is dict
assert len(ignore) == 0 assert len(ignore) == 0
return ifcopenshell_wrapper.get_info_cpp(self.wrapped_data) return ifcopenshell_wrapper.get_info_cpp(self.wrapped_data, include_identifier)
@@ -58,3 +58,12 @@ class TestGetInfo2(test.bootstrap.IFC4):
{"Coordinates": (3.0,), "id": 5, "type": "IfcCartesianPoint"}, {"Coordinates": (3.0,), "id": 5, "type": "IfcCartesianPoint"},
), ),
) )
def test_exclude_identifier(self):
brep = self.file.create_entity("IfcFacetedBrep")
shell = self.file.create_entity("IfcClosedShell")
brep.Outer = shell
assert brep.get_info_2(recursive=True, include_identifier=False) == {
"Outer": {"CfsFaces": None, "type": "IfcClosedShell"},
"type": "IfcFacetedBrep",
}
+17 -16
View File
@@ -755,12 +755,12 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
%} %}
%{ %{
PyObject* get_info_cpp(IfcUtil::IfcBaseClass* v); PyObject* get_info_cpp(IfcUtil::IfcBaseClass* v, bool include_identifier);
// @todo refactor this to remove duplication with the typemap. // @todo refactor this to remove duplication with the typemap.
// except this is calls the above function in case of instances. // except this is calls the above function in case of instances.
PyObject* convert_cpp_attribute_to_python(AttributeValue arg) { PyObject* convert_cpp_attribute_to_python(AttributeValue arg, bool include_identifier = true) {
return arg.array_->apply_visitor([](auto& v){ return arg.array_->apply_visitor([include_identifier](auto& v){
using U = std::decay_t<decltype(v)>; using U = std::decay_t<decltype(v)>;
if constexpr (is_std_vector_v<U>) { if constexpr (is_std_vector_v<U>) {
return pythonize_vector(v); return pythonize_vector(v);
@@ -774,11 +774,11 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
return static_cast<PyObject*>(Py_None); return static_cast<PyObject*>(Py_None);
} }
} else if constexpr (std::is_same_v<U, IfcUtil::IfcBaseClass*>) { } else if constexpr (std::is_same_v<U, IfcUtil::IfcBaseClass*>) {
return get_info_cpp(v); return get_info_cpp(v, include_identifier);
} else if constexpr (std::is_same_v<U, aggregate_of_instance::ptr>) { } else if constexpr (std::is_same_v<U, aggregate_of_instance::ptr>) {
auto r = PyTuple_New(v->size()); auto r = PyTuple_New(v->size());
for (unsigned i = 0; i < v->size(); ++i) { for (unsigned i = 0; i < v->size(); ++i) {
PyTuple_SetItem(r, i, get_info_cpp((*v)[i])); PyTuple_SetItem(r, i, get_info_cpp((*v)[i], include_identifier));
} }
return r; return r;
} else if constexpr (std::is_same_v<U, aggregate_of_aggregate_of_instance::ptr>) { } else if constexpr (std::is_same_v<U, aggregate_of_aggregate_of_instance::ptr>) {
@@ -787,7 +787,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
auto v_i = it; auto v_i = it;
auto r = PyTuple_New(v_i->size()); auto r = PyTuple_New(v_i->size());
for (unsigned i = 0; i < v_i->size(); ++i) { for (unsigned i = 0; i < v_i->size(); ++i) {
PyTuple_SetItem(r, i, get_info_cpp((*v_i)[i])); PyTuple_SetItem(r, i, get_info_cpp((*v_i)[i], include_identifier));
} }
PyTuple_SetItem(rs, std::distance(v->begin(), it), r); PyTuple_SetItem(rs, std::distance(v->begin(), it), r);
} }
@@ -802,7 +802,7 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
} }
%} %}
%inline %{ %inline %{
PyObject* get_info_cpp(IfcUtil::IfcBaseClass* v) { PyObject* get_info_cpp(IfcUtil::IfcBaseClass* v, bool include_identifier = true) {
PyObject *d = PyDict_New(); PyObject *d = PyDict_New();
if (v->declaration().as_entity()) { if (v->declaration().as_entity()) {
@@ -816,23 +816,24 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas
? IfcUtil::Argument_DERIVED ? IfcUtil::Argument_DERIVED
: IfcUtil::from_parameter_type((*it)->type_of_attribute()); : IfcUtil::from_parameter_type((*it)->type_of_attribute());
auto value_cpp = v->data().get_attribute_value(std::distance(attrs.begin(), it)); auto value_cpp = v->data().get_attribute_value(std::distance(attrs.begin(), it));
auto value_py = convert_cpp_attribute_to_python(value_cpp); auto value_py = convert_cpp_attribute_to_python(value_cpp, include_identifier);
PyDict_SetItem(d, name_py, value_py); PyDict_SetItem(d, name_py, value_py);
Py_DECREF(name_py); Py_DECREF(name_py);
Py_DECREF(value_py); Py_DECREF(value_py);
} }
if (include_identifier) {
const std::string& id_cpp = "id"; const std::string& id_cpp = "id";
auto id_py = pythonize(id_cpp); auto id_py = pythonize(id_cpp);
auto id_v_py = pythonize(v->as<IfcUtil::IfcBaseEntity>()->id()); auto id_v_py = pythonize(v->as<IfcUtil::IfcBaseEntity>()->id());
PyDict_SetItem(d, id_py, id_v_py); PyDict_SetItem(d, id_py, id_v_py);
Py_DECREF(id_py); Py_DECREF(id_py);
Py_DECREF(id_v_py); Py_DECREF(id_v_py);
}
} else { } else {
const std::string& name_cpp = "wrappedValue"; const std::string& name_cpp = "wrappedValue";
auto name_py = pythonize(name_cpp); auto name_py = pythonize(name_cpp);
auto value_cpp = v->data().get_attribute_value(0); auto value_cpp = v->data().get_attribute_value(0);
auto value_py = convert_cpp_attribute_to_python(value_cpp); auto value_py = convert_cpp_attribute_to_python(value_cpp, include_identifier);
PyDict_SetItem(d, name_py, value_py); PyDict_SetItem(d, name_py, value_py);
Py_DECREF(name_py); Py_DECREF(name_py);
Py_DECREF(value_py); Py_DECREF(value_py);