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=a1902daac8aafe9f4cfc43d9c83906a2e769242f;hp=9f8e9c06cee7d341826425543431413b1133869b;hb=e330934ca6f8bb1f67b5367bb65a861868998aeb;hpb=0635c9fc80f67d1e5dc0e94ec85f487286a92070 diff --git a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx index 9f8e9c06c..a1902daac 100644 --- a/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx +++ b/src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx @@ -1,42 +1,48 @@ -// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE +// 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 +// 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. +// 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. // -// 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. +// 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 +// 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 +// 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 #include "DriverMED_W_SMESHDS_Mesh.h" -#include "DriverMED_W_SMDS_Mesh.h" -#include "DriverMED_Family.h" -#include "SMESHDS_Mesh.hxx" -#include "SMDS_MeshElement.hxx" +#include "DriverMED_Family.h" +#include "MED_Factory.hxx" +#include "MED_Utilities.hxx" +#include "SMDS_IteratorOnIterators.hxx" #include "SMDS_MeshNode.hxx" -#include "SMDS_PolyhedralVolumeOfNodes.hxx" +#include "SMDS_SetIterator.hxx" +#include "SMESHDS_Mesh.hxx" -#include "utilities.h" +#include + +#include +#include +#include + +#include -#include "MED_Utilities.hxx" #define _EDF_NODE_IDS_ //#define _ELEMENTS_BY_DIM_ @@ -50,44 +56,49 @@ DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh(): myDoGroupOfNodes (false), myDoGroupOfEdges (false), myDoGroupOfFaces (false), - myDoGroupOfVolumes (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) +void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName, int theMinor) { - myMed = CrWrapper(theFileName,theId); + myMinor = theMinor; Driver_SMESHDS_Mesh::SetFile(theFileName); } -void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName) -{ - return SetFile(theFileName,MED::eV2_2); -} - -string DriverMED_W_SMESHDS_Mesh::GetVersionString(const MED::EVersion theVersion, int theNbDigits) +/*! + * MED version is either the latest available, or with an inferior minor, + * to ensure backward compatibility on writing med files. + */ +string DriverMED_W_SMESHDS_Mesh::GetVersionString(int theVersion, int theNbDigits) { TInt majeur, mineur, release; - majeur = mineur = release = 0; - if ( theVersion == eV2_1 ) - MED::GetVersionRelease(majeur, mineur, release); + majeur=MED_MAJOR_NUM; + mineur=MED_MINOR_NUM; + release=MED_RELEASE_NUM; + TInt imposedMineur = mineur; + + if (theVersion < 0) + imposedMineur = mineur; + else if (theVersion > MED_MINOR_NUM) + imposedMineur = mineur; else - MED::GetVersionRelease(majeur, mineur, release); + imposedMineur = theVersion; + ostringstream name; if ( theNbDigits > 0 ) name << majeur; if ( theNbDigits > 1 ) - name << "." << mineur; + name << "." << imposedMineur; if ( theNbDigits > 2 ) name << "." << release; return name.str(); } -void DriverMED_W_SMESHDS_Mesh::SetMeshName(const std::string& theMeshName) -{ - myMeshName = theMeshName; -} - void DriverMED_W_SMESHDS_Mesh::AddGroup(SMESHDS_GroupBase* theGroup) { myGroups.push_back(theGroup); @@ -100,7 +111,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() @@ -123,7 +134,34 @@ void DriverMED_W_SMESHDS_Mesh::AddGroupOfVolumes() myDoGroupOfVolumes = true; } -namespace{ +void DriverMED_W_SMESHDS_Mesh::AddGroupOf0DElems() +{ + myDoGroupOf0DElems = true; +} + +void DriverMED_W_SMESHDS_Mesh::AddGroupOfBalls() +{ + myDoGroupOfBalls = true; +} + +//================================================================================ +/*! + * \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. + */ +//================================================================================ + +void DriverMED_W_SMESHDS_Mesh::AddAllToGroup() +{ + myDoAllInGroups = true; +} + + +namespace +{ typedef double (SMDS_MeshNode::* TGetCoord)() const; typedef const char* TName; typedef const char* TUnit; @@ -189,9 +227,9 @@ namespace{ TUnit* myUnit; public: TCoordHelper(const SMDS_NodeIteratorPtr& theNodeIter, - TGetCoord* theGetCoord, - TName* theName, - TUnit* theUnit = aUnit): + TGetCoord* theGetCoord, + TName* theName, + TUnit* theUnit = aUnit): myNodeIter(theNodeIter), myGetCoord(theGetCoord), myName(theName), @@ -200,7 +238,7 @@ namespace{ virtual ~TCoordHelper(){} bool Next(){ return myNodeIter->more() && - (myCurrentNode = myNodeIter->next()); + (myCurrentNode = myNodeIter->next()); } const SMDS_MeshNode* GetNode(){ return myCurrentNode; @@ -220,34 +258,6 @@ namespace{ }; typedef boost::shared_ptr TCoordHelperPtr; - - //------------------------------------------------------- - /*! - * \brief Class helping to use either SMDS_EdgeIterator, SMDS_FaceIterator - * or SMDS_VolumeIterator in the same code - */ - //------------------------------------------------------- - struct TElemIterator - { - virtual const SMDS_MeshElement* next() = 0; - virtual ~TElemIterator() {} - }; - typedef boost::shared_ptr PElemIterator; - - template< class SMDSIteratorPtr > class TypedElemIterator: public TElemIterator - { - SMDSIteratorPtr myItPtr; - public: - TypedElemIterator(SMDSIteratorPtr it): myItPtr(it) {} - virtual const SMDS_MeshElement* next() { - if ( myItPtr->more() ) return myItPtr->next(); - else return 0; - } - }; - typedef TypedElemIterator< SMDS_EdgeIteratorPtr > TEdgeIterator; - typedef TypedElemIterator< SMDS_FaceIteratorPtr > TFaceIterator; - typedef TypedElemIterator< SMDS_VolumeIteratorPtr > TVolumeIterator; - //------------------------------------------------------- /*! * \brief Structure describing element type @@ -266,7 +276,6 @@ namespace{ typedef NCollection_DataMap< Standard_Address, int > TElemFamilyMap; - //typedef map TElemFamilyMap; //================================================================================ /*! @@ -280,7 +289,6 @@ namespace{ const SMDSAbs_ElementType anElemType) { anElemFamMap.Clear(); - //anElemFamMap.clear(); list::iterator aFamsIter = aFamilies.begin(); while ( aFamsIter != aFamilies.end() ) { @@ -289,12 +297,11 @@ namespace{ } else { int aFamId = (*aFamsIter)->GetId(); - const set& anElems = (*aFamsIter)->GetElements(); - set::const_iterator anElemsIter = anElems.begin(); + const ElementsSet& anElems = (*aFamsIter)->GetElements(); + ElementsSet::const_iterator anElemsIter = anElems.begin(); for (; anElemsIter != anElems.end(); anElemsIter++) { anElemFamMap.Bind( (Standard_Address)*anElemsIter, aFamId ); - //anElemFamMap[*anElemsIter] = aFamId; } // remove a family from the list aFamilies.erase( aFamsIter++ ); @@ -314,22 +321,30 @@ namespace{ { if ( anElemFamMap.IsBound( (Standard_Address) anElement )) return anElemFamMap( (Standard_Address) anElement ); -// TElemFamilyMap::iterator elem_famNum = anElemFamMap.find( anElement ); -// if ( elem_famNum != anElemFamMap.end() ) -// return elem_famNum->second; + 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 DRS_FAIL; - } try { - MESSAGE("Perform - myFile : "<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; - 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; - aMeshDimension = anIsXDimension + anIsYDimension + anIsZDimension; - if(!aMeshDimension) - 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 ( aMeshDimension == 2 && anIsZDimension ) // 2D only if mesh is in XOY plane - aMeshDimension = 3; + 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 ( aMeshDimension == 1 && !anIsXDimension ) // 1D only if mesh is along OX + if ( aSpaceDimension == 1 && !anIsXDimension ) {// 1D only if mesh is along OX if ( anIsYDimension ) { - aMeshDimension = 2; + aSpaceDimension = 2; anIsXDimension = true; } else { - aMeshDimension = 3; + aSpaceDimension = 3; } + } } SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator(); - switch(aMeshDimension){ + switch ( aSpaceDimension ) { case 3: - aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXYZGetCoord,aXYZName)); - break; + 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; + 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; + 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; } } - - PMeshInfo aMeshInfo = myMed->CrMeshInfo(aMeshDimension,aMeshName); - MESSAGE("Add - aMeshName : "<GetName()); + MED::PWrapper myMed = CrWrapperW(myFile, myMinor); + PMeshInfo aMeshInfo = myMed->CrMeshInfo(aMeshDimension,aSpaceDimension,aMeshName); + //MESSAGE("Add - aMeshName : "<GetName()); myMed->SetMeshInfo(aMeshInfo); // Storing SMDS groups and sub-meshes as med families //---------------------------------------------------- - int myNodesDefaultFamilyId = 0; - int myEdgesDefaultFamilyId = 0; - int myFacesDefaultFamilyId = 0; - int myVolumesDefaultFamilyId = 0; - int nbNodes = myMesh->NbNodes(); - int nbEdges = myMesh->NbEdges(); - int nbFaces = myMesh->NbFaces(); - int nbVolumes = myMesh->NbVolumes(); - if (myDoGroupOfNodes && nbNodes) - myNodesDefaultFamilyId = REST_NODES_FAMILY; - if (myDoGroupOfEdges && nbEdges) - myEdgesDefaultFamilyId = REST_EDGES_FAMILY; - if (myDoGroupOfFaces && nbFaces) - myFacesDefaultFamilyId = REST_FACES_FAMILY; - if (myDoGroupOfVolumes && nbVolumes) - myVolumesDefaultFamilyId = REST_VOLUMES_FAMILY; - - MESSAGE("Perform - aFamilyInfo"); - //cout << " DriverMED_Family::MakeFamilies() " << endl; + 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) { aFamilies = DriverMED_Family::MakeFamilies @@ -447,16 +499,22 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() myDoGroupOfNodes && nbNodes, myDoGroupOfEdges && nbEdges, myDoGroupOfFaces && nbFaces, - myDoGroupOfVolumes && nbVolumes); - } else { + myDoGroupOfVolumes && nbVolumes, + myDoGroupOf0DElems && nb0DElements, + myDoGroupOfBalls && nbBalls, + myDoAllInGroups); + } + else { aFamilies = DriverMED_Family::MakeFamilies - (mySubMeshes, myGroups, + (getIterator( mySubMeshes ), myGroups, myDoGroupOfNodes && nbNodes, myDoGroupOfEdges && nbEdges, myDoGroupOfFaces && nbFaces, - myDoGroupOfVolumes && nbVolumes); + myDoGroupOfVolumes && nbVolumes, + myDoGroupOf0DElems && nb0DElements, + myDoGroupOfBalls && nbBalls, + myDoAllInGroups); } - //cout << " myMed->SetFamilyInfo() " << endl; list::iterator aFamsIter; for (aFamsIter = aFamilies.begin(); aFamsIter != aFamilies.end(); aFamsIter++) { @@ -477,11 +535,9 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() const EConnectivite theConnMode = eNOD; TInt aNbNodes = myMesh->NbNodes(); - //cout << " myMed->CrNodeInfo() aNbNodes = " << aNbNodes << endl; PNodeInfo aNodeInfo = myMed->CrNodeInfo(aMeshInfo, aNbNodes, theMode, theSystem, theIsElemNum, theIsElemNames); - //cout << " fillElemFamilyMap( SMDSAbs_Node )" << endl; // find family numbers for nodes TElemFamilyMap anElemFamMap; fillElemFamilyMap( anElemFamMap, aFamilies, SMDSAbs_Node ); @@ -490,14 +546,14 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() { // coordinates TCoordSlice aTCoordSlice = aNodeInfo->GetCoordSlice( iNode ); - for(TInt iCoord = 0; iCoord < aMeshDimension; iCoord++){ - aTCoordSlice[iCoord] = aCoordHelperPtr->GetCoord(iCoord); + for(TInt iCoord = 0; iCoord < aSpaceDimension; iCoord++){ + aTCoordSlice[iCoord] = aCoordHelperPtr->GetCoord(iCoord); } // node number int aNodeID = aCoordHelperPtr->GetID(); aNodeInfo->SetElemNum( iNode, aNodeID ); #ifdef _EDF_NODE_IDS_ - aNodeIdMap[aNodeID] = iNode+1; + aNodeIdMap.insert( aNodeIdMap.end(), make_pair( aNodeID, iNode+1 )); #endif // family number const SMDS_MeshNode* aNode = aCoordHelperPtr->GetNode(); @@ -507,13 +563,12 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() anElemFamMap.Clear(); // coordinate names and units - for (TInt iCoord = 0; iCoord < aMeshDimension; iCoord++) { + for (TInt iCoord = 0; iCoord < aSpaceDimension; iCoord++) { aNodeInfo->SetCoordName( iCoord, aCoordHelperPtr->GetName(iCoord)); aNodeInfo->SetCoordUnit( iCoord, aCoordHelperPtr->GetUnit(iCoord)); } - //cout << " SetNodeInfo(aNodeInfo)" << endl; - MESSAGE("Perform - aNodeInfo->GetNbElem() = "<GetNbElem() = "<SetNodeInfo(aNodeInfo); aNodeInfo.reset(); // free memory used for arrays @@ -525,81 +580,134 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() const SMDS_MeshInfo& nbElemInfo = myMesh->GetMeshInfo(); // poly elements are not supported by med-2.1 - bool polyTypesSupported = myMed->CrPolygoneInfo(aMeshInfo,eMAILLE,ePOLYGONE,0,0); + bool polyTypesSupported = ( myMed->CrPolygoneInfo(aMeshInfo,eMAILLE,ePOLYGONE,0,0).get() != 0 ); TInt nbPolygonNodes = 0, nbPolyhedronNodes = 0, nbPolyhedronFaces = 0; + // nodes on VERTEXes where 0D elements are absent + std::vector nodesOf0D; + std::vector< SMDS_ElemIteratorPtr > iterVec; + SMDS_ElemIteratorPtr iterVecIter; + if ( myAddODOnVertices && getNodesOfMissing0DOnVert( myMesh, nodesOf0D )) + { + iterVec.resize(2); + iterVec[0] = myMesh->elementsIterator( SMDSAbs_0DElement ); + iterVec[1] = SMDS_ElemIteratorPtr + ( new SMDS_ElementVectorIterator( nodesOf0D.begin(), nodesOf0D.end() )); + + typedef SMDS_IteratorOnIterators + < const SMDS_MeshElement *, std::vector< SMDS_ElemIteratorPtr > > TItIterator; + iterVecIter = SMDS_ElemIteratorPtr( new TItIterator( iterVec )); + } + // collect info on all geom types list< TElemTypeData > aTElemTypeDatas; EEntiteMaillage anEntity = eMAILLE; +#ifdef _ELEMENTS_BY_DIM_ + anEntity = eNOEUD_ELEMENT; +#endif + aTElemTypeDatas.push_back(TElemTypeData(anEntity, + ePOINT1, + nbElemInfo.Nb0DElements() + nodesOf0D.size(), + SMDSAbs_0DElement)); +#ifdef _ELEMENTS_BY_DIM_ + anEntity = eSTRUCT_ELEMENT; +#endif + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + eBALL, + nbElemInfo.NbBalls(), + SMDSAbs_Ball)); #ifdef _ELEMENTS_BY_DIM_ anEntity = eARETE; #endif aTElemTypeDatas.push_back( TElemTypeData(anEntity, - eSEG2, - nbElemInfo.NbEdges( ORDER_LINEAR ), - SMDSAbs_Edge)); + eSEG2, + nbElemInfo.NbEdges( ORDER_LINEAR ), + SMDSAbs_Edge)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, - eSEG3, - nbElemInfo.NbEdges( ORDER_QUADRATIC ), - SMDSAbs_Edge)); + eSEG3, + nbElemInfo.NbEdges( ORDER_QUADRATIC ), + SMDSAbs_Edge)); #ifdef _ELEMENTS_BY_DIM_ anEntity = eFACE; #endif aTElemTypeDatas.push_back( TElemTypeData(anEntity, - eTRIA3, - nbElemInfo.NbTriangles( ORDER_LINEAR ), - SMDSAbs_Face)); + eTRIA3, + nbElemInfo.NbTriangles( ORDER_LINEAR ), + SMDSAbs_Face)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, - eTRIA6, - nbElemInfo.NbTriangles( ORDER_QUADRATIC ), - SMDSAbs_Face)); + eTRIA6, + nbElemInfo.NbTriangles( ORDER_QUADRATIC ) - + nbElemInfo.NbBiQuadTriangles(), + SMDSAbs_Face)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, - eQUAD4, - nbElemInfo.NbQuadrangles( ORDER_LINEAR ), - SMDSAbs_Face)); + eTRIA7, + nbElemInfo.NbBiQuadTriangles(), + SMDSAbs_Face)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, - eQUAD8, - nbElemInfo.NbQuadrangles( ORDER_QUADRATIC ), - SMDSAbs_Face)); + eQUAD4, + nbElemInfo.NbQuadrangles( ORDER_LINEAR ), + SMDSAbs_Face)); + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + eQUAD8, + nbElemInfo.NbQuadrangles( ORDER_QUADRATIC ) - + nbElemInfo.NbBiQuadQuadrangles(), + SMDSAbs_Face)); + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + eQUAD9, + nbElemInfo.NbBiQuadQuadrangles(), + SMDSAbs_Face)); if ( polyTypesSupported ) { aTElemTypeDatas.push_back( TElemTypeData(anEntity, ePOLYGONE, - nbElemInfo.NbPolygons(), + nbElemInfo.NbPolygons( ORDER_LINEAR ), SMDSAbs_Face)); // we need one more loop on poly elements to count nb of their nodes aTElemTypeDatas.push_back( TElemTypeData(anEntity, ePOLYGONE, - nbElemInfo.NbPolygons(), + nbElemInfo.NbPolygons( ORDER_LINEAR ), + SMDSAbs_Face)); + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + ePOLYGON2, + nbElemInfo.NbPolygons( ORDER_QUADRATIC ), + SMDSAbs_Face)); + // we need one more loop on QUAD poly elements to count nb of their nodes + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + ePOLYGON2, + nbElemInfo.NbPolygons( ORDER_QUADRATIC ), SMDSAbs_Face)); } #ifdef _ELEMENTS_BY_DIM_ anEntity = eMAILLE; #endif aTElemTypeDatas.push_back( TElemTypeData(anEntity, - eTETRA4, - nbElemInfo.NbTetras( ORDER_LINEAR ), - SMDSAbs_Volume)); + eTETRA4, + nbElemInfo.NbTetras( ORDER_LINEAR ), + SMDSAbs_Volume)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, - eTETRA10, - nbElemInfo.NbTetras( ORDER_QUADRATIC ), - SMDSAbs_Volume)); + eTETRA10, + nbElemInfo.NbTetras( ORDER_QUADRATIC ), + SMDSAbs_Volume)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, - ePYRA5, - nbElemInfo.NbPyramids( ORDER_LINEAR ), - SMDSAbs_Volume)); + ePYRA5, + nbElemInfo.NbPyramids( ORDER_LINEAR ), + SMDSAbs_Volume)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, - ePYRA13, - nbElemInfo.NbPyramids( ORDER_QUADRATIC ), - SMDSAbs_Volume)); + ePYRA13, + nbElemInfo.NbPyramids( ORDER_QUADRATIC ), + SMDSAbs_Volume)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, - ePENTA6, - nbElemInfo.NbPrisms( ORDER_LINEAR ), - SMDSAbs_Volume)); + ePENTA6, + nbElemInfo.NbPrisms( ORDER_LINEAR ), + SMDSAbs_Volume)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, ePENTA15, - nbElemInfo.NbPrisms( ORDER_QUADRATIC ), + nbElemInfo.NbQuadPrisms(), + SMDSAbs_Volume)); + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + ePENTA18, + nbElemInfo.NbBiQuadPrisms(), SMDSAbs_Volume)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, eHEXA8, @@ -607,7 +715,16 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() SMDSAbs_Volume)); aTElemTypeDatas.push_back( TElemTypeData(anEntity, eHEXA20, - nbElemInfo.NbHexas( ORDER_QUADRATIC ), + nbElemInfo.NbHexas( ORDER_QUADRATIC )- + nbElemInfo.NbTriQuadHexas(), + SMDSAbs_Volume)); + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + eHEXA27, + nbElemInfo.NbTriQuadHexas(), + SMDSAbs_Volume)); + aTElemTypeDatas.push_back( TElemTypeData(anEntity, + eOCTA12, + nbElemInfo.NbHexPrisms(), SMDSAbs_Volume)); if ( polyTypesSupported ) { aTElemTypeDatas.push_back( TElemTypeData(anEntity, @@ -631,40 +748,45 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() if ( aElemTypeData->_nbElems == 0 ) continue; - // iterator on elements of a current type - PElemIterator elemIterator; int defaultFamilyId = 0; switch ( aElemTypeData->_smdsType ) { - case SMDSAbs_Edge: - elemIterator = PElemIterator( new TEdgeIterator( myMesh->edgesIterator() )); - defaultFamilyId = myEdgesDefaultFamilyId; - break; - case SMDSAbs_Face: - elemIterator = PElemIterator( new TFaceIterator( myMesh->facesIterator() )); - defaultFamilyId = myFacesDefaultFamilyId; - break; - case SMDSAbs_Volume: - elemIterator = PElemIterator( new TVolumeIterator( myMesh->volumesIterator() )); - defaultFamilyId = myVolumesDefaultFamilyId; - break; + case SMDSAbs_0DElement: defaultFamilyId = my0DElementsDefaultFamilyId; break; + case SMDSAbs_Ball: defaultFamilyId = myBallsDefaultFamilyId; break; + case SMDSAbs_Edge: defaultFamilyId = myEdgesDefaultFamilyId; break; + case SMDSAbs_Face: defaultFamilyId = myFacesDefaultFamilyId; break; + case SMDSAbs_Volume: defaultFamilyId = myVolumesDefaultFamilyId; break; default: continue; } + + // build map of family numbers for this type + if ( !isElemFamMapBuilt[ aElemTypeData->_smdsType ]) + { + fillElemFamilyMap( anElemFamMap, aFamilies, aElemTypeData->_smdsType ); + isElemFamMapBuilt[ aElemTypeData->_smdsType ] = true; + } + + // iterator on elements of a current type + SMDS_ElemIteratorPtr elemIterator; int iElem = 0; - //cout << " Treat type " << aElemTypeData->_geomType << " nb = " <_nbElems<< endl; // Treat POLYGONs // --------------- - if ( aElemTypeData->_geomType == ePOLYGONE ) + if ( aElemTypeData->_geomType == ePOLYGONE || + aElemTypeData->_geomType == ePOLYGON2 ) { + if ( aElemTypeData->_geomType == ePOLYGONE ) + elemIterator = myMesh->elementEntityIterator( SMDSEntity_Polygon ); + else + elemIterator = myMesh->elementEntityIterator( SMDSEntity_Quad_Polygon ); + if ( nbPolygonNodes == 0 ) { // Count nb of nodes - while ( const SMDS_MeshElement* anElem = elemIterator->next() ) { - if ( anElem->IsPoly() ) { - nbPolygonNodes += anElem->NbNodes(); - if ( ++iElem == aElemTypeData->_nbElems ) - break; - } + while ( elemIterator->more() ) { + const SMDS_MeshElement* anElem = elemIterator->next(); + nbPolygonNodes += anElem->NbNodes(); + if ( ++iElem == aElemTypeData->_nbElems ) + break; } } else { @@ -679,11 +801,9 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() TElemNum & index = *(aPolygoneInfo->myIndex.get()); index[0] = 1; - while ( const SMDS_MeshElement* anElem = elemIterator->next() ) + while ( elemIterator->more() ) { - if ( !anElem->IsPoly() ) - continue; - + const SMDS_MeshElement* anElem = elemIterator->next(); // index TInt aNbNodes = anElem->NbNodes(); index[ iElem+1 ] = index[ iElem ] + aNbNodes; @@ -708,31 +828,26 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() if ( ++iElem == aPolygoneInfo->GetNbElem() ) break; } - // if(TInt aNbElems = aPolygoneElemNums.size()) - // // add one element in connectivities, - // // referenced by the last element in indices - // aPolygoneConn.push_back(0); - //cout << " SetPolygoneInfo(aPolygoneInfo)" << endl; myMed->SetPolygoneInfo(aPolygoneInfo); - } - } + nbPolygonNodes = 0; // to treat next polygon type + } + } // Treat POLYEDREs // ---------------- - else if (aElemTypeData->_geomType == ePOLYEDRE ) + else if ( aElemTypeData->_geomType == ePOLYEDRE ) { + elemIterator = myMesh->elementGeomIterator( SMDSGeom_POLYHEDRA ); + if ( nbPolyhedronNodes == 0 ) { // Count nb of nodes - while ( const SMDS_MeshElement* anElem = elemIterator->next() ) { - const SMDS_PolyhedralVolumeOfNodes* aPolyedre = - dynamic_cast( anElem ); - if ( aPolyedre ) { - nbPolyhedronNodes += aPolyedre->NbNodes(); - nbPolyhedronFaces += aPolyedre->NbFaces(); - if ( ++iElem == aElemTypeData->_nbElems ) - break; - } + while ( elemIterator->more() ) { + const SMDS_MeshElement* anElem = elemIterator->next(); + nbPolyhedronNodes += anElem->NbNodes(); + nbPolyhedronFaces += anElem->NbFaces(); + if ( ++iElem == aElemTypeData->_nbElems ) + break; } } else { @@ -753,13 +868,11 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() faces[0] = 1; TInt iFace = 0, iNode = 0; - while ( const SMDS_MeshElement* anElem = elemIterator->next() ) + while ( elemIterator->more() ) { - const SMDS_PolyhedralVolumeOfNodes* aPolyedre = - dynamic_cast( anElem ); - if ( !aPolyedre ) - continue; - + const SMDS_MeshElement* anElem = elemIterator->next(); + const SMDS_MeshVolume *aPolyedre = myMesh->DownCast< SMDS_MeshVolume >( anElem ); + if ( !aPolyedre ) continue; // index TInt aNbFaces = aPolyedre->NbFaces(); index[ iElem+1 ] = index[ iElem ] + aNbFaces; @@ -790,16 +903,48 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() if ( ++iElem == aPolyhInfo->GetNbElem() ) break; } - //cout << " SetPolyedreInfo(aPolyhInfo )" << endl; myMed->SetPolyedreInfo(aPolyhInfo); } } // if (aElemTypeData->_geomType == ePOLYEDRE ) + // Treat BALLs + // ---------------- + else if (aElemTypeData->_geomType == eBALL ) + { + // allocate data arrays + PBallInfo aBallInfo = myMed->CrBallInfo( aMeshInfo, aElemTypeData->_nbElems ); + + elemIterator = myMesh->elementsIterator( SMDSAbs_Ball ); + while ( elemIterator->more() ) + { + const SMDS_MeshElement* anElem = elemIterator->next(); + // connectivity + const SMDS_MeshElement* aNode = anElem->GetNode( 0 ); +#ifdef _EDF_NODE_IDS_ + (*aBallInfo->myConn)[ iElem ] = aNodeIdMap[aNode->GetID()]; +#else + (*aBallInfo->myConn)[ iElem ] = aNode->GetID(); +#endif + // element number + aBallInfo->SetElemNum( iElem, anElem->GetID() ); + + // diameter + aBallInfo->myDiameters[ iElem ] = + static_cast( anElem )->GetDiameter(); + + // family number + int famNum = getFamilyId( anElemFamMap, anElem, defaultFamilyId ); + aBallInfo->SetFamNum( iElem, famNum ); + ++iElem; + } + // store data in a file + myMed->SetBallInfo(aBallInfo); + } + else { // Treat standard types // --------------------- - // allocate data arrays PCellInfo aCellInfo = myMed->CrCellInfo( aMeshInfo, aElemTypeData->_entity, @@ -808,17 +953,14 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() theConnMode, theIsElemNum, theIsElemNames); - // build map of family numbers for this type - if ( !isElemFamMapBuilt[ aElemTypeData->_smdsType ]) - { - //cout << " fillElemFamilyMap()" << endl; - fillElemFamilyMap( anElemFamMap, aFamilies, aElemTypeData->_smdsType ); - isElemFamMapBuilt[ aElemTypeData->_smdsType ] = true; - } TInt aNbNodes = MED::GetNbNodes(aElemTypeData->_geomType); - while ( const SMDS_MeshElement* anElem = elemIterator->next() ) + elemIterator = myMesh->elementsIterator( aElemTypeData->_smdsType ); + if ( aElemTypeData->_smdsType == SMDSAbs_0DElement && ! nodesOf0D.empty() ) + elemIterator = iterVecIter; + while ( elemIterator->more() ) { + const SMDS_MeshElement* anElem = elemIterator->next(); if ( anElem->NbNodes() != aNbNodes || anElem->IsPoly() ) continue; // other geometry @@ -843,20 +985,16 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform() break; } // store data in a file - //cout << " SetCellInfo(aCellInfo)" << endl; myMed->SetCellInfo(aCellInfo); } - } // loop on geom types - - } catch(const std::exception& exc) { - INFOS("Follow exception was cought:\n\t"<& 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(); +}