Salome HOME
PAL10196. Rename GetGroupNames() -> GetGroupNamesAndTypes(), add checkFamilyId()
[modules/smesh.git] / src / DriverMED / DriverMED_R_SMESHDS_Mesh.cxx
index 5ae85bd8b46e8e0b4f6140f96d5759e2bfca8fef..8388327d91af7d64048b6ee04b50f72f003a7606 100644 (file)
 
 #include "DriverMED_R_SMESHDS_Mesh.h"
 #include "DriverMED_R_SMDS_Mesh.h"
+#include "SMESHDS_Mesh.hxx"
 #include "utilities.h"
 
 #include "DriverMED_Family.h"
 
 #include "SMESHDS_Group.hxx"
 
-#include "MEDA_Wrapper.hxx"
+#include "MED_Factory.hxx"
 #include "MED_Utilities.hxx"
 
 #include <stdlib.h>
 
-#define _EDF_NODE_IDS_
-
-DriverMED_R_SMESHDS_Mesh::DriverMED_R_SMESHDS_Mesh()
-     :
-       myMesh (NULL),
-       myFile (""),
-       myFileId (-1),
-       myMeshId (-1)
-{
-}
-
-DriverMED_R_SMESHDS_Mesh::~DriverMED_R_SMESHDS_Mesh()
-{
-//  map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
-//  for (; aFamsIter != myFamilies.end(); aFamsIter++)
-//  {
-//    delete (*aFamsIter).second;
-//  }
-}
-
-void DriverMED_R_SMESHDS_Mesh::SetMesh(SMDS_Mesh * aMesh)
-{
-  myMesh = aMesh;
-}
-
-void DriverMED_R_SMESHDS_Mesh::SetFile(string aFile)
-{
-  myFile = aFile;
-}
+#ifdef _DEBUG_
+static int MYDEBUG = 0;
+#else
+static int MYDEBUG = 0;
+#endif
 
-void DriverMED_R_SMESHDS_Mesh::SetFileId(med_idt aFileId)
-{
-  myFileId = aFileId;
-}
+#define _EDF_NODE_IDS_
 
-void DriverMED_R_SMESHDS_Mesh::SetMeshId(int aMeshId)
-{
-  myMeshId = aMeshId;
-}
+using namespace MED;
 
 void DriverMED_R_SMESHDS_Mesh::SetMeshName(string theMeshName)
 {
   myMeshName = theMeshName;
 }
 
-void DriverMED_R_SMESHDS_Mesh::Read()
-{
-
-  string myClass = string("SMDS_Mesh");
-  string myExtension = string("MED");
-
-  DriverMED_R_SMDS_Mesh *myReader = new DriverMED_R_SMDS_Mesh;
-
-  myReader->SetMesh(myMesh);
-  myReader->SetMeshId(myMeshId);
-  myReader->SetFile(myFile);
-  myReader->SetFileId(-1);
-
-  myReader->Read();
-}
-
-void DriverMED_R_SMESHDS_Mesh::Add()
-{
-  string myClass = string("SMDS_Mesh");
-  string myExtension = string("MED");
-
-  DriverMED_R_SMDS_Mesh *myReader = new DriverMED_R_SMDS_Mesh;
-
-  myReader->SetMesh(myMesh);
-  myReader->SetMeshId(myMeshId);
-
-  SCRUTE(myFileId);
-  myReader->SetFileId(myFileId);
-
-  myReader->Read();
-}
-
-
 static const SMDS_MeshNode* 
-FindNode(const SMDS_Mesh* theMesh, med_int theId){
+FindNode(const SMDS_Mesh* theMesh, TInt theId){
   const SMDS_MeshNode* aNode = theMesh->FindNode(theId);
   if(aNode) return aNode;
   EXCEPTION(runtime_error,"SMDS_Mesh::FindNode - cannot find a SMDS_MeshNode for ID = "<<theId);
@@ -124,15 +62,15 @@ FindNode(const SMDS_Mesh* theMesh, med_int theId){
 
 
 enum ECoordName{eX, eY, eZ, eNone};
-typedef med_float (*TGetCoord)(MEDA::PNodeInfo&, med_int);
+typedef TFloat (*TGetCoord)(MED::PNodeInfo&, TInt);
 
 template<ECoordName TheCoordId>
-med_float GetCoord(MEDA::PNodeInfo& thePNodeInfo, med_int theElemId){
+TFloat GetCoord(MED::PNodeInfo& thePNodeInfo, TInt theElemId){
   return thePNodeInfo->GetNodeCoord(theElemId,TheCoordId);
 }
 
 template<>
-med_float GetCoord<eNone>(MEDA::PNodeInfo& thePNodeInfo, med_int theElemId){
+TFloat GetCoord<eNone>(MED::PNodeInfo& thePNodeInfo, TInt theElemId){
   return 0.0;
 }
 
@@ -183,38 +121,36 @@ static TGetCoord aZGetCoord[3] = {
 
 
 class TCoordHelper{
-  MEDA::PNodeInfo myPNodeInfo;
+  MED::PNodeInfo myPNodeInfo;
   TGetCoord* myGetCoord;
 public:
-  TCoordHelper(const MEDA::PNodeInfo& thePNodeInfo,
+  TCoordHelper(const MED::PNodeInfo& thePNodeInfo,
               TGetCoord* theGetCoord):
     myPNodeInfo(thePNodeInfo),
     myGetCoord(theGetCoord)
   {}
   virtual ~TCoordHelper(){}
-  med_float GetCoord(med_int theElemId, med_int theCoodId){
+  TFloat GetCoord(TInt theElemId, TInt theCoodId){
     return (*myGetCoord[theCoodId])(myPNodeInfo,theElemId);
   }
 };
 typedef boost::shared_ptr<TCoordHelper> TCoordHelperPtr;
 
 
-DriverMED_R_SMESHDS_Mesh::ReadStatus DriverMED_R_SMESHDS_Mesh::ReadMySelf()
+Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform()
 {
-  ReadStatus result = DRS_FAIL;
+  Status aResult = DRS_FAIL;
   try{
-    using namespace MEDA;
-
     myFamilies.clear();
-    MESSAGE("ReadMySelf - myFile : "<<myFile);
-    TWrapper aMed(myFile);
+    if(MYDEBUG) MESSAGE("Perform - myFile : "<<myFile);
+    PWrapper aMed = CrWrapper(myFile);
 
-    result = DRS_EMPTY;
-    if(med_int aNbMeshes = aMed.GetNbMeshes()){
+    aResult = DRS_EMPTY;
+    if(TInt aNbMeshes = aMed->GetNbMeshes()){
       for(int iMesh = 0; iMesh < aNbMeshes; iMesh++){
        // Reading the MED mesh
        //---------------------
-       PMeshInfo aMeshInfo = aMed.GetMeshInfo(iMesh);
+       PMeshInfo aMeshInfo = aMed->GetPMeshInfo(iMesh+1);
         string aMeshName;
         if (myMeshId != -1) {
           ostringstream aMeshNameStr;
@@ -223,40 +159,45 @@ DriverMED_R_SMESHDS_Mesh::ReadStatus DriverMED_R_SMESHDS_Mesh::ReadMySelf()
         } else {
           aMeshName = myMeshName;
         }
-       MESSAGE("ReadMySelf - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
+       if(MYDEBUG) MESSAGE("Perform - aMeshName : "<<aMeshName<<"; "<<aMeshInfo->GetName());
        if(aMeshName != aMeshInfo->GetName()) continue;
-        result = DRS_OK;
-
+        aResult = DRS_OK;
+       //TInt aMeshDim = aMeshInfo->GetDim();
+       
         // Reading MED families to the temporary structure
        //------------------------------------------------
-        med_int aNbFams = aMed.GetNbFamilies(aMeshInfo);
-        MESSAGE("Read " << aNbFams << " families");
-        for (med_int iFam = 0; iFam < aNbFams; iFam++) {
-          PFamilyInfo aFamilyInfo = aMed.GetFamilyInfo(aMeshInfo, iFam);
-          med_int aFamId = aFamilyInfo->GetId();
-          MESSAGE("Family " << aFamId << " :");
-
+       TErr anErr;
+       TInt aNbFams = aMed->GetNbFamilies(aMeshInfo);
+        if(MYDEBUG) MESSAGE("Read " << aNbFams << " families");
+        for (TInt iFam = 0; iFam < aNbFams; iFam++) {
+         PFamilyInfo aFamilyInfo = aMed->GetPFamilyInfo(aMeshInfo,iFam+1,&anErr);
+         if(anErr >= 0){
+           TInt aFamId = aFamilyInfo->GetId();
+           if(MYDEBUG) MESSAGE("Family " << aFamId << " :");
+           
             DriverMED_FamilyPtr aFamily (new DriverMED_Family);
-
-            med_int aNbGrp = aFamilyInfo->GetNbGroup();
-            MESSAGE("belong to " << aNbGrp << " groups");
-            for (med_int iGr = 0; iGr < aNbGrp; iGr++) {
+           
+            TInt aNbGrp = aFamilyInfo->GetNbGroup();
+            if(MYDEBUG) MESSAGE("belong to " << aNbGrp << " groups");
+            for (TInt iGr = 0; iGr < aNbGrp; iGr++) {
               string aGroupName = aFamilyInfo->GetGroupName(iGr);
-              MESSAGE(aGroupName);
+              if(MYDEBUG) MESSAGE(aGroupName);
               aFamily->AddGroupName(aGroupName);
             }
+            aFamily->SetId( aFamId );
             myFamilies[aFamId] = aFamily;
+         }
         }
 
         // Reading MED nodes to the corresponding SMDS structure
        //------------------------------------------------------
-       PNodeInfo aNodeInfo = aMed.GetNodeInfo(aMeshInfo);
+       PNodeInfo aNodeInfo = aMed->GetPNodeInfo(aMeshInfo);
 
        TCoordHelperPtr aCoordHelperPtr;
        {
-         med_int aMeshDimension = aMeshInfo->GetDim();
+         TInt aMeshDimension = aMeshInfo->GetDim();
          bool anIsDimPresent[3] = {false, false, false};
-          for(med_int iDim = 0; iDim < aMeshDimension; iDim++){
+          for(TInt iDim = 0; iDim < aMeshDimension; iDim++){
            string aDimName = aNodeInfo->GetCoordName(iDim);
            if(aDimName == "x" || aDimName == "X")
              anIsDimPresent[eX] = true;
@@ -288,12 +229,13 @@ DriverMED_R_SMESHDS_Mesh::ReadStatus DriverMED_R_SMESHDS_Mesh::ReadMySelf()
          }
        }
 
-       med_booleen anIsNodeNum = aNodeInfo->IsElemNum();
-       med_int aNbElems = aNodeInfo->GetNbElem();
-       MESSAGE("ReadMySelf - aNodeInfo->GetNbElem() = "<<aNbElems<<"; anIsNodeNum = "<<anIsNodeNum);
-        for(med_int iElem = 0; iElem < aNbElems; iElem++){
+       EBooleen anIsNodeNum = aNodeInfo->IsElemNum();
+       TInt aNbElems = aNodeInfo->GetNbElem();
+       if(MYDEBUG) MESSAGE("Perform - aNodeInfo->GetNbElem() = "<<aNbElems<<"; anIsNodeNum = "<<anIsNodeNum);
+        DriverMED_FamilyPtr aFamily = myFamilies.begin()->second;
+        for(TInt iElem = 0; iElem < aNbElems; iElem++){
           double aCoords[3] = {0.0, 0.0, 0.0};
-          for(med_int iDim = 0; iDim < 3; iDim++)
+          for(TInt iDim = 0; iDim < 3; iDim++)
             aCoords[iDim] = aCoordHelperPtr->GetCoord(iElem,iDim);
           const SMDS_MeshNode* aNode;
           if(anIsNodeNum) {
@@ -306,92 +248,278 @@ DriverMED_R_SMESHDS_Mesh::ReadStatus DriverMED_R_SMESHDS_Mesh::ReadMySelf()
           //cout<<aNode->GetID()<<": "<<aNode->X()<<", "<<aNode->Y()<<", "<<aNode->Z()<<endl;
 
           // Save reference to this node from its family
-          med_int aFamNum = aNodeInfo->GetFamNum(iElem);
-          if (myFamilies.find(aFamNum) != myFamilies.end())
+          TInt aFamNum = aNodeInfo->GetFamNum(iElem);
+          if ( checkFamilyID ( aFamily, aFamNum ))
           {
-            myFamilies[aFamNum]->AddElement(aNode);
-            myFamilies[aFamNum]->SetType(SMDSAbs_Node);
+            aFamily->AddElement(aNode);
+            aFamily->SetType(SMDSAbs_Node);
           }
         }
 
        // Reading pre information about all MED cells
        //--------------------------------------------
         bool takeNumbers = true;  // initially we trust the numbers from file
-       MED::TEntityInfo aEntityInfo = aMed.GetEntityInfo(aMeshInfo);
+       MED::TEntityInfo aEntityInfo = aMed->GetEntityInfo(aMeshInfo);
        MED::TEntityInfo::iterator anEntityIter = aEntityInfo.begin();
        for(; anEntityIter != aEntityInfo.end(); anEntityIter++){
-         const med_entite_maillage& anEntity = anEntityIter->first;
-         if(anEntity == MED_NOEUD) continue;
+         const EEntiteMaillage& anEntity = anEntityIter->first;
+         if(anEntity == eNOEUD) continue;
          // Reading MED cells to the corresponding SMDS structure
          //------------------------------------------------------
          const MED::TGeom& aTGeom = anEntityIter->second;
          MED::TGeom::const_iterator anTGeomIter = aTGeom.begin();
          for(; anTGeomIter != aTGeom.end(); anTGeomIter++){
-           const med_geometrie_element& aGeom = anTGeomIter->first;
-           if(aGeom == MED_POINT1) continue;
-           PCellInfo aCellInfo = aMed.GetCellInfo(aMeshInfo,anEntity,aGeom);
-           med_booleen anIsElemNum = takeNumbers ? aCellInfo->IsElemNum() : MED_FAUX;
-           med_int aNbElems = aCellInfo->GetNbElem();
-           MESSAGE("ReadMySelf - anEntity = "<<anEntity<<"; anIsElemNum = "<<anIsElemNum);
-           MESSAGE("ReadMySelf - aGeom = "<<aGeom<<"; aNbElems = "<<aNbElems);
+           const EGeometrieElement& aGeom = anTGeomIter->first;
+
+           if (aGeom == ePOINT1) {
+              continue;
+
+            } else if (aGeom == ePOLYGONE) {
+              PPolygoneInfo aPolygoneInfo = aMed->GetPPolygoneInfo(aMeshInfo,anEntity,aGeom);
+              EBooleen anIsElemNum = takeNumbers ? aPolygoneInfo->IsElemNum() : eFAUX;
+
+              TElemNum aConn  = aPolygoneInfo->GetConnectivite();
+              TElemNum aIndex = aPolygoneInfo->GetIndex();
+
+              TInt nbPolygons = aPolygoneInfo->GetNbElem();
+
+              for (TInt iPG = 0; iPG < nbPolygons; iPG++) {
+                // get nodes
+                TInt aCurrPG_FirstNodeIndex = aIndex[iPG] - 1;
+                int nbNodes = aPolygoneInfo->GetNbConn(iPG);
+                std::vector<int> nodes_ids (nbNodes);
+                //for (TInt inode = 0; inode < nbNodes; inode++) {
+                //  nodes_ids[inode] = aConn[aCurrPG_FirstNodeIndex + inode];
+                //}
+#ifdef _EDF_NODE_IDS_
+               if (anIsNodeNum) {
+                 for (TInt inode = 0; inode < nbNodes; inode++) {
+                   nodes_ids[inode] = aNodeInfo->GetElemNum(aConn[aCurrPG_FirstNodeIndex + inode] - 1);
+                 }
+               } else {
+                 for (TInt inode = 0; inode < nbNodes; inode++) {
+                   nodes_ids[inode] = aConn[aCurrPG_FirstNodeIndex + inode];
+                 }
+               }
+#else
+               for (TInt inode = 0; inode < nbNodes; inode++) {
+                 nodes_ids[inode] = aConn[aCurrPG_FirstNodeIndex + inode];
+               }
+#endif
+
+                bool isRenum = false;
+                SMDS_MeshElement* anElement = NULL;
+                TInt aFamNum = aPolygoneInfo->GetFamNum(iPG);
+
+                try {
+                  if (anIsElemNum) {
+                    anElement = myMesh->AddPolygonalFaceWithID
+                      (nodes_ids, aPolygoneInfo->GetElemNum(iPG));
+                  }
+                  if (!anElement) {
+                    std::vector<const SMDS_MeshNode*> nodes (nbNodes);
+                    for (int inode = 0; inode < nbNodes; inode++) {
+                      nodes[inode] = FindNode(myMesh, nodes_ids[inode]);
+                    }
+                    anElement = myMesh->AddPolygonalFace(nodes);
+                    isRenum = anIsElemNum;
+                  }
+                } catch (const std::exception& exc) {
+                  aResult = DRS_FAIL;
+                } catch (...) {
+                  aResult = DRS_FAIL;
+                }
+
+                if (!anElement) {
+                  aResult = DRS_WARN_SKIP_ELEM;
+                } else {
+                  if (isRenum) {
+                    anIsElemNum = eFAUX;
+                    takeNumbers = false;
+                    if (aResult < DRS_WARN_RENUMBER)
+                      aResult = DRS_WARN_RENUMBER;
+                  }
+                  if ( checkFamilyID ( aFamily, aFamNum ))
+                  {
+                    // Save reference to this element from its family
+                    aFamily->AddElement(anElement);
+                    aFamily->SetType(anElement->GetType());
+                  }
+                }
+              } // for (TInt iPG = 0; iPG < nbPolygons; iPG++)
+              continue;
+
+            } else if (aGeom == ePOLYEDRE) {
+              PPolyedreInfo aPolyedreInfo = aMed->GetPPolyedreInfo(aMeshInfo,anEntity,aGeom);
+              EBooleen anIsElemNum = takeNumbers ? aPolyedreInfo->IsElemNum() : eFAUX;
+
+              TElemNum aConn       = aPolyedreInfo->GetConnectivite();
+              TElemNum aFacesIndex = aPolyedreInfo->GetFacesIndex();
+              TElemNum aIndex      = aPolyedreInfo->GetIndex();
+
+              TInt nbPolyedres = aPolyedreInfo->GetNbElem();
+
+              for (int iPE = 0; iPE < nbPolyedres; iPE++) {
+                // get faces
+                int aCurrPE_FirstFaceIndex = aIndex[iPE] - 1;
+                int aNextPE_FirstFaceIndex = aIndex[iPE + 1] - 1;
+                int nbFaces = aNextPE_FirstFaceIndex - aCurrPE_FirstFaceIndex;
+                std::vector<int> quantities (nbFaces);
+                for (int iFa = 0; iFa < nbFaces; iFa++) {
+                  int aCurrFace_FirstNodeIndex = aFacesIndex[aCurrPE_FirstFaceIndex + iFa] - 1;
+                  int aNextFace_FirstNodeIndex = aFacesIndex[aCurrPE_FirstFaceIndex + iFa + 1] - 1;
+
+                  int nbNodes = aNextFace_FirstNodeIndex - aCurrFace_FirstNodeIndex;
+                  quantities[iFa] = nbNodes;
+                }
+
+                // get nodes
+                int aCurrPE_FirstNodeIndex = aFacesIndex[aCurrPE_FirstFaceIndex] - 1;
+                int nbPENodes = aPolyedreInfo->GetNbConn(iPE);
+                std::vector<int> nodes_ids (nbPENodes);
+                //for (int inode = 0; inode < nbPENodes; inode++) {
+                //  nodes_ids[inode] = aConn[aCurrPE_FirstNodeIndex + inode];
+                //}
+#ifdef _EDF_NODE_IDS_
+               if (anIsNodeNum) {
+                 for (int inode = 0; inode < nbPENodes; inode++) {
+                   nodes_ids[inode] = aNodeInfo->GetElemNum(aConn[aCurrPE_FirstNodeIndex + inode] - 1);
+                 }
+               } else {
+                 for (int inode = 0; inode < nbPENodes; inode++) {
+                   nodes_ids[inode] = aConn[aCurrPE_FirstNodeIndex + inode];
+                 }
+               }
+#else
+               for (int inode = 0; inode < nbPENodes; inode++) {
+                 nodes_ids[inode] = aConn[aCurrPE_FirstNodeIndex + inode];
+               }
+#endif
+
+                bool isRenum = false;
+                SMDS_MeshElement* anElement = NULL;
+                TInt aFamNum = aPolyedreInfo->GetFamNum(iPE);
+
+                try {
+                  if (anIsElemNum) {
+                    anElement = myMesh->AddPolyhedralVolumeWithID
+                      (nodes_ids, quantities, aPolyedreInfo->GetElemNum(iPE));
+                  }
+                  if (!anElement) {
+                    std::vector<const SMDS_MeshNode*> nodes (nbPENodes);
+                    for (int inode = 0; inode < nbPENodes; inode++) {
+                      nodes[inode] = FindNode(myMesh, nodes_ids[inode]);
+                    }
+                    anElement = myMesh->AddPolyhedralVolume(nodes, quantities);
+                    isRenum = anIsElemNum;
+                  }
+                } catch (const std::exception& exc) {
+                  aResult = DRS_FAIL;
+                } catch (...) {
+                  aResult = DRS_FAIL;
+                }
+
+                if (!anElement) {
+                  aResult = DRS_WARN_SKIP_ELEM;
+                } else {
+                  if (isRenum) {
+                    anIsElemNum = eFAUX;
+                    takeNumbers = false;
+                    if (aResult < DRS_WARN_RENUMBER)
+                      aResult = DRS_WARN_RENUMBER;
+                  }
+                  if ( checkFamilyID ( aFamily, aFamNum ))
+                  {
+                    // Save reference to this element from its family
+                    aFamily->AddElement(anElement);
+                    aFamily->SetType(anElement->GetType());
+                  }
+                }
+              } // for (int iPE = 0; iPE < nbPolyedres; iPE++)
+              continue;
+
+            } else {
+            }
+
+           PCellInfo aCellInfo = aMed->GetPCellInfo(aMeshInfo,anEntity,aGeom);
+           EBooleen anIsElemNum = takeNumbers ? aCellInfo->IsElemNum() : eFAUX;
+           TInt aNbElems = aCellInfo->GetNbElem();
+           if(MYDEBUG) MESSAGE("Perform - anEntity = "<<anEntity<<"; anIsElemNum = "<<anIsElemNum);
+           if(MYDEBUG) MESSAGE("Perform - aGeom = "<<aGeom<<"; aNbElems = "<<aNbElems);
 
            for(int iElem = 0; iElem < aNbElems; iElem++){
-             med_int aNbNodes = -1;
+             TInt aNbNodes = -1;
              switch(aGeom){
-             case MED_SEG2:
-             case MED_SEG3:
+             case eSEG2:
+             case eSEG3:
                aNbNodes = 2;
                break;
-             case MED_TRIA3:
-             case MED_TRIA6:
+             case eTRIA3:
+             case eTRIA6:
                aNbNodes = 3;
                break;
                break;
-             case MED_QUAD4:
-             case MED_QUAD8:
+             case eQUAD4:
+             case eQUAD8:
                aNbNodes = 4;
                 break;
-              case MED_TETRA4:
-             case MED_TETRA10:
+              case eTETRA4:
+             case eTETRA10:
                aNbNodes = 4;
                break;
-             case MED_PYRA5:
-             case MED_PYRA13:
+             case ePYRA5:
+             case ePYRA13:
                aNbNodes = 5;
                break;
-             case MED_PENTA6:
-             case MED_PENTA15:
+             case ePENTA6:
+             case ePENTA15:
                aNbNodes = 6;
                break;
-             case MED_HEXA8:
-             case MED_HEXA20:
+             case eHEXA8:
+             case eHEXA20:
                aNbNodes = 8;
                break;
              }
-             vector<med_int> aNodeIds(aNbNodes);
+             vector<TInt> aNodeIds(aNbNodes);
+             bool anIsValidConnect = false;
+
+             try{
 #ifdef _EDF_NODE_IDS_
-             if(anIsNodeNum) {
-               for(int i = 0; i < aNbNodes; i++){
-                 aNodeIds[i] = aNodeInfo->GetElemNum(aCellInfo->GetConn(iElem,i)-1);
+               if(anIsNodeNum) {
+                 for(int i = 0; i < aNbNodes; i++){
+                   aNodeIds[i] = aNodeInfo->GetElemNum(aCellInfo->GetConn(iElem,i)-1);
+                 }
+               }else{
+                 for(int i = 0; i < aNbNodes; i++){
+                   aNodeIds[i] = aCellInfo->GetConn(iElem,i);
+                 }
                }
-             }else{
+#else
                for(int i = 0; i < aNbNodes; i++){
                  aNodeIds[i] = aCellInfo->GetConn(iElem,i);
                }
-             }
-#else
-             for(int i = 0; i < aNbNodes; i++){
-               aNodeIds[i] = aCellInfo->GetConn(iElem,i);
-             }
 #endif
+               anIsValidConnect = true;
+             }catch(const std::exception& exc){
+               //INFOS("Follow exception was cought:\n\t"<<exc.what());
+               aResult = DRS_FAIL;
+             }catch(...){
+               //INFOS("Unknown exception was cought !!!");
+               aResult = DRS_FAIL;
+             }
+             
+             if(!anIsValidConnect)
+               continue;
 
              bool isRenum = false;
              SMDS_MeshElement* anElement = NULL;
-             med_int aFamNum = aCellInfo->GetFamNum(iElem);
+             TInt aFamNum = aCellInfo->GetFamNum(iElem);
              try{
+                //MESSAGE("Try to create element # " << iElem << " with id = "
+                //        << aCellInfo->GetElemNum(iElem));
                switch(aGeom){
-               case MED_SEG2:
-               case MED_SEG3:
+               case eSEG2:
+               case eSEG3:
                  if(anIsElemNum)
                    anElement = myMesh->AddEdgeWithID(aNodeIds[0],
                                                      aNodeIds[1],
@@ -402,8 +530,8 @@ DriverMED_R_SMESHDS_Mesh::ReadStatus DriverMED_R_SMESHDS_Mesh::ReadMySelf()
                    isRenum = anIsElemNum;
                  }
                  break;
-               case MED_TRIA3:
-               case MED_TRIA6:
+               case eTRIA3:
+               case eTRIA6:
                  aNbNodes = 3;
                  if(anIsElemNum)
                    anElement = myMesh->AddFaceWithID(aNodeIds[0],
@@ -417,8 +545,8 @@ DriverMED_R_SMESHDS_Mesh::ReadStatus DriverMED_R_SMESHDS_Mesh::ReadMySelf()
                    isRenum = anIsElemNum;
                  }
                  break;
-               case MED_QUAD4:
-               case MED_QUAD8:
+               case eQUAD4:
+               case eQUAD8:
                  aNbNodes = 4;
                  // There is some differnce between SMDS and MED
                  if(anIsElemNum)
@@ -435,8 +563,8 @@ DriverMED_R_SMESHDS_Mesh::ReadStatus DriverMED_R_SMESHDS_Mesh::ReadMySelf()
                    isRenum = anIsElemNum;
                  }
                  break;
-               case MED_TETRA4:
-               case MED_TETRA10:
+               case eTETRA4:
+               case eTETRA10:
                  aNbNodes = 4;
                  if(anIsElemNum)
                    anElement = myMesh->AddVolumeWithID(aNodeIds[0],
@@ -452,8 +580,8 @@ DriverMED_R_SMESHDS_Mesh::ReadStatus DriverMED_R_SMESHDS_Mesh::ReadMySelf()
                    isRenum = anIsElemNum;
                  }
                  break;
-               case MED_PYRA5:
-               case MED_PYRA13:
+               case ePYRA5:
+               case ePYRA13:
                  aNbNodes = 5;
                  // There is some differnce between SMDS and MED
                  if(anIsElemNum)
@@ -472,8 +600,8 @@ DriverMED_R_SMESHDS_Mesh::ReadStatus DriverMED_R_SMESHDS_Mesh::ReadMySelf()
                    isRenum = anIsElemNum;
                  }
                  break;
-               case MED_PENTA6:
-               case MED_PENTA15:
+               case ePENTA6:
+               case ePENTA15:
                  aNbNodes = 6;
                  if(anIsElemNum)
                    anElement = myMesh->AddVolumeWithID(aNodeIds[0],
@@ -493,8 +621,8 @@ DriverMED_R_SMESHDS_Mesh::ReadStatus DriverMED_R_SMESHDS_Mesh::ReadMySelf()
                    isRenum = anIsElemNum;
                  }
                  break;
-               case MED_HEXA8:
-               case MED_HEXA20:
+               case eHEXA8:
+               case eHEXA20:
                  aNbNodes = 8;
                  if(anIsElemNum)
                    anElement = myMesh->AddVolumeWithID(aNodeIds[0],
@@ -521,26 +649,27 @@ DriverMED_R_SMESHDS_Mesh::ReadStatus DriverMED_R_SMESHDS_Mesh::ReadMySelf()
                }
              }catch(const std::exception& exc){
                //INFOS("Follow exception was cought:\n\t"<<exc.what());
-               result = DRS_FAIL;
+               aResult = DRS_FAIL;
              }catch(...){
                //INFOS("Unknown exception was cought !!!");
-               result = DRS_FAIL;
+               aResult = DRS_FAIL;
              }
                
               if (!anElement) {
-                result = DRS_WARN_SKIP_ELEM;
+                aResult = DRS_WARN_SKIP_ELEM;
               }
               else {
                 if (isRenum) {
-                  anIsElemNum = MED_FAUX;
+                  anIsElemNum = eFAUX;
                   takeNumbers = false;
-                  if (result < DRS_WARN_RENUMBER)
-                    result = DRS_WARN_RENUMBER;
+                  if (aResult < DRS_WARN_RENUMBER)
+                    aResult = DRS_WARN_RENUMBER;
                 }
-                if (myFamilies.find(aFamNum) != myFamilies.end()) {
+                if ( checkFamilyID ( aFamily, aFamNum ))
+                {
                   // Save reference to this element from its family
-                  myFamilies[aFamNum]->AddElement(anElement);
-                  myFamilies[aFamNum]->SetType(anElement->GetType());
+                  aFamily->AddElement(anElement);
+                  aFamily->SetType(anElement->GetType());
                 }
               }
             }
@@ -551,61 +680,61 @@ DriverMED_R_SMESHDS_Mesh::ReadStatus DriverMED_R_SMESHDS_Mesh::ReadMySelf()
     }
   }catch(const std::exception& exc){
     INFOS("Follow exception was cought:\n\t"<<exc.what());
-    result = DRS_FAIL;
+    aResult = DRS_FAIL;
   }catch(...){
     INFOS("Unknown exception was cought !!!");
-    result = DRS_FAIL;
+    aResult = DRS_FAIL;
   }
-  MESSAGE("ReadMySelf - result status = "<<result);
-  return result;
+  if(MYDEBUG) MESSAGE("Perform - aResult status = "<<aResult);
+  return aResult;
 }
 
-list<string> DriverMED_R_SMESHDS_Mesh::GetMeshNames()
+list<string> DriverMED_R_SMESHDS_Mesh::GetMeshNames(Status& theStatus)
 {
   list<string> aMeshNames;
 
   try {
-    using namespace MEDA;
+    if(MYDEBUG) MESSAGE("GetMeshNames - myFile : " << myFile);
+    theStatus = DRS_OK;
+    PWrapper aMed = CrWrapper(myFile);
 
-    MESSAGE("GetMeshNames - myFile : " << myFile);
-    TWrapper aMed (myFile);
-
-    if (med_int aNbMeshes = aMed.GetNbMeshes()) {
+    if (TInt aNbMeshes = aMed->GetNbMeshes()) {
       for (int iMesh = 0; iMesh < aNbMeshes; iMesh++) {
        // Reading the MED mesh
        //---------------------
-       PMeshInfo aMeshInfo = aMed.GetMeshInfo(iMesh);
+       PMeshInfo aMeshInfo = aMed->GetPMeshInfo(iMesh+1);
        aMeshNames.push_back(aMeshInfo->GetName());
       }
     }
   }catch(const std::exception& exc){
     INFOS("Follow exception was cought:\n\t"<<exc.what());
+    theStatus = DRS_FAIL;
   }catch(...){
     INFOS("Unknown exception was cought !!!");
+    theStatus = DRS_FAIL;
   }
 
   return aMeshNames;
 }
 
-list<string> DriverMED_R_SMESHDS_Mesh::GetGroupNames()
+list<TNameAndType> DriverMED_R_SMESHDS_Mesh::GetGroupNamesAndTypes()
 {
-  list<string> aResult;
-  set<string> aResGroupNames;
+  list<TNameAndType> aResult;
+  set<TNameAndType> aResGroupNames;
 
   map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
   for (; aFamsIter != myFamilies.end(); aFamsIter++)
   {
     DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
     const MED::TStringSet& aGroupNames = aFamily->GetGroupNames();
-    set<string>::iterator aGrNamesIter = aGroupNames.begin();
+    set<string>::const_iterator aGrNamesIter = aGroupNames.begin();
     for (; aGrNamesIter != aGroupNames.end(); aGrNamesIter++)
     {
-      string aName = *aGrNamesIter;
+      TNameAndType aNameAndType = make_pair( *aGrNamesIter, aFamily->GetType() );
       // Check, if this is a Group or SubMesh name
 //if (aName.substr(0, 5) == string("Group")) {
-        if (aResGroupNames.find(aName) == aResGroupNames.end()) {
-          aResGroupNames.insert(aName);
-          aResult.push_back(aName);
+        if ( aResGroupNames.insert( aNameAndType ).second ) {
+          aResult.push_back( aNameAndType );
         }
 //    }
     }
@@ -617,20 +746,24 @@ list<string> DriverMED_R_SMESHDS_Mesh::GetGroupNames()
 void DriverMED_R_SMESHDS_Mesh::GetGroup(SMESHDS_Group* theGroup)
 {
   string aGroupName (theGroup->GetStoreName());
-  MESSAGE("Get Group " << aGroupName);
+  if(MYDEBUG) MESSAGE("Get Group " << aGroupName);
 
   map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
   for (; aFamsIter != myFamilies.end(); aFamsIter++)
   {
     DriverMED_FamilyPtr aFamily = (*aFamsIter).second;
-    if (aFamily->MemberOf(aGroupName))
+    if (aFamily->GetType() == theGroup->GetType() && aFamily->MemberOf(aGroupName))
     {
       const set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
-      set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
+      set<const SMDS_MeshElement *>::const_iterator anElemsIter = anElements.begin();
+      const SMDS_MeshElement * element = 0;
       for (; anElemsIter != anElements.end(); anElemsIter++)
       {
-        theGroup->SMDS_MeshGroup::Add(*anElemsIter);
+        element = *anElemsIter;
+       theGroup->SMDSGroup().Add(element);
       }
+      if ( element )
+        theGroup->SetType( element->GetType() );
     }
   }
 }
@@ -648,7 +781,7 @@ void DriverMED_R_SMESHDS_Mesh::GetSubMesh (SMESHDS_SubMesh* theSubMesh,
     if (aFamily->MemberOf(aName))
     {
       const set<const SMDS_MeshElement *>& anElements = aFamily->GetElements();
-      set<const SMDS_MeshElement *>::iterator anElemsIter = anElements.begin();
+      set<const SMDS_MeshElement *>::const_iterator anElemsIter = anElements.begin();
       if (aFamily->GetType() == SMDSAbs_Node)
       {
         for (; anElemsIter != anElements.end(); anElemsIter++)
@@ -670,10 +803,6 @@ void DriverMED_R_SMESHDS_Mesh::GetSubMesh (SMESHDS_SubMesh* theSubMesh,
 
 void DriverMED_R_SMESHDS_Mesh::CreateAllSubMeshes ()
 {
-  SMESHDS_Mesh* aSMESHDSMesh = dynamic_cast<SMESHDS_Mesh*>(myMesh);
-  if (!aSMESHDSMesh) {
-    EXCEPTION(runtime_error,"Can not cast SMDS_Mesh to SMESHDS_Mesh");
-  }
   map<int, DriverMED_FamilyPtr>::iterator aFamsIter = myFamilies.begin();
   for (; aFamsIter != myFamilies.end(); aFamsIter++)
   {
@@ -693,21 +822,48 @@ void DriverMED_R_SMESHDS_Mesh::CreateAllSubMeshes ()
         {
           for (; anElemsIter != anElements.end(); anElemsIter++)
           {
-            const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>(*anElemsIter);
-            aSMESHDSMesh->SetNodeInVolume(node, Id);
-//            aSMESHDSMesh->SetNodeOnFace(node, Id);
-//            aSMESHDSMesh->SetNodeOnEdge(node, Id);
-//            aSMESHDSMesh->SetNodeOnVertex(node, Id);
+            SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>
+              ( static_cast<const SMDS_MeshNode*>( *anElemsIter ));
+            // find out a shape type
+            TopoDS_Shape aShape = myMesh->IndexToShape( Id );
+            int aShapeType = ( aShape.IsNull() ? -1 : aShape.ShapeType() );
+            switch ( aShapeType ) {
+            case TopAbs_FACE:
+              myMesh->SetNodeOnFace(node, Id); break;
+            case TopAbs_EDGE:
+              myMesh->SetNodeOnEdge(node, Id); break;
+            case TopAbs_VERTEX:
+              myMesh->SetNodeOnVertex(node, Id); break;
+            default:
+              myMesh->SetNodeInVolume(node, Id);
+            }
           }
         }
         else
         {
           for (; anElemsIter != anElements.end(); anElemsIter++)
           {
-            aSMESHDSMesh->SetMeshElementOnShape(*anElemsIter, Id);
+            myMesh->SetMeshElementOnShape(*anElemsIter, Id);
           }
         }
       }
     }
   }
 }
+/*!
+ * \brief Ensure aFamily to have required ID
+ * \param aFamily - a family to check and update
+ * \param anID - an ID aFamily should have
+ * \retval bool  - true if successful
+ */
+bool DriverMED_R_SMESHDS_Mesh::checkFamilyID(DriverMED_FamilyPtr & aFamily, int anID) const
+{
+  if ( !aFamily || aFamily->GetId() != anID ) {
+    map<int, DriverMED_FamilyPtr>::const_iterator i_fam = myFamilies.find(anID);
+    if ( i_fam == myFamilies.end() )
+      return false;
+    aFamily = i_fam->second;
+  }
+  return ( aFamily->GetId() == anID );
+}
+