X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FDriverGMF%2FDriverGMF_Write.cxx;h=0a3c5ca683972dd79eb23f5f5ebd8c5d547ce70d;hb=refs%2Ftags%2FdistribGeom_06Mar13;hp=78f414b43aeb08d1422aec3cc81fa6799a782172;hpb=d9d9b3662766e52325dbf71a029b7e89990f0f63;p=modules%2Fsmesh.git diff --git a/src/DriverGMF/DriverGMF_Write.cxx b/src/DriverGMF/DriverGMF_Write.cxx index 78f414b43..0a3c5ca68 100644 --- a/src/DriverGMF/DriverGMF_Write.cxx +++ b/src/DriverGMF/DriverGMF_Write.cxx @@ -24,11 +24,14 @@ // Author : Edward AGAPOV (eap) #include "DriverGMF_Write.hxx" +#include "DriverGMF.hxx" #include "SMESHDS_GroupBase.hxx" #include "SMESHDS_Mesh.hxx" #include "SMESH_Comment.hxx" +#include + extern "C" { #include "libmesh5.h" @@ -37,42 +40,74 @@ extern "C" #include #define BEGIN_ELEM_WRITE( SMDSEntity, GmfKwd, elem ) \ - elemIt = myMesh->elementEntityIterator( SMDSEntity ); \ + elemIt = elementIterator( SMDSEntity ); \ if ( elemIt->more() ) \ { \ - GmfSetKwd(meshID, GmfKwd, myMesh->GetMeshInfo().NbEntities( SMDSEntity )); \ + GmfSetKwd(meshID, GmfKwd, myMesh->GetMeshInfo().NbElements( SMDSEntity )); \ for ( int gmfID = 1; elemIt->more(); ++gmfID ) \ { \ const SMDS_MeshElement* elem = elemIt->next(); \ GmfSetLin(meshID, GmfKwd, +#define BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom, LinType, GmfKwd, elem ) \ + elemIt = elementIterator( SMDSGeom ); \ + if ( elemIt->more() ) \ + { \ + 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 ) \ + { \ + const SMDS_MeshElement* elem = elemIt->next(); \ + if ( elem->IsQuadratic() ) { \ + GmfSetLin(meshID, GmfKwd, gmfID, elem->NbNodes() - elem->NbCornerNodes(), + #define END_ELEM_WRITE( elem ) \ elem->getshapeId() ); \ - }} \ + }} #define END_ELEM_WRITE_ADD_TO_MAP( elem, e2id ) \ elem->getshapeId() ); \ e2id.insert( e2id.end(), make_pair( elem, gmfID )); \ - }} \ + }} + +#define END_EXTRA_VERTICES_WRITE() \ + ); \ + }}}} DriverGMF_Write::DriverGMF_Write(): - Driver_SMESHDS_Mesh() + Driver_SMESHDS_Mesh(), _exportRequiredGroups( true ) { } DriverGMF_Write::~DriverGMF_Write() { } +//================================================================================ +/*! + * \brief Reads a GMF file + */ +//================================================================================ + Driver_Mesh::Status DriverGMF_Write::Perform() { - const int dim = 3, version = 3; + Kernel_Utils::Localizer loc; + + const int dim = 3, version = sizeof(long) == 4 ? 2 : 3; int meshID = GmfOpenMesh( myFile.c_str(), GmfWrite, version, dim ); if ( !meshID ) - return addMessage( SMESH_Comment("Can't open for writing ") << myFile, /*fatal=*/true ); + { + if ( DriverGMF::isExtensionCorrect( myFile )) + return addMessage( SMESH_Comment("Can't open for writing ") << 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 + DriverGMF::MeshCloser aMeshCloser( meshID ); // An object closing GMF mesh at destruction // nodes std::map< const SMDS_MeshNode* , int > node2IdMap; @@ -96,80 +131,73 @@ Driver_Mesh::Status DriverGMF_Write::Perform() // edges TElem2IDMap edge2IDMap; - BEGIN_ELEM_WRITE( SMDSEntity_Edge, GmfEdges, edge ) + BEGIN_ELEM_WRITE( SMDSGeom_EDGE, GmfEdges, edge ) 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 ) - node2IdMap[ edge->GetNode( 0 )], - node2IdMap[ edge->GetNode( 1 )], - node2IdMap[ edge->GetNode( 2 )], - END_ELEM_WRITE( edge ); - + + // nodes of quadratic edges + BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom_EDGE, SMDSEntity_Edge, + GmfExtraVerticesAtEdges, edge ) + node2IdMap[ edge->GetNode( 2 )] + END_EXTRA_VERTICES_WRITE(); + // triangles TElem2IDMap tria2IDMap; - BEGIN_ELEM_WRITE( SMDSEntity_Triangle, GmfTriangles, tria ) + BEGIN_ELEM_WRITE( SMDSGeom_TRIANGLE, GmfTriangles, tria ) node2IdMap[ tria->GetNode( 0 )], 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 ) - node2IdMap[ tria->GetNode( 0 )], - node2IdMap[ tria->GetNode( 1 )], - node2IdMap[ tria->GetNode( 2 )], + + // nodes of quadratic triangles + BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom_TRIANGLE, SMDSEntity_Triangle, + GmfExtraVerticesAtTriangles, tria ) node2IdMap[ tria->GetNode( 3 )], node2IdMap[ tria->GetNode( 4 )], - node2IdMap[ tria->GetNode( 5 )], - END_ELEM_WRITE( tria ); - + node2IdMap[ tria->GetNode( 5 )] + //node2IdMap[ tria->GetNodeWrap( 6 )] // for TRIA7 + END_EXTRA_VERTICES_WRITE(); + // quadrangles TElem2IDMap quad2IDMap; - BEGIN_ELEM_WRITE( SMDSEntity_Quadrangle, GmfQuadrilaterals, quad ) + BEGIN_ELEM_WRITE( SMDSGeom_QUADRANGLE, GmfQuadrilaterals, quad ) node2IdMap[ quad->GetNode( 0 )], node2IdMap[ quad->GetNode( 1 )], node2IdMap[ quad->GetNode( 2 )], node2IdMap[ quad->GetNode( 3 )], END_ELEM_WRITE_ADD_TO_MAP( quad, quad2IDMap ); - // bi-quadratic quadrangles - BEGIN_ELEM_WRITE( SMDSEntity_BiQuad_Quadrangle, GmfQuadrilateralsQ2, 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 )], + // nodes of quadratic quadrangles + BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom_QUADRANGLE, SMDSEntity_Quadrangle, + GmfExtraVerticesAtQuadrilaterals, quad ) node2IdMap[ quad->GetNode( 4 )], - node2IdMap[ quad->GetNode( 8 )], - END_ELEM_WRITE( quad ); - + node2IdMap[ quad->GetNode( 5 )], + node2IdMap[ quad->GetNode( 6 )], + node2IdMap[ quad->GetNode( 7 )], + node2IdMap[ quad->GetNodeWrap( 8 )] // for QUAD9 + END_EXTRA_VERTICES_WRITE(); + // terahedra - BEGIN_ELEM_WRITE( SMDSEntity_Tetra, GmfTetrahedra, tetra ) + BEGIN_ELEM_WRITE( SMDSGeom_TETRA, GmfTetrahedra, tetra ) node2IdMap[ tetra->GetNode( 0 )], node2IdMap[ tetra->GetNode( 2 )], 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 )], - node2IdMap[ tetra->GetNode( 2 )], - node2IdMap[ tetra->GetNode( 1 )], - node2IdMap[ tetra->GetNode( 3 )], + + // nodes of quadratic terahedra + BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom_TETRA, SMDSEntity_Tetra, + GmfExtraVerticesAtTetrahedra, tetra ) node2IdMap[ tetra->GetNode( 6 )], node2IdMap[ tetra->GetNode( 5 )], node2IdMap[ tetra->GetNode( 4 )], node2IdMap[ tetra->GetNode( 7 )], node2IdMap[ tetra->GetNode( 9 )], - node2IdMap[ tetra->GetNode( 8 )], - END_ELEM_WRITE( tetra ); - + node2IdMap[ tetra->GetNode( 8 )] + //node2IdMap[ tetra->GetNodeWrap( 10 )], // for TETRA11 + END_EXTRA_VERTICES_WRITE(); + // pyramids BEGIN_ELEM_WRITE( SMDSEntity_Pyramid, GmfPyramids, pyra ) node2IdMap[ pyra->GetNode( 0 )], @@ -180,7 +208,7 @@ Driver_Mesh::Status DriverGMF_Write::Perform() END_ELEM_WRITE( pyra ); // hexahedra - BEGIN_ELEM_WRITE( SMDSEntity_Hexa, GmfHexahedra, hexa ) + BEGIN_ELEM_WRITE( SMDSGeom_HEXA, GmfHexahedra, hexa ) node2IdMap[ hexa->GetNode( 0 )], node2IdMap[ hexa->GetNode( 3 )], node2IdMap[ hexa->GetNode( 2 )], @@ -191,36 +219,29 @@ Driver_Mesh::Status DriverGMF_Write::Perform() node2IdMap[ hexa->GetNode( 5 )], END_ELEM_WRITE( hexa ); - // tri-quadratic hexahedra - BEGIN_ELEM_WRITE( SMDSEntity_TriQuad_Hexa, GmfHexahedraQ2, hexa ) - node2IdMap[ hexa->GetNode( 0 )], - node2IdMap[ hexa->GetNode( 3 )], - node2IdMap[ hexa->GetNode( 2 )], - node2IdMap[ hexa->GetNode( 1 )], - node2IdMap[ hexa->GetNode( 4 )], - node2IdMap[ hexa->GetNode( 7 )], - node2IdMap[ hexa->GetNode( 6 )], - node2IdMap[ hexa->GetNode( 5 )], - node2IdMap[ hexa->GetNode( 11 )], + // nodes of quadratic hexahedra + BEGIN_EXTRA_VERTICES_WRITE( SMDSGeom_HEXA, SMDSEntity_Hexa, + GmfExtraVerticesAtHexahedra, hexa ) + node2IdMap[ hexa->GetNode( 11 )], // HEXA20 node2IdMap[ hexa->GetNode( 10 )], - node2IdMap[ hexa->GetNode( 9 )], - node2IdMap[ hexa->GetNode( 8 )], - node2IdMap[ hexa->GetNode( 12 )], + node2IdMap[ hexa->GetNode( 9 )], + node2IdMap[ hexa->GetNode( 8 )], node2IdMap[ hexa->GetNode( 15 )], node2IdMap[ hexa->GetNode( 14 )], node2IdMap[ hexa->GetNode( 13 )], - node2IdMap[ hexa->GetNode( 19 )], - node2IdMap[ hexa->GetNode( 18 )], - node2IdMap[ hexa->GetNode( 17 )], + node2IdMap[ hexa->GetNode( 12 )], node2IdMap[ hexa->GetNode( 16 )], - 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_ELEM_WRITE( hexa ); + node2IdMap[ hexa->GetNode( 19 )], + node2IdMap[ hexa->GetNodeWrap( 18 )], // + HEXA27 + node2IdMap[ hexa->GetNodeWrap( 17 )], + node2IdMap[ hexa->GetNodeWrap( 20 )], + node2IdMap[ hexa->GetNodeWrap( 24 )], + node2IdMap[ hexa->GetNodeWrap( 23 )], + node2IdMap[ hexa->GetNodeWrap( 22 )], + node2IdMap[ hexa->GetNodeWrap( 21 )], + node2IdMap[ hexa->GetNodeWrap( 25 )], + node2IdMap[ hexa->GetNodeWrap( 26 )] + END_EXTRA_VERTICES_WRITE(); // prism BEGIN_ELEM_WRITE( SMDSEntity_Penta, GmfPrisms, prism ) @@ -233,87 +254,107 @@ Driver_Mesh::Status DriverGMF_Write::Perform() END_ELEM_WRITE( prism ); - // required entities - SMESH_Comment badGroups; - const std::set& groupSet = myMesh->GetGroups(); - std::set::const_iterator grIt = groupSet.begin(); - for ( ; grIt != groupSet.end(); ++grIt ) + if ( _exportRequiredGroups ) { - const SMESHDS_GroupBase* group = *grIt; - std::string groupName = group->GetStoreName(); - std::string::size_type pos = groupName.find( "_required_" ); - if ( pos == std::string::npos ) continue; - - int gmfKwd; - SMDSAbs_EntityType smdsEntity; - std::string entity = groupName.substr( pos + strlen("_required_")); - if ( entity == "Vertices" ) { - gmfKwd = GmfRequiredVertices; - smdsEntity = SMDSEntity_Node; - } - else if ( entity == "Edges" ) { - gmfKwd = GmfRequiredEdges; - smdsEntity = SMDSEntity_Edge; - } - else if ( entity == "Triangles" ) { - gmfKwd = GmfRequiredTriangles; - smdsEntity = SMDSEntity_Triangle; - } - else if ( entity == "Quadrilaterals" ) { - gmfKwd = GmfRequiredQuadrilaterals; - smdsEntity = SMDSEntity_Quadrangle; - } - else { - addMessage( SMESH_Comment("Invalig gmf entity name: ") << entity, /*fatal=*/false ); - continue; - } - - // check elem type in the group - int nbOkElems = 0; - SMDS_ElemIteratorPtr elemIt = group->GetElements(); - while ( elemIt->more() ) - nbOkElems += ( elemIt->next()->GetEntityType() == smdsEntity ); - - if ( nbOkElems != group->Extent() && nbOkElems == 0 ) + // required entities + SMESH_Comment badGroups; + const std::set& groupSet = myMesh->GetGroups(); + std::set::const_iterator grIt = groupSet.begin(); + for ( ; grIt != groupSet.end(); ++grIt ) { - badGroups << " " << groupName; - continue; - } - - // choose a TElem2IDMap - TElem2IDMap* elem2IDMap = 0; - if ( smdsEntity == SMDSEntity_Quadrangle && - myMesh->GetMeshInfo().NbEntities( smdsEntity ) != myMesh->NbFaces() ) - elem2IDMap = & quad2IDMap; - else if ( smdsEntity == SMDSEntity_Triangle && - myMesh->GetMeshInfo().NbEntities( smdsEntity ) != myMesh->NbFaces() ) - elem2IDMap = & tria2IDMap; - else if ( smdsEntity == SMDSEntity_Edge && - myMesh->GetMeshInfo().NbEntities( smdsEntity ) != myMesh->NbEdges() ) - elem2IDMap = & edge2IDMap; - - // write the group - GmfSetKwd( meshID, gmfKwd, nbOkElems ); - if ( elem2IDMap ) - for ( elemIt = group->GetElements(); elemIt->more(); ) - { - const SMDS_MeshElement* elem = elemIt->next(); - if ( elem->GetEntityType() == smdsEntity ) - GmfSetLin( meshID, gmfKwd, (*elem2IDMap)[ elem ] ); + const SMESHDS_GroupBase* group = *grIt; + std::string groupName = group->GetStoreName(); + std::string::size_type pos = groupName.find( "_required_" ); + if ( pos == std::string::npos ) continue; + + int gmfKwd; + SMDSAbs_EntityType smdsEntity; + std::string entity = groupName.substr( pos + strlen("_required_")); + if ( entity == "Vertices" ) { + gmfKwd = GmfRequiredVertices; + smdsEntity = SMDSEntity_Node; } - else - for ( elemIt = group->GetElements(); elemIt->more(); ) + else if ( entity == "Edges" ) { + gmfKwd = GmfRequiredEdges; + smdsEntity = SMDSEntity_Edge; + } + else if ( entity == "Triangles" ) { + gmfKwd = GmfRequiredTriangles; + smdsEntity = SMDSEntity_Triangle; + } + else if ( entity == "Quadrilaterals" ) { + gmfKwd = GmfRequiredQuadrilaterals; + smdsEntity = SMDSEntity_Quadrangle; + } + else { + addMessage( SMESH_Comment("Invalig gmf entity name: ") << entity, /*fatal=*/false ); + continue; + } + + // check elem type in the group + int nbOkElems = 0; + SMDS_ElemIteratorPtr elemIt = group->GetElements(); + while ( elemIt->more() ) + nbOkElems += ( elemIt->next()->GetEntityType() == smdsEntity ); + + if ( nbOkElems != group->Extent() && nbOkElems == 0 ) { - const SMDS_MeshElement* elem = elemIt->next(); - if ( elem->GetEntityType() == smdsEntity ) - GmfSetLin( meshID, gmfKwd, elem->GetID() ); + badGroups << " " << groupName; + continue; } - } // loop on groups + // choose a TElem2IDMap + TElem2IDMap* elem2IDMap = 0; + if ( smdsEntity == SMDSEntity_Quadrangle && nbOkElems != myMesh->NbFaces() ) + elem2IDMap = & quad2IDMap; + else if ( smdsEntity == SMDSEntity_Triangle && nbOkElems != myMesh->NbFaces() ) + elem2IDMap = & tria2IDMap; + else if ( smdsEntity == SMDSEntity_Edge && nbOkElems != myMesh->NbEdges() ) + elem2IDMap = & edge2IDMap; + + // write the group + GmfSetKwd( meshID, gmfKwd, nbOkElems ); + elemIt = group->GetElements(); + if ( elem2IDMap ) + for ( ; elemIt->more(); ) + { + const SMDS_MeshElement* elem = elemIt->next(); + if ( elem->GetEntityType() == smdsEntity ) + GmfSetLin( meshID, gmfKwd, (*elem2IDMap)[ elem ] ); + } + else + for ( int gmfID = 1; elemIt->more(); ++gmfID) + { + const SMDS_MeshElement* elem = elemIt->next(); + if ( elem->GetEntityType() == smdsEntity ) + GmfSetLin( meshID, gmfKwd, gmfID ); + } + + } // loop on groups - if ( !badGroups.empty() ) - addMessage( SMESH_Comment("Groups including elements of inappropriate geometry:") - << badGroups, /*fatal=*/false ); + if ( !badGroups.empty() ) + addMessage( SMESH_Comment("Groups of elements of inappropriate geometry:") + << badGroups, /*fatal=*/false ); + } 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); +}