#include <boost/tuple/tuple.hpp>
+#include "ReceiverFactory.hxx"
+#include "MED_SliceArray.hxx"
+
using namespace std;
using namespace VISU;
{
using namespace SALOME_MED;
- const int MED_NBR_GEOMETRIE_MAILLE = 15;
+ const int MED_NBR_GEOMETRIE_MAILLE = 17;
medGeometryElement
CELLGEOM[MED_NBR_GEOMETRIE_MAILLE] = {
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;
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;
}
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);
}
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);
}
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;
}
}
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];
}
}
}
}
+//---------------------------------------------------------------
+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
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;