diff --git a/src/ifcgeom/IfcGeomIteratorImplementation.h b/src/ifcgeom/IfcGeomIteratorImplementation.h index f52da1233a..b3bff90ac6 100644 --- a/src/ifcgeom/IfcGeomIteratorImplementation.h +++ b/src/ifcgeom/IfcGeomIteratorImplementation.h @@ -156,6 +156,8 @@ namespace IfcGeom { // Structures for chunking int offset = 0; int colour_offset = 0; + std::vector chunked_guids; + std::vector chunked_guid_ids; std::vector chunked_verts; std::vector chunked_faces; std::vector chunked_materials; @@ -984,6 +986,14 @@ namespace IfcGeom { const auto& materials = ret->geometry().materials(); const auto& material_ids = ret->geometry().material_ids(); + chunked_guids.push_back(ret->guid()); + int guid_ids_size = chunked_guid_ids.size(); + if (guid_ids_size > 0) { + chunked_guid_ids.push_back(chunked_guid_ids[guid_ids_size - 1] + geometry_faces.size() / 3); + } else { + chunked_guid_ids.push_back(geometry_faces.size() / 3); + } + std::vector verts; apply_matrix_to_flat_verts(geometry_verts, matrix, verts); @@ -1057,6 +1067,8 @@ namespace IfcGeom { chunk get_chunk() { chunk result = { + std::move(chunked_guids), + std::move(chunked_guid_ids), std::move(chunked_verts), std::move(chunked_faces), std::move(chunked_materials), diff --git a/src/ifcgeom_schema_agnostic/IfcGeomTree.h b/src/ifcgeom_schema_agnostic/IfcGeomTree.h index 803733b563..bc898488f2 100644 --- a/src/ifcgeom_schema_agnostic/IfcGeomTree.h +++ b/src/ifcgeom_schema_agnostic/IfcGeomTree.h @@ -91,6 +91,9 @@ namespace IfcGeom { std::vector faces; std::vector materials; std::vector material_ids; + // Guids only used in chunked results + std::vector guids; + std::vector guid_ids; }; struct chunked_model { @@ -1870,6 +1873,17 @@ namespace IfcGeom { } } + std::string uint8_to_b64(const std::vector& uuids_array) { + std::string hex_str; + for (auto byte : uuids_array) { + // Convert each byte to a two-digit hexadecimal string and append it to the result + char hex[3]; // Two characters for the hex value and one for the null terminator + snprintf(hex, sizeof(hex), "%02x", byte); + hex_str.append(hex); + } + return hex_str; + } + chunked_model load_h5() { H5::H5File file("/home/dion/cpp.h5", H5F_ACC_RDONLY); @@ -1932,6 +1946,8 @@ namespace IfcGeom { std::vector elements; int offset = 0; + std::vector chunked_guids; + std::vector chunked_guid_ids; std::vector chunked_verts; std::vector chunked_faces; std::vector chunked_materials; @@ -1945,6 +1961,15 @@ namespace IfcGeom { std::vector element_shape_ids(element_shape_ids_ds.getSpace().getSimpleExtentNpoints()); element_shape_ids_ds.read(element_shape_ids.data(), H5::PredType::NATIVE_INT); + H5::DataSet element_global_ids_ds = file.openDataSet("element_global_ids"); + H5::DataSpace element_global_ids_s = element_global_ids_ds.getSpace(); + hsize_t element_global_ids_d[16]; + element_global_ids_s.getSimpleExtentDims(element_global_ids_d); + size_t total_element_global_ids = element_global_ids_d[0]; + size_t element_global_ids_size = 16; + std::vector element_global_ids_b(total_element_global_ids * element_global_ids_size); + element_global_ids_ds.read(element_global_ids_b.data(), H5::PredType::NATIVE_UINT8); + H5::DataSet matrices_ds = file.openDataSet("element_matrices"); H5::DataSpace matrices_s = matrices_ds.getSpace(); hsize_t matrices_d[2]; @@ -1958,9 +1983,24 @@ namespace IfcGeom { for (size_t i = 0; i < total_matrices; ++i) { material_map.clear(); - std::vector matrix(matrices_b.begin() + i * matrix_size, matrices_b.begin() + (i + 1) * matrix_size); h5_shape& shape = shapes[element_shape_ids[i]]; + std::vector element_global_id( + element_global_ids_b.begin() + i * element_global_ids_size, + element_global_ids_b.begin() + (i + 1) * element_global_ids_size); + + chunked_guids.push_back(uint8_to_b64(element_global_id)); + int guid_ids_size = chunked_guid_ids.size(); + if (guid_ids_size > 0) { + chunked_guid_ids.push_back(chunked_guid_ids[guid_ids_size - 1] + shape.faces.size() / 3); + } else { + chunked_guid_ids.push_back(shape.faces.size() / 3); + } + + std::vector matrix( + matrices_b.begin() + i * matrix_size, + matrices_b.begin() + (i + 1) * matrix_size); + std::vector verts; apply_matrix_to_flat_verts(shape.verts, matrix, verts); @@ -2004,7 +2044,10 @@ namespace IfcGeom { std::move(chunked_verts), std::move(chunked_faces), std::move(chunked_materials), - std::move(chunked_material_ids)}); + std::move(chunked_material_ids), + std::move(chunked_guids), + std::move(chunked_guid_ids) + }); chunked_verts.clear(); chunked_faces.clear(); chunked_materials.clear(); @@ -2018,7 +2061,10 @@ namespace IfcGeom { std::move(chunked_verts), std::move(chunked_faces), std::move(chunked_materials), - std::move(chunked_material_ids)}); + std::move(chunked_material_ids), + std::move(chunked_guids), + std::move(chunked_guid_ids) + }); } return { materials, elements }; diff --git a/src/ifcgeom_schema_agnostic/chunk.h b/src/ifcgeom_schema_agnostic/chunk.h index 5ac1102432..1f860e1d51 100644 --- a/src/ifcgeom_schema_agnostic/chunk.h +++ b/src/ifcgeom_schema_agnostic/chunk.h @@ -6,6 +6,8 @@ namespace IfcGeom { struct chunk { + std::vector guids; + std::vector guid_ids; std::vector verts; std::vector faces; std::vector materials; diff --git a/src/ifcwrap/IfcPython.i b/src/ifcwrap/IfcPython.i index 1dcdfdcc5c..b857796ef1 100644 --- a/src/ifcwrap/IfcPython.i +++ b/src/ifcwrap/IfcPython.i @@ -86,6 +86,7 @@ #include "../ifcgeom_schema_agnostic/IfcGeomIterator.h" #include "../ifcgeom_schema_agnostic/Serialization.h" #include "../ifcgeom_schema_agnostic/IfcGeomTree.h" + #include "../ifcgeom_schema_agnostic/chunk.h" #include "../serializers/SvgSerializer.h" #include "../serializers/WavefrontObjSerializer.h" @@ -152,6 +153,7 @@ #include "../ifcgeom_schema_agnostic/IfcGeomIterator.h" #include "../ifcgeom_schema_agnostic/Serialization.h" #include "../ifcgeom_schema_agnostic/IfcGeomTree.h" + #include "../ifcgeom_schema_agnostic/chunk.h" #include "../serializers/SvgSerializer.h" #include "../serializers/WavefrontObjSerializer.h" @@ -209,6 +211,7 @@ %include "IfcGeomWrapper.i" %include "IfcParseWrapper.i" %include "std_vector.i" +%include "../ifcgeom_schema_agnostic/chunk.h" %include "numpy.i" %init %{ import_array(); @@ -219,12 +222,14 @@ namespace std { %template(FloatVector) vector; %template(IntVector) std::vector; %template(DoubleVector) std::vector; + %template(StringVector) std::vector; %template(FloatVectorVector) std::vector>; + %template(DoubleVectorVector) std::vector>; %template(H5ShapeVector) std::vector; } %extend IfcGeom::h5_shape { - PyObject* IfcGeom::h5_shape::get_verts() { + PyObject* get_verts() { npy_intp dims[1] = { (npy_intp)$self->verts.size() }; PyObject* array = PyArray_SimpleNewFromData(1, dims, NPY_FLOAT, (void*)$self->verts.data()); PyArray_CLEARFLAGS((PyArrayObject*)array, NPY_ARRAY_WRITEABLE); // Make the array read-only @@ -252,3 +257,33 @@ namespace std { return array; } } + +%extend IfcGeom::chunk { + PyObject* get_verts() { + npy_intp dims[1] = { (npy_intp)$self->verts.size() }; + PyObject* array = PyArray_SimpleNewFromData(1, dims, NPY_DOUBLE, (void*)$self->verts.data()); + PyArray_CLEARFLAGS((PyArrayObject*)array, NPY_ARRAY_WRITEABLE); // Make the array read-only + return array; + } + + PyObject* get_faces() { + npy_intp dims[1] = { (npy_intp)$self->faces.size() }; + PyObject* array = PyArray_SimpleNewFromData(1, dims, NPY_INT, (void*)$self->faces.data()); + PyArray_CLEARFLAGS((PyArrayObject*)array, NPY_ARRAY_WRITEABLE); // Make the array read-only + return array; + } + + PyObject* get_materials() { + npy_intp dims[1] = { (npy_intp)$self->materials.size() }; + PyObject* array = PyArray_SimpleNewFromData(1, dims, NPY_INT, (void*)$self->materials.data()); + PyArray_CLEARFLAGS((PyArrayObject*)array, NPY_ARRAY_WRITEABLE); // Make the array read-only + return array; + } + + PyObject* get_material_ids() { + npy_intp dims[1] = { (npy_intp)$self->material_ids.size() }; + PyObject* array = PyArray_SimpleNewFromData(1, dims, NPY_INT, (void*)$self->material_ids.data()); + PyArray_CLEARFLAGS((PyArrayObject*)array, NPY_ARRAY_WRITEABLE); // Make the array read-only + return array; + } +}