Salome HOME
Porting to CGNS-4x
authoreap <eap@opencascade.com>
Mon, 29 Mar 2021 14:10:19 +0000 (17:10 +0300)
committereap <eap@opencascade.com>
Mon, 29 Mar 2021 14:10:19 +0000 (17:10 +0300)
src/DriverCGNS/DriverCGNS_Read.cxx
src/DriverCGNS/DriverCGNS_Write.cxx

index 7786b09d4a62cd858a5c69cef8b4bac91f53bfb2..9f1f212ad07dc2f74f82174cea9fc7f0f920305e 100644 (file)
@@ -544,11 +544,15 @@ namespace
                                   ids[14],ids[13],ids[19],ids[18],ids[17],ids[16],
                                   ids[20],ids[24],ids[23],ids[22],ids[21],ids[25],ids[26], ID );
   }
-  SMDS_MeshElement* add_NGON(cgsize_t* ids, SMESHDS_Mesh* mesh, int ID)
+  SMDS_MeshElement* add_NGON(cgsize_t* ids, int nbNodes, SMESHDS_Mesh* mesh, int ID)
   {
-    vector<int> idVec( ids[0] );
-    for ( int i = 0; i < ids[0]; ++i )
-      idVec[ i ] = (int) ids[ i + 1];
+#if CGNS_VERSION < 4000
+    nbNodes = ids[0];
+    ++ids;
+#endif
+    vector<int> idVec( nbNodes );
+    for ( int i = 0; i < nbNodes; ++i )
+      idVec[ i ] = (int) ids[ i ];
     return mesh->AddPolygonalFaceWithID( idVec, ID );
   }
 
@@ -585,7 +589,7 @@ namespace
       funVec[ CGNS_ENUMV( HEXA_8   )] = add_HEXA_8  ;
       funVec[ CGNS_ENUMV( HEXA_20  )] = add_HEXA_20 ;
       funVec[ CGNS_ENUMV( HEXA_27  )] = add_HEXA_27 ;
-      funVec[ CGNS_ENUMV( NGON_n   )] = add_NGON    ;
+      //funVec[ CGNS_ENUMV( NGON_n   )] = add_NGON    ;
     }
     return &funVec[0];
   }
@@ -854,16 +858,34 @@ Driver_Mesh::Status DriverCGNS_Read::Perform()
           addMessage( cg_get_error() );
           continue;
         }
-        vector< cgsize_t > elemData( eDataSize );
-        if ( cg_elements_read( _fn, cgnsBase, iZone, iSec, &elemData[0], NULL ) != CG_OK )
+        vector< cgsize_t > elemData( eDataSize ), polyOffset;
+#if CGNS_VERSION >= 4000
+        if ( elemType == CGNS_ENUMV( MIXED ) ||
+             elemType == CGNS_ENUMV( NGON_n ) ||
+             elemType == CGNS_ENUMV( NFACE_n ))
         {
-          addMessage( cg_get_error() );
-          continue;
+          polyOffset.resize( end - start + 2 );
+          if ( cg_poly_elements_read( _fn, cgnsBase, iZone, iSec,
+                                      elemData.data(), polyOffset.data(), NULL ) != CG_OK )
+          {
+            addMessage( cg_get_error() );
+            continue;
+          }
+        }
+        else
+#endif
+        {
+          if ( cg_elements_read( _fn, cgnsBase, iZone, iSec, elemData.data(), NULL ) != CG_OK )
+          {
+            addMessage( cg_get_error() );
+            continue;
+          }
         }
         // store elements
 
         MESSAGE("   store elements");
         int pos = 0, cgnsNbNodes = 0, elemID = start + zone._elemIdShift;
+        size_t iElem = 0;
         cg_npe( elemType, &cgnsNbNodes ); // get nb nodes by element type
         curAddElemFun = addElemFuns[ elemType ];
         SMDS_MeshElement* newElem = 0;
@@ -885,17 +907,26 @@ Driver_Mesh::Status DriverCGNS_Read::Perform()
           {
             if ( currentType == CGNS_ENUMV( NFACE_n )) // polyhedron
             {
-              //ElementConnectivity = Nfaces1, Face11, Face21, ... FaceN1,
-              //                      Nfaces2, Face12, Face22, ... FaceN2,
-              //                      ...
-              //                      NfacesM, Face1M, Face2M, ... FaceNM
-              const int nbFaces = elemData[ pos++ ];
+              int nbFaces = 0;
+              if ( polyOffset.empty() )
+                //ElementConnectivity = Nfaces1, Face11, Face21, ... FaceN1,
+                //                      Nfaces2, Face12, Face22, ... FaceN2,
+                //                      ...
+                //                      NfacesM, Face1M, Face2M, ... FaceNM
+                nbFaces = elemData[ pos++ ];
+              else // CGNS_VERSION >= 4000
+                // ElementConnectivity = Face11, Face21, ... FaceN1,
+                //                       Face12, Face22, ... FaceN2,
+                //                       ...
+                //                       Face1M, Face2M, ... FaceNM
+                nbFaces = polyOffset[ iElem + 1 ] - polyOffset[ iElem ];
+
               vector<int> quantities( nbFaces );
               vector<const SMDS_MeshNode*> nodes, faceNodes;
               nodes.reserve( nbFaces * 4 );
               for ( int iF = 0; iF < nbFaces; ++iF )
               {
-                const int faceID = std::abs( elemData[ pos++ ]) + zone._elemIdShift; 
+                const int faceID = std::abs( elemData[ pos++ ]) + zone._elemIdShift;
                 if (( face = myMesh->FindElement( faceID )) && face->GetType() == SMDSAbs_Face )
                 {
                   const bool reverse = ( elemData[ pos-1 ] < 0 );
@@ -924,14 +955,23 @@ Driver_Mesh::Status DriverCGNS_Read::Perform()
             }
             else if ( currentType == CGNS_ENUMV( NGON_n )) // polygon
             {
-              // ElementConnectivity = Nnodes1, Node11, Node21, ... NodeN1,
-              //                       Nnodes2, Node12, Node22, ... NodeN2,
-              //                       ...
-              //                       NnodesM, Node1M, Node2M, ... NodeNM
-              const int nbNodes = elemData[ pos ];
-              zone.ReplaceNodes( &elemData[pos+1], nbNodes, zone._nodeIdShift );
-              newElem = add_NGON( &elemData[pos  ], myMesh, elemID );
-              pos += nbNodes + 1;
+              int nbNodes;
+              if ( polyOffset.empty() )
+                // ElementConnectivity = Nnodes1, Node11, Node21, ... NodeN1,
+                //                       Nnodes2, Node12, Node22, ... NodeN2,
+                //                       ...
+                //                       NnodesM, Node1M, Node2M, ... NodeNM
+                nbNodes = elemData[ pos ];
+              else // CGNS_VERSION >= 4000
+                // ElementConnectivity = Node11, Node21, ... NodeN1,
+                //                       Node12, Node22, ... NodeN2,
+                //                       ...
+                //                       Node1M, Node2M, ... NodeNM
+                nbNodes = polyOffset[ iElem + 1 ] - polyOffset[ iElem ];
+
+              zone.ReplaceNodes( &elemData[ pos + polyOffset.empty()], nbNodes, zone._nodeIdShift );
+              newElem = add_NGON( &elemData[ pos ], nbNodes, myMesh, elemID );
+              pos += nbNodes + polyOffset.empty();
             }
           }
           else // standard elements
@@ -942,6 +982,7 @@ Driver_Mesh::Status DriverCGNS_Read::Perform()
             nbNotSuppElem += int( newElem && newElem->NbNodes() != cgnsNbNodes );
           }
           elemID++;
+          iElem++;
 
         } // loop on elemData
       } // loop on cgns sections
@@ -960,7 +1001,7 @@ Driver_Mesh::Status DriverCGNS_Read::Perform()
     // -------------------------------------------
     // Read Boundary Conditions into SMESH groups
     // -------------------------------------------
-    
+
     MESSAGE("  read Boundary Conditions");
     int nbBC = 0;
     if ( cg_nbocos( _fn, cgnsBase, iZone, &nbBC) == CG_OK )
index e4c06781a35968e3fdc42a12b4bec7fe0cc20bd1..b4d3dfe42b959ab9daab365c37c74f56adef12d2 100644 (file)
@@ -233,6 +233,25 @@ namespace
     return ( e2id == elem2cgID.end() ? elem->GetID() : e2id->second );
   }
 
+  //================================================================================
+  /*!
+   * \brief save nb nodes of a polygon
+   */
+  //================================================================================
+
+  void addPolySize( const cgsize_t            nbNodes,
+                    std::vector< cgsize_t >& elemData,
+                    std::vector< cgsize_t >& polyOffset )
+  {
+#if CGNS_VERSION < 4100
+    elemData.push_back( nbNodes );
+    polyOffset.clear(); // just avoid warning: unused parameter
+#else
+    polyOffset.push_back((cgsize_t) elemData.size() );
+    (void)nbNodes; // avoid warning: unused parameter
+#endif
+  }
+
 } // namespace
 
 //================================================================================
@@ -335,7 +354,7 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
 
   // write into a section all successive elements of one geom type
   int iSec;
-  vector< cgsize_t > elemData;
+  vector< cgsize_t > elemData, polyOffset;
   SMDS_ElemIteratorPtr elemIt = myMesh->elementsIterator();
   vector< SMDS_ElemIteratorPtr > elemItVec;
   if ( _elementsByType )
@@ -384,7 +403,7 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
     else if ( elemType == SMDSEntity_Polygon ) // POLYGONS
       do
       {
-        elemData.push_back( elem->NbNodes() );
+        addPolySize( elem->NbNodes(), elemData, polyOffset );
         for ( int i = 0, nb = elem->NbNodes(); i < nb; ++i )
           elemData.push_back( cgnsID( elem->GetNode(i), n2cgID ));
         if ( elem->GetID() != cgID )
@@ -397,7 +416,7 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
     else if ( elemType == SMDSEntity_Quad_Polygon ) // QUADRATIC POLYGONS
       do // write as linear NGON_n
       {
-        elemData.push_back( elem->NbNodes() );
+        addPolySize( elem->NbNodes(), elemData, polyOffset );
         interlace = & SMDS_MeshCell::interlacedSmdsOrder( SMDSEntity_Quad_Polygon,
                                                           elem->NbNodes() )[0];
         for ( int i = 0, nb = elem->NbNodes(); i < nb; ++i )
@@ -433,9 +452,23 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
     SMESH_Comment sectionName( cg_ElementTypeName( cgType ));
     sectionName << " " << startID << " - " << cgID-1;
 
-    if ( cg_section_write(_fn, iBase, iZone, sectionName.c_str(), cgType, startID,
-                          cgID-1, /*nbndry=*/0, &elemData[0], &iSec) != CG_OK )
-      return addMessage( cg_get_error(), /*fatal = */true );
+
+#if CGNS_VERSION >= 4000
+    if ( !polyOffset.empty() )
+    {
+      polyOffset.push_back((cgsize_t) elemData.size() );
+      if ( cg_poly_section_write(_fn, iBase, iZone, sectionName.c_str(), cgType, startID,
+                                 cgID-1, /*nbndry=*/0,
+                                 elemData.data(), polyOffset.data(), &iSec) != CG_OK )
+        return addMessage( cg_get_error(), /*fatal = */true );
+    }
+    else
+#endif
+    {
+      if ( cg_section_write(_fn, iBase, iZone, sectionName.c_str(), cgType, startID,
+                            cgID-1, /*nbndry=*/0, elemData.data(), &iSec) != CG_OK )
+        return addMessage( cg_get_error(), /*fatal = */true );
+    }
   }
 
   // Write polyhedral volumes
@@ -450,11 +483,13 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
     set< TPolyhedFace > faces;
     set< TPolyhedFace >::iterator faceInSet;
     vector<const SMDS_MeshNode *> faceNodesVec;
+    vector< cgsize_t > faceOffset;
     int nbPolygones = 0, faceID;
 
     SMDS_VolumeTool vol;
 
     elemData.clear();
+    polyOffset.clear();
 
     int nbPolyhTreated = 0;
 
@@ -473,7 +508,7 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
         vol.Set( elem );
         vol.SetExternalNormal();
         const int nbFaces = vol.NbFaces();
-        elemData.push_back( nbFaces );
+        addPolySize( nbFaces, elemData, polyOffset );
         for ( int iF = 0; iF < nbFaces; ++iF )
         {
           const int nbNodes = vol.NbFaceNodes( iF );
@@ -489,7 +524,7 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
             // the face is not shared by volumes
             faceID = cgID++;
             ++nbPolygones;
-            faceData.push_back( nbNodes );
+            addPolySize( nbNodes, faceData, faceOffset );
             for ( int i = 0; i < nbNodes; ++i )
               faceData.push_back( cgnsID( faceNodes[i], n2cgID ));
           }
@@ -501,7 +536,7 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
             {
               faceID = cgID++;
               ++nbPolygones;
-              faceData.push_back( nbNodes );
+              addPolySize( nbNodes, faceData, faceOffset );
               for ( int i = 0; i < nbNodes; ++i )
                 faceData.push_back( cgnsID( faceNodes[i], n2cgID ));
             }
@@ -518,18 +553,35 @@ Driver_Mesh::Status DriverCGNS_Write::Perform()
       }
     }
 
+#if CGNS_VERSION >= 4000
+    if ( nbPolygones > 0 )
+    {
+      faceOffset.push_back((cgsize_t) faceData.size() );
+      if ( cg_poly_section_write(_fn, iBase, iZone, "Faces of Polyhedrons", CGNS_ENUMV( NGON_n ),
+                                 cgID - nbPolygones, cgID-1, /*nbndry=*/0,
+                                 faceData.data(), faceOffset.data(), &iSec) != CG_OK )
+        return addMessage( cg_get_error(), /*fatal = */true );
+    }
+
+    polyOffset.push_back((cgsize_t) elemData.size() );
+    if ( cg_poly_section_write(_fn, iBase, iZone, "Polyhedrons",
+                               CGNS_ENUMV( NFACE_n ), cgID, cgID+nbPolyhTreated-1,
+                               /*nbndry=*/0, &elemData[0], polyOffset.data(), &iSec) != CG_OK )
+      return addMessage( cg_get_error(), /*fatal = */true );
+#else
     if ( nbPolygones > 0 )
     {
       if ( cg_section_write(_fn, iBase, iZone, "Faces of Polyhedrons",
-                             CGNS_ENUMV( NGON_n ), cgID - nbPolygones, cgID-1,
-                             /*nbndry=*/0, &faceData[0], &iSec) != CG_OK )
+                            CGNS_ENUMV( NGON_n ), cgID - nbPolygones, cgID-1,
+                            /*nbndry=*/0, &faceData[0], &iSec) != CG_OK )
         return addMessage( cg_get_error(), /*fatal = */true );
     }
-    
-    if ( cg_section_write(_fn, iBase, iZone, "Polyhedrons", 
-                             CGNS_ENUMV( NFACE_n ), cgID, cgID+nbPolyhTreated-1,
-                           /*nbndry=*/0, &elemData[0], &iSec) != CG_OK )
+
+    if ( cg_section_write(_fn, iBase, iZone, "Polyhedrons",
+                          CGNS_ENUMV( NFACE_n ), cgID, cgID+nbPolyhTreated-1,
+                          /*nbndry=*/0, &elemData[0], &iSec) != CG_OK )
       return addMessage( cg_get_error(), /*fatal = */true );
+#endif
 
     if ( !myMesh->GetGroups().empty() )
     {