From 1841c623c37becac2279122b1cd8cf4221054cf1 Mon Sep 17 00:00:00 2001 From: Christophe Bourcier Date: Fri, 13 Dec 2024 18:33:46 +0100 Subject: [PATCH] Fix export structured CGNS when there is a group on several volumes that leads to duplicate name in 1to1 connectivity TODO: do not put _1 if there is only one group with this name --- src/DriverCGNS/DriverStructuredCGNS_Write.cxx | 85 ++++++++++++++----- src/DriverCGNS/DriverStructuredCGNS_Write.hxx | 6 ++ 2 files changed, 69 insertions(+), 22 deletions(-) diff --git a/src/DriverCGNS/DriverStructuredCGNS_Write.cxx b/src/DriverCGNS/DriverStructuredCGNS_Write.cxx index 0cf6ba851..687a4aef1 100644 --- a/src/DriverCGNS/DriverStructuredCGNS_Write.cxx +++ b/src/DriverCGNS/DriverStructuredCGNS_Write.cxx @@ -81,7 +81,48 @@ std::string DriverStructuredCGNS_Write::GetGroupName( const int shapeToIndex, in } } } - return std::string(""); + // else by convention, create a group called ZONESOLID or ZONEFACE + std::string emptyZoneName("ZONE"); + if (dim == 3) + emptyZoneName += "SOLID"; + else + emptyZoneName += "FACE"; + return emptyZoneName; +} + +void DriverStructuredCGNS_Write::GetGroupNamesMap( const TopoDS_Shape& shape, int dim, std::map& groupNameMapById ) +{ + // get all zone names + // get a unique name for each zone name +// std::map groupNameMapById; + std::map countGroupName; + TopAbs_ShapeEnum exploreType; + if (dim == 3) + exploreType = TopAbs_SOLID; + else + exploreType = TopAbs_FACE; + for ( TopExp_Explorer fEx( shape, exploreType ); fEx.More(); fEx.Next() ) + { + unsigned int solidId; + if (dim == 3) + { + auto currentSolid = TopoDS::Solid(fEx.Current()); + solidId = myMesh->ShapeToIndex(currentSolid); + } + else + { + auto currentSolid = TopoDS::Face(fEx.Current()); + solidId = myMesh->ShapeToIndex(currentSolid); + } + std::string zoneName = GetGroupName(solidId, dim); + // update the frequency count + countGroupName[zoneName]++; + int count = countGroupName[zoneName]; + // Append frequency count to end of the string + zoneName += "_"+std::to_string(count); + // store the name + groupNameMapById[solidId] = zoneName; + } } void DriverStructuredCGNS_Write::CheckForGroupNameOnFaceInterfaces( const SMESHUtils::SMESH_RegularGrid* grid, std::vector& boundaryNames ) @@ -196,7 +237,10 @@ Driver_Mesh::Status DriverStructuredCGNS_Write::Perform() if ( meshDim == 3 ) { - std::set zNames; + // get a map of unique names for each solid + std::map groupNameMapById; + GetGroupNamesMap(shape, meshDim, groupNameMapById); + // Fill the cgns info for each solid for ( TopExp_Explorer fEx( shape, TopAbs_SOLID ); fEx.More(); fEx.Next() ) { TopoDS_Solid currentSolid = TopoDS::Solid(fEx.Current()); @@ -210,11 +254,8 @@ Driver_Mesh::Status DriverStructuredCGNS_Write::Perform() cgsize_t size[9] = {imax, jmax, kmax, imax - 1, jmax - 1, kmax - 1, 0, 0, 0}; - std::string zoneName = GetGroupName(myMesh->ShapeToIndex(currentSolid),meshDim); - zoneName = zoneName.empty() ? "ZONESOLID" + std::to_string(myMesh->ShapeToIndex(currentSolid)) : zoneName; - if ( zNames.count(zoneName) != 0 ) - zoneName = zoneName + "_" + std::to_string(myMesh->ShapeToIndex(currentSolid)); - zNames.insert( zoneName ); + unsigned int currentSolidId = myMesh->ShapeToIndex(currentSolid); + std::string zoneName = groupNameMapById[currentSolidId]; // write Zone int iZone; if(cg_zone_write(_fn, iBase, zoneName.c_str(), size, @@ -309,12 +350,13 @@ Driver_Mesh::Status DriverStructuredCGNS_Write::Perform() { std::vector interfacecgns( 12 ); for (size_t i = 0; i < 12; i++) - interfacecgns[i] = cgsize_t(interface[i+1]); + interfacecgns[i] = cgsize_t(interface[i+1]); int iConn; - std::string neigbourZoneName = GetGroupName(myMesh->ShapeToIndex(neighbourSolid),meshDim); - neigbourZoneName = neigbourZoneName.empty() ? "ZONESOLID" + std::to_string(myMesh->ShapeToIndex(neighbourSolid)) : neigbourZoneName; - std::string interfaceName = zoneName + "_" + neigbourZoneName + "_" + std::to_string(interface[0]); + unsigned int neighbourSolidId = myMesh->ShapeToIndex(neighbourSolid); + std::string neigbourZoneName = groupNameMapById[neighbourSolidId]; + // interfaceName must be unique (it should be by construction) + std::string interfaceName = zoneName + "_" + neigbourZoneName; if(cg_1to1_write(_fn, iBase, iZone, interfaceName.c_str(), neigbourZoneName.c_str(), &interfacecgns[0], &interfacecgns[6], &interface[13], &iConn) != CG_OK) return addMessage(cg_get_error(), /*fatal = */true); } @@ -326,7 +368,9 @@ Driver_Mesh::Status DriverStructuredCGNS_Write::Perform() } else if ( meshDim == 2 ) { - std::set zNames; + // get a map of unique names for each face + std::map groupNameMapById; + GetGroupNamesMap(shape, meshDim, groupNameMapById); for ( TopExp_Explorer fEx( shape, TopAbs_FACE ); fEx.More(); fEx.Next() ) { TopoDS_Face currentFace = TopoDS::Face(fEx.Current()); @@ -339,12 +383,9 @@ Driver_Mesh::Status DriverStructuredCGNS_Write::Perform() int iZone; cgsize_t size[6] = {imax, jmax, imax - 1, jmax - 1, 0, 0}; - std::string zoneName = GetGroupName(myMesh->ShapeToIndex(currentFace),meshDim); - zoneName = zoneName.empty() ? "ZONEFACE" + std::to_string(myMesh->ShapeToIndex(currentFace)) : zoneName; - - if ( zNames.count(zoneName) != 0 ) - zoneName = zoneName + "_" + std::to_string(myMesh->ShapeToIndex(currentFace)); - zNames.insert( zoneName ); + unsigned int currentFaceId = myMesh->ShapeToIndex(currentFace); + std::string zoneName = groupNameMapById[currentFaceId]; + // write Zone if(cg_zone_write(_fn, iBase, zoneName.c_str(), size, CGNS_ENUMV(Structured), &iZone) != CG_OK) @@ -441,10 +482,10 @@ Driver_Mesh::Status DriverStructuredCGNS_Write::Perform() for (size_t i = 0; i < 8; i++) interfacecgns[i] = cgsize_t(interface[i+1]); - int iConn; - std::string neigbourZoneName = GetGroupName(myMesh->ShapeToIndex(neighbourFace),meshDim); - neigbourZoneName = neigbourZoneName.empty() ? "ZONEFACE" + std::to_string(myMesh->ShapeToIndex(neighbourFace)) : neigbourZoneName; - std::string interfaceName = zoneName + "_" + neigbourZoneName + "_" + std::to_string(interface[0]); + int iConn; + unsigned int neighbourFaceId = myMesh->ShapeToIndex(neighbourFace); + std::string neigbourZoneName = groupNameMapById[neighbourFaceId]; + std::string interfaceName = zoneName + "_" + neigbourZoneName; if(cg_1to1_write(_fn, iBase, iZone, interfaceName.c_str(), neigbourZoneName.c_str(), &interfacecgns[0], &interfacecgns[4], &interface[9], &iConn) != CG_OK) return addMessage(cg_get_error(), /*fatal = */true); diff --git a/src/DriverCGNS/DriverStructuredCGNS_Write.hxx b/src/DriverCGNS/DriverStructuredCGNS_Write.hxx index 0198612e3..ace4e3f27 100644 --- a/src/DriverCGNS/DriverStructuredCGNS_Write.hxx +++ b/src/DriverCGNS/DriverStructuredCGNS_Write.hxx @@ -25,6 +25,7 @@ // occt #include +#include // smesh #include "SMESH_DriverCGNS.hxx" @@ -65,6 +66,11 @@ public: private: int _fn; //!< file index + /*! + * \brief Get the map between a solid (or face) id and its unique name. + * Add a suffix if needed to avoid duplicate group name. + */ + void GetGroupNamesMap( const TopoDS_Shape& shape, int dim, std::map& groupNameMapById ); }; #endif