Salome HOME
Check mesh size before export
[modules/smesh.git] / src / DriverCGNS / DriverCGNS_Write.cxx
index 06abf1dad98d7bf046d68c803753993d564ad7c5..0643273cb61733042cd22c00c283db33c3b4d186 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2020  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -130,6 +130,11 @@ namespace
         interlaces[SMDSEntity_Quad_Penta] = ids;
         cgTypes   [SMDSEntity_Quad_Penta] = CGNS_ENUMV( PENTA_15 );
       }
+      {
+        static int ids[] = { 0,2,1,3,5,4,8,7,6,9,11,10,14,13,12,15,16,17 }; // TODO: check CGNS ORDER
+        interlaces[SMDSEntity_BiQuad_Penta] = ids;
+        cgTypes   [SMDSEntity_BiQuad_Penta] = CGNS_ENUMV( PENTA_18 );
+      }
       {
         static int ids[] = { 0,3,2,1,4,7,6,5 };
         interlaces[SMDSEntity_Hexa] = ids;
@@ -196,17 +201,17 @@ namespace
    */
   struct TPolyhedFace
   {
-    int _id; // id of NGON_n
-    vector< int > _nodes; // lowest node IDs used for sorting
+    smIdType _id; // id of NGON_n
+    vector< smIdType > _nodes; // lowest node IDs used for sorting
 
-    TPolyhedFace( const SMDS_MeshNode** nodes, const int nbNodes, int ID):_id(ID)
+    TPolyhedFace( const SMDS_MeshNode** nodes, const smIdType nbNodes, smIdType ID):_id(ID)
     {
-      set< int > ids;
-      for ( int i = 0; i < nbNodes; ++i )
+      set< smIdType > ids;
+      for ( smIdType i = 0; i < nbNodes; ++i )
         ids.insert( nodes[i]->GetID() );
 
       _nodes.resize( 3 ); // std::min( nbNodes, 4 )); hope 3 nodes is enough
-      set< int >::iterator idIt = ids.begin();
+      set< smIdType >::iterator idIt = ids.begin();
       for ( size_t j = 0; j < _nodes.size(); ++j, ++idIt )
         _nodes[j] = *idIt;
     }
@@ -243,6 +248,9 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
   if ( !myMesh || myMesh->GetMeshInfo().NbElements() < 1 )
     return addMessage( !myMesh ? "NULL mesh" : "Empty mesh (no elements)", /*fatal = */true );
 
+  if ( Driver_Mesh::IsMeshTooLarge< cgsize_t >( myMesh, /*checkIDs =*/ false))
+    return DRS_TOO_LARGE_MESH;
+
   // open the file
   if ( cg_open(myFile.c_str(), CG_MODE_MODIFY, &_fn) != CG_OK &&
        cg_open(myFile.c_str(), CG_MODE_WRITE,  &_fn) != CG_OK )
@@ -271,13 +279,15 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
   // create a Zone
   // --------------
 
-  int nbCells = myMesh->NbEdges();
+  smIdType nbCells = myMesh->NbEdges();
   if ( meshDim == 3 )
     nbCells = myMesh->NbVolumes();
   else if ( meshDim == 2 )
     nbCells = myMesh->NbFaces();
 
-  cgsize_t size[9] = { myMesh->NbNodes(), nbCells, /*NBoundVertex=*/0, 0,0,0,0,0,0 };
+  cgsize_t size[9] = { FromIdType<cgsize_t>( myMesh->NbNodes() ),
+                       FromIdType<cgsize_t>( nbCells ),
+                       /*NBoundVertex=*/0, 0,0,0,0,0,0 };
   int iZone;
   if ( cg_zone_write( _fn, iBase, "SMESH_Mesh", size,
                       CGNS_ENUMV( Unstructured ), &iZone) != CG_OK )
@@ -296,26 +306,26 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
     vector< double > coords( myMesh->NbNodes() );
     int iC;
     // X
-    SMDS_NodeIteratorPtr nIt = myMesh->nodesIterator( /*idInceasingOrder=*/true );
+    SMDS_NodeIteratorPtr nIt = myMesh->nodesIterator();
     for ( int i = 0; nIt->more(); ++i ) coords[i] = nIt->next()->X();
     if ( cg_coord_write( _fn, iBase, iZone, CGNS_ENUMV(RealDouble),
                           "CoordinateX", &coords[0], &iC) != CG_OK )
       return addMessage( cg_get_error(), /*fatal = */true );
     // Y
-    nIt = myMesh->nodesIterator( /*idInceasingOrder=*/true );
+    nIt = myMesh->nodesIterator();
     for ( int i = 0; nIt->more(); ++i ) coords[i] = nIt->next()->Y();
     if ( cg_coord_write( _fn, iBase, iZone, CGNS_ENUMV(RealDouble),
                           "CoordinateY", &coords[0], &iC) != CG_OK )
       return addMessage( cg_get_error(), /*fatal = */true );
     // Z
-    nIt = myMesh->nodesIterator( /*idInceasingOrder=*/true );
+    nIt = myMesh->nodesIterator();
     for ( int i = 0; nIt->more(); ++i ) coords[i] = nIt->next()->Z();
     if ( cg_coord_write( _fn, iBase, iZone, CGNS_ENUMV(RealDouble),
                           "CoordinateZ", &coords[0], &iC) != CG_OK )
       return addMessage( cg_get_error(), /*fatal = */true );
 
     // store CGNS ids of nodes
-    nIt = myMesh->nodesIterator( /*idInceasingOrder=*/true );
+    nIt = myMesh->nodesIterator();
     for ( int i = 0; nIt->more(); ++i )
     {
       const SMDS_MeshElement* n = nIt->next();
@@ -562,7 +572,11 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
       switch ( meshDim ) {
       case 3:
         switch ( group->GetType() ) {
+#if CGNS_VERSION > 3130
         case SMDSAbs_Volume: location = CGNS_ENUMV( CellCenter ); break;
+#else
+        case SMDSAbs_Volume: location = CGNS_ENUMV( FaceCenter ); break;
+#endif
         case SMDSAbs_Face:   location = CGNS_ENUMV( FaceCenter ); break;
         case SMDSAbs_Edge:   location = CGNS_ENUMV( EdgeCenter ); break;
         default:;
@@ -570,13 +584,21 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
         break;
       case 2:
         switch ( group->GetType() ) {
+#if CGNS_VERSION > 3130
         case SMDSAbs_Face: location = CGNS_ENUMV( CellCenter ); break;
+#else
+        case SMDSAbs_Face: location = CGNS_ENUMV( FaceCenter ); break;
+#endif
         case SMDSAbs_Edge: location = CGNS_ENUMV( EdgeCenter ); break;
         default:;
         }
         break;
       case 1:
+#if CGNS_VERSION > 3130
         location = CGNS_ENUMV( CellCenter ); break;
+#else
+        location = CGNS_ENUMV( EdgeCenter ); break;
+#endif
         break;
       }
     }
@@ -611,7 +633,7 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
       return addMessage( cg_get_error(), /*fatal = */true);
 
     // write BC location
-    if ( location != CGNS_ENUMV( Vertex ))
+    if ( location != CGNS_ENUMV( Vertex ) || meshDim == 1 )
     {
       if ( cg_boco_gridlocation_write( _fn, iBase, iZone, iBC, location) != CG_OK )
         return addMessage( cg_get_error(), /*fatal = */false);