diff --git a/src/ifcgeom_schema_agnostic/IfcGeomRepresentation.cpp b/src/ifcgeom_schema_agnostic/IfcGeomRepresentation.cpp index c17ce210ee..7b0bd95756 100644 --- a/src/ifcgeom_schema_agnostic/IfcGeomRepresentation.cpp +++ b/src/ifcgeom_schema_agnostic/IfcGeomRepresentation.cpp @@ -332,7 +332,7 @@ IfcGeom::Representation::Triangulation::Triangulation(const BRep& shape_model) for (int i = 1; i <= tri->NbNodes(); ++i) { coords.push_back(tri->Node(i).Transformed(loc).XYZ()); trsf.Transforms(*coords.rbegin()); - dict[i] = addVertex(surface_style_id, *coords.rbegin()); + dict[i] = addVertex(iit->ItemId(), surface_style_id, *coords.rbegin()); if (calculate_normals) { const gp_Pnt2d& uv = tri->UVNode(i); @@ -387,6 +387,7 @@ IfcGeom::Representation::Triangulation::Triangulation(const BRep& shape_model) _faces.push_back(dict[n3]); _material_ids.push_back(surface_style_id); + _item_ids.push_back(iit->ItemId()); addEdge(dict[n1], dict[n2], edgecount, edges_temp); addEdge(dict[n2], dict[n3], edgecount, edges_temp); @@ -420,7 +421,7 @@ IfcGeom::Representation::Triangulation::Triangulation(const BRep& shape_model) for (int i = 1; i <= n; ++i) { gp_XYZ p = tessellater.Value(i).XYZ(); - int current = addVertex(surface_style_id, p); + int current = addVertex(iit->ItemId(), surface_style_id, p); std::vector> segments; if (i > 1) { @@ -452,8 +453,8 @@ IfcGeom::Representation::Triangulation::Triangulation(const BRep& shape_model) trsf.Transforms(p3); trsf.Transforms(p); - int left = addVertex(surface_style_id, p2); - int right = addVertex(surface_style_id, p3); + int left = addVertex(iit->ItemId(), surface_style_id, p2); + int right = addVertex(iit->ItemId(), surface_style_id, p3); segments.push_back(std::make_pair(left, current)); segments.push_back(std::make_pair(right, current)); @@ -463,6 +464,7 @@ IfcGeom::Representation::Triangulation::Triangulation(const BRep& shape_model) _edges.push_back(sgmt.first); _edges.push_back(sgmt.second); _material_ids.push_back(surface_style_id); + _item_ids.push_back(iit->ItemId()); } previous = current; @@ -505,14 +507,14 @@ std::vector IfcGeom::Representation::Triangulation::box_project_uvs(cons return uvs; } -int IfcGeom::Representation::Triangulation::addVertex(int material_index, const gp_XYZ & p) { +int IfcGeom::Representation::Triangulation::addVertex(int item_index, int material_index, const gp_XYZ & p) { const bool convert = settings().get(IteratorSettings::CONVERT_BACK_UNITS); const double X = convert ? (p.X() / settings().unit_magnitude()) : p.X(); const double Y = convert ? (p.Y() / settings().unit_magnitude()) : p.Y(); const double Z = convert ? (p.Z() / settings().unit_magnitude()) : p.Z(); int i = (int)_verts.size() / 3; if (settings().get(IteratorSettings::WELD_VERTICES)) { - const VertexKey key = std::make_pair(material_index, std::make_pair(X, std::make_pair(Y, Z))); + const VertexKey key = std::make_tuple(item_index, material_index, X, Y, Z); typename VertexKeyMap::const_iterator it = welds.find(key); if (it != welds.end()) return it->second; i = (int)(welds.size() + weld_offset_); diff --git a/src/ifcgeom_schema_agnostic/IfcGeomRepresentation.h b/src/ifcgeom_schema_agnostic/IfcGeomRepresentation.h index ecb71f374c..2762e40321 100644 --- a/src/ifcgeom_schema_agnostic/IfcGeomRepresentation.h +++ b/src/ifcgeom_schema_agnostic/IfcGeomRepresentation.h @@ -105,10 +105,8 @@ namespace IfcGeom { class Triangulation : public Representation { private: - // A nested pair of floats and a material index to be able to store an XYZ coordinate in a map. - // TODO: Make this a std::tuple when compilers add support for that. - typedef typename std::pair > Coordinate; - typedef typename std::pair VertexKey; + // A tuple of to store as a key in a map. + typedef typename std::tuple VertexKey; typedef std::map VertexKeyMap; typedef std::pair Edge; @@ -120,6 +118,7 @@ namespace IfcGeom { std::vector uvs_; std::vector _material_ids; std::vector _materials; + std::vector _item_ids; size_t weld_offset_; VertexKeyMap welds; @@ -137,6 +136,7 @@ namespace IfcGeom { const std::vector& uvs() const { return uvs_; } const std::vector& material_ids() const { return _material_ids; } const std::vector& materials() const { return _materials; } + const std::vector& item_ids() const { return _item_ids; } Triangulation(const BRep& shape_model); @@ -149,7 +149,8 @@ namespace IfcGeom { const std::vector& normals, const std::vector& uvs, const std::vector& material_ids, - const std::vector>& styles) + const std::vector>& styles, + const std::vector& item_ids) : Representation(settings) , id_(id) , _verts(verts) @@ -159,6 +160,7 @@ namespace IfcGeom { , uvs_(uvs) , _material_ids(material_ids) , styles_(styles) + , _item_ids(item_ids) { for (auto& s : styles_) { _materials.push_back(IfcGeom::Material(s)); @@ -173,7 +175,7 @@ namespace IfcGeom { private: /// Welds vertices that belong to different faces - int addVertex(int material_index, const gp_XYZ& p); + int addVertex(int item_index, int material_index, const gp_XYZ& p); void addEdge(int n1, int n2, std::map, int>& edgecount, std::vector >& edges_temp); Triangulation(); diff --git a/src/ifcwrap/IfcGeomWrapper.i b/src/ifcwrap/IfcGeomWrapper.i index 8e568ce0ea..206b40d166 100644 --- a/src/ifcwrap/IfcGeomWrapper.i +++ b/src/ifcwrap/IfcGeomWrapper.i @@ -241,6 +241,7 @@ struct ShapeRTTI : public boost::static_visitor edges = property(edges) material_ids = property(material_ids) materials = property(materials) + item_ids = property(item_ids) %} }; diff --git a/src/serializers/HdfSerializer.cpp b/src/serializers/HdfSerializer.cpp index 72569065bd..b8b5bcc99b 100644 --- a/src/serializers/HdfSerializer.cpp +++ b/src/serializers/HdfSerializer.cpp @@ -437,6 +437,7 @@ IfcGeom::Element* HdfSerializer::read(IfcParse::IfcFile& f, const std::string& g auto normals = read_dataset(meshGroup, DATASET_NAME_NORMALS); auto uvcoords = read_dataset(meshGroup, DATASET_NAME_UVCOORDS); auto material_ids = read_dataset(meshGroup, DATASET_NAME_MATERIAL_IDS); + auto item_ids = read_dataset(meshGroup, DATASET_NAME_ITEM_IDS); std::vector surface_styles; @@ -471,7 +472,8 @@ IfcGeom::Element* HdfSerializer::read(IfcParse::IfcFile& f, const std::string& g normals, uvcoords, material_ids, - surface_style_ptrs + surface_style_ptrs, + item_ids )); triangulation_cache_.insert({ representation_id_str, triangulation_geometry }); @@ -706,6 +708,7 @@ void HdfSerializer::write(const IfcGeom::TriangulationElement* o) { write_dataset(meshGroup, DATASET_NAME_NORMALS, mesh.normals(), 2); write_dataset(meshGroup, DATASET_NAME_UVCOORDS, mesh.uvs(), 2); write_dataset(meshGroup, DATASET_NAME_MATERIAL_IDS, mesh.material_ids(), 1); + write_dataset(meshGroup, DATASET_NAME_ITEM_IDS, mesh.item_ids(), 1); { auto& ts = mesh.materials(); @@ -732,6 +735,7 @@ const H5std_string HdfSerializer::DATASET_NAME_NORMALS = "normals"; const H5std_string HdfSerializer::DATASET_NAME_INDICES = "indices"; const H5std_string HdfSerializer::DATASET_NAME_EDGES = "edges"; const H5std_string HdfSerializer::DATASET_NAME_MATERIAL_IDS = "material_ids"; +const H5std_string HdfSerializer::DATASET_NAME_ITEM_IDS = "item_ids"; const H5std_string HdfSerializer::DATASET_NAME_MATERIALS = "materials"; const H5std_string HdfSerializer::DATASET_NAME_OCCT = "brep"; const H5std_string HdfSerializer::DATASET_NAME_PLACEMENT = "placement"; diff --git a/src/serializers/HdfSerializer.h b/src/serializers/HdfSerializer.h index 35d82b1aae..527dd383b8 100644 --- a/src/serializers/HdfSerializer.h +++ b/src/serializers/HdfSerializer.h @@ -46,6 +46,7 @@ private: static const H5std_string DATASET_NAME_INDICES; static const H5std_string DATASET_NAME_EDGES; static const H5std_string DATASET_NAME_MATERIAL_IDS; + static const H5std_string DATASET_NAME_ITEM_IDS; static const H5std_string DATASET_NAME_MATERIALS; static const H5std_string DATASET_NAME_OCCT; static const H5std_string DATASET_NAME_PLACEMENT;