Salome HOME
Update copyright information
[modules/smesh.git] / src / SMDS / SMDS_Downward.cxx
index ed6fc38988c1600ebe50fc0b785cb6fed0efc915..67ff05ffc8d5076dfc687d3af2e367d9377a0585 100644 (file)
@@ -1,9 +1,25 @@
-/*
- * SMDS_Downward.cxx
- *
- *  Created on: Jun 3, 2010
- *      Author: prascle
- */
+// Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// File: SMDS_Downward.cxx
+// Created: Jun 3, 2010
+// Author: prascle
 
 #include "SMDS_Downward.hxx"
 #include "SMDS_Mesh.hxx"
@@ -27,23 +43,6 @@ vector<int> SMDS_Downward::_cellDimension;
  */
 int SMDS_Downward::getCellDimension(unsigned char cellType)
 {
-  return _cellDimension[cellType];
-}
-
-// ---------------------------------------------------------------------------
-
-/*! Generic constructor for all the downward connectivity structures (one per vtk cell type).
- *  The static structure for cell dimension is set only once.
- * @param grid unstructured grid associated to the mesh.
- * @param nbDownCells number of downward entities associated to this vtk type of cell.
- * @return
- */
-SMDS_Downward::SMDS_Downward(SMDS_UnstructuredGrid *grid, int nbDownCells) :
-  _grid(grid), _nbDownCells(nbDownCells)
-{
-  this->_maxId = 0;
-  this->_cellIds.clear();
-  this->_cellTypes.clear();
   if (_cellDimension.empty())
     {
       _cellDimension.resize(VTK_MAXTYPE + 1, 0);
@@ -53,15 +52,37 @@ SMDS_Downward::SMDS_Downward(SMDS_UnstructuredGrid *grid, int nbDownCells) :
       _cellDimension[VTK_QUADRATIC_TRIANGLE] = 2;
       _cellDimension[VTK_QUAD] = 2;
       _cellDimension[VTK_QUADRATIC_QUAD] = 2;
+      _cellDimension[VTK_BIQUADRATIC_QUAD] = 2;
       _cellDimension[VTK_TETRA] = 3;
       _cellDimension[VTK_QUADRATIC_TETRA] = 3;
       _cellDimension[VTK_HEXAHEDRON] = 3;
       _cellDimension[VTK_QUADRATIC_HEXAHEDRON] = 3;
+      _cellDimension[VTK_TRIQUADRATIC_HEXAHEDRON] = 3;
       _cellDimension[VTK_WEDGE] = 3;
       _cellDimension[VTK_QUADRATIC_WEDGE] = 3;
       _cellDimension[VTK_PYRAMID] = 3;
       _cellDimension[VTK_QUADRATIC_PYRAMID] = 3;
+      _cellDimension[VTK_HEXAGONAL_PRISM] = 3;
     }
+  return _cellDimension[cellType];
+}
+
+// ---------------------------------------------------------------------------
+
+/*! Generic constructor for all the downward connectivity structures (one per vtk cell type).
+ *  The static structure for cell dimension is set only once.
+ * @param grid unstructured grid associated to the mesh.
+ * @param nbDownCells number of downward entities associated to this vtk type of cell.
+ * @return
+ */
+SMDS_Downward::SMDS_Downward(SMDS_UnstructuredGrid *grid, int nbDownCells) :
+  _grid(grid), _nbDownCells(nbDownCells)
+{
+  this->_maxId = 0;
+  this->_cellIds.clear();
+  this->_cellTypes.clear();
+  if (_cellDimension.empty())
+    getCellDimension( VTK_LINE );
 }
 
 SMDS_Downward::~SMDS_Downward()
@@ -416,7 +437,7 @@ int SMDS_Down1D::computeFaces(int* pts, int* vtkIds, int nbcells, int* downFaces
           downTypes[cnt] = vtkType;
           cnt++;
         }
-      else
+      else if (SMDS_Downward::getCellDimension(vtkType) == 3)
         {
           int volId = _grid->CellIdToDownId(vtkId);
           SMDS_Downward * downvol = _grid->getDownArray(vtkType);
@@ -782,7 +803,6 @@ void SMDS_Down3D::getNodeIds(int cellId, std::set<int>& nodeSet)
 int SMDS_Down3D::FindFaceByNodes(int cellId, ElemByNodesType& faceByNodes)
 {
   int *faces = &_cellIds[_nbDownCells * cellId];
-  int faceNodeSet[10];
   int npoints = 0;
 
   for (int i = 0; i < _nbDownCells; i++)
@@ -790,11 +810,7 @@ int SMDS_Down3D::FindFaceByNodes(int cellId, ElemByNodesType& faceByNodes)
       if ((faces[i] >= 0) && (faceByNodes.vtkType == _cellTypes[i]))
         {
           if (npoints == 0)
-            {
-              for (int j = 0; j < faceByNodes.nbNodes; j++)
-                faceNodeSet[j] = faceByNodes.nodeIds[j];
-              npoints = faceByNodes.nbNodes;
-            }
+            npoints = faceByNodes.nbNodes;
 
           int nodeSet[10];
           int npts = this->_grid->getDownArray(faceByNodes.vtkType)->getNodeSet(faces[i], nodeSet);
@@ -947,15 +963,15 @@ void SMDS_DownQuadTriangle::addDownCell(int cellId, int lowCellId, unsigned char
 {
   //ASSERT((cellId >=0)&& (cellId < _maxId));
   //ASSERT(aType == VTK_QUADRATIC_EDGE);
-  int *faces = &_cellIds[_nbDownCells * cellId];
+  int *edges = &_cellIds[_nbDownCells * cellId];
   for (int i = 0; i < _nbDownCells; i++)
     {
-      if (faces[i] < 0)
+      if (edges[i] < 0)
         {
-          faces[i] = lowCellId;
+          edges[i] = lowCellId;
           return;
         }
-      if (faces[i] == lowCellId)
+      if (edges[i] == lowCellId)
         return;
     }
   ASSERT(0);
@@ -1113,7 +1129,8 @@ void SMDS_DownTetra::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& o
   _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
 
   set<int> tofind;
-  int ids[12] = { 0, 1, 2, 0, 1, 3, 0, 2, 3, 1, 2, 3 };
+  int ids[12] = { 0, 1, 2,  0, 3, 1,  2, 3, 0,   1, 3, 2 };
+//int ids[12] = { 2, 1, 0,  1, 3, 0,  0, 3, 2,   2, 3, 1 };
   for (int k = 0; k < 4; k++)
     {
       tofind.clear();
@@ -1209,7 +1226,34 @@ SMDS_DownQuadTetra::~SMDS_DownQuadTetra()
 
 void SMDS_DownQuadTetra::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
 {
-  // TODO
+  set<int> setNodes;
+  setNodes.clear();
+  for (int i = 0; i < orderedNodes.size(); i++)
+    setNodes.insert(orderedNodes[i]);
+  //MESSAGE("cellId = " << cellId);
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
+
+  set<int> tofind;
+  int ids[24] = { 0, 1, 2, 4, 5, 6,  0, 3, 1, 7, 8, 4,  2, 3, 0, 9, 7, 6,  1, 3, 2, 8, 9, 5 };
+//int ids[24] = { 2, 1, 0, 5, 4, 6,  1, 3, 0, 8, 7, 4,  0, 3, 2, 7, 9, 6,  2, 3, 1, 9, 8, 5 };
+  for (int k = 0; k < 4; k++)
+    {
+      tofind.clear();
+      for (int i = 0; i < 6; i++)
+        tofind.insert(nodes[ids[6 * k + i]]);
+      if (setNodes == tofind)
+        {
+          for (int i = 0; i < 6; i++)
+            orderedNodes[i] = nodes[ids[6 * k + i]];
+          return;
+        }
+    }
+  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
+  MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
+  MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
 }
 
 void SMDS_DownQuadTetra::addDownCell(int cellId, int lowCellId, unsigned char aType)
@@ -1263,8 +1307,8 @@ void SMDS_DownQuadTetra::computeFacesWithNodes(int cellId, ListElemByNodesType&
   facesWithNodes.elems[1].nodeIds[1] = nodes[1];
   facesWithNodes.elems[1].nodeIds[2] = nodes[3];
   facesWithNodes.elems[1].nodeIds[3] = nodes[4];
-  facesWithNodes.elems[1].nodeIds[4] = nodes[7];
-  facesWithNodes.elems[1].nodeIds[5] = nodes[8];
+  facesWithNodes.elems[1].nodeIds[4] = nodes[8];
+  facesWithNodes.elems[1].nodeIds[5] = nodes[7];
   facesWithNodes.elems[1].nbNodes = 6;
   facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_TRIANGLE;
 
@@ -1272,8 +1316,8 @@ void SMDS_DownQuadTetra::computeFacesWithNodes(int cellId, ListElemByNodesType&
   facesWithNodes.elems[2].nodeIds[1] = nodes[2];
   facesWithNodes.elems[2].nodeIds[2] = nodes[3];
   facesWithNodes.elems[2].nodeIds[3] = nodes[6];
-  facesWithNodes.elems[2].nodeIds[4] = nodes[7];
-  facesWithNodes.elems[2].nodeIds[5] = nodes[9];
+  facesWithNodes.elems[2].nodeIds[4] = nodes[9];
+  facesWithNodes.elems[2].nodeIds[5] = nodes[7];
   facesWithNodes.elems[2].nbNodes = 6;
   facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_TRIANGLE;
 
@@ -1281,8 +1325,8 @@ void SMDS_DownQuadTetra::computeFacesWithNodes(int cellId, ListElemByNodesType&
   facesWithNodes.elems[3].nodeIds[1] = nodes[2];
   facesWithNodes.elems[3].nodeIds[2] = nodes[3];
   facesWithNodes.elems[3].nodeIds[3] = nodes[5];
-  facesWithNodes.elems[3].nodeIds[4] = nodes[8];
-  facesWithNodes.elems[3].nodeIds[5] = nodes[9];
+  facesWithNodes.elems[3].nodeIds[4] = nodes[9];
+  facesWithNodes.elems[3].nodeIds[5] = nodes[8];
   facesWithNodes.elems[3].nbNodes = 6;
   facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE;
 }
@@ -1305,7 +1349,43 @@ SMDS_DownPyramid::~SMDS_DownPyramid()
 
 void SMDS_DownPyramid::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
 {
-  // TODO
+  set<int> setNodes;
+  setNodes.clear();
+  for (int i = 0; i < orderedNodes.size(); i++)
+    setNodes.insert(orderedNodes[i]);
+  //MESSAGE("cellId = " << cellId);
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
+
+  set<int> tofind;
+  int ids[16] = { 0, 1, 2, 3,   0, 3, 4,   3, 2, 4,   2, 1, 4,   1, 0, 4 };
+
+  tofind.clear();
+  for (int i = 0; i < 4; i++)
+    tofind.insert(nodes[ids[i]]);
+  if (setNodes == tofind)
+    {
+      for (int i = 0; i < 4; i++)
+        orderedNodes[i] = nodes[ids[i]];
+      return;
+    }
+  for (int k = 0; k < 4; k++)
+    {
+      tofind.clear();
+      for (int i = 0; i < 3; i++)
+        tofind.insert(nodes[ids[4 + 3 * k + i]]);
+      if (setNodes == tofind)
+        {
+          for (int i = 0; i < 3; i++)
+            orderedNodes[i] = nodes[ids[4 + 3 * k + i]];
+          return;
+        }
+    }
+  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
+  MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
+  MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
 }
 
 void SMDS_DownPyramid::addDownCell(int cellId, int lowCellId, unsigned char aType)
@@ -1409,7 +1489,44 @@ SMDS_DownQuadPyramid::~SMDS_DownQuadPyramid()
 
 void SMDS_DownQuadPyramid::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
 {
-  // TODO
+  set<int> setNodes;
+  setNodes.clear();
+  for (int i = 0; i < orderedNodes.size(); i++)
+    setNodes.insert(orderedNodes[i]);
+  //MESSAGE("cellId = " << cellId);
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
+
+  set<int> tofind;
+  int ids[32] = { 0, 1, 2, 3, 5, 6, 7, 8,
+                  0, 3, 4, 8, 12, 9,   3, 2, 4, 7 , 11, 12,   2, 1, 4, 6, 10, 11,   1, 0, 4, 5, 9, 10 };
+
+  tofind.clear();
+  for (int i = 0; i < 4; i++)
+    tofind.insert(nodes[ids[i]]);
+  if (setNodes == tofind)
+    {
+      for (int i = 0; i < 8; i++)
+        orderedNodes[i] = nodes[ids[i]];
+      return;
+    }
+  for (int k = 0; k < 4; k++)
+    {
+      tofind.clear();
+      for (int i = 0; i < 6; i++)
+        tofind.insert(nodes[ids[8 + 6 * k + i]]);
+      if (setNodes == tofind)
+        {
+          for (int i = 0; i < 6; i++)
+            orderedNodes[i] = nodes[ids[8 + 6 * k + i]];
+          return;
+        }
+    }
+  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
+  MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
+  MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
 }
 
 void SMDS_DownQuadPyramid::addDownCell(int cellId, int lowCellId, unsigned char aType)
@@ -1479,8 +1596,8 @@ void SMDS_DownQuadPyramid::computeFacesWithNodes(int cellId, ListElemByNodesType
   facesWithNodes.elems[1].nodeIds[1] = nodes[1];
   facesWithNodes.elems[1].nodeIds[2] = nodes[4];
   facesWithNodes.elems[1].nodeIds[3] = nodes[5];
-  facesWithNodes.elems[1].nodeIds[4] = nodes[9];
-  facesWithNodes.elems[1].nodeIds[5] = nodes[10];
+  facesWithNodes.elems[1].nodeIds[4] = nodes[10];
+  facesWithNodes.elems[1].nodeIds[5] = nodes[9];
   facesWithNodes.elems[1].nbNodes = 6;
   facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_TRIANGLE;
 
@@ -1488,8 +1605,8 @@ void SMDS_DownQuadPyramid::computeFacesWithNodes(int cellId, ListElemByNodesType
   facesWithNodes.elems[2].nodeIds[1] = nodes[2];
   facesWithNodes.elems[2].nodeIds[2] = nodes[4];
   facesWithNodes.elems[2].nodeIds[3] = nodes[6];
-  facesWithNodes.elems[2].nodeIds[4] = nodes[10];
-  facesWithNodes.elems[2].nodeIds[5] = nodes[11];
+  facesWithNodes.elems[2].nodeIds[4] = nodes[11];
+  facesWithNodes.elems[2].nodeIds[5] = nodes[10];
   facesWithNodes.elems[2].nbNodes = 6;
   facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_TRIANGLE;
 
@@ -1497,8 +1614,8 @@ void SMDS_DownQuadPyramid::computeFacesWithNodes(int cellId, ListElemByNodesType
   facesWithNodes.elems[3].nodeIds[1] = nodes[3];
   facesWithNodes.elems[3].nodeIds[2] = nodes[4];
   facesWithNodes.elems[3].nodeIds[3] = nodes[7];
-  facesWithNodes.elems[3].nodeIds[4] = nodes[11];
-  facesWithNodes.elems[3].nodeIds[5] = nodes[12];
+  facesWithNodes.elems[3].nodeIds[4] = nodes[12];
+  facesWithNodes.elems[3].nodeIds[5] = nodes[11];
   facesWithNodes.elems[3].nbNodes = 6;
   facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE;
 
@@ -1530,7 +1647,47 @@ SMDS_DownPenta::~SMDS_DownPenta()
 
 void SMDS_DownPenta::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
 {
-  // TODO
+  set<int> setNodes;
+  setNodes.clear();
+  for (int i = 0; i < orderedNodes.size(); i++)
+    setNodes.insert(orderedNodes[i]);
+  //MESSAGE("cellId = " << cellId);
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
+
+  set<int> tofind;
+//int ids[18] = { 0, 2, 1,  3, 4, 5,   0, 1, 4, 3,   1, 2, 5, 4,   2, 0, 3, 5 };
+  int ids[18] = { 0, 1, 2,  3, 5, 4,   0, 3, 4, 1,   1, 4, 5, 2,   2, 5, 3, 0 };
+
+  for (int k = 0; k < 2; k++)
+    {
+      tofind.clear();
+      for (int i = 0; i < 3; i++)
+        tofind.insert(nodes[ids[3 * k + i]]);
+      if (setNodes == tofind)
+        {
+          for (int i = 0; i < 3; i++)
+            orderedNodes[i] = nodes[ids[3 * k + i]];
+          return;
+        }
+    }
+  for (int k = 0; k < 3; k++)
+    {
+      tofind.clear();
+      for (int i = 0; i < 4; i++)
+        tofind.insert(nodes[ids[6 + 4 * k + i]]);
+      if (setNodes == tofind)
+        {
+          for (int i = 0; i < 4; i++)
+            orderedNodes[i] = nodes[ids[6 + 4 * k + i]];
+          return;
+        }
+    }
+  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
+  MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
+  MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
 }
 
 void SMDS_DownPenta::addDownCell(int cellId, int lowCellId, unsigned char aType)
@@ -1538,7 +1695,7 @@ void SMDS_DownPenta::addDownCell(int cellId, int lowCellId, unsigned char aType)
   //ASSERT((cellId >=0) && (cellId < _maxId));
   int *faces = &_cellIds[_nbDownCells * cellId];
   if (aType == VTK_QUAD)
-    for (int i = 0; i < 2; i++)
+    for (int i = 0; i < 3; i++)
       {
         if (faces[i] < 0)
           {
@@ -1551,7 +1708,7 @@ void SMDS_DownPenta::addDownCell(int cellId, int lowCellId, unsigned char aType)
   else
     {
       //ASSERT(aType == VTK_TRIANGLE);
-      for (int i = 2; i < _nbDownCells; i++)
+      for (int i = 3; i < _nbDownCells; i++)
         {
           if (faces[i] < 0)
             {
@@ -1638,7 +1795,48 @@ SMDS_DownQuadPenta::~SMDS_DownQuadPenta()
 
 void SMDS_DownQuadPenta::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
 {
-  // TODO
+  set<int> setNodes;
+  setNodes.clear();
+  for (int i = 0; i < orderedNodes.size(); i++)
+    setNodes.insert(orderedNodes[i]);
+  //MESSAGE("cellId = " << cellId);
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
+
+  set<int> tofind;
+//int ids[18] = { 0, 2, 1,  3, 4, 5,   0, 1, 4, 3,   1, 2, 5, 4,   2, 0, 3, 5 };
+  int ids[36] = { 0, 1, 2, 6, 7, 8,  3, 5, 4, 11, 10, 9,
+                  0, 3, 4, 1, 12, 9, 13, 6,   1, 4, 5, 2, 13, 10, 14, 7,   2, 5, 3, 0, 14, 11, 12, 8 };
+
+  for (int k = 0; k < 2; k++)
+    {
+      tofind.clear();
+      for (int i = 0; i < 6; i++)
+        tofind.insert(nodes[ids[6 * k + i]]);
+      if (setNodes == tofind)
+        {
+          for (int i = 0; i < 6; i++)
+            orderedNodes[i] = nodes[ids[6 * k + i]];
+          return;
+        }
+    }
+  for (int k = 0; k < 3; k++)
+    {
+      tofind.clear();
+      for (int i = 0; i < 8; i++)
+        tofind.insert(nodes[ids[12 + 8 * k + i]]);
+      if (setNodes == tofind)
+        {
+          for (int i = 0; i < 8; i++)
+            orderedNodes[i] = nodes[ids[12 + 8 * k + i]];
+          return;
+        }
+    }
+  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
+  MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2]);
+  MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
 }
 
 void SMDS_DownQuadPenta::addDownCell(int cellId, int lowCellId, unsigned char aType)
@@ -1646,7 +1844,7 @@ void SMDS_DownQuadPenta::addDownCell(int cellId, int lowCellId, unsigned char aT
   //ASSERT((cellId >=0) && (cellId < _maxId));
   int *faces = &_cellIds[_nbDownCells * cellId];
   if (aType == VTK_QUADRATIC_QUAD)
-    for (int i = 0; i < 2; i++)
+    for (int i = 0; i < 3; i++)
       {
         if (faces[i] < 0)
           {
@@ -1659,7 +1857,7 @@ void SMDS_DownQuadPenta::addDownCell(int cellId, int lowCellId, unsigned char aT
   else
     {
       //ASSERT(aType == VTK_QUADRATIC_TRIANGLE);
-      for (int i = 2; i < _nbDownCells; i++)
+      for (int i = 3; i < _nbDownCells; i++)
         {
           if (faces[i] < 0)
             {
@@ -1777,7 +1975,8 @@ void SMDS_DownHexa::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& or
   _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
 
   set<int> tofind;
-  int ids[24] = { 0, 1, 2, 3,  4, 5, 6, 7,  0, 1, 5, 4,  3, 2, 6, 7,  0, 3, 7, 4,  1, 2, 6, 5};
+//int ids[24] = { 0, 1, 2, 3,  7, 6, 5, 4,  4, 0, 3, 7,  5, 1, 0, 4,  6, 2, 1, 5,  7, 3, 2, 6};
+  int ids[24] = { 3, 2, 1, 0,  4, 5, 6, 7,  7, 3, 0, 4,  4, 0, 1, 5,  5, 1, 2, 6,  6, 2, 3, 7};
   for (int k = 0; k < 6; k++) // loop on the 6 faces
     {
       tofind.clear();
@@ -1896,7 +2095,35 @@ SMDS_DownQuadHexa::~SMDS_DownQuadHexa()
 
 void SMDS_DownQuadHexa::getOrderedNodesOfFace(int cellId, std::vector<vtkIdType>& orderedNodes)
 {
-  // TODO
+  set<int> setNodes;
+  setNodes.clear();
+  for (int i = 0; i < orderedNodes.size(); i++)
+    setNodes.insert(orderedNodes[i]);
+  //MESSAGE("cellId = " << cellId);
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(this->_vtkCellIds[cellId], npts, nodes);
+
+  set<int> tofind;
+  //int ids[24] = { 3, 2, 1, 0,  4, 5, 6, 7,  7, 3, 0, 4,  4, 0, 1, 5,  5, 1, 2, 6,  6, 2, 3, 7};
+  int ids[48] = { 3, 2, 1, 0,10, 9, 8,11,   4, 5, 6, 7,12,13,14,15,   7, 3, 0, 4,19,11,16,15,
+                  4, 0, 1, 5,16, 8,17,12,   5, 1, 2, 6,17, 9,18,13,   6, 2, 3, 7,18,10,19,14};
+  for (int k = 0; k < 6; k++)
+    {
+      tofind.clear();
+      for (int i = 0; i < 8; i++)
+        tofind.insert(nodes[ids[8 * k + i]]);
+      if (setNodes == tofind)
+        {
+          for (int i = 0; i < 8; i++)
+            orderedNodes[i] = nodes[ids[8 * k + i]];
+          return;
+        }
+    }
+  MESSAGE("=== Problem volume " << _vtkCellIds[cellId] << " " << _grid->_mesh->fromVtkToSmds(_vtkCellIds[cellId]));
+  MESSAGE(orderedNodes[0] << " " << orderedNodes[1] << " " << orderedNodes[2] << " " << orderedNodes[3]);
+  MESSAGE(nodes[0] << " " << nodes[1] << " " << nodes[2] << " " << nodes[3]);
 }
 
 void SMDS_DownQuadHexa::addDownCell(int cellId, int lowCellId, unsigned char aType)