From ab9600ccf01448cceaf0ea77396003596cbf809f Mon Sep 17 00:00:00 2001 From: eap Date: Fri, 22 Feb 2013 08:22:12 +0000 Subject: [PATCH] 0022134: DriverGMF : reading quadratic meshes BEGINNING OF The way of storage of quadratic elements has been corrected --- src/DriverGMF/DriverGMF_Read.cxx | 153 ++++++++++++++++++++++-------- src/DriverGMF/DriverGMF_Write.cxx | 82 ++++++++++++---- 2 files changed, 175 insertions(+), 60 deletions(-) diff --git a/src/DriverGMF/DriverGMF_Read.cxx b/src/DriverGMF/DriverGMF_Read.cxx index 9cf599fee..99b821209 100644 --- a/src/DriverGMF/DriverGMF_Read.cxx +++ b/src/DriverGMF/DriverGMF_Read.cxx @@ -107,85 +107,156 @@ Driver_Mesh::Status DriverGMF_Read::Perform() // Read elements - int iN[28]; + int iN[28]; // 28 - nb nodes in HEX27 (+ 1 for safety :) + + /* Read extra vertices for quadratic edges */ + std::vector quadNodesAtEdges; + int nbQuadEdges = 0; + if ( (nbQuadEdges = GmfStatKwd(meshID, GmfExtraVerticesAtEdges)) ) + { + quadNodesAtEdges.reserve( nbQuadEdges ); + GmfGotoKwd(meshID, GmfExtraVerticesAtEdges); + for ( int i = 1; i <= nbQuadEdges; ++i ) + { + GmfGetLin(meshID, GmfExtraVerticesAtEdges, &iN[0], &iN[1], &iN[2]); + quadNodesAtEdges.push_back(iN[2]); + } + } /* Read edges */ const int edgeIDShift = myMesh->GetMeshInfo().NbElements(); if ( int nbEdges = GmfStatKwd(meshID, GmfEdges)) { + const bool readQuadNodes = ( nbQuadEdges == nbEdges ); GmfGotoKwd(meshID, GmfEdges); for ( int i = 1; i <= nbEdges; ++i ) { 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] ); + if ( readQuadNodes ) + { + const int midN = quadNodesAtEdges[i-1]; + 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 quadratic edges */ - const int edge2IDShift = myMesh->GetMeshInfo().NbElements(); - if ( int nbEdges = GmfStatKwd(meshID, GmfEdgesP2)) + + /* Read extra vertices for quadratic triangles */ + std::vector< std::vector > quadNodes; + int nbQuadTria = 0; + if ( (nbQuadTria = GmfStatKwd(meshID, GmfExtraVerticesAtTriangles)) ) { - GmfGotoKwd(meshID, GmfEdgesP2); - for ( int i = 1; i <= nbEdges; ++i ) + GmfGotoKwd(meshID, GmfExtraVerticesAtTriangles); + quadNodes.reserve( nbQuadTria ); + std::vector nodes(4); + for ( int i = 1; i <= nbQuadTria; ++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, GmfExtraVerticesAtTriangles, + &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], + &iN[5]); // iN[5] - preview TRIA7 + nodes.clear(); + nodes.push_back(iN[2]); + nodes.push_back(iN[3]); + nodes.push_back(iN[4]); + nodes.push_back(iN[5]); + nodes.resize( iN[1] ); + + quadNodes.push_back(nodes); } } + /* Read triangles */ const int triaIDShift = myMesh->GetMeshInfo().NbElements(); if ( int nbTria = GmfStatKwd(meshID, GmfTriangles)) { + const bool readQuadNodes = (nbQuadTria == nbTria); GmfGotoKwd(meshID, GmfTriangles); for ( int i = 1; i <= nbTria; ++i ) { 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] ); + if ( readQuadNodes ) + { + const std::vector& midN = quadNodes[ i-1 ]; + 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] ); + } } } - /* Read quadratic triangles */ - const int tria2IDShift = myMesh->GetMeshInfo().NbElements(); - if ( int nbTria = GmfStatKwd(meshID, GmfTrianglesP2)) + + /* Read extra vertices for quadratic quadrangles */ + std::vector< std::vector > quadNodesAtQuadrilaterals; + int nbQuadQuad = 0; + if ( (nbQuadQuad = GmfStatKwd(meshID, GmfExtraVerticesAtQuadrilaterals)) ) { - GmfGotoKwd(meshID, GmfTrianglesP2); - for ( int i = 1; i <= nbTria; ++i ) + GmfGotoKwd(meshID, GmfExtraVerticesAtQuadrilaterals); + quadNodesAtQuadrilaterals.reserve( nbQuadQuad ); + std::vector nodes( 5 ); + for ( int i = 1; i <= nbQuadQuad; ++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, GmfExtraVerticesAtQuadrilaterals, + &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5], &iN[6]); + nodes.clear(); + nodes.push_back(iN[2]); + nodes.push_back(iN[3]); + nodes.push_back(iN[4]); + nodes.push_back(iN[5]); + nodes.push_back(iN[6]); + nodes.resize( iN[1] ); + + quadNodesAtQuadrilaterals.push_back(nodes); } } - /* Read quadrangles */ + + /* Read quadrangles */ const int quadIDShift = myMesh->GetMeshInfo().NbElements(); if ( int nbQuad = GmfStatKwd(meshID, GmfQuadrilaterals)) { + const bool readQuadNodes = (nbQuadQuad == nbQuad); GmfGotoKwd(meshID, GmfQuadrilaterals); for ( int i = 1; i <= nbQuad; ++i ) { 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] ); - } - } - /* Read bi-quadratic quadrangles */ - const int quad2IDShift = myMesh->GetMeshInfo().NbElements(); - if ( int nbQuad = GmfStatKwd(meshID, GmfQuadrilateralsQ2)) - { - GmfGotoKwd(meshID, GmfQuadrilateralsQ2); - 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] ); + if ( readQuadNodes ) + { + const std::vector& midN = quadNodesAtQuadrilaterals[ i-1 ]; + if ( midN.size() == 4 ) + { + 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 ( !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 + { + 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] ); + } } } + /* Read terahedra */ const int tetIDShift = myMesh->GetMeshInfo().NbElements(); if ( int nbTet = GmfStatKwd(meshID, GmfTetrahedra)) diff --git a/src/DriverGMF/DriverGMF_Write.cxx b/src/DriverGMF/DriverGMF_Write.cxx index 926f7f4c3..7aeaf95a8 100644 --- a/src/DriverGMF/DriverGMF_Write.cxx +++ b/src/DriverGMF/DriverGMF_Write.cxx @@ -49,6 +49,16 @@ extern "C" const SMDS_MeshElement* elem = elemIt->next(); \ GmfSetLin(meshID, GmfKwd, +#define BEGIN_EXTRA_VERTICES_WRITE( SMDSEntity, GmfKwd, elem, nbVertices ) \ + elemIt = myMesh->elementEntityIterator( SMDSEntity ); \ + if ( elemIt->more() ) \ + { \ + GmfSetKwd(meshID, GmfKwd, myMesh->GetMeshInfo().NbEntities( SMDSEntity )); \ + for ( int gmfID = 1; elemIt->more(); ++gmfID ) \ + { \ + const SMDS_MeshElement* elem = elemIt->next(); \ + GmfSetLin(meshID, GmfKwd, gmfID, nbVertices, + #define END_ELEM_WRITE( elem ) \ elem->getshapeId() ); \ }} \ @@ -58,6 +68,10 @@ extern "C" e2id.insert( e2id.end(), make_pair( elem, gmfID )); \ }} \ +#define END_EXTRA_VERTICES_WRITE() \ + ); \ + }} \ + DriverGMF_Write::DriverGMF_Write(): Driver_SMESHDS_Mesh(), _exportRequiredGroups( true ) @@ -67,6 +81,12 @@ DriverGMF_Write::~DriverGMF_Write() { } +//================================================================================ +/*! + * \brief Reads a GMF file + */ +//================================================================================ + Driver_Mesh::Status DriverGMF_Write::Perform() { Kernel_Utils::Localizer loc; @@ -110,14 +130,17 @@ Driver_Mesh::Status DriverGMF_Write::Perform() node2IdMap[ edge->GetNode( 0 )], node2IdMap[ edge->GetNode( 1 )], END_ELEM_WRITE_ADD_TO_MAP( edge, edge2IDMap ); - + // quadratic edges - BEGIN_ELEM_WRITE( SMDSEntity_Quad_Edge, GmfEdgesP2, edge ) + BEGIN_ELEM_WRITE( SMDSEntity_Quad_Edge, GmfEdges, edge ) node2IdMap[ edge->GetNode( 0 )], node2IdMap[ edge->GetNode( 1 )], - node2IdMap[ edge->GetNode( 2 )], END_ELEM_WRITE( edge ); - + + BEGIN_EXTRA_VERTICES_WRITE( SMDSEntity_Quad_Edge, GmfExtraVerticesAtEdges, edge, 1 ) + node2IdMap[ edge->GetNode( 2 )] + END_EXTRA_VERTICES_WRITE(); + // triangles TElem2IDMap tria2IDMap; BEGIN_ELEM_WRITE( SMDSEntity_Triangle, GmfTriangles, tria ) @@ -125,17 +148,20 @@ Driver_Mesh::Status DriverGMF_Write::Perform() node2IdMap[ tria->GetNode( 1 )], node2IdMap[ tria->GetNode( 2 )], END_ELEM_WRITE_ADD_TO_MAP( tria, tria2IDMap ); - + // quadratic triangles - BEGIN_ELEM_WRITE( SMDSEntity_Quad_Triangle, GmfTrianglesP2, tria ) + BEGIN_ELEM_WRITE( SMDSEntity_Quad_Triangle, GmfTriangles, tria ) node2IdMap[ tria->GetNode( 0 )], node2IdMap[ tria->GetNode( 1 )], node2IdMap[ tria->GetNode( 2 )], + END_ELEM_WRITE( tria ); + + BEGIN_EXTRA_VERTICES_WRITE( SMDSEntity_Quad_Triangle, GmfExtraVerticesAtTriangles, tria, 3 ) node2IdMap[ tria->GetNode( 3 )], node2IdMap[ tria->GetNode( 4 )], - node2IdMap[ tria->GetNode( 5 )], - END_ELEM_WRITE( tria ); - + node2IdMap[ tria->GetNode( 5 )] + END_EXTRA_VERTICES_WRITE(); + // quadrangles TElem2IDMap quad2IDMap; BEGIN_ELEM_WRITE( SMDSEntity_Quadrangle, GmfQuadrilaterals, quad ) @@ -145,19 +171,37 @@ Driver_Mesh::Status DriverGMF_Write::Perform() node2IdMap[ quad->GetNode( 3 )], END_ELEM_WRITE_ADD_TO_MAP( quad, quad2IDMap ); - // bi-quadratic quadrangles - BEGIN_ELEM_WRITE( SMDSEntity_BiQuad_Quadrangle, GmfQuadrilateralsQ2, quad ) + // quadratic quadrangles + BEGIN_ELEM_WRITE( SMDSEntity_Quad_Quadrangle, GmfQuadrilaterals, quad ) node2IdMap[ quad->GetNode( 0 )], - node2IdMap[ quad->GetNode( 3 )], - node2IdMap[ quad->GetNode( 2 )], node2IdMap[ quad->GetNode( 1 )], - node2IdMap[ quad->GetNode( 7 )], - node2IdMap[ quad->GetNode( 6 )], - node2IdMap[ quad->GetNode( 5 )], + node2IdMap[ quad->GetNode( 2 )], + node2IdMap[ quad->GetNode( 3 )], + END_ELEM_WRITE( quad ); + + BEGIN_EXTRA_VERTICES_WRITE( SMDSEntity_Quad_Quadrangle, GmfExtraVerticesAtQuadrilaterals, quad, 4 ) node2IdMap[ quad->GetNode( 4 )], - node2IdMap[ quad->GetNode( 8 )], + node2IdMap[ quad->GetNode( 5 )], + node2IdMap[ quad->GetNode( 6 )], + node2IdMap[ quad->GetNode( 7 )] + END_EXTRA_VERTICES_WRITE(); + + // bi-quadratic quadrangles + BEGIN_ELEM_WRITE( SMDSEntity_BiQuad_Quadrangle, GmfQuadrilaterals, quad ) + node2IdMap[ quad->GetNode( 0 )], + node2IdMap[ quad->GetNode( 1 )], + node2IdMap[ quad->GetNode( 2 )], + node2IdMap[ quad->GetNode( 3 )], END_ELEM_WRITE( quad ); - + + BEGIN_EXTRA_VERTICES_WRITE( SMDSEntity_BiQuad_Quadrangle, GmfExtraVerticesAtQuadrilaterals, quad, 5 ) + node2IdMap[ quad->GetNode( 4 )], + node2IdMap[ quad->GetNode( 5 )], + node2IdMap[ quad->GetNode( 6 )], + node2IdMap[ quad->GetNode( 7 )], + node2IdMap[ quad->GetNode( 8 )] + END_EXTRA_VERTICES_WRITE(); + // terahedra BEGIN_ELEM_WRITE( SMDSEntity_Tetra, GmfTetrahedra, tetra ) node2IdMap[ tetra->GetNode( 0 )], @@ -165,7 +209,7 @@ Driver_Mesh::Status DriverGMF_Write::Perform() node2IdMap[ tetra->GetNode( 1 )], node2IdMap[ tetra->GetNode( 3 )], END_ELEM_WRITE( tetra ); - + // quadratic terahedra BEGIN_ELEM_WRITE( SMDSEntity_Quad_Tetra, GmfTetrahedraP2, tetra ) node2IdMap[ tetra->GetNode( 0 )], -- 2.30.2