X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FDriverGMF%2FDriverGMF_Write.cxx;h=178e0b52b5eb3033cf3fb6139058ebcf3cf83a27;hp=cdddd629d11af0c0ba9f1c03ccef63eb5b2f5d95;hb=95ac4b3747821ff5ec084ef062f40ffe8c67b59e;hpb=f5016d85b7b4b88623723027a1585c6414c4dc66 diff --git a/src/DriverGMF/DriverGMF_Write.cxx b/src/DriverGMF/DriverGMF_Write.cxx index cdddd629d..178e0b52b 100644 --- a/src/DriverGMF/DriverGMF_Write.cxx +++ b/src/DriverGMF/DriverGMF_Write.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -24,11 +24,16 @@ // Author : Edward AGAPOV (eap) #include "DriverGMF_Write.hxx" +#include "DriverGMF.hxx" #include "SMESHDS_GroupBase.hxx" #include "SMESHDS_Mesh.hxx" #include "SMESH_Comment.hxx" +#include + +#include "utilities.h" + extern "C" { #include "libmesh5.h" @@ -37,42 +42,97 @@ 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() \ + ); \ + }}}} + + +Control_Pnt::Control_Pnt(): gp_Pnt() +{ + size=0; +} +Control_Pnt::Control_Pnt( const gp_Pnt& aPnt, + double theSize): gp_Pnt( aPnt ) +{ + size=theSize; +} +Control_Pnt::Control_Pnt(double theX, + double theY, + double theZ): gp_Pnt(theX, theY, theZ) +{ + size=0; +} +Control_Pnt::Control_Pnt(double theX, + double theY, + double theZ, + double theSize): gp_Pnt(theX, theY, theZ) +{ + size=theSize; +} 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 +156,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->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 +233,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 +244,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,85 +279,148 @@ 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 && 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 ] ); + 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 ( int gmfID = 1; elemIt->more(); ++gmfID) + 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, gmfID ); + 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 of elements of inappropriate geometry:") + << badGroups, /*fatal=*/false ); + } + + return DRS_OK; +} - if ( !badGroups.empty() ) - addMessage( SMESH_Comment("Groups of elements of inappropriate geometry:") - << badGroups, /*fatal=*/false ); +Driver_Mesh::Status DriverGMF_Write::PerformSizeMap( const std::vector& points ) +{ +// const int dim = 3, version = sizeof(long) == 4 ? 2 : 3; + const int dim = 3, version = 2; // Version 3 not supported by mg-hexa + + // Open files + int verticesFileID = GmfOpenMesh( myVerticesFile.c_str(), GmfWrite, version, dim ); + int solFileID = GmfOpenMesh( mySolFile.c_str(), GmfWrite, version, dim ); + + int pointsNumber = points.size(); + + // Vertices Keyword + GmfSetKwd( verticesFileID, GmfVertices, pointsNumber ); + // SolAtVertices Keyword + int TypTab[] = {GmfSca}; + GmfSetKwd(solFileID, GmfSolAtVertices, pointsNumber, 1, TypTab); + + // Read the control points information from the vector and write it into the files + std::vector::const_iterator points_it; + for (points_it = points.begin(); points_it != points.end(); points_it++ ) + { + GmfSetLin( verticesFileID, GmfVertices, points_it->X(), points_it->Y(), points_it->Z(), 0 ); + double ValTab[] = {points_it->Size()}; + GmfSetLin( solFileID, GmfSolAtVertices, ValTab); + } + + // Close Files + GmfCloseMesh( verticesFileID ); + GmfCloseMesh( solFileID ); return DRS_OK; } + +std::vector DriverGMF_Write::GetSizeMapFiles() +{ + std::vector files; + files.push_back(myVerticesFile); + files.push_back(mySolFile); + return files; +} + +//================================================================================ +/*! + * \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); +}