X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FDriverMED%2FDriverMED_W_SMESHDS_Mesh.cxx;h=82722c15f3e4f327e412a593d228d6eaaa165c63;hp=5b77395aa7603aa328f51419e0ba24ac0a7ddc9d;hb=ccb5e3c25bf204e839c0094f50f543eacedba5e6;hpb=c3bf92bd87b770fd81631a3853f7f5bb1ac6a4e8 diff --git a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx index 5b77395aa..82722c15f 100644 --- a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx +++ b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx @@ -1,86 +1,122 @@ -// SMESH DriverMED : driver to read and write 'med' files +// Copyright (C) 2007-2016 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 +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. // +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + +// SMESH DriverMED : driver to read and write 'med' files // File : DriverMED_W_SMESHDS_Mesh.cxx // Module : SMESH +// #include "DriverMED_W_SMESHDS_Mesh.h" -#include "DriverMED_W_SMDS_Mesh.h" -#include "DriverMED_Family.h" +#include "DriverMED_Family.h" +#include "MED_Factory.hxx" +#include "MED_Utilities.hxx" +#include "SMDS_IteratorOnIterators.hxx" #include "SMDS_MeshElement.hxx" #include "SMDS_MeshNode.hxx" -#include "utilities.h" +#include "SMDS_PolyhedralVolumeOfNodes.hxx" +#include "SMDS_SetIterator.hxx" +#include "SMESHDS_Mesh.hxx" -#include "MEDA_Wrapper.hxx" -#include +#include +#include +#include -#include "MED_Utilities.hxx" +#include -DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh() - : - myMesh (NULL), - myFile (""), - myFileId (-1), - myMeshId (-1), - myAllSubMeshes (false), - myDoGroupOfNodes (false), - myDoGroupOfEdges (false), - myDoGroupOfFaces (false), - myDoGroupOfVolumes (false) -{ -} -DriverMED_W_SMESHDS_Mesh::~DriverMED_W_SMESHDS_Mesh() -{ -} +#define _EDF_NODE_IDS_ +//#define _ELEMENTS_BY_DIM_ -void DriverMED_W_SMESHDS_Mesh::SetMesh(SMDS_Mesh * aMesh) -{ - myMesh = aMesh; -} +using namespace std; +using namespace MED; -void DriverMED_W_SMESHDS_Mesh::SetFile(string aFile) -{ - myFile = aFile; -} -void DriverMED_W_SMESHDS_Mesh::SetFileId(med_idt aFileId) +DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh(): + myMedVersion(MED::eV2_2), + myAllSubMeshes (false), + myDoGroupOfNodes (false), + myDoGroupOfEdges (false), + myDoGroupOfFaces (false), + myDoGroupOfVolumes (false), + myDoGroupOf0DElems(false), + myDoGroupOfBalls(false), + myAutoDimension(false), + myAddODOnVertices(false), + myDoAllInGroups(false) +{} + +void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName, + MED::EVersion theId) { - myFileId = aFileId; + Driver_SMESHDS_Mesh::SetFile(theFileName); + myMedVersion = theId; + //MESSAGE("myMedVersion:"<(majeur, mineur, release); + TInt imposedMineur = mineur; + switch( theVersion ) { + case MED::eV2_1 : + case MED::eV2_2 : + case MED::eLATEST : break; + case MED::eMINOR_0 : imposedMineur = 0; break; + case MED::eMINOR_1 : imposedMineur = 1; break; + case MED::eMINOR_2 : imposedMineur = 2; break; + case MED::eMINOR_3 : imposedMineur = 3; break; + case MED::eMINOR_4 : imposedMineur = 4; break; + case MED::eMINOR_5 : imposedMineur = 5; break; + case MED::eMINOR_6 : imposedMineur = 6; break; + case MED::eMINOR_7 : imposedMineur = 7; break; + case MED::eMINOR_8 : imposedMineur = 8; break; + case MED::eMINOR_9 : imposedMineur = 9; break; + case MED::eVUnknown : imposedMineur = mineur; break; + } + if (imposedMineur > mineur) + imposedMineur = mineur; + ostringstream name; + if ( theNbDigits > 0 ) + name << majeur; + if ( theNbDigits > 1 ) + name << "." << imposedMineur; + if ( theNbDigits > 2 ) + name << "." << release; + return name.str(); } -void DriverMED_W_SMESHDS_Mesh::AddGroup(SMESHDS_Group* theGroup) +void DriverMED_W_SMESHDS_Mesh::AddGroup(SMESHDS_GroupBase* theGroup) { myGroups.push_back(theGroup); } @@ -92,7 +128,7 @@ void DriverMED_W_SMESHDS_Mesh::AddAllSubMeshes() void DriverMED_W_SMESHDS_Mesh::AddSubMesh(SMESHDS_SubMesh* theSubMesh, int theID) { - mySubMeshes[theID] = theSubMesh; + mySubMeshes.push_back( theSubMesh ); } void DriverMED_W_SMESHDS_Mesh::AddGroupOfNodes() @@ -115,33 +151,221 @@ void DriverMED_W_SMESHDS_Mesh::AddGroupOfVolumes() myDoGroupOfVolumes = true; } -void DriverMED_W_SMESHDS_Mesh::Write() +void DriverMED_W_SMESHDS_Mesh::AddGroupOf0DElems() { - string myClass = string("SMDS_Mesh"); - string myExtension = string("MED"); + myDoGroupOf0DElems = true; +} - DriverMED_W_SMDS_Mesh *myWriter = new DriverMED_W_SMDS_Mesh; +void DriverMED_W_SMESHDS_Mesh::AddGroupOfBalls() +{ + myDoGroupOfBalls = true; +} - myWriter->SetMesh(myMesh); - // myWriter->SetFile(myFile); - myWriter->SetMeshId(myMeshId); - myWriter->SetFileId(myFileId); +//================================================================================ +/*! + * \brief Set up a flag to add all elements not belonging to any group to + * some auxiliary group. This is needed for SMESH -> SAUVE -> SMESH conversion, + * which since PAL0023285 reads only SAUVE elements belonging to any group, + * and hence can lose some elements. That auxiliary group is ignored while + * reading a MED file. + */ +//================================================================================ - myWriter->Write(); +void DriverMED_W_SMESHDS_Mesh::AddAllToGroup() +{ + myDoAllInGroups = true; } -void DriverMED_W_SMESHDS_Mesh::Add() + +namespace { + typedef double (SMDS_MeshNode::* TGetCoord)() const; + typedef const char* TName; + typedef const char* TUnit; + + // name length in a mesh must be equal to 16 : + // 1234567890123456 + TName M = "m "; + TName X = "x "; + TName Y = "y "; + TName Z = "z "; + + TUnit aUnit[3] = {M,M,M}; + + // 3 dim + TGetCoord aXYZGetCoord[3] = { + &SMDS_MeshNode::X, + &SMDS_MeshNode::Y, + &SMDS_MeshNode::Z + }; + TName aXYZName[3] = {X,Y,Z}; + + // 2 dim + TGetCoord aXYGetCoord[2] = { + &SMDS_MeshNode::X, + &SMDS_MeshNode::Y + }; + TName aXYName[2] = {X,Y}; + + TGetCoord aYZGetCoord[2] = { + &SMDS_MeshNode::Y, + &SMDS_MeshNode::Z + }; + TName aYZName[2] = {Y,Z}; + + TGetCoord aXZGetCoord[2] = { + &SMDS_MeshNode::X, + &SMDS_MeshNode::Z + }; + TName aXZName[2] = {X,Z}; + + // 1 dim + TGetCoord aXGetCoord[1] = { + &SMDS_MeshNode::X + }; + TName aXName[1] = {X}; + + TGetCoord aYGetCoord[1] = { + &SMDS_MeshNode::Y + }; + TName aYName[1] = {Y}; + + TGetCoord aZGetCoord[1] = { + &SMDS_MeshNode::Z + }; + TName aZName[1] = {Z}; + + + class TCoordHelper{ + SMDS_NodeIteratorPtr myNodeIter; + const SMDS_MeshNode* myCurrentNode; + TGetCoord* myGetCoord; + TName* myName; + TUnit* myUnit; + public: + TCoordHelper(const SMDS_NodeIteratorPtr& theNodeIter, + TGetCoord* theGetCoord, + TName* theName, + TUnit* theUnit = aUnit): + myNodeIter(theNodeIter), + myGetCoord(theGetCoord), + myName(theName), + myUnit(theUnit) + {} + virtual ~TCoordHelper(){} + bool Next(){ + return myNodeIter->more() && + (myCurrentNode = myNodeIter->next()); + } + const SMDS_MeshNode* GetNode(){ + return myCurrentNode; + } + MED::TIntVector::value_type GetID(){ + return myCurrentNode->GetID(); + } + MED::TFloatVector::value_type GetCoord(TInt theCoodId){ + return (myCurrentNode->*myGetCoord[theCoodId])(); + } + MED::TStringVector::value_type GetName(TInt theDimId){ + return myName[theDimId]; + } + MED::TStringVector::value_type GetUnit(TInt theDimId){ + return myUnit[theDimId]; + } + }; + typedef boost::shared_ptr TCoordHelperPtr; + + //------------------------------------------------------- + /*! + * \brief Structure describing element type + */ + //------------------------------------------------------- + struct TElemTypeData + { + EEntiteMaillage _entity; + EGeometrieElement _geomType; + TInt _nbElems; + SMDSAbs_ElementType _smdsType; + + TElemTypeData (EEntiteMaillage entity, EGeometrieElement geom, TInt nb, SMDSAbs_ElementType type) + : _entity(entity), _geomType(geom), _nbElems( nb ), _smdsType( type ) {} + }; + + + typedef NCollection_DataMap< Standard_Address, int > TElemFamilyMap; + + //================================================================================ + /*! + * \brief Fills element to famaly ID map for element type. + * Removes all families of anElemType + */ + //================================================================================ + + void fillElemFamilyMap( TElemFamilyMap & anElemFamMap, + list & aFamilies, + const SMDSAbs_ElementType anElemType) + { + anElemFamMap.Clear(); + list::iterator aFamsIter = aFamilies.begin(); + while ( aFamsIter != aFamilies.end() ) + { + if ((*aFamsIter)->GetType() != anElemType) { + aFamsIter++; + } + else { + int aFamId = (*aFamsIter)->GetId(); + const ElementsSet& anElems = (*aFamsIter)->GetElements(); + ElementsSet::const_iterator anElemsIter = anElems.begin(); + for (; anElemsIter != anElems.end(); anElemsIter++) + { + anElemFamMap.Bind( (Standard_Address)*anElemsIter, aFamId ); + } + // remove a family from the list + aFamilies.erase( aFamsIter++ ); + } + } + } + + //================================================================================ + /*! + * \brief For an element, return family ID found in the map or a default one + */ + //================================================================================ + + int getFamilyId( const TElemFamilyMap & anElemFamMap, + const SMDS_MeshElement* anElement, + const int aDefaultFamilyId) + { + if ( anElemFamMap.IsBound( (Standard_Address) anElement )) + return anElemFamMap( (Standard_Address) anElement ); + + return aDefaultFamilyId; + } + + //================================================================================ + /*! + * \brief Returns iterator on sub-meshes + */ + //================================================================================ + + SMESHDS_SubMeshIteratorPtr getIterator( std::vector& mySubMeshes ) + { + return SMESHDS_SubMeshIteratorPtr + ( new SMDS_SetIterator + < const SMESHDS_SubMesh*, std::vector< SMESHDS_SubMesh* >::iterator >( mySubMeshes.begin(), + mySubMeshes.end() )); + } +} + +Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() +{ + Status aResult = DRS_OK; if (myMesh->hasConstructionEdges() || myMesh->hasConstructionFaces()) { INFOS("SMDS_MESH with hasConstructionEdges() or hasConstructionFaces() do not supports!!!"); - return; + return DRS_FAIL; } - try{ - using namespace MEDA; - using namespace boost; - - MESSAGE("Add - myFile : "<GetName()); - aMed.SetMeshInfo(aMeshInfo); - - // Storing SMDS groups and sub-meshes - //----------------------------------- - int myNodesDefaultFamilyId = 0; - int myEdgesDefaultFamilyId = 0; - int myFacesDefaultFamilyId = 0; - int myVolumesDefaultFamilyId = 0; - if (myDoGroupOfNodes) - myNodesDefaultFamilyId = REST_NODES_FAMILY; - if (myDoGroupOfEdges) - myEdgesDefaultFamilyId = REST_EDGES_FAMILY; - if (myDoGroupOfFaces) - myFacesDefaultFamilyId = REST_FACES_FAMILY; - if (myDoGroupOfVolumes) - myVolumesDefaultFamilyId = REST_VOLUMES_FAMILY; - - MESSAGE("Add - aFamilyInfo"); - map anElemFamMap; + + // Mesh dimension definition + + TInt aMeshDimension = 0; + if ( myMesh->NbEdges() > 0 ) + aMeshDimension = 1; + if ( myMesh->NbFaces() > 0 ) + aMeshDimension = 2; + if ( myMesh->NbVolumes() > 0 ) + aMeshDimension = 3; + + TInt aSpaceDimension = 3; + TCoordHelperPtr aCoordHelperPtr; + { + bool anIsXDimension = false; + bool anIsYDimension = false; + bool anIsZDimension = false; + if ( myAutoDimension && aMeshDimension < 3 ) + { + SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator(); + double aBounds[6]; + if(aNodesIter->more()){ + const SMDS_MeshNode* aNode = aNodesIter->next(); + aBounds[0] = aBounds[1] = aNode->X(); + aBounds[2] = aBounds[3] = aNode->Y(); + aBounds[4] = aBounds[5] = aNode->Z(); + } + while(aNodesIter->more()){ + const SMDS_MeshNode* aNode = aNodesIter->next(); + aBounds[0] = min(aBounds[0],aNode->X()); + aBounds[1] = max(aBounds[1],aNode->X()); + + aBounds[2] = min(aBounds[2],aNode->Y()); + aBounds[3] = max(aBounds[3],aNode->Y()); + + aBounds[4] = min(aBounds[4],aNode->Z()); + aBounds[5] = max(aBounds[5],aNode->Z()); + } + + double EPS = 1.0E-7; + TopoDS_Shape mainShape = myMesh->ShapeToMesh(); + bool hasShapeToMesh = ( myMesh->SubMeshIndices().size() > 1 ); + if ( !mainShape.IsNull() && hasShapeToMesh ) + { + // define EPS by max tolerance of the mainShape (IPAL53097) + TopExp_Explorer subShape; + for ( subShape.Init( mainShape, TopAbs_FACE ); subShape.More(); subShape.Next() ) { + EPS = Max( EPS, BRep_Tool::Tolerance( TopoDS::Face( subShape.Current() ))); + } + for ( subShape.Init( mainShape, TopAbs_EDGE ); subShape.More(); subShape.Next() ) { + EPS = Max( EPS, BRep_Tool::Tolerance( TopoDS::Edge( subShape.Current() ))); + } + for ( subShape.Init( mainShape, TopAbs_VERTEX ); subShape.More(); subShape.Next() ) { + EPS = Max( EPS, BRep_Tool::Tolerance( TopoDS::Vertex( subShape.Current() ))); + } + EPS *= 2.; + } + anIsXDimension = (aBounds[1] - aBounds[0]) + abs(aBounds[1]) + abs(aBounds[0]) > EPS; + anIsYDimension = (aBounds[3] - aBounds[2]) + abs(aBounds[3]) + abs(aBounds[2]) > EPS; + anIsZDimension = (aBounds[5] - aBounds[4]) + abs(aBounds[5]) + abs(aBounds[4]) > EPS; + aSpaceDimension = Max( aMeshDimension, anIsXDimension + anIsYDimension + anIsZDimension ); + if ( !aSpaceDimension ) + aSpaceDimension = 3; + // PAL16857(SMESH not conform to the MED convention): + if ( aSpaceDimension == 2 && anIsZDimension ) // 2D only if mesh is in XOY plane + aSpaceDimension = 3; + // PAL18941(a saved study with a mesh belong Z is opened and the mesh is belong X) + if ( aSpaceDimension == 1 && !anIsXDimension ) {// 1D only if mesh is along OX + if ( anIsYDimension ) { + aSpaceDimension = 2; + anIsXDimension = true; + } else { + aSpaceDimension = 3; + } + } + } + + SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator(/*idInceasingOrder=*/true); + switch ( aSpaceDimension ) { + case 3: + aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXYZGetCoord,aXYZName)); + break; + case 2: + if(anIsXDimension && anIsYDimension) + aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXYGetCoord,aXYName)); + if(anIsYDimension && anIsZDimension) + aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aYZGetCoord,aYZName)); + if(anIsXDimension && anIsZDimension) + aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXZGetCoord,aXZName)); + break; + case 1: + if(anIsXDimension) + aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXGetCoord,aXName)); + if(anIsYDimension) + aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aYGetCoord,aYName)); + if(anIsZDimension) + aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aZGetCoord,aZName)); + break; + } + } + //MESSAGE("myMedVersion:"<CrMeshInfo(aMeshDimension,aSpaceDimension,aMeshName); + //MESSAGE("Add - aMeshName : "<GetName()); + myMed->SetMeshInfo(aMeshInfo); + + // Storing SMDS groups and sub-meshes as med families + //---------------------------------------------------- + int myNodesDefaultFamilyId = 0; + int my0DElementsDefaultFamilyId = 0; + int myBallsDefaultFamilyId = 0; + int myEdgesDefaultFamilyId = 0; + int myFacesDefaultFamilyId = 0; + int myVolumesDefaultFamilyId = 0; + int nbNodes = myMesh->NbNodes(); + int nb0DElements = myMesh->Nb0DElements(); + int nbBalls = myMesh->NbBalls(); + int nbEdges = myMesh->NbEdges(); + int nbFaces = myMesh->NbFaces(); + int nbVolumes = myMesh->NbVolumes(); + if (myDoGroupOfNodes) myNodesDefaultFamilyId = REST_NODES_FAMILY; + if (myDoGroupOfEdges) myEdgesDefaultFamilyId = REST_EDGES_FAMILY; + if (myDoGroupOfFaces) myFacesDefaultFamilyId = REST_FACES_FAMILY; + if (myDoGroupOfVolumes) myVolumesDefaultFamilyId = REST_VOLUMES_FAMILY; + if (myDoGroupOf0DElems) my0DElementsDefaultFamilyId = REST_0DELEM_FAMILY; + if (myDoGroupOfBalls) myBallsDefaultFamilyId = REST_BALL_FAMILY; + if (myDoAllInGroups ) + { + if (!myDoGroupOfEdges) myEdgesDefaultFamilyId = NIG_EDGES_FAMILY ; + if (!myDoGroupOfFaces) myFacesDefaultFamilyId = NIG_FACES_FAMILY ; + if (!myDoGroupOfVolumes) myVolumesDefaultFamilyId = NIG_VOLS_FAMILY ; + if (!myDoGroupOf0DElems) my0DElementsDefaultFamilyId = NIG_0DELEM_FAMILY ; + if (!myDoGroupOfBalls) myBallsDefaultFamilyId = NIG_BALL_FAMILY ; + } + + //MESSAGE("Perform - aFamilyInfo"); list aFamilies; if (myAllSubMeshes) { - SMESHDS_Mesh* aSMESHDSMesh = dynamic_cast(myMesh); - if (!aSMESHDSMesh) { - EXCEPTION(runtime_error,"Can not cast SMDS_Mesh to SMESHDS_Mesh"); - } aFamilies = DriverMED_Family::MakeFamilies - (aSMESHDSMesh->SubMeshes(), myGroups, - myDoGroupOfNodes, myDoGroupOfEdges, myDoGroupOfFaces, myDoGroupOfVolumes); - } else { + (myMesh->SubMeshes(), myGroups, + myDoGroupOfNodes && nbNodes, + myDoGroupOfEdges && nbEdges, + myDoGroupOfFaces && nbFaces, + myDoGroupOfVolumes && nbVolumes, + myDoGroupOf0DElems && nb0DElements, + myDoGroupOfBalls && nbBalls, + myDoAllInGroups); + } + else { aFamilies = DriverMED_Family::MakeFamilies - (mySubMeshes, myGroups, - myDoGroupOfNodes, myDoGroupOfEdges, myDoGroupOfFaces, myDoGroupOfVolumes); + (getIterator( mySubMeshes ), myGroups, + myDoGroupOfNodes && nbNodes, + myDoGroupOfEdges && nbEdges, + myDoGroupOfFaces && nbFaces, + myDoGroupOfVolumes && nbVolumes, + myDoGroupOf0DElems && nb0DElements, + myDoGroupOfBalls && nbBalls, + myDoAllInGroups); } - list::iterator aFamsIter = aFamilies.begin(); - - for (; aFamsIter != aFamilies.end(); aFamsIter++) + list::iterator aFamsIter; + for (aFamsIter = aFamilies.begin(); aFamsIter != aFamilies.end(); aFamsIter++) { - PFamilyInfo aFamilyInfo = (*aFamsIter)->GetFamilyInfo(aMeshInfo); - aMed.SetFamilyInfo(aFamilyInfo); - int aFamId = (*aFamsIter)->GetId(); - - const set& anElems = (*aFamsIter)->GetElements(); - set::iterator anElemsIter = anElems.begin(); - for (; anElemsIter != anElems.end(); anElemsIter++) - { - anElemFamMap[*anElemsIter] = aFamId; - } -// delete (*aFamsIter); + PFamilyInfo aFamilyInfo = (*aFamsIter)->GetFamilyInfo(myMed,aMeshInfo); + myMed->SetFamilyInfo(aFamilyInfo); } // Storing SMDS nodes to the MED file for the MED mesh //---------------------------------------------------- - typedef map TNodeIdMap; +#ifdef _EDF_NODE_IDS_ + typedef map TNodeIdMap; TNodeIdMap aNodeIdMap; +#endif + const EModeSwitch theMode = eFULL_INTERLACE; + const ERepere theSystem = eCART; + const EBooleen theIsElemNum = eVRAI; + const EBooleen theIsElemNames = eFAUX; + const EConnectivite theConnMode = eNOD; - med_int aNbElems = myMesh->NbNodes(); - MED::TIntVector anElemNums(aNbElems); - MED::TIntVector aFamilyNums(aNbElems); - MED::TFloatVector aCoordinates(aNbElems*SMDS_MESH_DIM); - SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator(); - for(med_int iNode = 0, iCoord = 0; aNodesIter->more(); iNode++, iCoord+=SMDS_MESH_DIM){ - const SMDS_MeshNode* aNode = aNodesIter->next(); - aCoordinates[iCoord] = aNode->X(); - aCoordinates[iCoord+1] = aNode->Y(); - aCoordinates[iCoord+2] = aNode->Z(); - TNodeIdMap::key_type aNodeId = aNode->GetID(); - anElemNums[iNode] = aNodeId; - aNodeIdMap[aNodeId] = iNode+1; - //cout<GetID()<<": "<X()<<", "<Y()<<", "<Z()<NbNodes(); + PNodeInfo aNodeInfo = myMed->CrNodeInfo(aMeshInfo, aNbNodes, + theMode, theSystem, theIsElemNum, theIsElemNames); - MED::TStringVector aCoordNames(3); - aCoordNames[0] = "x"; aCoordNames[1] = "y"; aCoordNames[2] = "z"; - - MED::TStringVector aCoordUnits(3); - aCoordUnits[0] = "m"; aCoordUnits[1] = "m"; aCoordUnits[2] = "m"; - - const med_repere SMDS_COORDINATE_SYSTEM = MED_CART; - - PNodeInfo aNodeInfo = TWrapper::CrNodeInfo(aMeshInfo, - SMDS_COORDINATE_SYSTEM, - aCoordinates, - aCoordNames, - aCoordUnits, - aFamilyNums, - anElemNums); - MESSAGE("Add - aNodeInfo->GetNbElem() = "<NbEdges()){ - SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator(); - med_int aNbConnectivity = MED::GetNbConn(SMDS_MED_ENTITY,MED_SEG2,SMDS_MESH_DIM); - MED::TIntVector anElemNums(aNbElems); - MED::TIntVector aFamilyNums(aNbElems); - MED::TIntVector aConnectivity(aNbElems*aNbConnectivity); - - for(med_int iElem = 0, iConn = 0; anIter->more(); iElem++, iConn+=aNbConnectivity){ - const SMDS_MeshEdge* anElem = anIter->next(); - SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator(); - for(med_int iNode = 0; iNode < aNbConnectivity && aNodesIter->more(); iNode++){ - const SMDS_MeshElement* aNode = aNodesIter->next(); - aConnectivity[iConn+iNode] = aNodeIdMap[aNode->GetID()]; - } - anElemNums[iElem] = anElem->GetID(); - - if (anElemFamMap.find(anElem) != anElemFamMap.end()) - aFamilyNums[iElem] = anElemFamMap[anElem]; - else - aFamilyNums[iElem] = myEdgesDefaultFamilyId; + // find family numbers for nodes + TElemFamilyMap anElemFamMap; + fillElemFamilyMap( anElemFamMap, aFamilies, SMDSAbs_Node ); + + for (TInt iNode = 0; aCoordHelperPtr->Next(); iNode++) + { + // coordinates + TCoordSlice aTCoordSlice = aNodeInfo->GetCoordSlice( iNode ); + for(TInt iCoord = 0; iCoord < aSpaceDimension; iCoord++){ + aTCoordSlice[iCoord] = aCoordHelperPtr->GetCoord(iCoord); } - - PCellInfo aCellInfo = TWrapper::CrCellInfo(aMeshInfo, - SMDS_MED_ENTITY, - MED_SEG2, - SMDS_MED_CONNECTIVITY, - aConnectivity, - aFamilyNums, - anElemNums); - aMed.SetCellInfo(aCellInfo); + // node number + int aNodeID = aCoordHelperPtr->GetID(); + aNodeInfo->SetElemNum( iNode, aNodeID ); +#ifdef _EDF_NODE_IDS_ + aNodeIdMap.insert( aNodeIdMap.end(), make_pair( aNodeID, iNode+1 )); +#endif + // family number + const SMDS_MeshNode* aNode = aCoordHelperPtr->GetNode(); + int famNum = getFamilyId( anElemFamMap, aNode, myNodesDefaultFamilyId ); + aNodeInfo->SetFamNum( iNode, famNum ); } + anElemFamMap.Clear(); - // Storing SMDS Faces - if(med_int aNbElems = myMesh->NbFaces()){ - SMDS_FaceIteratorPtr anIter = myMesh->facesIterator(); - - med_int aNbTriaConn = MED::GetNbConn(SMDS_MED_ENTITY,MED_TRIA3,SMDS_MESH_DIM); - MED::TIntVector anTriaElemNums; - anTriaElemNums.reserve(aNbElems); - MED::TIntVector aTriaFamilyNums; - aTriaFamilyNums.reserve(aNbElems); - MED::TIntVector aTriaConn; - aTriaConn.reserve(aNbElems*aNbTriaConn); - - med_int aNbQuadConn = MED::GetNbConn(SMDS_MED_ENTITY,MED_QUAD4,SMDS_MESH_DIM); - MED::TIntVector aQuadElemNums; - aQuadElemNums.reserve(aNbElems); - MED::TIntVector aQuadFamilyNums; - aQuadFamilyNums.reserve(aNbElems); - MED::TIntVector aQuadConn; - aQuadConn.reserve(aNbElems*aNbQuadConn); - - for(med_int iElem = 0; iElem < aNbElems && anIter->more(); iElem++){ - const SMDS_MeshFace* anElem = anIter->next(); - med_int aNbNodes = anElem->NbNodes(); - SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator(); - med_int aNbConnectivity; - MED::TIntVector* anElemNums; - MED::TIntVector* aFamilyNums; - MED::TIntVector* aConnectivity; - switch(aNbNodes){ - case 3: - aNbConnectivity = aNbTriaConn; - anElemNums = &anTriaElemNums; - aFamilyNums = &aTriaFamilyNums; - aConnectivity = &aTriaConn; - break; - case 4: - aNbConnectivity = aNbQuadConn; - anElemNums = &aQuadElemNums; - aFamilyNums = &aQuadFamilyNums; - aConnectivity = &aQuadConn; - break; - } - MED::TIntVector aVector(aNbNodes); - for(med_int iNode = 0; aNodesIter->more(); iNode++){ - const SMDS_MeshElement* aNode = aNodesIter->next(); - aVector[iNode] = aNode->GetID(); - } - - med_int aSize = aConnectivity->size(); - aConnectivity->resize(aSize+aNbConnectivity); - // There is some differnce between SMDS and MED in cells mapping - switch(aNbNodes){ - case 4: - (*aConnectivity)[aSize+0] = aNodeIdMap[aVector[0]]; - (*aConnectivity)[aSize+1] = aNodeIdMap[aVector[1]]; - (*aConnectivity)[aSize+2] = aNodeIdMap[aVector[3]]; - (*aConnectivity)[aSize+3] = aNodeIdMap[aVector[2]]; - default: - for(med_int iNode = 0; iNode < aNbNodes; iNode++) - (*aConnectivity)[aSize+iNode] = aNodeIdMap[aVector[iNode]]; - } - anElemNums->push_back(anElem->GetID()); - - if (anElemFamMap.find(anElem) != anElemFamMap.end()) - aFamilyNums->push_back(anElemFamMap[anElem]); - else - aFamilyNums->push_back(myFacesDefaultFamilyId); - } - if(med_int aNbElems = anTriaElemNums.size()){ - PCellInfo aCellInfo = TWrapper::CrCellInfo(aMeshInfo, - SMDS_MED_ENTITY, - MED_TRIA3, - SMDS_MED_CONNECTIVITY, - aTriaConn, - aTriaFamilyNums, - anTriaElemNums); - MESSAGE("Add - anEntity = "<GetNbElem() = "<SetNodeInfo(aNodeInfo); + aNodeInfo.reset(); // free memory used for arrays - if(med_int aNbElems = anTetraElemNums.size()){ - PCellInfo aCellInfo = TWrapper::CrCellInfo(aMeshInfo, - SMDS_MED_ENTITY, - MED_TETRA4, - SMDS_MED_CONNECTIVITY, - aTetraConn, - aTetraFamilyNums, - anTetraElemNums); - MESSAGE("Add - anEntity = "<& nodes) +{ + nodes.clear(); + for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i ) + { + if ( meshDS->IndexToShape( i ).ShapeType() != TopAbs_VERTEX ) + continue; + if ( SMESHDS_SubMesh* sm = meshDS->MeshElements(i) ) { + SMDS_NodeIteratorPtr nIt= sm->GetNodes(); + while (nIt->more()) + { + const SMDS_MeshNode* n = nIt->next(); + if ( n->NbInverseElements( SMDSAbs_0DElement ) == 0 ) + nodes.push_back( n ); + } + } + } + return !nodes.empty(); }