]> SALOME platform Git repositories - modules/visu.git/commitdiff
Salome HOME
PAL12929 (Impossible to create presentation of group after "import Structure" for...
authoreap <eap@opencascade.com>
Fri, 26 Jan 2007 12:54:47 +0000 (12:54 +0000)
committereap <eap@opencascade.com>
Fri, 26 Jan 2007 12:54:47 +0000 (12:54 +0000)
       Support poly elements

src/VISU_I/VISU_CorbaMedConvertor.cxx

index 0713b49674d08d6150a01c641c42bd741c474244..c21c978cdc5f7a51c71dbd9341cea3f6c138238e 100644 (file)
@@ -33,6 +33,9 @@
 
 #include <boost/tuple/tuple.hpp>
 
+#include "ReceiverFactory.hxx"
+#include "MED_SliceArray.hxx"
+
 using namespace std;
 using namespace VISU;
 
@@ -62,7 +65,7 @@ namespace
 {
   using namespace SALOME_MED;
   
-  const int MED_NBR_GEOMETRIE_MAILLE = 15;
+  const int MED_NBR_GEOMETRIE_MAILLE = 17;
   
   medGeometryElement 
   CELLGEOM[MED_NBR_GEOMETRIE_MAILLE] = {
@@ -80,17 +83,20 @@ namespace
     MED_TETRA10,
     MED_PYRA13,
     MED_PENTA15,
-    MED_HEXA20
+    MED_HEXA20,
+    MED_POLYGON,
+    MED_POLYHEDRA
   };
   
-  const int MED_NBR_GEOMETRIE_FACE = 4;
+  const int MED_NBR_GEOMETRIE_FACE = 5;
   
   medGeometryElement
   FACEGEOM[MED_NBR_GEOMETRIE_FACE] = {
     MED_TRIA3,
     MED_QUAD4,
     MED_TRIA6,
-    MED_QUAD8
+    MED_QUAD8,
+    MED_POLYGON
   };
   
   const int MED_NBR_GEOMETRIE_ARETE = 2;
@@ -169,6 +175,8 @@ namespace
     case MED_PENTA15: return VISU::ePENTA15;
     case MED_PYRA5: return VISU::ePYRA5;
     case MED_PYRA13: return VISU::ePYRA13;
+    case MED_POLYGON: return VISU::ePOLYGONE;
+    case MED_POLYHEDRA: return VISU::ePOLYEDRE;
     }
     return VISU::eNONE;
   }
@@ -194,6 +202,8 @@ namespace
     case VISU::eHEXA20: return MED_HEXA20;
     case VISU::ePENTA15: return MED_PENTA15;
     case VISU::ePYRA13: return MED_PYRA13;
+    case VISU::ePOLYGONE: return MED_POLYGON;
+    case VISU::ePOLYEDRE: return  MED_POLYHEDRA;
     }
     return medGeometryElement(-1);
   }
@@ -211,6 +221,7 @@ namespace
     case VTK_HEXAHEDRON: return MED_HEXA8;
     case VTK_WEDGE: return MED_PENTA6;
     case VTK_PYRAMID: return MED_PYRA5;
+    case VTK_POLYGON: return MED_POLYGON;
     }
     return medGeometryElement(-1);
   }
@@ -263,17 +274,16 @@ namespace
               SALOME_MED::MESH_ptr theMEDMesh,
               const VISU::TEntity& theVEntity)
   {
-    medGeometryElement* aGeomElems;
     theNbCells = theCellsSize = 0;
-    int iGeomEnd = GetEntity2Geom(theVEntity,aGeomElems);
-    const medEntityMesh& aMEntity = VTKEntityToMED(theVEntity);
     if(MYDEBUG) MESSAGE("GetCellsSize - theVEntity = "<<theVEntity);
+    const medEntityMesh& aMEntity = VTKEntityToMED(theVEntity);
+    SALOME_MED::MESH::connectivityInfos_var connInfo=theMEDMesh->getConnectGlobal(aMEntity);
+    int iGeomEnd = connInfo->meshTypes.length();
     for(int iGeom = 0; iGeom < iGeomEnd; iGeom++){
-      medGeometryElement aMEDGeom = aGeomElems[iGeom];
-      int iNumElemEnd = theMEDMesh->getNumberOfElements(aMEntity,aMEDGeom);
+      int iNumElemEnd = connInfo->numberOfElements[iGeom];
       if(iNumElemEnd > 0){
        if(MYDEBUG) MESSAGE("GetCellsSize - iNumElemEnd = "<<iNumElemEnd);
-       theCellsSize += iNumElemEnd*(MEDGeom2NbNodes(aMEDGeom) + 1);
+       theCellsSize += iNumElemEnd + connInfo->nodalConnectivityLength[iGeom];
        theNbCells += iNumElemEnd;
       }
     }
@@ -286,18 +296,16 @@ namespace
               vtkIdType& theCellsSize,
               SALOME_MED::FAMILY_ptr theMEDFamily)
   {
-    medGeometryElement_array_var aGeom = theMEDFamily->getTypes();
-    int iGeomEnd = aGeom->length();
     theNbCells = theCellsSize = 0;
+    SALOME_MED::SUPPORT::supportInfos_var suppInfo=theMEDFamily->getSupportGlobal();
+    int iGeomEnd = suppInfo->types.length();
     if(MYDEBUG) MESSAGE("GetCellsSize - iGeomEnd = "<<iGeomEnd);
     for(int iGeom = 0; iGeom < iGeomEnd; iGeom++) {
-      medGeometryElement aMEDGeom = aGeom[iGeom];
-      long_array_var aCellNumForType = theMEDFamily->getNumber(aMEDGeom);
-      int iNumElemEnd = aCellNumForType->length();
+      int iNumElemEnd = suppInfo->nbEltTypes[iGeom];
       if(iNumElemEnd > 0){
        if(MYDEBUG) MESSAGE("GetCellsSize - iNumElemEnd = "<<iNumElemEnd);
        theNbCells += iNumElemEnd;
-       theCellsSize += iNumElemEnd*(MEDGeom2NbNodes(aMEDGeom) + 1);
+       theCellsSize += iNumElemEnd + suppInfo->nodalConnectivityLength[iGeom];
       }
     }
   }
@@ -1295,6 +1303,74 @@ VISU_MEDConvertor
 }
 
 
+//---------------------------------------------------------------
+namespace {
+
+  typedef vector< int >              TCIntArray;
+  typedef MED::TCSlice< TCIntArray > TConnSlice;
+  //---------------------------------------------------------------
+  class MEDPolygonConnectivity { //! retriver of polygon connectivity
+    TCIntArray myConn, myConnIndex;
+  public:
+    MEDPolygonConnectivity(SALOME_MED::MESH_var      theMesh,
+                           SALOME_MED::medEntityMesh theEntity) {
+      SALOME::SenderInt_var connSender, connIndexSender;
+      connSender      = theMesh->getSenderForPolygonsConnectivity (MED_NODAL, theEntity);
+      connIndexSender = theMesh->getSenderForPolygonsConnectivityIndex (MED_NODAL, theEntity);
+      long connSize, connIndexSize;
+      int* conn  = ReceiverFactory::getValue(connSender,connSize);
+      int* index = ReceiverFactory::getValue(connIndexSender,connIndexSize);
+      myConn.assign( conn, & conn[connSize] );
+      myConnIndex.assign( index, &index[connIndexSize] );
+      // should we delete arrays got via ReceiverFactory? nobody knows
+    }
+    TConnSlice GetConn(int theId) const {
+      int offset = myConnIndex[ theId ] - 1;
+      int size = myConnIndex[ theId + 1 ] - myConnIndex[ theId ];
+      return TConnSlice(myConn,std::slice(offset,size,1));
+    }
+    int GetNbElem() const {
+      return myConnIndex.size() - 1;
+    }
+    int GetCellSize() const {
+      return myConn.size() + GetNbElem();
+    }
+  };
+  //---------------------------------------------------------------
+  class MEDPolyhedraConnectivity {//! retriver of polyhedron connectivity
+    TCIntArray myConn, myConnIndex, myFaceIndex;
+  public:
+    MEDPolyhedraConnectivity(SALOME_MED::MESH_var theMesh) {
+      SALOME::SenderInt_var connSender, connIndexSender, faceIndexSender;
+      connSender      = theMesh->getSenderForPolyhedronConnectivity (MED_NODAL);
+      connIndexSender = theMesh->getSenderForPolyhedronIndex (MED_NODAL);
+      faceIndexSender = theMesh->getSenderForPolyhedronFacesIndex ();
+      long connSize, connIndexSize, facesSize;
+      int* conn  = ReceiverFactory::getValue(connSender,connSize);
+      int* index = ReceiverFactory::getValue(connIndexSender,connIndexSize);
+      int* faces = ReceiverFactory::getValue(faceIndexSender,facesSize);
+      myConn.assign( conn, & conn[connSize] );
+      myConnIndex.assign( index, &index[connIndexSize] );
+      myFaceIndex.assign( faces, &faces[facesSize] );
+      // should we delete arrays got via ReceiverFactory? nobody knows
+    }
+    int GetUniqueConn(int id, std::set<int>& connSet) const {
+      connSet.clear();
+      int f1 = myConnIndex[ id ]-1, f2 = myConnIndex[ id+1 ]-2;
+      int i1 = myFaceIndex[ f1 ]-1, i2 = myFaceIndex[ f2+1 ]-1;
+      for ( int i = i1; i < i2; ++i )
+        connSet.insert( myConn[ i ]);
+      return connSet.size();
+    }
+    int GetNbElem() const {
+      return myConnIndex.size() - 1;
+    }
+    int GetCellSize() const {
+      return myConn.size();//???? + GetNbElem();
+    }
+  };
+}
+
 //---------------------------------------------------------------
 int 
 VISU_MEDConvertor
@@ -1308,115 +1384,192 @@ VISU_MEDConvertor
   SALOME_MED::MESH_var aMedMesh = aMedSupport->getMesh();
 
   //Main part of code
-  SALOME_MED::medGeometryElement* aGeomElems;
   const TEntity& aVEntity = theMeshOnEntity->myEntity;
-  int iGeomEnd = GetEntity2Geom(aVEntity,aGeomElems);
   const SALOME_MED::medEntityMesh& aMEntity = VTKEntityToMED(aVEntity);
+  SALOME_MED::MESH::connectivityInfos_var connInfo;
+  try {
+    connInfo= aMedMesh->getConnectGlobal(aMEntity);
+  }
+  catch (const std::exception & ex) {
+    return 0;
+  }
+  int iGeomEnd = connInfo->meshTypes.length();
   const TNamedPointCoords& aCoords = theMesh->myNamedPointCoords;
   TGeom2SubMesh& aGeom2SubMesh = theMeshOnEntity->myGeom2SubMesh;
   int aNbPoints = aCoords.GetNbPoints();
 
-  for(int iGeom = 0, aCounter = 0; iGeom < iGeomEnd; iGeom++){
-    SALOME_MED::medGeometryElement aMGeom = aGeomElems[iGeom];
-    int aMNbNodes = MEDGeom2NbNodes(aMGeom);
+  for(int iGeom = 0, aCounter = 0; iGeom < iGeomEnd; iGeom++) {
+    SALOME_MED::medGeometryElement aMGeom = connInfo->meshTypes[iGeom];
     VISU::EGeometry aEGeom = MEDGeom2VISU(aMGeom);
-    int aVNbNodes = VISUGeom2NbNodes(aEGeom);
-    int aNbElem = aMedMesh->getNumberOfElements(aMEntity,aMGeom);
-    if (aNbElem > 0) {
-      using namespace SALOME_MED;
-      SALOME_MED::long_array_var conn = 
-       aMedMesh->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,aMEntity,aMGeom);
-      PSubMeshImpl aSubMesh = aGeom2SubMesh[aEGeom](new TCSubMesh());
-
-      aSubMesh->myNbCells = aNbElem;      
-      aSubMesh->myCellsSize = aNbElem*(aVNbNodes+1);
-
-      TCell2Connect& aCell2Connect = aSubMesh->myCell2Connect;
-      std::vector<int> aConnect(aMNbNodes);
-      int aNbConnForElem = conn->length()/aNbElem;
-
-      if(MYDEBUG) MESSAGE("LoadCellsOnEntity - aMGeom = "<<aMGeom<<
-                         "; aNbElem = "<<aNbElem<<
-                         "; aMNbNodes = "<<aMNbNodes<<
-                         "; aVNbNodes = "<<aVNbNodes<<
-                         "; aNbConnForElem = "<<aNbConnForElem);
-
-      for(int iElem = 0; iElem < aNbElem; iElem++){
-       VISU::TConnect anArray(aVNbNodes);
-       for(int k = 0, kj = iElem*aNbConnForElem; k < aMNbNodes; k++)
-         aConnect[k] = conn[kj+k] - 1;
-
-       switch(aMGeom){
+    int aNbElem = connInfo->numberOfElements[ iGeom ];
+    switch (aMGeom) {
+    case SALOME_MED::MED_POLYGON:
+    {
+      MEDPolygonConnectivity conn(aMedMesh, aMEntity);
+      aNbElem = conn.GetNbElem();
+      if (aNbElem) {
+        PSubMeshImpl aSubMesh = aGeom2SubMesh[aEGeom](new TCSubMesh());
+        aSubMesh->myNbCells   = aNbElem;
+        aSubMesh->myCellsSize = conn.GetCellSize();
+
+        TCell2Connect& aCell2Connect = aSubMesh->myCell2Connect;
+        aCell2Connect.resize(aNbElem);
+
+        for(int iElem = 0; iElem < aNbElem; iElem++) {
+          TConnSlice aConnSlice = conn.GetConn(iElem);
+          TConnect& anArray = aCell2Connect[iElem];
+          anArray.resize(aConnSlice.size());
+          for(int iConn = 0; iConn < aConnSlice.size(); iConn++)
+            anArray[iConn] = aConnSlice[iConn] - 1;
+        }
+      }
+    }
+    break;
+    case SALOME_MED::MED_POLYHEDRA:
+    {
+      MEDPolyhedraConnectivity conn( aMedMesh );
+      aNbElem = conn.GetNbElem();
+      if (aNbElem) {
+        PSubMeshImpl aSubMesh = aGeom2SubMesh[aEGeom](new TCSubMesh());
+        aSubMesh->myNbCells   = aNbElem;
+        aSubMesh->myCellsSize = conn.GetCellSize();
+
+        TCell2Connect& aCell2Connect = aSubMesh->myCell2Connect;
+        aCell2Connect.resize(aNbElem);
+
+        std::set< int > aConnectSet;
+        for(int iElem = 0; iElem < aNbElem; iElem++) {
+          if ( conn.GetUniqueConn( iElem, aConnectSet )) {
+            int aNbConn = aConnectSet.size();
+            TConnect& anArray = aCell2Connect[iElem];
+            anArray.resize(aNbConn);
+            std::set<int>::iterator anIter = aConnectSet.begin();
+            for(int i = 0; anIter != aConnectSet.end(); anIter++, i++)
+              anArray[i] = *anIter - 1;
+          }
+        }
+      }
+    }
+    break;
+    default:
+    {        
+      int aMNbNodes = MEDGeom2NbNodes(aMGeom);
+      int aVNbNodes = VISUGeom2NbNodes(aEGeom);
+      if (aNbElem > 0) {
+        using namespace SALOME_MED;
+        SALOME_MED::long_array_var conn = 
+          aMedMesh->getConnectivity(MED_FULL_INTERLACE,MED_NODAL,aMEntity,aMGeom);
+        PSubMeshImpl aSubMesh = aGeom2SubMesh[aEGeom](new TCSubMesh());
+
+        aSubMesh->myNbCells = aNbElem;
+        aSubMesh->myCellsSize = aNbElem*(aVNbNodes+1);
+
+        TCell2Connect& aCell2Connect = aSubMesh->myCell2Connect;
+        std::vector<int> aConnect(aMNbNodes);
+        int aNbConnForElem = conn->length()/aNbElem;
+
+        if(MYDEBUG) MESSAGE("LoadCellsOnEntity - aMGeom = "<<aMGeom<<
+                            "; aNbElem = "<<aNbElem<<
+                            "; aMNbNodes = "<<aMNbNodes<<
+                            "; aVNbNodes = "<<aVNbNodes<<
+                            "; aNbConnForElem = "<<aNbConnForElem);
+
+        for(int iElem = 0; iElem < aNbElem; iElem++) {
+          VISU::TConnect anArray(aVNbNodes);
+          for(int k = 0, kj = iElem*aNbConnForElem; k < aMNbNodes; k++)
+            aConnect[k] = conn[kj+k] - 1;
+
+          switch(aMGeom){
 #if !(defined(VTK_QUADRATIC_EDGE) && defined(VISU_USE_VTK_QUADRATIC)) && defined(VISU_ENABLE_QUADRATIC)
-       case SALOME_MED::MED_SEG3:
-         anArray[0] = aConnect[0];
-         anArray[2] = aConnect[1];  
-         
-         anArray[1] = aConnect[2];
-         break;
+          case SALOME_MED::MED_SEG3:
+            anArray[0] = aConnect[0];
+            anArray[2] = aConnect[1];  
+
+            anArray[1] = aConnect[2];
+            break;
 #endif
 #if !(defined(VTK_QUADRATIC_TRIANGLE) && defined(VISU_USE_VTK_QUADRATIC)) && defined(VISU_ENABLE_QUADRATIC)
-       case SALOME_MED::MED_TRIA6:
-         anArray[0] = aConnect[0];
-         anArray[2] = aConnect[1];  
-         anArray[4] = aConnect[2];  
-         
-         anArray[1] = aConnect[3];
-         anArray[3] = aConnect[4];  
-         anArray[5] = aConnect[5];  
-         break;
+          case SALOME_MED::MED_TRIA6:
+            anArray[0] = aConnect[0];
+            anArray[2] = aConnect[1];  
+            anArray[4] = aConnect[2];  
+
+            anArray[1] = aConnect[3];
+            anArray[3] = aConnect[4];  
+            anArray[5] = aConnect[5];  
+            break;
 #endif
 #if !(defined(VTK_QUADRATIC_QUAD) && defined(VISU_USE_VTK_QUADRATIC)) && defined(VISU_ENABLE_QUADRATIC)
-       case SALOME_MED::MED_QUAD8:
-         anArray[0] = aConnect[0];
-         anArray[2] = aConnect[1];  
-         anArray[4] = aConnect[2];  
-         anArray[6] = aConnect[3];  
-         
-         anArray[1] = aConnect[4];
-         anArray[3] = aConnect[5];  
-         anArray[5] = aConnect[6];  
-         anArray[7] = aConnect[7];  
-         break;
+          case SALOME_MED::MED_QUAD8:
+            anArray[0] = aConnect[0];
+            anArray[2] = aConnect[1];  
+            anArray[4] = aConnect[2];  
+            anArray[6] = aConnect[3];  
+
+            anArray[1] = aConnect[4];
+            anArray[3] = aConnect[5];  
+            anArray[5] = aConnect[6];  
+            anArray[7] = aConnect[7];  
+            break;
 #endif
 #if (defined(VTK_QUADRATIC_TETRA) && defined(VISU_USE_VTK_QUADRATIC)) && defined(VISU_ENABLE_QUADRATIC)
-       case SALOME_MED::MED_TETRA10 :
+          case SALOME_MED::MED_TETRA10 :
 #endif
-       case SALOME_MED::MED_TETRA4 :
-         anArray[0] = aConnect[0];
-         anArray[1] = aConnect[1];
-         anArray[2] = aConnect[3];  
-         anArray[3] = aConnect[2];  
-         break;
+          case SALOME_MED::MED_TETRA4 :
+            anArray[0] = aConnect[0];
+            anArray[1] = aConnect[1];
+            anArray[2] = aConnect[3];  
+            anArray[3] = aConnect[2];  
+            break;
 #if (defined(VTK_QUADRATIC_PYRAMID) && defined(VISU_USE_VTK_QUADRATIC)) && defined(VISU_ENABLE_QUADRATIC)
-       case SALOME_MED::MED_PYRA13:
+          case SALOME_MED::MED_PYRA13:
 #endif
-       case SALOME_MED::MED_PYRA5 :
-         anArray[0] = aConnect[0];
-         anArray[1] = aConnect[3];  
-         anArray[2] = aConnect[2];
-         anArray[3] = aConnect[1];  
-         anArray[4] = aConnect[4];
-         break;
-       default:
-         for (int k = 0; k < aVNbNodes; k++) 
-           anArray[k] = aConnect[k];
-       }
-       for (int k = 0; k < aVNbNodes; k++) 
-         if(anArray[k] < 0 || aNbPoints <= anArray[k]){
-           static QString aString;
-           aString.sprintf("LoadCellsOnEntity >> aNbPoints(%d) <= anArray[%d][%d]=%d < 0 !!!",aNbPoints,iElem,k,anArray[k]);
-           throw std::runtime_error(aString.latin1());
-         }
-       aCell2Connect.push_back(anArray);
+          case SALOME_MED::MED_PYRA5 :
+            anArray[0] = aConnect[0];
+            anArray[1] = aConnect[3];  
+            anArray[2] = aConnect[2];
+            anArray[3] = aConnect[1];  
+            anArray[4] = aConnect[4];
+            break;
+          default:
+            for (int k = 0; k < aVNbNodes; k++) 
+              anArray[k] = aConnect[k];
+          }
+          for (int k = 0; k < aVNbNodes; k++) 
+            if(anArray[k] < 0 || aNbPoints <= anArray[k]){
+              static QString aString;
+              aString.sprintf("LoadCellsOnEntity >> aNbPoints(%d) <= anArray[%d][%d]=%d < 0 !!!",aNbPoints,iElem,k,anArray[k]);
+              throw std::runtime_error(aString.latin1());
+            }
+          aCell2Connect.push_back(anArray);
+        } // loop on elements
       }
-      //Workaround for MED Component data structure
-      int aSize = aCell2Connect.size();
-      if(MYDEBUG) MESSAGE("LoadCellsOnEntity - aCounter = "<<aCounter<<"; aSize = "<<aSize<<"; aMGeom = "<<aMGeom);
-      theMeshOnEntity->myCellsFirstIndex[aMGeom] = TIndexAndSize(aCounter,aSize);
-      aCounter += aSize;
-    }
-  }
+    }} // switch( aMGeom )
+    //Workaround for MED Component data structure
+    int aSize = aNbElem; //aCell2Connect.size();
+    if(MYDEBUG) MESSAGE("LoadCellsOnEntity - aCounter = "<<aCounter<<"; aSize = "<<aSize<<"; aMGeom = "<<aMGeom);
+    theMeshOnEntity->myCellsFirstIndex[aMGeom] = TIndexAndSize(aCounter,aSize);
+    aCounter += aSize;
+  } //loop on types
+
+  // Dump result connectivity
+// #ifdef _DEBUG_
+//   TGeom2SubMesh::iterator geom_sm = aGeom2SubMesh.begin();
+//   for ( ; geom_sm!=aGeom2SubMesh.end(); ++geom_sm ) {
+//     cout << "TYPE: " << geom_sm->first << endl;
+//     PSubMeshImpl aSubMesh = geom_sm->second;
+//     TCell2Connect& aCell2Connect = aSubMesh->myCell2Connect;
+//     TCell2Connect::iterator id_conn = aCell2Connect.begin();
+//     for ( int i = 0; id_conn !=aCell2Connect.end(); ++id_conn ) {
+//       cout << "\t" << i++ << ": [";
+//       TConnect& anArray = *id_conn;
+//       TConnect::iterator n = anArray.begin();
+//       for ( ; n != anArray.end(); ++n )
+//         cout << " " << *n + 1;
+//       cout << " ]"<< endl;
+//     }
+//   }
+// #endif
 
   theMeshOnEntity->myIsDone = true;