X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FDriverGMF%2FDriverGMF_Read.cxx;h=0d70c8d5aeea181d2218c555e43e0a7036cf33b0;hp=e28bcb998a3db4e446c6ca613d06c87cbade7d22;hb=373c03904b8e3fc5490ff4e17716f0cdcb39c03c;hpb=e867938e10d505136831cb1072d73c44de93cb69 diff --git a/src/DriverGMF/DriverGMF_Read.cxx b/src/DriverGMF/DriverGMF_Read.cxx index e28bcb998..0d70c8d5a 100644 --- a/src/DriverGMF/DriverGMF_Read.cxx +++ b/src/DriverGMF/DriverGMF_Read.cxx @@ -24,11 +24,14 @@ // Author : Edward AGAPOV (eap) #include "DriverGMF_Read.hxx" -#include "DriverGMF_Write.hxx" +#include "DriverGMF.hxx" #include "SMESHDS_Group.hxx" #include "SMESHDS_Mesh.hxx" #include "SMESH_Comment.hxx" +#include "SMESH_TypeDefs.hxx" + +#include extern "C" { @@ -37,13 +40,6 @@ extern "C" #include -// -------------------------------------------------------------------------------- -// Closing GMF mesh at destruction -DriverGMF_MeshCloser::~DriverGMF_MeshCloser() -{ - if ( _gmfMeshID ) - GmfCloseMesh( _gmfMeshID ); -} // -------------------------------------------------------------------------------- DriverGMF_Read::DriverGMF_Read(): Driver_SMESHDS_Mesh(), @@ -63,6 +59,8 @@ DriverGMF_Read::~DriverGMF_Read() Driver_Mesh::Status DriverGMF_Read::Perform() { + Kernel_Utils::Localizer loc; + Status status = DRS_OK; int dim, version; @@ -70,9 +68,15 @@ Driver_Mesh::Status DriverGMF_Read::Perform() // open the file int meshID = GmfOpenMesh( myFile.c_str(), GmfRead, &version, &dim ); if ( !meshID ) - return addMessage( SMESH_Comment("Can't open for reading ") << myFile, /*fatal=*/true ); - - DriverGMF_MeshCloser aMeshCloser( meshID ); // An object closing GMF mesh at destruction + { + if ( DriverGMF::isExtensionCorrect( myFile )) + return addMessage( SMESH_Comment("Can't open for reading ") << myFile, + /*fatal=*/true ); + else + return addMessage( SMESH_Comment("Not '.mesh' or '.meshb' extension of file ") << myFile, + /*fatal=*/true ); + } + DriverGMF::MeshCloser aMeshCloser( meshID ); // An object closing GMF mesh at destruction // Read nodes @@ -106,113 +110,187 @@ Driver_Mesh::Status DriverGMF_Read::Perform() // Read elements - int iN[28]; + int iN[28]; // 28 - nb nodes in HEX27 (+ 1 for safety :) /* Read edges */ const int edgeIDShift = myMesh->GetMeshInfo().NbElements(); if ( int nbEdges = GmfStatKwd(meshID, GmfEdges)) { - GmfGotoKwd(meshID, GmfEdges); - for ( int i = 1; i <= nbEdges; ++i ) + // read extra vertices for quadratic edges + std::vector quadNodesAtEdges( nbEdges + 1, -1 ); + if ( int nbQuadEdges = GmfStatKwd(meshID, GmfExtraVerticesAtEdges)) { - GmfGetLin(meshID, GmfEdges, &iN[0], &iN[1], &ref); - if ( !myMesh->AddEdgeWithID( iN[0], iN[1], edgeIDShift + i )) - status = storeBadNodeIds( "GmfEdges",i, 2, iN[0], iN[1] ); + GmfGotoKwd(meshID, GmfExtraVerticesAtEdges); + for ( int i = 1; i <= nbQuadEdges; ++i ) + { + GmfGetLin(meshID, GmfExtraVerticesAtEdges, &iN[0], &iN[1], &iN[2]); + if ( iN[1] >= 1 ) + quadNodesAtEdges[ iN[0] ] = iN[2]; + } } - } - /* Read quadratic edges */ - const int edge2IDShift = myMesh->GetMeshInfo().NbElements(); - if ( int nbEdges = GmfStatKwd(meshID, GmfEdgesP2)) - { - GmfGotoKwd(meshID, GmfEdgesP2); + // create edges + GmfGotoKwd(meshID, GmfEdges); for ( int i = 1; i <= nbEdges; ++i ) { - GmfGetLin(meshID, GmfEdgesP2, &iN[0], &iN[1], &iN[2], &ref); - if ( !myMesh->AddEdgeWithID( iN[0], iN[1], iN[2], edge2IDShift + i )) - status = storeBadNodeIds( "GmfEdgesP2",i, 3, iN[0], iN[1], iN[2] ); + GmfGetLin(meshID, GmfEdges, &iN[0], &iN[1], &ref); + const int midN = quadNodesAtEdges[ i ]; + if ( midN > 0 ) + { + if ( !myMesh->AddEdgeWithID( iN[0], iN[1], midN, edgeIDShift + i )) + status = storeBadNodeIds( "GmfEdges + GmfExtraVerticesAtEdges",i, + 3, iN[0], iN[1], midN); + } + else + { + if ( !myMesh->AddEdgeWithID( iN[0], iN[1], edgeIDShift + i )) + status = storeBadNodeIds( "GmfEdges",i, 2, iN[0], iN[1] ); + } } } + /* Read triangles */ const int triaIDShift = myMesh->GetMeshInfo().NbElements(); if ( int nbTria = GmfStatKwd(meshID, GmfTriangles)) { - GmfGotoKwd(meshID, GmfTriangles); - for ( int i = 1; i <= nbTria; ++i ) + // read extra vertices for quadratic triangles + std::vector< std::vector > quadNodesAtTriangles( nbTria + 1 ); + if ( int nbQuadTria = GmfStatKwd(meshID, GmfExtraVerticesAtTriangles )) { - GmfGetLin(meshID, GmfTriangles, &iN[0], &iN[1], &iN[2], &ref); - if ( !myMesh->AddFaceWithID( iN[0], iN[1], iN[2], triaIDShift + i )) - status = storeBadNodeIds( "GmfTriangles",i, 3, iN[0], iN[1], iN[2] ); + GmfGotoKwd( meshID, GmfExtraVerticesAtTriangles ); + for ( int i = 1; i <= nbQuadTria; ++i ) + { + GmfGetLin(meshID, GmfExtraVerticesAtTriangles, + &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], + &iN[5]); // iN[5] - preview TRIA7 + if ( iN[0] <= nbTria ) + { + std::vector& nodes = quadNodesAtTriangles[ iN[0] ]; + nodes.insert( nodes.end(), & iN[2], & iN[5+1] ); + nodes.resize( iN[1] ); + } + } } - } - /* Read quadratic triangles */ - const int tria2IDShift = myMesh->GetMeshInfo().NbElements(); - if ( int nbTria = GmfStatKwd(meshID, GmfTrianglesP2)) - { - GmfGotoKwd(meshID, GmfTrianglesP2); + // create triangles + GmfGotoKwd(meshID, GmfTriangles); for ( int i = 1; i <= nbTria; ++i ) { - GmfGetLin(meshID, GmfTrianglesP2, - &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5], &ref); - if ( !myMesh->AddFaceWithID( iN[0],iN[1],iN[2],iN[3],iN[4],iN[5], - tria2IDShift + i )) - status = storeBadNodeIds( "GmfTrianglesP2",i, 6, iN[0],iN[1],iN[2],iN[3],iN[4],iN[5] ); + GmfGetLin(meshID, GmfTriangles, &iN[0], &iN[1], &iN[2], &ref); + std::vector& midN = quadNodesAtTriangles[ i ]; + if ( midN.size() >= 3 ) + { + if ( !myMesh->AddFaceWithID( iN[0],iN[1],iN[2], midN[0],midN[1],midN[2], + triaIDShift + i )) + status = storeBadNodeIds( "GmfTriangles + GmfExtraVerticesAtTriangles",i, 6, + iN[0],iN[1],iN[2], midN[0],midN[1],midN[2] ); + } + else + { + if ( !myMesh->AddFaceWithID( iN[0], iN[1], iN[2], triaIDShift + i )) + status = storeBadNodeIds( "GmfTriangles",i, 3, iN[0], iN[1], iN[2] ); + } + if ( !midN.empty() ) SMESHUtils::FreeVector( midN ); } } + /* Read quadrangles */ const int quadIDShift = myMesh->GetMeshInfo().NbElements(); if ( int nbQuad = GmfStatKwd(meshID, GmfQuadrilaterals)) { - GmfGotoKwd(meshID, GmfQuadrilaterals); - for ( int i = 1; i <= nbQuad; ++i ) + // read extra vertices for quadratic quadrangles + std::vector< std::vector > quadNodesAtQuadrilaterals( nbQuad + 1 ); + if ( int nbQuadQuad = GmfStatKwd( meshID, GmfExtraVerticesAtQuadrilaterals )) { - GmfGetLin(meshID, GmfQuadrilaterals, &iN[0], &iN[1], &iN[2], &iN[3], &ref); - if ( !myMesh->AddFaceWithID( iN[0], iN[1], iN[2], iN[3], quadIDShift + i )) - status = storeBadNodeIds( "GmfQuadrilaterals",i, 4, iN[0], iN[1],iN[2], iN[3] ); + GmfGotoKwd(meshID, GmfExtraVerticesAtQuadrilaterals); + for ( int i = 1; i <= nbQuadQuad; ++i ) + { + GmfGetLin(meshID, GmfExtraVerticesAtQuadrilaterals, + &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5], &iN[6]); + if ( iN[0] <= nbQuad ) + { + std::vector& nodes = quadNodesAtQuadrilaterals[ iN[0] ]; + nodes.insert( nodes.end(), & iN[2], & iN[6+1] ); + nodes.resize( iN[1] ); + } + } } - } - /* Read bi-quadratic quadrangles */ - const int quad2IDShift = myMesh->GetMeshInfo().NbElements(); - if ( int nbQuad = GmfStatKwd(meshID, GmfQuadrilateralsQ2)) - { - GmfGotoKwd(meshID, GmfQuadrilateralsQ2); + // create quadrangles + GmfGotoKwd(meshID, GmfQuadrilaterals); for ( int i = 1; i <= nbQuad; ++i ) { - GmfGetLin(meshID, GmfQuadrilateralsQ2, - &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5], &iN[6], &iN[7], &iN[8], &ref); - if ( !myMesh->AddFaceWithID( iN[0],iN[1],iN[2],iN[3],iN[4],iN[5],iN[6],iN[7],iN[8], - quad2IDShift + i )) - status = storeBadNodeIds( "GmfQuadrilateralsQ2",i, - 9, iN[0],iN[1],iN[2],iN[3],iN[4],iN[5],iN[6],iN[7],iN[8] ); + GmfGetLin(meshID, GmfQuadrilaterals, &iN[0], &iN[1], &iN[2], &iN[3], &ref); + std::vector& midN = quadNodesAtQuadrilaterals[ i ]; + if ( midN.size() == 8-4 ) // QUAD8 + { + if ( !myMesh->AddFaceWithID( iN[0], iN[1], iN[2], iN[3], + midN[0], midN[1], midN[2], midN[3], + quadIDShift + i )) + status = storeBadNodeIds( "GmfQuadrilaterals + GmfExtraVerticesAtQuadrilaterals",i, 8, + iN[0], iN[1],iN[2], iN[3], + midN[0], midN[1], midN[2], midN[3]); + } + else if ( midN.size() > 8-4 ) // QUAD9 + { + if ( !myMesh->AddFaceWithID( iN[0], iN[1], iN[2], iN[3], + midN[0], midN[1], midN[2], midN[3], midN[4], + quadIDShift + i )) + status = storeBadNodeIds( "GmfQuadrilaterals + GmfExtraVerticesAtQuadrilaterals",i, 9, + iN[0], iN[1],iN[2], iN[3], + midN[0], midN[1], midN[2], midN[3], midN[4]); + } + else // QUAD4 + { + if ( !myMesh->AddFaceWithID( iN[0], iN[1], iN[2], iN[3], quadIDShift + i )) + status = storeBadNodeIds( "GmfQuadrilaterals",i, 4, iN[0], iN[1],iN[2], iN[3] ); + } + if ( !midN.empty() ) SMESHUtils::FreeVector( midN ); } } + /* Read terahedra */ const int tetIDShift = myMesh->GetMeshInfo().NbElements(); - if ( int nbTet = GmfStatKwd(meshID, GmfTetrahedra)) + if ( int nbTet = GmfStatKwd( meshID, GmfTetrahedra )) { - GmfGotoKwd(meshID, GmfTetrahedra); - for ( int i = 1; i <= nbTet; ++i ) + // read extra vertices for quadratic tetrahedra + std::vector< std::vector > quadNodesAtTetrahedra( nbTet + 1 ); + if ( int nbQuadTetra = GmfStatKwd( meshID, GmfExtraVerticesAtTetrahedra )) { - GmfGetLin(meshID, GmfTetrahedra, &iN[0], &iN[1], &iN[2], &iN[3], &ref); - if ( !myMesh->AddVolumeWithID( iN[0], iN[2], iN[1], iN[3], tetIDShift + i )) - status = storeBadNodeIds( "GmfTetrahedra",i, 4, iN[0], iN[1],iN[2], iN[3] ); + GmfGotoKwd(meshID, GmfExtraVerticesAtTetrahedra); + for ( int i = 1; i <= nbQuadTetra; ++i ) + { + GmfGetLin(meshID, GmfExtraVerticesAtTetrahedra, + &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5], &iN[6], &iN[7]); + if ( iN[0] <= nbTet ) + { + std::vector& nodes = quadNodesAtTetrahedra[ iN[0] ]; + nodes.insert( nodes.end(), & iN[2], & iN[7+1] ); + nodes.resize( iN[1] ); + } + } } - } - /* Read quadratic terahedra */ - const int tet2IDShift = myMesh->GetMeshInfo().NbElements(); - if ( int nbTet = GmfStatKwd(meshID, GmfTetrahedraP2)) - { - GmfGotoKwd(meshID, GmfTetrahedraP2); + // create tetrahedra + GmfGotoKwd(meshID, GmfTetrahedra); for ( int i = 1; i <= nbTet; ++i ) { - GmfGetLin(meshID, GmfTetrahedraP2, &iN[0], &iN[1], &iN[2], - &iN[3], &iN[4], &iN[5], &iN[6], &iN[7], &iN[8], &iN[9], &ref); - if ( !myMesh->AddVolumeWithID( iN[0],iN[2],iN[1],iN[3], - iN[6],iN[5],iN[4], - iN[7],iN[9],iN[8], tet2IDShift + i )) - status = storeBadNodeIds( "GmfTetrahedraP2",i, 10, iN[0],iN[1],iN[2],iN[3], - iN[4],iN[5],iN[6],iN[7],iN[8],iN[9] ); + GmfGetLin(meshID, GmfTetrahedra, &iN[0], &iN[1], &iN[2], &iN[3], &ref); + std::vector& midN = quadNodesAtTetrahedra[ i ]; + if ( midN.size() >= 10-4 ) // TETRA10 + { + if ( !myMesh->AddVolumeWithID( iN[0], iN[2], iN[1], iN[3], + midN[2], midN[1], midN[0], midN[3], midN[5], midN[4], + tetIDShift + i )) + status = storeBadNodeIds( "GmfTetrahedra + GmfExtraVerticesAtTetrahedra",i, 10, + iN[0], iN[2], iN[1], iN[3], + midN[2], midN[1], midN[0], midN[3], midN[5], midN[4] ); + } + else // TETRA4 + { + if ( !myMesh->AddVolumeWithID( iN[0], iN[2], iN[1], iN[3], tetIDShift + i )) + status = storeBadNodeIds( "GmfTetrahedra" ,i, 4, iN[0], iN[2], iN[1], iN[3] ); + } + if ( !midN.empty() ) SMESHUtils::FreeVector( midN ); } } + /* Read pyramids */ const int pyrIDShift = myMesh->GetMeshInfo().NbElements(); if ( int nbPyr = GmfStatKwd(meshID, GmfPyramids)) @@ -225,42 +303,90 @@ Driver_Mesh::Status DriverGMF_Read::Perform() status = storeBadNodeIds( "GmfPyramids",i, 5, iN[0], iN[1],iN[2], iN[3], iN[4] ); } } + /* Read hexahedra */ const int hexIDShift = myMesh->GetMeshInfo().NbElements(); if ( int nbHex = GmfStatKwd(meshID, GmfHexahedra)) { - GmfGotoKwd(meshID, GmfHexahedra); - for ( int i = 1; i <= nbHex; ++i ) + // read extra vertices for quadratic hexahedra + std::vector< std::vector > quadNodesAtHexahedra( nbHex + 1 ); + if ( int nbQuadHexa = GmfStatKwd( meshID, GmfExtraVerticesAtHexahedra )) { - GmfGetLin(meshID, GmfHexahedra, - &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5], &iN[6], &iN[7], &ref); - if ( !myMesh->AddVolumeWithID( iN[0], iN[3], iN[2], iN[1], iN[4], iN[7], iN[6], iN[5], - hexIDShift + i)) - status = storeBadNodeIds( "GmfHexahedra",i, - 8, iN[0], iN[1],iN[2], iN[3], iN[4], iN[7], iN[6], iN[5] ); + GmfGotoKwd(meshID, GmfExtraVerticesAtHexahedra); + for ( int i = 1; i <= nbQuadHexa; ++i ) + { + GmfGetLin(meshID, GmfExtraVerticesAtHexahedra, &iN[0], &iN[1], // Hexa Id, Nb extra vertices + &iN[2], &iN[3], &iN[4], &iN[5], + &iN[6], &iN[7], &iN[8], &iN[9], + &iN[10], &iN[11], &iN[12], &iN[13], // HEXA20 + &iN[14], + &iN[15], &iN[16], &iN[17], &iN[18], + &iN[19], + &iN[20]); // HEXA27 + if ( iN[0] <= nbHex ) + { + std::vector& nodes = quadNodesAtHexahedra[ iN[0] ]; + nodes.insert( nodes.end(), & iN[2], & iN[20+1] ); + nodes.resize( iN[1] ); + } + } } - } - /* Read tri-quadratic hexahedra */ - const int hex2IDShift = myMesh->GetMeshInfo().NbElements(); - if ( int nbHex = GmfStatKwd(meshID, GmfHexahedraQ2)) - { - GmfGotoKwd(meshID, GmfHexahedraQ2); + // create hexhedra + GmfGotoKwd(meshID, GmfHexahedra); for ( int i = 1; i <= nbHex; ++i ) { - GmfGetLin(meshID, GmfHexahedraQ2, &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5], - &iN[6], &iN[7], &iN[8],&iN[9],&iN[10],&iN[11],&iN[12],&iN[13],&iN[14], - &iN[15],&iN[16],&iN[17],&iN[18],&iN[19],&iN[20],&iN[21],&iN[22],&iN[23], - &iN[24],&iN[25],&iN[26], &ref); - if ( !myMesh->AddVolumeWithID( iN[0],iN[3],iN[2],iN[1],iN[4],iN[7],iN[6],iN[5],iN[11],iN[10], - iN[9],iN[8],iN[12],iN[15],iN[14], iN[13],iN[19],iN[18],iN[17], - iN[16],iN[20],iN[24],iN[23],iN[22],iN[21], iN[25],iN[26], - hex2IDShift + i )) - status = storeBadNodeIds( "GmfHexahedraQ2",i, 27, - iN[0],iN[3],iN[2],iN[1],iN[4], iN[7],iN[6],iN[5],iN[11],iN[10], - iN[9],iN[8],iN[12],iN[15],iN[14], iN[13],iN[19],iN[18],iN[17], - iN[16],iN[20],iN[24],iN[23],iN[22],iN[21], iN[25],iN[26]); + GmfGetLin(meshID, GmfHexahedra, &iN[0], &iN[1], &iN[2], &iN[3], + &iN[4], &iN[5], &iN[6], &iN[7], &ref); + std::vector& midN = quadNodesAtHexahedra[ i ]; + if ( midN.size() == 20-8 ) // HEXA20 + { + if ( !myMesh->AddVolumeWithID( iN[0], iN[3], iN[2], iN[1], + iN[4], iN[7], iN[6], iN[5], + midN[3], midN[2], midN[1], midN[0], + midN[7], midN[6], midN[5], midN[4], + midN[8], midN[11], midN[10], midN[9], + hexIDShift + i )) + status = storeBadNodeIds( "GmfHexahedra + GmfExtraVerticesAtHexahedra",i, 20, + iN[0], iN[3], iN[2], iN[1], + iN[4], iN[7], iN[6], iN[5], + midN[3], midN[2], midN[1], midN[0], + midN[7], midN[6], midN[5], midN[4], + midN[8], midN[11], midN[10], midN[9]); + } + else if ( midN.size() >= 27-8 ) // HEXA27 + { + if ( !myMesh->AddVolumeWithID( iN[0], iN[3], iN[2], iN[1], + iN[4], iN[7], iN[6], iN[5], + midN[3], midN[2], midN[1], midN[0], + midN[7], midN[6], midN[5], midN[4], + midN[8], midN[11], midN[10], midN[9], + midN[12], + midN[16], midN[15], midN[14], midN[13], + midN[17], + midN[18], + hexIDShift + i )) + status = storeBadNodeIds( "GmfHexahedra + GmfExtraVerticesAtHexahedra",i, 27, + iN[0], iN[3], iN[2], iN[1], + iN[4], iN[7], iN[6], iN[5], + midN[3], midN[2], midN[1], midN[0], + midN[7], midN[6], midN[5], midN[4], + midN[8], midN[11], midN[10], midN[9], + midN[12], + midN[16], midN[15], midN[14], midN[13], + midN[17], + midN[18]); + } + else // HEXA8 + { + if ( !myMesh->AddVolumeWithID( iN[0], iN[3], iN[2], iN[1], + iN[4], iN[7], iN[6], iN[5], hexIDShift + i ) ) + status = storeBadNodeIds( "GmfHexahedra" ,i, 8, iN[0], iN[3], iN[2], iN[1], + iN[4], iN[7], iN[6], iN[5] ); + } + if ( !midN.empty() ) SMESHUtils::FreeVector( midN ); } } + /* Read prism */ const int prismIDShift = myMesh->GetMeshInfo().NbElements(); if ( int nbPrism = GmfStatKwd(meshID, GmfPrisms)) @@ -268,8 +394,7 @@ Driver_Mesh::Status DriverGMF_Read::Perform() GmfGotoKwd(meshID, GmfPrisms); for ( int i = 1; i <= nbPrism; ++i ) { - GmfGetLin(meshID, GmfPrisms, - &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5], &ref); + GmfGetLin(meshID, GmfPrisms, &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5], &ref); if ( !myMesh->AddVolumeWithID( iN[0], iN[2], iN[1], iN[3], iN[5], iN[4], prismIDShift + i)) status = storeBadNodeIds( "GmfPrisms",i, 6, iN[0], iN[1],iN[2], iN[3], iN[4], iN[5] );