0022134: DriverGMF : reading quadratic meshes

Fix errors of import/export of meshes including both linear and
  quadratic elements.
This commit is contained in:
eap 2013-02-28 11:36:54 +00:00
parent 12e809327d
commit 1dbda4f113
2 changed files with 239 additions and 336 deletions

View File

@ -29,6 +29,7 @@
#include "SMESHDS_Group.hxx" #include "SMESHDS_Group.hxx"
#include "SMESHDS_Mesh.hxx" #include "SMESHDS_Mesh.hxx"
#include "SMESH_Comment.hxx" #include "SMESH_Comment.hxx"
#include "SMESH_TypeDefs.hxx"
#include <Basics_Utils.hxx> #include <Basics_Utils.hxx>
@ -69,9 +70,11 @@ Driver_Mesh::Status DriverGMF_Read::Perform()
if ( !meshID ) if ( !meshID )
{ {
if ( DriverGMF::isExtensionCorrect( myFile )) if ( DriverGMF::isExtensionCorrect( myFile ))
return addMessage( SMESH_Comment("Can't open for reading ") << myFile, /*fatal=*/true ); return addMessage( SMESH_Comment("Can't open for reading ") << myFile,
/*fatal=*/true );
else else
return addMessage( SMESH_Comment("Not '.mesh' or '.meshb' extension of file ") << myFile, /*fatal=*/true ); 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 DriverGMF::MeshCloser aMeshCloser( meshID ); // An object closing GMF mesh at destruction
@ -109,34 +112,33 @@ Driver_Mesh::Status DriverGMF_Read::Perform()
int iN[28]; // 28 - nb nodes in HEX27 (+ 1 for safety :) int iN[28]; // 28 - nb nodes in HEX27 (+ 1 for safety :)
/* Read extra vertices for quadratic edges */
std::vector<int> 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 */ /* Read edges */
const int edgeIDShift = myMesh->GetMeshInfo().NbElements(); const int edgeIDShift = myMesh->GetMeshInfo().NbElements();
if ( int nbEdges = GmfStatKwd(meshID, GmfEdges)) if ( int nbEdges = GmfStatKwd(meshID, GmfEdges))
{ {
const bool readQuadNodes = ( nbQuadEdges == nbEdges ); // read extra vertices for quadratic edges
std::vector<int> quadNodesAtEdges( nbEdges + 1, -1 );
if ( int nbQuadEdges = GmfStatKwd(meshID, GmfExtraVerticesAtEdges))
{
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];
}
}
// create edges
GmfGotoKwd(meshID, GmfEdges); GmfGotoKwd(meshID, GmfEdges);
for ( int i = 1; i <= nbEdges; ++i ) for ( int i = 1; i <= nbEdges; ++i )
{ {
GmfGetLin(meshID, GmfEdges, &iN[0], &iN[1], &ref); GmfGetLin(meshID, GmfEdges, &iN[0], &iN[1], &ref);
if ( readQuadNodes ) const int midN = quadNodesAtEdges[ i ];
if ( midN > 0 )
{ {
const int midN = quadNodesAtEdges[i-1];
if ( !myMesh->AddEdgeWithID( iN[0], iN[1], midN, edgeIDShift + i )) if ( !myMesh->AddEdgeWithID( iN[0], iN[1], midN, edgeIDShift + i ))
status = storeBadNodeIds( "GmfEdges + GmfExtraVerticesAtEdges",i, 3, iN[0],iN[1],midN); status = storeBadNodeIds( "GmfEdges + GmfExtraVerticesAtEdges",i,
3, iN[0], iN[1], midN);
} }
else else
{ {
@ -145,47 +147,40 @@ Driver_Mesh::Status DriverGMF_Read::Perform()
} }
} }
} }
// the vector of extra vertices at edges won't be used anymore so it is cleared
quadNodesAtEdges.clear();
/* Read extra vertices for quadratic triangles */
std::vector< std::vector<int> > quadNodesAtTriangles;
int nbQuadTria = 0;
if ( (nbQuadTria = GmfStatKwd(meshID, GmfExtraVerticesAtTriangles)) )
{
GmfGotoKwd(meshID, GmfExtraVerticesAtTriangles);
quadNodesAtTriangles.reserve( nbQuadTria );
std::vector<int> nodes(4);
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
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] );
quadNodesAtTriangles.push_back(nodes);
}
}
/* Read triangles */ /* Read triangles */
const int triaIDShift = myMesh->GetMeshInfo().NbElements(); const int triaIDShift = myMesh->GetMeshInfo().NbElements();
if ( int nbTria = GmfStatKwd(meshID, GmfTriangles)) if ( int nbTria = GmfStatKwd(meshID, GmfTriangles))
{ {
const bool readQuadNodes = (nbQuadTria == nbTria); // read extra vertices for quadratic triangles
std::vector< std::vector<int> > quadNodesAtTriangles( nbTria + 1 );
if ( int nbQuadTria = GmfStatKwd(meshID, GmfExtraVerticesAtTriangles ))
{
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<int>& nodes = quadNodesAtTriangles[ iN[0] ];
nodes.insert( nodes.end(), & iN[2], & iN[5+1] );
nodes.resize( iN[1] );
}
}
}
// create triangles
GmfGotoKwd(meshID, GmfTriangles); GmfGotoKwd(meshID, GmfTriangles);
for ( int i = 1; i <= nbTria; ++i ) for ( int i = 1; i <= nbTria; ++i )
{ {
GmfGetLin(meshID, GmfTriangles, &iN[0], &iN[1], &iN[2], &ref); GmfGetLin(meshID, GmfTriangles, &iN[0], &iN[1], &iN[2], &ref);
if ( readQuadNodes ) std::vector<int>& midN = quadNodesAtTriangles[ i ];
if ( midN.size() >= 3 )
{ {
const std::vector<int>& midN = quadNodesAtTriangles[ i-1 ]; if ( !myMesh->AddFaceWithID( iN[0],iN[1],iN[2], midN[0],midN[1],midN[2],
if ( !myMesh->AddFaceWithID( iN[0],iN[1],iN[2], midN[0],midN[1],midN[2], triaIDShift + i )) triaIDShift + i ))
status = storeBadNodeIds( "GmfTriangles + GmfExtraVerticesAtTriangles",i, 6, status = storeBadNodeIds( "GmfTriangles + GmfExtraVerticesAtTriangles",i, 6,
iN[0],iN[1],iN[2], midN[0],midN[1],midN[2] ); iN[0],iN[1],iN[2], midN[0],midN[1],midN[2] );
} }
else else
@ -193,127 +188,108 @@ Driver_Mesh::Status DriverGMF_Read::Perform()
if ( !myMesh->AddFaceWithID( iN[0], iN[1], iN[2], triaIDShift + i )) if ( !myMesh->AddFaceWithID( iN[0], iN[1], iN[2], triaIDShift + i ))
status = storeBadNodeIds( "GmfTriangles",i, 3, iN[0], iN[1], iN[2] ); status = storeBadNodeIds( "GmfTriangles",i, 3, iN[0], iN[1], iN[2] );
} }
} if ( !midN.empty() ) SMESHUtils::FreeVector( midN );
}
// the vector of extra vertices at triangles won't be used anymore so it is cleared
quadNodesAtTriangles.clear();
/* Read extra vertices for quadratic quadrangles */
std::vector< std::vector<int> > quadNodesAtQuadrilaterals;
int nbQuadQuad = 0;
if ( (nbQuadQuad = GmfStatKwd(meshID, GmfExtraVerticesAtQuadrilaterals)) )
{
GmfGotoKwd(meshID, GmfExtraVerticesAtQuadrilaterals);
quadNodesAtQuadrilaterals.reserve( nbQuadQuad );
std::vector<int> nodes( 5 );
for ( int i = 1; i <= nbQuadQuad; ++i )
{
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(); const int quadIDShift = myMesh->GetMeshInfo().NbElements();
if ( int nbQuad = GmfStatKwd(meshID, GmfQuadrilaterals)) if ( int nbQuad = GmfStatKwd(meshID, GmfQuadrilaterals))
{ {
const bool readQuadNodes = (nbQuadQuad == nbQuad); // read extra vertices for quadratic quadrangles
std::vector< std::vector<int> > quadNodesAtQuadrilaterals( nbQuad + 1 );
if ( int nbQuadQuad = GmfStatKwd( meshID, GmfExtraVerticesAtQuadrilaterals ))
{
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<int>& nodes = quadNodesAtQuadrilaterals[ iN[0] ];
nodes.insert( nodes.end(), & iN[2], & iN[6+1] );
nodes.resize( iN[1] );
}
}
}
// create quadrangles
GmfGotoKwd(meshID, GmfQuadrilaterals); GmfGotoKwd(meshID, GmfQuadrilaterals);
for ( int i = 1; i <= nbQuad; ++i ) for ( int i = 1; i <= nbQuad; ++i )
{ {
GmfGetLin(meshID, GmfQuadrilaterals, &iN[0], &iN[1], &iN[2], &iN[3], &ref); GmfGetLin(meshID, GmfQuadrilaterals, &iN[0], &iN[1], &iN[2], &iN[3], &ref);
if ( readQuadNodes ) std::vector<int>& midN = quadNodesAtQuadrilaterals[ i ];
if ( midN.size() == 8-4 ) // QUAD8
{ {
const std::vector<int>& midN = quadNodesAtQuadrilaterals[ i-1 ]; if ( !myMesh->AddFaceWithID( iN[0], iN[1], iN[2], iN[3],
if ( midN.size() == 4 ) midN[0], midN[1], midN[2], midN[3],
{ quadIDShift + i ))
if ( !myMesh->AddFaceWithID( iN[0], iN[1], iN[2], iN[3], status = storeBadNodeIds( "GmfQuadrilaterals + GmfExtraVerticesAtQuadrilaterals",i, 8,
midN[0], midN[1], midN[2], midN[3], iN[0], iN[1],iN[2], iN[3],
quadIDShift + i )) midN[0], midN[1], midN[2], midN[3]);
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 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 )) 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] ); status = storeBadNodeIds( "GmfQuadrilaterals",i, 4, iN[0], iN[1],iN[2], iN[3] );
} }
if ( !midN.empty() ) SMESHUtils::FreeVector( midN );
} }
} }
// the vector of extra vertices at quadrilaterals won't be used anymore so it is cleared
quadNodesAtQuadrilaterals.clear();
/* Read extra vertices for quadratic tetrahedra */
std::vector< std::vector<int> > quadNodesAtTetrahedra;
int nbQuadTetra = 0;
if ( (nbQuadTetra = GmfStatKwd(meshID, GmfExtraVerticesAtTetrahedra)) )
{
GmfGotoKwd(meshID, GmfExtraVerticesAtTetrahedra);
quadNodesAtTetrahedra.reserve( nbQuadTetra );
std::vector<int> nodes( 6 );
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]);
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.push_back(iN[7]);
nodes.resize( iN[1] );
quadNodesAtTetrahedra.push_back(nodes);
}
}
/* Read terahedra */ /* Read terahedra */
const int tetIDShift = myMesh->GetMeshInfo().NbElements(); const int tetIDShift = myMesh->GetMeshInfo().NbElements();
if ( int nbTet = GmfStatKwd(meshID, GmfTetrahedra)) if ( int nbTet = GmfStatKwd( meshID, GmfTetrahedra ))
{ {
const bool readQuadNodes = (nbQuadTetra == nbTet); // read extra vertices for quadratic tetrahedra
std::vector< std::vector<int> > quadNodesAtTetrahedra( nbTet + 1 );
if ( int nbQuadTetra = GmfStatKwd( meshID, GmfExtraVerticesAtTetrahedra ))
{
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<int>& nodes = quadNodesAtTetrahedra[ iN[0] ];
nodes.insert( nodes.end(), & iN[2], & iN[7+1] );
nodes.resize( iN[1] );
}
}
}
// create tetrahedra
GmfGotoKwd(meshID, GmfTetrahedra); GmfGotoKwd(meshID, GmfTetrahedra);
for ( int i = 1; i <= nbTet; ++i ) for ( int i = 1; i <= nbTet; ++i )
{ {
GmfGetLin(meshID, GmfTetrahedra, &iN[0], &iN[1], &iN[2], &iN[3], &ref); GmfGetLin(meshID, GmfTetrahedra, &iN[0], &iN[1], &iN[2], &iN[3], &ref);
if ( readQuadNodes ) std::vector<int>& midN = quadNodesAtTetrahedra[ i ];
if ( midN.size() >= 10-4 ) // TETRA10
{ {
const std::vector<int>& midN = quadNodesAtTetrahedra[ i-1 ];
if ( !myMesh->AddVolumeWithID( iN[0], iN[2], iN[1], iN[3], 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 )) midN[2], midN[1], midN[0], midN[3], midN[5], midN[4],
status = storeBadNodeIds( "GmfTetrahedra + GmfExtraVerticesAtTetrahedra",i, 10, iN[0], iN[2], iN[1], iN[3], tetIDShift + i ))
midN[2], midN[1], midN[0], midN[3], midN[5], midN[4] ); 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 else // TETRA4
{ {
if ( !myMesh->AddVolumeWithID( iN[0], iN[2], iN[1], iN[3], tetIDShift + i ) ) 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] ); status = storeBadNodeIds( "GmfTetrahedra" ,i, 4, iN[0], iN[2], iN[1], iN[3] );
} }
if ( !midN.empty() ) SMESHUtils::FreeVector( midN );
} }
} }
// the vector of extra vertices at tetrahedra won't be used anymore so it is cleared
quadNodesAtTetrahedra.clear();
/* Read pyramids */ /* Read pyramids */
const int pyrIDShift = myMesh->GetMeshInfo().NbElements(); const int pyrIDShift = myMesh->GetMeshInfo().NbElements();
@ -328,92 +304,58 @@ Driver_Mesh::Status DriverGMF_Read::Perform()
} }
} }
/* Read extra vertices for quadratic hexahedra */
std::vector< std::vector<int> > quadNodesAtHexahedra;
int nbQuadHexa = 0;
if ( (nbQuadHexa = GmfStatKwd(meshID, GmfExtraVerticesAtHexahedra)) )
{
GmfGotoKwd(meshID, GmfExtraVerticesAtHexahedra);
quadNodesAtHexahedra.reserve( nbQuadHexa );
std::vector<int> nodes( 19 );
for ( int i = 1; i <= nbQuadHexa; ++i )
{
GmfGetLin(meshID, GmfExtraVerticesAtHexahedra, &iN[0], &iN[1], // Hexa Id, Nb of 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
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.push_back(iN[7]);
nodes.push_back(iN[8]);
nodes.push_back(iN[9]);
nodes.push_back(iN[10]);
nodes.push_back(iN[11]);
nodes.push_back(iN[12]);
nodes.push_back(iN[13]);
nodes.push_back(iN[14]);
nodes.push_back(iN[15]);
nodes.push_back(iN[16]);
nodes.push_back(iN[17]);
nodes.push_back(iN[18]);
nodes.push_back(iN[19]);
nodes.push_back(iN[20]);
nodes.resize( iN[1] );
quadNodesAtHexahedra.push_back(nodes);
}
}
/* Read hexahedra */ /* Read hexahedra */
const int hexIDShift = myMesh->GetMeshInfo().NbElements(); const int hexIDShift = myMesh->GetMeshInfo().NbElements();
if ( int nbHex = GmfStatKwd(meshID, GmfHexahedra)) if ( int nbHex = GmfStatKwd(meshID, GmfHexahedra))
{ {
const bool readQuadNodes = (nbQuadHexa == nbHex); // read extra vertices for quadratic hexahedra
std::vector< std::vector<int> > quadNodesAtHexahedra( nbHex + 1 );
if ( int nbQuadHexa = GmfStatKwd( meshID, GmfExtraVerticesAtHexahedra ))
{
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<int>& nodes = quadNodesAtHexahedra[ iN[0] ];
nodes.insert( nodes.end(), & iN[2], & iN[20+1] );
nodes.resize( iN[1] );
}
}
}
// create hexhedra
GmfGotoKwd(meshID, GmfHexahedra); GmfGotoKwd(meshID, GmfHexahedra);
for ( int i = 1; i <= nbHex; ++i ) for ( int i = 1; i <= nbHex; ++i )
{ {
GmfGetLin(meshID, GmfHexahedra, &iN[0], &iN[1], &iN[2], &iN[3], GmfGetLin(meshID, GmfHexahedra, &iN[0], &iN[1], &iN[2], &iN[3],
&iN[4], &iN[5], &iN[6], &iN[7],&ref); &iN[4], &iN[5], &iN[6], &iN[7], &ref);
if ( readQuadNodes ) std::vector<int>& midN = quadNodesAtHexahedra[ i ];
if ( midN.size() == 20-8 ) // HEXA20
{ {
const std::vector<int>& midN = quadNodesAtHexahedra[ i-1 ]; if ( !myMesh->AddVolumeWithID( iN[0], iN[3], iN[2], iN[1],
if ( midN.size() == 12 ) // 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],
tetIDShift + i ))
status = storeBadNodeIds( "GmfHexahedra + GmfExtraVerticesAtHexahedra",i, 20,
iN[0], iN[3], iN[2], iN[1],
iN[4], iN[7], iN[6], iN[5], iN[4], iN[7], iN[6], iN[5],
midN[3], midN[2], midN[1], midN[0], midN[3], midN[2], midN[1], midN[0],
midN[7], midN[6], midN[5], midN[4], midN[7], midN[6], midN[5], midN[4],
midN[8], midN[11], midN[10], midN[9]); midN[8], midN[11], midN[10], midN[9],
} hexIDShift + i ))
else // HEXA27 status = storeBadNodeIds( "GmfHexahedra + GmfExtraVerticesAtHexahedra",i, 20,
{ iN[0], iN[3], iN[2], iN[1],
if ( !myMesh->AddVolumeWithID( iN[0], iN[3], iN[2], iN[1], iN[4], iN[7], iN[6], iN[5],
iN[4], iN[7], iN[6], iN[5], midN[3], midN[2], midN[1], midN[0],
midN[3], midN[2], midN[1], midN[0], midN[7], midN[6], midN[5], midN[4],
midN[7], midN[6], midN[5], midN[4], midN[8], midN[11], midN[10], midN[9]);
midN[8], midN[11], midN[10], midN[9], }
midN[12], else if ( midN.size() >= 27-8 ) // HEXA27
midN[16], midN[15], midN[14], midN[13], {
midN[17], if ( !myMesh->AddVolumeWithID( iN[0], iN[3], iN[2], iN[1],
midN[18],
tetIDShift + i ))
status = storeBadNodeIds( "GmfHexahedra + GmfExtraVerticesAtHexahedra",i, 27,
iN[0], iN[3], iN[2], iN[1],
iN[4], iN[7], iN[6], iN[5], iN[4], iN[7], iN[6], iN[5],
midN[3], midN[2], midN[1], midN[0], midN[3], midN[2], midN[1], midN[0],
midN[7], midN[6], midN[5], midN[4], midN[7], midN[6], midN[5], midN[4],
@ -421,20 +363,29 @@ Driver_Mesh::Status DriverGMF_Read::Perform()
midN[12], midN[12],
midN[16], midN[15], midN[14], midN[13], midN[16], midN[15], midN[14], midN[13],
midN[17], midN[17],
midN[18]); 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 else // HEXA8
{ {
if ( !myMesh->AddVolumeWithID( iN[0], iN[3], iN[2], iN[1], if ( !myMesh->AddVolumeWithID( iN[0], iN[3], iN[2], iN[1],
iN[4], iN[7], iN[6], iN[5], hexIDShift + i ) ) iN[4], iN[7], iN[6], iN[5], hexIDShift + i ) )
status = storeBadNodeIds( "GmfHexahedra" ,i, 8, iN[0], iN[3], iN[2], iN[1], status = storeBadNodeIds( "GmfHexahedra" ,i, 8, iN[0], iN[3], iN[2], iN[1],
iN[4], iN[7], iN[6], iN[5] ); iN[4], iN[7], iN[6], iN[5] );
} }
if ( !midN.empty() ) SMESHUtils::FreeVector( midN );
} }
} }
// the vector of extra vertices at tetrahedra won't be used anymore so it is cleared
quadNodesAtHexahedra.clear();
/* Read prism */ /* Read prism */
const int prismIDShift = myMesh->GetMeshInfo().NbElements(); const int prismIDShift = myMesh->GetMeshInfo().NbElements();
@ -443,8 +394,7 @@ Driver_Mesh::Status DriverGMF_Read::Perform()
GmfGotoKwd(meshID, GmfPrisms); GmfGotoKwd(meshID, GmfPrisms);
for ( int i = 1; i <= nbPrism; ++i ) for ( int i = 1; i <= nbPrism; ++i )
{ {
GmfGetLin(meshID, GmfPrisms, GmfGetLin(meshID, GmfPrisms, &iN[0], &iN[1], &iN[2], &iN[3], &iN[4], &iN[5], &ref);
&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)) if ( !myMesh->AddVolumeWithID( iN[0], iN[2], iN[1], iN[3], iN[5], iN[4], prismIDShift + i))
status = storeBadNodeIds( "GmfPrisms",i, status = storeBadNodeIds( "GmfPrisms",i,
6, iN[0], iN[1],iN[2], iN[3], iN[4], iN[5] ); 6, iN[0], iN[1],iN[2], iN[3], iN[4], iN[5] );

View File

@ -40,37 +40,42 @@ extern "C"
#include <vector> #include <vector>
#define BEGIN_ELEM_WRITE( SMDSEntity, GmfKwd, elem ) \ #define BEGIN_ELEM_WRITE( SMDSEntity, GmfKwd, elem ) \
elemIt = myMesh->elementEntityIterator( SMDSEntity ); \ elemIt = elementIterator( SMDSEntity ); \
if ( elemIt->more() ) \ if ( elemIt->more() ) \
{ \ { \
GmfSetKwd(meshID, GmfKwd, myMesh->GetMeshInfo().NbEntities( SMDSEntity )); \ GmfSetKwd(meshID, GmfKwd, myMesh->GetMeshInfo().NbElements( SMDSEntity )); \
for ( int gmfID = 1; elemIt->more(); ++gmfID ) \ for ( int gmfID = 1; elemIt->more(); ++gmfID ) \
{ \ { \
const SMDS_MeshElement* elem = elemIt->next(); \ const SMDS_MeshElement* elem = elemIt->next(); \
GmfSetLin(meshID, GmfKwd, GmfSetLin(meshID, GmfKwd,
#define BEGIN_EXTRA_VERTICES_WRITE( SMDSEntity, GmfKwd, elem, nbVertices ) \ #define BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom, LinType, GmfKwd, elem ) \
elemIt = myMesh->elementEntityIterator( SMDSEntity ); \ elemIt = elementIterator( SMDSGeom ); \
if ( elemIt->more() ) \ if ( elemIt->more() ) \
{ \ { \
GmfSetKwd(meshID, GmfKwd, myMesh->GetMeshInfo().NbEntities( SMDSEntity )); \ int totalNbElems = myMesh->GetMeshInfo().NbElements( SMDSGeom ); \
int nbLinearElems = myMesh->GetMeshInfo().NbElements( LinType ); \
if ( totalNbElems - nbLinearElems > 0 ) \
{ \
GmfSetKwd(meshID, GmfKwd, totalNbElems - nbLinearElems); \
for ( int gmfID = 1; elemIt->more(); ++gmfID ) \ for ( int gmfID = 1; elemIt->more(); ++gmfID ) \
{ \ { \
const SMDS_MeshElement* elem = elemIt->next(); \ const SMDS_MeshElement* elem = elemIt->next(); \
GmfSetLin(meshID, GmfKwd, gmfID, nbVertices, if ( elem->IsQuadratic() ) { \
GmfSetLin(meshID, GmfKwd, gmfID, elem->NbNodes() - elem->NbCornerNodes(),
#define END_ELEM_WRITE( elem ) \ #define END_ELEM_WRITE( elem ) \
elem->getshapeId() ); \ elem->getshapeId() ); \
}} \ }}
#define END_ELEM_WRITE_ADD_TO_MAP( elem, e2id ) \ #define END_ELEM_WRITE_ADD_TO_MAP( elem, e2id ) \
elem->getshapeId() ); \ elem->getshapeId() ); \
e2id.insert( e2id.end(), make_pair( elem, gmfID )); \ e2id.insert( e2id.end(), make_pair( elem, gmfID )); \
}} \ }}
#define END_EXTRA_VERTICES_WRITE() \ #define END_EXTRA_VERTICES_WRITE() \
); \ ); \
}} \ }}}}
DriverGMF_Write::DriverGMF_Write(): DriverGMF_Write::DriverGMF_Write():
@ -126,107 +131,73 @@ Driver_Mesh::Status DriverGMF_Write::Perform()
// edges // edges
TElem2IDMap edge2IDMap; TElem2IDMap edge2IDMap;
BEGIN_ELEM_WRITE( SMDSEntity_Edge, GmfEdges, edge ) BEGIN_ELEM_WRITE( SMDSGeom_EDGE, GmfEdges, edge )
node2IdMap[ edge->GetNode( 0 )], node2IdMap[ edge->GetNode( 0 )],
node2IdMap[ edge->GetNode( 1 )], node2IdMap[ edge->GetNode( 1 )],
END_ELEM_WRITE_ADD_TO_MAP( edge, edge2IDMap ); END_ELEM_WRITE_ADD_TO_MAP( edge, edge2IDMap );
// quadratic edges // nodes of quadratic edges
BEGIN_ELEM_WRITE( SMDSEntity_Quad_Edge, GmfEdges, edge ) BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom_EDGE, SMDSEntity_Edge,
node2IdMap[ edge->GetNode( 0 )], GmfExtraVerticesAtEdges, edge )
node2IdMap[ edge->GetNode( 1 )],
END_ELEM_WRITE( edge );
BEGIN_EXTRA_VERTICES_WRITE( SMDSEntity_Quad_Edge, GmfExtraVerticesAtEdges, edge, 1 )
node2IdMap[ edge->GetNode( 2 )] node2IdMap[ edge->GetNode( 2 )]
END_EXTRA_VERTICES_WRITE(); END_EXTRA_VERTICES_WRITE();
// triangles // triangles
TElem2IDMap tria2IDMap; TElem2IDMap tria2IDMap;
BEGIN_ELEM_WRITE( SMDSEntity_Triangle, GmfTriangles, tria ) BEGIN_ELEM_WRITE( SMDSGeom_TRIANGLE, GmfTriangles, tria )
node2IdMap[ tria->GetNode( 0 )], node2IdMap[ tria->GetNode( 0 )],
node2IdMap[ tria->GetNode( 1 )], node2IdMap[ tria->GetNode( 1 )],
node2IdMap[ tria->GetNode( 2 )], node2IdMap[ tria->GetNode( 2 )],
END_ELEM_WRITE_ADD_TO_MAP( tria, tria2IDMap ); END_ELEM_WRITE_ADD_TO_MAP( tria, tria2IDMap );
// quadratic triangles // nodes of quadratic triangles
BEGIN_ELEM_WRITE( SMDSEntity_Quad_Triangle, GmfTriangles, tria ) BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom_TRIANGLE, SMDSEntity_Triangle,
node2IdMap[ tria->GetNode( 0 )], GmfExtraVerticesAtTriangles, tria )
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( 3 )],
node2IdMap[ tria->GetNode( 4 )], node2IdMap[ tria->GetNode( 4 )],
node2IdMap[ tria->GetNode( 5 )] node2IdMap[ tria->GetNode( 5 )]
//node2IdMap[ tria->GetNodeWrap( 6 )] // for TRIA7
END_EXTRA_VERTICES_WRITE(); END_EXTRA_VERTICES_WRITE();
// quadrangles // quadrangles
TElem2IDMap quad2IDMap; TElem2IDMap quad2IDMap;
BEGIN_ELEM_WRITE( SMDSEntity_Quadrangle, GmfQuadrilaterals, quad ) BEGIN_ELEM_WRITE( SMDSGeom_QUADRANGLE, GmfQuadrilaterals, quad )
node2IdMap[ quad->GetNode( 0 )], node2IdMap[ quad->GetNode( 0 )],
node2IdMap[ quad->GetNode( 1 )], node2IdMap[ quad->GetNode( 1 )],
node2IdMap[ quad->GetNode( 2 )], node2IdMap[ quad->GetNode( 2 )],
node2IdMap[ quad->GetNode( 3 )], node2IdMap[ quad->GetNode( 3 )],
END_ELEM_WRITE_ADD_TO_MAP( quad, quad2IDMap ); END_ELEM_WRITE_ADD_TO_MAP( quad, quad2IDMap );
// quadratic quadrangles // nodes of quadratic quadrangles
BEGIN_ELEM_WRITE( SMDSEntity_Quad_Quadrangle, GmfQuadrilaterals, quad ) BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom_QUADRANGLE, SMDSEntity_Quadrangle,
node2IdMap[ quad->GetNode( 0 )], GmfExtraVerticesAtQuadrilaterals, quad )
node2IdMap[ quad->GetNode( 1 )],
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( 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( 4 )],
node2IdMap[ quad->GetNode( 5 )], node2IdMap[ quad->GetNode( 5 )],
node2IdMap[ quad->GetNode( 6 )], node2IdMap[ quad->GetNode( 6 )],
node2IdMap[ quad->GetNode( 7 )], node2IdMap[ quad->GetNode( 7 )],
node2IdMap[ quad->GetNode( 8 )] node2IdMap[ quad->GetNodeWrap( 8 )] // for QUAD9
END_EXTRA_VERTICES_WRITE(); END_EXTRA_VERTICES_WRITE();
// terahedra // terahedra
BEGIN_ELEM_WRITE( SMDSEntity_Tetra, GmfTetrahedra, tetra ) BEGIN_ELEM_WRITE( SMDSGeom_TETRA, GmfTetrahedra, tetra )
node2IdMap[ tetra->GetNode( 0 )], node2IdMap[ tetra->GetNode( 0 )],
node2IdMap[ tetra->GetNode( 2 )], node2IdMap[ tetra->GetNode( 2 )],
node2IdMap[ tetra->GetNode( 1 )], node2IdMap[ tetra->GetNode( 1 )],
node2IdMap[ tetra->GetNode( 3 )], node2IdMap[ tetra->GetNode( 3 )],
END_ELEM_WRITE( tetra ); END_ELEM_WRITE( tetra );
// quadratic terahedra // nodes of quadratic terahedra
BEGIN_ELEM_WRITE( SMDSEntity_Quad_Tetra, GmfTetrahedra, tetra ) BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom_TETRA, SMDSEntity_Tetra,
node2IdMap[ tetra->GetNode( 0 )], GmfExtraVerticesAtTetrahedra, tetra )
node2IdMap[ tetra->GetNode( 2 )],
node2IdMap[ tetra->GetNode( 1 )],
node2IdMap[ tetra->GetNode( 3 )],
END_ELEM_WRITE( tetra );
BEGIN_EXTRA_VERTICES_WRITE( SMDSEntity_Quad_Tetra, GmfExtraVerticesAtTetrahedra, tetra, 6 )
node2IdMap[ tetra->GetNode( 6 )], node2IdMap[ tetra->GetNode( 6 )],
node2IdMap[ tetra->GetNode( 5 )], node2IdMap[ tetra->GetNode( 5 )],
node2IdMap[ tetra->GetNode( 4 )], node2IdMap[ tetra->GetNode( 4 )],
node2IdMap[ tetra->GetNode( 7 )], node2IdMap[ tetra->GetNode( 7 )],
node2IdMap[ tetra->GetNode( 9 )], node2IdMap[ tetra->GetNode( 9 )],
node2IdMap[ tetra->GetNode( 8 )] node2IdMap[ tetra->GetNode( 8 )]
//node2IdMap[ tetra->GetNodeWrap( 10 )], // for TETRA11
END_EXTRA_VERTICES_WRITE(); END_EXTRA_VERTICES_WRITE();
// pyramids // pyramids
BEGIN_ELEM_WRITE( SMDSEntity_Pyramid, GmfPyramids, pyra ) BEGIN_ELEM_WRITE( SMDSEntity_Pyramid, GmfPyramids, pyra )
node2IdMap[ pyra->GetNode( 0 )], node2IdMap[ pyra->GetNode( 0 )],
@ -237,7 +208,7 @@ Driver_Mesh::Status DriverGMF_Write::Perform()
END_ELEM_WRITE( pyra ); END_ELEM_WRITE( pyra );
// hexahedra // hexahedra
BEGIN_ELEM_WRITE( SMDSEntity_Hexa, GmfHexahedra, hexa ) BEGIN_ELEM_WRITE( SMDSGeom_HEXA, GmfHexahedra, hexa )
node2IdMap[ hexa->GetNode( 0 )], node2IdMap[ hexa->GetNode( 0 )],
node2IdMap[ hexa->GetNode( 3 )], node2IdMap[ hexa->GetNode( 3 )],
node2IdMap[ hexa->GetNode( 2 )], node2IdMap[ hexa->GetNode( 2 )],
@ -248,65 +219,28 @@ Driver_Mesh::Status DriverGMF_Write::Perform()
node2IdMap[ hexa->GetNode( 5 )], node2IdMap[ hexa->GetNode( 5 )],
END_ELEM_WRITE( hexa ); END_ELEM_WRITE( hexa );
// quadratic hexahedra // nodes of quadratic hexahedra
BEGIN_ELEM_WRITE( SMDSEntity_Quad_Hexa, GmfHexahedra, hexa ) BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom_HEXA, SMDSEntity_Hexa,
node2IdMap[ hexa->GetNode( 0 )], GmfExtraVerticesAtHexahedra, hexa )
node2IdMap[ hexa->GetNode( 3 )], node2IdMap[ hexa->GetNode( 11 )], // HEXA20
node2IdMap[ hexa->GetNode( 2 )],
node2IdMap[ hexa->GetNode( 1 )],
node2IdMap[ hexa->GetNode( 4 )],
node2IdMap[ hexa->GetNode( 7 )],
node2IdMap[ hexa->GetNode( 6 )],
node2IdMap[ hexa->GetNode( 5 )],
END_ELEM_WRITE( hexa );
BEGIN_EXTRA_VERTICES_WRITE( SMDSEntity_Quad_Hexa, GmfExtraVerticesAtHexahedra, hexa, 12 )
node2IdMap[ hexa->GetNode( 11 )],
node2IdMap[ hexa->GetNode( 10 )], node2IdMap[ hexa->GetNode( 10 )],
node2IdMap[ hexa->GetNode( 9 )], node2IdMap[ hexa->GetNode( 9 )],
node2IdMap[ hexa->GetNode( 8 )], node2IdMap[ hexa->GetNode( 8 )],
node2IdMap[ hexa->GetNode( 15 )], node2IdMap[ hexa->GetNode( 15 )],
node2IdMap[ hexa->GetNode( 14 )], node2IdMap[ hexa->GetNode( 14 )],
node2IdMap[ hexa->GetNode( 13 )], node2IdMap[ hexa->GetNode( 13 )],
node2IdMap[ hexa->GetNode( 12 )], node2IdMap[ hexa->GetNode( 12 )],
node2IdMap[ hexa->GetNode( 16 )], node2IdMap[ hexa->GetNode( 16 )],
node2IdMap[ hexa->GetNode( 19 )], node2IdMap[ hexa->GetNode( 19 )],
node2IdMap[ hexa->GetNode( 18 )], node2IdMap[ hexa->GetNodeWrap( 18 )], // + HEXA27
node2IdMap[ hexa->GetNode( 17 )] node2IdMap[ hexa->GetNodeWrap( 17 )],
END_EXTRA_VERTICES_WRITE(); node2IdMap[ hexa->GetNodeWrap( 20 )],
node2IdMap[ hexa->GetNodeWrap( 24 )],
// tri-quadratic hexahedra node2IdMap[ hexa->GetNodeWrap( 23 )],
BEGIN_ELEM_WRITE( SMDSEntity_TriQuad_Hexa, GmfHexahedra, hexa ) node2IdMap[ hexa->GetNodeWrap( 22 )],
node2IdMap[ hexa->GetNode( 0 )], node2IdMap[ hexa->GetNodeWrap( 21 )],
node2IdMap[ hexa->GetNode( 3 )], node2IdMap[ hexa->GetNodeWrap( 25 )],
node2IdMap[ hexa->GetNode( 2 )], node2IdMap[ hexa->GetNodeWrap( 26 )]
node2IdMap[ hexa->GetNode( 1 )],
node2IdMap[ hexa->GetNode( 4 )],
node2IdMap[ hexa->GetNode( 7 )],
node2IdMap[ hexa->GetNode( 6 )],
node2IdMap[ hexa->GetNode( 5 )],
END_ELEM_WRITE( hexa );
BEGIN_EXTRA_VERTICES_WRITE( SMDSEntity_TriQuad_Hexa, GmfExtraVerticesAtHexahedra, hexa, 19 )
node2IdMap[ hexa->GetNode( 11 )],
node2IdMap[ hexa->GetNode( 10 )],
node2IdMap[ hexa->GetNode( 9 )],
node2IdMap[ hexa->GetNode( 8 )],
node2IdMap[ hexa->GetNode( 15 )],
node2IdMap[ hexa->GetNode( 14 )],
node2IdMap[ hexa->GetNode( 13 )],
node2IdMap[ hexa->GetNode( 12 )],
node2IdMap[ hexa->GetNode( 16 )],
node2IdMap[ hexa->GetNode( 19 )],
node2IdMap[ hexa->GetNode( 18 )],
node2IdMap[ hexa->GetNode( 17 )],
node2IdMap[ hexa->GetNode( 20 )],
node2IdMap[ hexa->GetNode( 24 )],
node2IdMap[ hexa->GetNode( 23 )],
node2IdMap[ hexa->GetNode( 22 )],
node2IdMap[ hexa->GetNode( 21 )],
node2IdMap[ hexa->GetNode( 25 )],
node2IdMap[ hexa->GetNode( 26 )]
END_EXTRA_VERTICES_WRITE(); END_EXTRA_VERTICES_WRITE();
// prism // prism
@ -405,3 +339,22 @@ Driver_Mesh::Status DriverGMF_Write::Perform()
return DRS_OK; return DRS_OK;
} }
//================================================================================
/*!
* \brief Returns an iterator on elements of a certain type
*/
//================================================================================
SMDS_ElemIteratorPtr DriverGMF_Write::elementIterator(SMDSAbs_ElementType type)
{
return myMesh->elementsIterator(type);
}
SMDS_ElemIteratorPtr DriverGMF_Write::elementIterator(SMDSAbs_EntityType type)
{
return myMesh->elementEntityIterator(type);
}
SMDS_ElemIteratorPtr DriverGMF_Write::elementIterator(SMDSAbs_GeometryType type)
{
return myMesh->elementGeomIterator(type);
}