Version: 6.3.1

src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx

Go to the documentation of this file.
00001 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 //  SMESH DriverMED : driver to read and write 'med' files
00024 //  File   : DriverMED_W_SMESHDS_Mesh.cxx
00025 //  Module : SMESH
00026 //
00027 #include <sstream>
00028 
00029 #include "DriverMED_W_SMESHDS_Mesh.h"
00030 #include "DriverMED_W_SMDS_Mesh.h"
00031 #include "DriverMED_Family.h"
00032 
00033 #include "SMESHDS_Mesh.hxx"
00034 #include "SMDS_MeshElement.hxx"
00035 #include "SMDS_MeshNode.hxx"
00036 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
00037 
00038 #include "utilities.h"
00039 
00040 #include "MED_Utilities.hxx"
00041 
00042 #define _EDF_NODE_IDS_
00043 //#define _ELEMENTS_BY_DIM_
00044 
00045 using namespace std;
00046 using namespace MED;
00047 
00048 
00049 DriverMED_W_SMESHDS_Mesh::DriverMED_W_SMESHDS_Mesh():
00050   myAllSubMeshes (false),
00051   myDoGroupOfNodes (false),
00052   myDoGroupOfEdges (false),
00053   myDoGroupOfFaces (false),
00054   myDoGroupOfVolumes (false)
00055 {}
00056 
00057 void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName, 
00058                                        MED::EVersion theId)
00059 {
00060   myMed = CrWrapper(theFileName,theId);
00061   Driver_SMESHDS_Mesh::SetFile(theFileName);
00062 }
00063 
00064 void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName)
00065 {
00066   return SetFile(theFileName,MED::eV2_2);
00067 }
00068 
00069 string DriverMED_W_SMESHDS_Mesh::GetVersionString(const MED::EVersion theVersion, int theNbDigits)
00070 {
00071   TInt majeur, mineur, release;
00072   majeur =  mineur = release = 0;
00073 //   if ( theVersion == eV2_1 )
00074 //     MED::GetVersionRelease<eV2_1>(majeur, mineur, release);
00075 //   else
00076     MED::GetVersionRelease<eV2_2>(majeur, mineur, release);
00077   ostringstream name;
00078   if ( theNbDigits > 0 )
00079     name << majeur;
00080   if ( theNbDigits > 1 )
00081     name << "." << mineur;
00082   if ( theNbDigits > 2 )
00083     name << "." << release;
00084   return name.str();
00085 }
00086 
00087 void DriverMED_W_SMESHDS_Mesh::SetMeshName(const std::string& theMeshName)
00088 {
00089   myMeshName = theMeshName;
00090 }
00091 
00092 void DriverMED_W_SMESHDS_Mesh::AddGroup(SMESHDS_GroupBase* theGroup)
00093 {
00094   myGroups.push_back(theGroup);
00095 }
00096 
00097 void DriverMED_W_SMESHDS_Mesh::AddAllSubMeshes()
00098 {
00099   myAllSubMeshes = true;
00100 }
00101 
00102 void DriverMED_W_SMESHDS_Mesh::AddSubMesh(SMESHDS_SubMesh* theSubMesh, int theID)
00103 {
00104   mySubMeshes[theID] = theSubMesh;
00105 }
00106 
00107 void DriverMED_W_SMESHDS_Mesh::AddGroupOfNodes()
00108 {
00109   myDoGroupOfNodes = true;
00110 }
00111 
00112 void DriverMED_W_SMESHDS_Mesh::AddGroupOfEdges()
00113 {
00114   myDoGroupOfEdges = true;
00115 }
00116 
00117 void DriverMED_W_SMESHDS_Mesh::AddGroupOfFaces()
00118 {
00119   myDoGroupOfFaces = true;
00120 }
00121 
00122 void DriverMED_W_SMESHDS_Mesh::AddGroupOfVolumes()
00123 {
00124   myDoGroupOfVolumes = true;
00125 }
00126 
00127 namespace{
00128   typedef double (SMDS_MeshNode::* TGetCoord)() const;
00129   typedef const char* TName;
00130   typedef const char* TUnit;
00131 
00132   // name length in a mesh must be equal to 16 :
00133   //         1234567890123456
00134   TName M = "m               ";
00135   TName X = "x               ";
00136   TName Y = "y               ";
00137   TName Z = "z               ";
00138 
00139   TUnit aUnit[3] = {M,M,M};
00140 
00141   // 3 dim
00142   TGetCoord aXYZGetCoord[3] = {
00143     &SMDS_MeshNode::X, 
00144     &SMDS_MeshNode::Y, 
00145     &SMDS_MeshNode::Z
00146   };
00147   TName aXYZName[3] = {X,Y,Z};
00148   
00149   // 2 dim
00150   TGetCoord aXYGetCoord[2] = {
00151     &SMDS_MeshNode::X, 
00152     &SMDS_MeshNode::Y
00153   };
00154   TName aXYName[2] = {X,Y};
00155 
00156   TGetCoord aYZGetCoord[2] = {
00157     &SMDS_MeshNode::Y, 
00158     &SMDS_MeshNode::Z
00159   };
00160   TName aYZName[2] = {Y,Z};
00161 
00162   TGetCoord aXZGetCoord[2] = {
00163     &SMDS_MeshNode::X, 
00164     &SMDS_MeshNode::Z
00165   };
00166   TName aXZName[2] = {X,Z};
00167 
00168   // 1 dim
00169   TGetCoord aXGetCoord[1] = {
00170     &SMDS_MeshNode::X
00171   };
00172   TName aXName[1] = {X};
00173 
00174   TGetCoord aYGetCoord[1] = {
00175     &SMDS_MeshNode::Y
00176   };
00177   TName aYName[1] = {Y};
00178 
00179   TGetCoord aZGetCoord[1] = {
00180     &SMDS_MeshNode::Z
00181   };
00182   TName aZName[1] = {Z};
00183 
00184 
00185   class TCoordHelper{
00186     SMDS_NodeIteratorPtr myNodeIter;
00187     const SMDS_MeshNode* myCurrentNode;
00188     TGetCoord* myGetCoord;
00189     TName* myName;
00190     TUnit* myUnit;
00191   public:
00192     TCoordHelper(const SMDS_NodeIteratorPtr& theNodeIter,
00193                  TGetCoord* theGetCoord,
00194                  TName* theName,
00195                  TUnit* theUnit = aUnit):
00196       myNodeIter(theNodeIter),
00197       myGetCoord(theGetCoord),
00198       myName(theName),
00199       myUnit(theUnit)
00200     {}
00201     virtual ~TCoordHelper(){}
00202     bool Next(){ 
00203       return myNodeIter->more() && 
00204         (myCurrentNode = myNodeIter->next());
00205     }
00206     const SMDS_MeshNode* GetNode(){
00207       return myCurrentNode;
00208     }
00209     MED::TIntVector::value_type GetID(){
00210       return myCurrentNode->GetID();
00211     }
00212     MED::TFloatVector::value_type GetCoord(TInt theCoodId){
00213       return (myCurrentNode->*myGetCoord[theCoodId])();
00214     }
00215     MED::TStringVector::value_type GetName(TInt theDimId){
00216       return myName[theDimId];
00217     }
00218     MED::TStringVector::value_type GetUnit(TInt theDimId){
00219       return myUnit[theDimId];
00220     }
00221   };
00222   typedef boost::shared_ptr<TCoordHelper> TCoordHelperPtr;
00223 
00224 
00225   //-------------------------------------------------------
00231   //-------------------------------------------------------
00232   struct TElemIterator
00233   {
00234     virtual const SMDS_MeshElement* next() = 0;
00235     virtual ~TElemIterator() {}
00236   };
00237   typedef boost::shared_ptr<TElemIterator> PElemIterator;
00238 
00239   template< class SMDSIteratorPtr > class TypedElemIterator: public TElemIterator
00240   {
00241     SMDSIteratorPtr myItPtr;
00242   public:
00243     TypedElemIterator(SMDSIteratorPtr it): myItPtr(it) {}
00244     virtual const SMDS_MeshElement* next() {
00245       if ( myItPtr->more() ) return myItPtr->next();
00246       else                   return 0;
00247     }
00248   };
00249   typedef TypedElemIterator< SMDS_0DElementIteratorPtr > T0DElementIterator;
00250   typedef TypedElemIterator< SMDS_EdgeIteratorPtr > TEdgeIterator;
00251   typedef TypedElemIterator< SMDS_FaceIteratorPtr > TFaceIterator;
00252   typedef TypedElemIterator< SMDS_VolumeIteratorPtr > TVolumeIterator;
00253 
00254   //-------------------------------------------------------
00258   //-------------------------------------------------------
00259   struct TElemTypeData
00260   {
00261     EEntiteMaillage     _entity;
00262     EGeometrieElement   _geomType;
00263     TInt                _nbElems;
00264     SMDSAbs_ElementType _smdsType;
00265 
00266     TElemTypeData (EEntiteMaillage entity, EGeometrieElement geom, TInt nb, SMDSAbs_ElementType type)
00267       : _entity(entity), _geomType(geom), _nbElems( nb ), _smdsType( type ) {}
00268   };
00269 
00270 
00271   typedef NCollection_DataMap< Standard_Address, int > TElemFamilyMap;
00272   //typedef map<const SMDS_MeshElement *, int> TElemFamilyMap;
00273 
00274   //================================================================================
00279   //================================================================================
00280 
00281   void fillElemFamilyMap( TElemFamilyMap &            anElemFamMap,
00282                           list<DriverMED_FamilyPtr> & aFamilies,
00283                           const SMDSAbs_ElementType   anElemType)
00284   {
00285     anElemFamMap.Clear();
00286     //anElemFamMap.clear();
00287     list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
00288     while ( aFamsIter != aFamilies.end() )
00289     {
00290       if ((*aFamsIter)->GetType() != anElemType) {
00291         aFamsIter++;
00292       }
00293       else {
00294         int aFamId = (*aFamsIter)->GetId();
00295         const set<const SMDS_MeshElement *>& anElems = (*aFamsIter)->GetElements();
00296         set<const SMDS_MeshElement *>::const_iterator anElemsIter = anElems.begin();
00297         for (; anElemsIter != anElems.end(); anElemsIter++)
00298         {
00299           anElemFamMap.Bind( (Standard_Address)*anElemsIter, aFamId );
00300           //anElemFamMap[*anElemsIter] = aFamId;
00301         }
00302         // remove a family from the list
00303         aFamilies.erase( aFamsIter++ );
00304       }
00305     }
00306   }
00307 
00308   //================================================================================
00312   //================================================================================
00313 
00314   int getFamilyId( const TElemFamilyMap &  anElemFamMap,
00315                    const SMDS_MeshElement* anElement,
00316                    const int               aDefaultFamilyId)
00317   {
00318     if ( anElemFamMap.IsBound( (Standard_Address) anElement ))
00319       return anElemFamMap( (Standard_Address) anElement );
00320 //     TElemFamilyMap::iterator elem_famNum = anElemFamMap.find( anElement );
00321 //     if ( elem_famNum != anElemFamMap.end() )
00322 //       return elem_famNum->second;
00323     return aDefaultFamilyId;
00324   }
00325 }
00326 
00327 Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
00328 {
00329   Status aResult = DRS_OK;
00330   if (myMesh->hasConstructionEdges() || myMesh->hasConstructionFaces()) {
00331     INFOS("SMDS_MESH with hasConstructionEdges() or hasConstructionFaces() do not supports!!!");
00332     return DRS_FAIL;
00333   }
00334   try {
00335     MESSAGE("Perform - myFile : "<<myFile);
00336 
00337     // Creating the MED mesh for corresponding SMDS structure
00338     //-------------------------------------------------------
00339     string aMeshName;
00340     if (myMeshId != -1) {
00341       ostringstream aMeshNameStr;
00342       aMeshNameStr<<myMeshId;
00343       aMeshName = aMeshNameStr.str();
00344     } else {
00345       aMeshName = myMeshName;
00346     }
00347 
00348     // Mesh dimension definition
00349     TInt aSpaceDimension;
00350     TCoordHelperPtr aCoordHelperPtr;
00351     {  
00352       bool anIsXDimension = false;
00353       bool anIsYDimension = false;
00354       bool anIsZDimension = false;
00355       {
00356         SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator();
00357         double aBounds[6];
00358         if(aNodesIter->more()){
00359           const SMDS_MeshNode* aNode = aNodesIter->next();
00360           aBounds[0] = aBounds[1] = aNode->X();
00361           aBounds[2] = aBounds[3] = aNode->Y();
00362           aBounds[4] = aBounds[5] = aNode->Z();
00363         }
00364         while(aNodesIter->more()){
00365           const SMDS_MeshNode* aNode = aNodesIter->next();
00366           aBounds[0] = min(aBounds[0],aNode->X());
00367           aBounds[1] = max(aBounds[1],aNode->X());
00368           
00369           aBounds[2] = min(aBounds[2],aNode->Y());
00370           aBounds[3] = max(aBounds[3],aNode->Y());
00371           
00372           aBounds[4] = min(aBounds[4],aNode->Z());
00373           aBounds[5] = max(aBounds[5],aNode->Z());
00374         }
00375 
00376         double EPS = 1.0E-7;
00377         anIsXDimension = (aBounds[1] - aBounds[0]) + abs(aBounds[1]) + abs(aBounds[0]) > EPS;
00378         anIsYDimension = (aBounds[3] - aBounds[2]) + abs(aBounds[3]) + abs(aBounds[2]) > EPS;
00379         anIsZDimension = (aBounds[5] - aBounds[4]) + abs(aBounds[5]) + abs(aBounds[4]) > EPS;
00380         aSpaceDimension = anIsXDimension + anIsYDimension + anIsZDimension;
00381         if(!aSpaceDimension)
00382           aSpaceDimension = 3;
00383         // PAL16857(SMESH not conform to the MED convention):
00384         if ( aSpaceDimension == 2 && anIsZDimension ) // 2D only if mesh is in XOY plane
00385           aSpaceDimension = 3;
00386         // PAL18941(a saved study with a mesh belong Z is opened and the mesh is belong X)
00387         if ( aSpaceDimension == 1 && !anIsXDimension ) {// 1D only if mesh is along OX
00388           if ( anIsYDimension ) {
00389             aSpaceDimension = 2;
00390             anIsXDimension = true;
00391           } else {
00392             aSpaceDimension = 3;
00393           }
00394         }
00395       }
00396 
00397       SMDS_NodeIteratorPtr aNodesIter = myMesh->nodesIterator(/*idInceasingOrder=*/true);
00398       switch(aSpaceDimension){
00399       case 3:
00400         aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXYZGetCoord,aXYZName));
00401         break;
00402       case 2:
00403         if(anIsXDimension && anIsYDimension)
00404           aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXYGetCoord,aXYName));
00405         if(anIsYDimension && anIsZDimension)
00406           aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aYZGetCoord,aYZName));
00407         if(anIsXDimension && anIsZDimension)
00408           aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXZGetCoord,aXZName));
00409         break;
00410       case 1:
00411         if(anIsXDimension)
00412           aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aXGetCoord,aXName));
00413         if(anIsYDimension)
00414           aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aYGetCoord,aYName));
00415         if(anIsZDimension)
00416           aCoordHelperPtr.reset(new TCoordHelper(aNodesIter,aZGetCoord,aZName));
00417         break;
00418       }
00419     }
00420     TInt aMeshDimension = 0;
00421     if ( myMesh->NbEdges() > 0 )
00422       aMeshDimension = 1;
00423     if ( myMesh->NbFaces() > 0 )
00424       aMeshDimension = 2;
00425     if ( myMesh->NbVolumes() > 0 )
00426       aMeshDimension = 3;
00427     
00428     PMeshInfo aMeshInfo = myMed->CrMeshInfo(aMeshDimension,aSpaceDimension,aMeshName);
00429     MESSAGE("Add - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
00430     myMed->SetMeshInfo(aMeshInfo);
00431 
00432     // Storing SMDS groups and sub-meshes as med families
00433     //----------------------------------------------------
00434     int myNodesDefaultFamilyId   = 0;
00435     int my0DElementsDefaultFamilyId = 0;
00436     int myEdgesDefaultFamilyId   = 0;
00437     int myFacesDefaultFamilyId   = 0;
00438     int myVolumesDefaultFamilyId = 0;
00439     int nbNodes   = myMesh->NbNodes();
00440     //int nb0DElements = myMesh->Nb0DElements();
00441     int nbEdges   = myMesh->NbEdges();
00442     int nbFaces   = myMesh->NbFaces();
00443     int nbVolumes = myMesh->NbVolumes();
00444     if (myDoGroupOfNodes && nbNodes)
00445       myNodesDefaultFamilyId = REST_NODES_FAMILY;
00446     if (myDoGroupOfEdges && nbEdges)
00447       myEdgesDefaultFamilyId = REST_EDGES_FAMILY;
00448     if (myDoGroupOfFaces && nbFaces)
00449       myFacesDefaultFamilyId = REST_FACES_FAMILY;
00450     if (myDoGroupOfVolumes && nbVolumes)
00451       myVolumesDefaultFamilyId = REST_VOLUMES_FAMILY;
00452 
00453     MESSAGE("Perform - aFamilyInfo");
00454     //cout << " DriverMED_Family::MakeFamilies() " << endl;
00455     list<DriverMED_FamilyPtr> aFamilies;
00456     if (myAllSubMeshes) {
00457       aFamilies = DriverMED_Family::MakeFamilies
00458         (myMesh->SubMeshes(), myGroups,
00459          myDoGroupOfNodes   && nbNodes,
00460          myDoGroupOfEdges   && nbEdges,
00461          myDoGroupOfFaces   && nbFaces,
00462          myDoGroupOfVolumes && nbVolumes);
00463     } else {
00464       aFamilies = DriverMED_Family::MakeFamilies
00465         (mySubMeshes, myGroups,
00466          myDoGroupOfNodes   && nbNodes,
00467          myDoGroupOfEdges   && nbEdges,
00468          myDoGroupOfFaces   && nbFaces,
00469          myDoGroupOfVolumes && nbVolumes);
00470     }
00471     //cout << " myMed->SetFamilyInfo() " << endl;
00472     list<DriverMED_FamilyPtr>::iterator aFamsIter;
00473     for (aFamsIter = aFamilies.begin(); aFamsIter != aFamilies.end(); aFamsIter++)
00474     {
00475       PFamilyInfo aFamilyInfo = (*aFamsIter)->GetFamilyInfo(myMed,aMeshInfo);
00476       myMed->SetFamilyInfo(aFamilyInfo);
00477     }
00478 
00479     // Storing SMDS nodes to the MED file for the MED mesh
00480     //----------------------------------------------------
00481 #ifdef _EDF_NODE_IDS_
00482     typedef map<TInt,TInt> TNodeIdMap;
00483     TNodeIdMap aNodeIdMap;
00484 #endif
00485     const EModeSwitch   theMode        = eFULL_INTERLACE;
00486     const ERepere       theSystem      = eCART;
00487     const EBooleen      theIsElemNum   = eVRAI;
00488     const EBooleen      theIsElemNames = eFAUX;
00489     const EConnectivite theConnMode    = eNOD;
00490 
00491     TInt aNbNodes = myMesh->NbNodes();
00492     //cout << " myMed->CrNodeInfo() aNbNodes = " << aNbNodes << endl;
00493     PNodeInfo aNodeInfo = myMed->CrNodeInfo(aMeshInfo, aNbNodes,
00494                                             theMode, theSystem, theIsElemNum, theIsElemNames);
00495 
00496     //cout << " fillElemFamilyMap( SMDSAbs_Node )" << endl;
00497     // find family numbers for nodes
00498     TElemFamilyMap anElemFamMap;
00499     fillElemFamilyMap( anElemFamMap, aFamilies, SMDSAbs_Node );
00500 
00501     for (TInt iNode = 0; aCoordHelperPtr->Next(); iNode++)
00502     {
00503       // coordinates
00504       TCoordSlice aTCoordSlice = aNodeInfo->GetCoordSlice( iNode );
00505       for(TInt iCoord = 0; iCoord < aSpaceDimension; iCoord++){
00506         aTCoordSlice[iCoord] = aCoordHelperPtr->GetCoord(iCoord);
00507       }
00508       // node number
00509       int aNodeID = aCoordHelperPtr->GetID();
00510       aNodeInfo->SetElemNum( iNode, aNodeID );
00511 #ifdef _EDF_NODE_IDS_
00512       aNodeIdMap[aNodeID] = iNode+1;
00513 #endif
00514       // family number
00515       const SMDS_MeshNode* aNode = aCoordHelperPtr->GetNode();
00516       int famNum = getFamilyId( anElemFamMap, aNode, myNodesDefaultFamilyId );
00517       aNodeInfo->SetFamNum( iNode, famNum );
00518     }
00519     anElemFamMap.Clear();
00520 
00521     // coordinate names and units
00522     for (TInt iCoord = 0; iCoord < aSpaceDimension; iCoord++) {
00523       aNodeInfo->SetCoordName( iCoord, aCoordHelperPtr->GetName(iCoord));
00524       aNodeInfo->SetCoordUnit( iCoord, aCoordHelperPtr->GetUnit(iCoord));
00525     }
00526 
00527     //cout << " SetNodeInfo(aNodeInfo)" << endl;
00528     MESSAGE("Perform - aNodeInfo->GetNbElem() = "<<aNbNodes);
00529     myMed->SetNodeInfo(aNodeInfo);
00530     aNodeInfo.reset(); // free memory used for arrays
00531 
00532 
00533     // Storing SMDS elements to the MED file for the MED mesh
00534     //-------------------------------------------------------
00535     // Write one element type at once in order to minimize memory usage (PAL19276)
00536 
00537     const SMDS_MeshInfo& nbElemInfo = myMesh->GetMeshInfo();
00538 
00539     // poly elements are not supported by med-2.1
00540     bool polyTypesSupported = myMed->CrPolygoneInfo(aMeshInfo,eMAILLE,ePOLYGONE,0,0);
00541     TInt nbPolygonNodes = 0, nbPolyhedronNodes = 0, nbPolyhedronFaces = 0;
00542 
00543     // collect info on all geom types
00544 
00545     list< TElemTypeData > aTElemTypeDatas;
00546 
00547     EEntiteMaillage anEntity = eMAILLE;
00548 #ifdef _ELEMENTS_BY_DIM_
00549     anEntity = eNOEUD_ELEMENT;
00550 #endif
00551     aTElemTypeDatas.push_back(TElemTypeData(anEntity,
00552                                             ePOINT1,
00553                                             nbElemInfo.Nb0DElements(),
00554                                             SMDSAbs_0DElement));
00555 #ifdef _ELEMENTS_BY_DIM_
00556     anEntity = eARETE;
00557 #endif
00558     aTElemTypeDatas.push_back( TElemTypeData(anEntity,
00559                                             eSEG2,
00560                                             nbElemInfo.NbEdges( ORDER_LINEAR ),
00561                                             SMDSAbs_Edge));
00562     aTElemTypeDatas.push_back( TElemTypeData(anEntity,
00563                                             eSEG3,
00564                                             nbElemInfo.NbEdges( ORDER_QUADRATIC ),
00565                                             SMDSAbs_Edge));
00566 #ifdef _ELEMENTS_BY_DIM_
00567     anEntity = eFACE;
00568 #endif
00569     aTElemTypeDatas.push_back( TElemTypeData(anEntity,
00570                                             eTRIA3,
00571                                             nbElemInfo.NbTriangles( ORDER_LINEAR ),
00572                                             SMDSAbs_Face));
00573     aTElemTypeDatas.push_back( TElemTypeData(anEntity,
00574                                             eTRIA6,
00575                                             nbElemInfo.NbTriangles( ORDER_QUADRATIC ),
00576                                             SMDSAbs_Face));
00577     aTElemTypeDatas.push_back( TElemTypeData(anEntity,
00578                                             eQUAD4,
00579                                             nbElemInfo.NbQuadrangles( ORDER_LINEAR ),
00580                                             SMDSAbs_Face));
00581     aTElemTypeDatas.push_back( TElemTypeData(anEntity,
00582                                             eQUAD8,
00583                                             nbElemInfo.NbQuadrangles( ORDER_QUADRATIC ),
00584                                             SMDSAbs_Face));
00585     if ( polyTypesSupported ) {
00586       aTElemTypeDatas.push_back( TElemTypeData(anEntity,
00587                                                ePOLYGONE,
00588                                                nbElemInfo.NbPolygons(),
00589                                                SMDSAbs_Face));
00590       // we need one more loop on poly elements to count nb of their nodes
00591       aTElemTypeDatas.push_back( TElemTypeData(anEntity,
00592                                                ePOLYGONE,
00593                                                nbElemInfo.NbPolygons(),
00594                                                SMDSAbs_Face));
00595     }
00596 #ifdef _ELEMENTS_BY_DIM_
00597     anEntity = eMAILLE;
00598 #endif
00599     aTElemTypeDatas.push_back( TElemTypeData(anEntity,
00600                                             eTETRA4,
00601                                             nbElemInfo.NbTetras( ORDER_LINEAR ),
00602                                             SMDSAbs_Volume));
00603     aTElemTypeDatas.push_back( TElemTypeData(anEntity,
00604                                             eTETRA10,
00605                                             nbElemInfo.NbTetras( ORDER_QUADRATIC ),
00606                                             SMDSAbs_Volume));
00607     aTElemTypeDatas.push_back( TElemTypeData(anEntity,
00608                                             ePYRA5,
00609                                             nbElemInfo.NbPyramids( ORDER_LINEAR ),
00610                                             SMDSAbs_Volume));
00611     aTElemTypeDatas.push_back( TElemTypeData(anEntity,
00612                                             ePYRA13,
00613                                             nbElemInfo.NbPyramids( ORDER_QUADRATIC ),
00614                                             SMDSAbs_Volume));
00615     aTElemTypeDatas.push_back( TElemTypeData(anEntity,
00616                                             ePENTA6,
00617                                             nbElemInfo.NbPrisms( ORDER_LINEAR ),
00618                                             SMDSAbs_Volume));
00619     aTElemTypeDatas.push_back( TElemTypeData(anEntity,
00620                                              ePENTA15,
00621                                              nbElemInfo.NbPrisms( ORDER_QUADRATIC ),
00622                                              SMDSAbs_Volume));
00623     aTElemTypeDatas.push_back( TElemTypeData(anEntity,
00624                                              eHEXA8,
00625                                              nbElemInfo.NbHexas( ORDER_LINEAR ),
00626                                              SMDSAbs_Volume));
00627     aTElemTypeDatas.push_back( TElemTypeData(anEntity,
00628                                              eHEXA20,
00629                                              nbElemInfo.NbHexas( ORDER_QUADRATIC ),
00630                                              SMDSAbs_Volume));
00631     if ( polyTypesSupported ) {
00632       //MESSAGE("polyTypesSupported");
00633       aTElemTypeDatas.push_back( TElemTypeData(anEntity,
00634                                                ePOLYEDRE,
00635                                                nbElemInfo.NbPolyhedrons(),
00636                                                SMDSAbs_Volume));
00637       // we need one more loop on poly elements to count nb of their nodes
00638       aTElemTypeDatas.push_back( TElemTypeData(anEntity,
00639                                                ePOLYEDRE,
00640                                                nbElemInfo.NbPolyhedrons(),
00641                                                SMDSAbs_Volume));
00642     }
00643 
00644     vector< bool > isElemFamMapBuilt( SMDSAbs_NbElementTypes, false );
00645 
00646     // loop on all geom types of elements
00647 
00648     list< TElemTypeData >::iterator aElemTypeData = aTElemTypeDatas.begin();
00649     for ( ; aElemTypeData != aTElemTypeDatas.end(); ++aElemTypeData )
00650     {
00651       if ( aElemTypeData->_nbElems == 0 )
00652         continue;
00653 
00654       // iterator on elements of a current type
00655       PElemIterator elemIterator;
00656       int defaultFamilyId = 0;
00657       switch ( aElemTypeData->_smdsType ) {
00658       case SMDSAbs_0DElement:
00659         elemIterator = PElemIterator( new T0DElementIterator( myMesh->elements0dIterator() ));
00660         defaultFamilyId = my0DElementsDefaultFamilyId;
00661         break;
00662       case SMDSAbs_Edge:
00663         elemIterator = PElemIterator( new TEdgeIterator( myMesh->edgesIterator() ));
00664         defaultFamilyId = myEdgesDefaultFamilyId;
00665         break;
00666       case SMDSAbs_Face:
00667         elemIterator = PElemIterator( new TFaceIterator( myMesh->facesIterator() ));
00668         defaultFamilyId = myFacesDefaultFamilyId;
00669         break;
00670       case SMDSAbs_Volume:
00671         elemIterator = PElemIterator( new TVolumeIterator( myMesh->volumesIterator() ));
00672         defaultFamilyId = myVolumesDefaultFamilyId;
00673         break;
00674       default:
00675         continue;
00676       }
00677       int iElem = 0;
00678 
00679       //cout << " Treat type " << aElemTypeData->_geomType << " nb = " <<aElemTypeData->_nbElems<< endl;
00680       // Treat POLYGONs
00681       // ---------------
00682       if ( aElemTypeData->_geomType == ePOLYGONE )
00683       {
00684         if ( nbPolygonNodes == 0 ) {
00685           // Count nb of nodes
00686           while ( const SMDS_MeshElement* anElem = elemIterator->next() ) {
00687             if ( anElem->IsPoly() ) {
00688               nbPolygonNodes += anElem->NbNodes();
00689               if ( ++iElem == aElemTypeData->_nbElems )
00690                 break;
00691             }
00692           }
00693         }
00694         else {
00695           // Store in med file
00696           PPolygoneInfo aPolygoneInfo = myMed->CrPolygoneInfo(aMeshInfo,
00697                                                               aElemTypeData->_entity,
00698                                                               aElemTypeData->_geomType,
00699                                                               aElemTypeData->_nbElems,
00700                                                               nbPolygonNodes,
00701                                                               theConnMode, theIsElemNum,
00702                                                               theIsElemNames);
00703           TElemNum & index = *(aPolygoneInfo->myIndex.get());
00704           index[0] = 1;
00705 
00706           while ( const SMDS_MeshElement* anElem = elemIterator->next() )
00707           {
00708             if ( !anElem->IsPoly() )
00709               continue;
00710 
00711             // index
00712             TInt aNbNodes = anElem->NbNodes();
00713             index[ iElem+1 ] = index[ iElem ] + aNbNodes;
00714 
00715             // connectivity
00716             TConnSlice aTConnSlice = aPolygoneInfo->GetConnSlice( iElem );
00717             for(TInt iNode = 0; iNode < aNbNodes; iNode++) {
00718               const SMDS_MeshElement* aNode = anElem->GetNode( iNode );
00719 #ifdef _EDF_NODE_IDS_
00720               aTConnSlice[ iNode ] = aNodeIdMap[aNode->GetID()];
00721 #else
00722               aTConnSlice[ iNode ] = aNode->GetID();
00723 #endif
00724             }
00725             // element number
00726             aPolygoneInfo->SetElemNum( iElem, anElem->GetID() );
00727 
00728             // family number
00729             int famNum = getFamilyId( anElemFamMap, anElem, defaultFamilyId );
00730             aPolygoneInfo->SetFamNum( iElem, famNum );
00731 
00732             if ( ++iElem == aPolygoneInfo->GetNbElem() )
00733               break;
00734           }
00735           //       if(TInt aNbElems = aPolygoneElemNums.size())
00736           //         // add one element in connectivities,
00737           //         // referenced by the last element in indices
00738           //         aPolygoneConn.push_back(0);
00739           //cout << " SetPolygoneInfo(aPolygoneInfo)" << endl;
00740           myMed->SetPolygoneInfo(aPolygoneInfo);
00741         }
00742 
00743       } 
00744 
00745       // Treat POLYEDREs
00746       // ----------------
00747       else if (aElemTypeData->_geomType == ePOLYEDRE )
00748       {
00749         //MESSAGE("_geomType == ePOLYEDRE");
00750         if ( nbPolyhedronNodes == 0 ) {
00751           // Count nb of nodes
00752           while ( const SMDS_MeshElement* anElem = elemIterator->next() ) {
00753               const SMDS_VtkVolume *aPolyedre = dynamic_cast<const SMDS_VtkVolume*>(anElem);
00754               if ( aPolyedre && aPolyedre->IsPoly()) {
00755               nbPolyhedronNodes += aPolyedre->NbNodes();
00756               nbPolyhedronFaces += aPolyedre->NbFaces();
00757               if ( ++iElem == aElemTypeData->_nbElems )
00758                 break;
00759             }
00760           }
00761           //MESSAGE("nbPolyhedronNodes=" << nbPolyhedronNodes);
00762           //MESSAGE("nbPolyhedronFaces=" << nbPolyhedronFaces);
00763           //MESSAGE("_nbElems="<< aElemTypeData->_nbElems);
00764         }
00765         else {
00766           // Store in med file
00767           PPolyedreInfo aPolyhInfo = myMed->CrPolyedreInfo(aMeshInfo,
00768                                                            aElemTypeData->_entity,
00769                                                            aElemTypeData->_geomType,
00770                                                            aElemTypeData->_nbElems,
00771                                                            nbPolyhedronFaces+1,
00772                                                            nbPolyhedronNodes,
00773                                                            theConnMode,
00774                                                            theIsElemNum,
00775                                                            theIsElemNames);
00776           TElemNum & index = *(aPolyhInfo->myIndex.get());
00777           TElemNum & faces = *(aPolyhInfo->myFaces.get());
00778           TElemNum & conn  = *(aPolyhInfo->myConn.get());
00779           index[0] = 1;
00780           faces[0] = 1;
00781 
00782           TInt iFace = 0, iNode = 0;
00783           while ( const SMDS_MeshElement* anElem = elemIterator->next() )
00784           {
00785             const SMDS_VtkVolume *aPolyedre = dynamic_cast<const SMDS_VtkVolume*>(anElem);
00786             if ( !aPolyedre )
00787               continue;
00788             if ( !aPolyedre->IsPoly() )
00789               continue;
00790             //MESSAGE("index[" << iElem << "]=" << index[iElem] << " iElem=" << iElem);
00791             // index
00792             TInt aNbFaces = aPolyedre->NbFaces();
00793             index[ iElem+1 ] = index[ iElem ] + aNbFaces;
00794             //MESSAGE("index[" << iElem+1 << "]=" << index[iElem+1] << " iElem=" << iElem);
00795 
00796             // face index
00797             for (TInt f = 1; f <= aNbFaces; ++f, ++iFace ) {
00798               int aNbFaceNodes = aPolyedre->NbFaceNodes( f );
00799               faces[ iFace+1 ] = faces[ iFace ] + aNbFaceNodes;
00800               //MESSAGE("faces[" << iFace+1 << "]=" << faces[iFace+1] << " iFace=" << iFace);
00801             }
00802             // connectivity
00803             SMDS_ElemIteratorPtr nodeIt = anElem->nodesIterator();
00804             while ( nodeIt->more() ) {
00805               const SMDS_MeshElement* aNode = nodeIt->next();
00806 #ifdef _EDF_NODE_IDS_
00807               conn[ iNode ] = aNodeIdMap[aNode->GetID()];
00808               //MESSAGE("conn["<< iNode << "]=" << conn[iNode] << " aNode->GetID()=" << aNode->GetID());
00809 #else
00810               conn[ iNode ] = aNode->GetID();
00811               //MESSAGE("conn["<< iNode << "]=" << conn[iNode]);
00812 #endif
00813               ++iNode;
00814             }
00815             // element number
00816             aPolyhInfo->SetElemNum( iElem, anElem->GetID() );
00817 
00818             // family number
00819             int famNum = getFamilyId( anElemFamMap, anElem, defaultFamilyId );
00820             aPolyhInfo->SetFamNum( iElem, famNum );
00821 
00822             if ( ++iElem == aPolyhInfo->GetNbElem() )
00823               break;
00824           }
00825           //cout << " SetPolyedreInfo(aPolyhInfo )" << endl;
00826           myMed->SetPolyedreInfo(aPolyhInfo);
00827         }
00828       } // if (aElemTypeData->_geomType == ePOLYEDRE )
00829 
00830       else
00831       {
00832         // Treat standard types
00833         // ---------------------
00834 
00835         // allocate data arrays
00836         PCellInfo aCellInfo = myMed->CrCellInfo( aMeshInfo,
00837                                                  aElemTypeData->_entity,
00838                                                  aElemTypeData->_geomType,
00839                                                  aElemTypeData->_nbElems,
00840                                                  theConnMode,
00841                                                  theIsElemNum,
00842                                                  theIsElemNames);
00843         // build map of family numbers for this type
00844         if ( !isElemFamMapBuilt[ aElemTypeData->_smdsType ])
00845         {
00846           //cout << " fillElemFamilyMap()" << endl;
00847           fillElemFamilyMap( anElemFamMap, aFamilies, aElemTypeData->_smdsType );
00848           isElemFamMapBuilt[ aElemTypeData->_smdsType ] = true;
00849         }
00850 
00851         TInt aNbNodes = MED::GetNbNodes(aElemTypeData->_geomType);
00852         while ( const SMDS_MeshElement* anElem = elemIterator->next() )
00853         {
00854           if ( anElem->NbNodes() != aNbNodes || anElem->IsPoly() )
00855             continue; // other geometry
00856 
00857           // connectivity
00858           TConnSlice aTConnSlice = aCellInfo->GetConnSlice( iElem );
00859           for (TInt iNode = 0; iNode < aNbNodes; iNode++) {
00860             const SMDS_MeshElement* aNode = anElem->GetNode( iNode );
00861 #ifdef _EDF_NODE_IDS_
00862             aTConnSlice[ iNode ] = aNodeIdMap[aNode->GetID()];
00863 #else
00864             aTConnSlice[ iNode ] = aNode->GetID();
00865 #endif
00866           }
00867           // element number
00868           aCellInfo->SetElemNum( iElem, anElem->GetID() );
00869 
00870           // family number
00871           int famNum = getFamilyId( anElemFamMap, anElem, defaultFamilyId );
00872           aCellInfo->SetFamNum( iElem, famNum );
00873 
00874           if ( ++iElem == aCellInfo->GetNbElem() )
00875             break;
00876         }
00877         // store data in a file
00878         //cout << " SetCellInfo(aCellInfo)" << endl;
00879         myMed->SetCellInfo(aCellInfo);
00880       }
00881 
00882     } // loop on geom types
00883 
00884 
00885   }
00886   catch(const std::exception& exc) {
00887     INFOS("The following exception was caught:\n\t"<<exc.what());
00888     throw;
00889   }
00890   catch(...) {
00891     INFOS("Unknown exception was caught !!!");
00892     throw;
00893   }
00894 
00895   myMeshId = -1;
00896   myGroups.clear();
00897   mySubMeshes.clear();
00898   return aResult;
00899 }
Copyright © 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
Copyright © 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS