Back to index

salome-smesh  6.5.0
SMDS_VtkVolume.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2010-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 #include "SMDS_VtkVolume.hxx"
00021 #include "SMDS_MeshNode.hxx"
00022 #include "SMDS_Mesh.hxx"
00023 #include "SMDS_VtkCellIterator.hxx"
00024 
00025 #include "utilities.h"
00026 
00027 #include <vector>
00028 
00029 SMDS_VtkVolume::SMDS_VtkVolume()
00030 {
00031 }
00032 
00033 SMDS_VtkVolume::SMDS_VtkVolume(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh)
00034 {
00035   init(nodeIds, mesh);
00036 }
00041 void SMDS_VtkVolume::init(const std::vector<vtkIdType>& nodeIds, SMDS_Mesh* mesh)
00042 {
00043   SMDS_MeshVolume::init();
00044   vtkUnstructuredGrid* grid = mesh->getGrid();
00045   myMeshId = mesh->getMeshId();
00046   vtkIdType aType = VTK_TETRA;
00047   switch (nodeIds.size()) // cases are in order of usage frequency
00048   {
00049     case 4:
00050       aType = VTK_TETRA;
00051       break;
00052     case 8:
00053       aType = VTK_HEXAHEDRON;
00054       break;
00055     case 5:
00056       aType = VTK_PYRAMID;
00057       break;
00058     case 6:
00059       aType = VTK_WEDGE;
00060       break;
00061     case 10:
00062       aType = VTK_QUADRATIC_TETRA;
00063       break;
00064     case 20:
00065       aType = VTK_QUADRATIC_HEXAHEDRON;
00066       break;
00067     case 13:
00068       aType = VTK_QUADRATIC_PYRAMID;
00069       break;
00070     case 15:
00071       aType = VTK_QUADRATIC_WEDGE;
00072       break;
00073     case 12:
00074       aType = VTK_HEXAGONAL_PRISM;
00075       break;
00076     case 27:
00077       aType = VTK_TRIQUADRATIC_HEXAHEDRON;
00078       break;
00079     default:
00080       aType = VTK_HEXAHEDRON;
00081       break;
00082   }
00083   myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType *) &nodeIds[0]);
00084   mesh->setMyModified();
00085   //MESSAGE("SMDS_VtkVolume::init myVtkID " << myVtkID);
00086 }
00087 
00088 //#ifdef VTK_HAVE_POLYHEDRON
00089 void SMDS_VtkVolume::initPoly(const std::vector<vtkIdType>& nodeIds,
00090                               const std::vector<int>&       nbNodesPerFace,
00091                               SMDS_Mesh*                    mesh)
00092 {
00093   SMDS_MeshVolume::init();
00094   //MESSAGE("SMDS_VtkVolume::initPoly");
00095   SMDS_UnstructuredGrid* grid = mesh->getGrid();
00096   //double center[3];
00097   //this->gravityCenter(grid, &nodeIds[0], nodeIds.size(), &center[0]);
00098   vector<vtkIdType> ptIds;
00099   vtkIdType nbFaces = nbNodesPerFace.size();
00100   int k = 0;
00101   for (int i = 0; i < nbFaces; i++)
00102     {
00103       int nf = nbNodesPerFace[i];
00104       ptIds.push_back(nf);
00105       // EAP: a right approach is:
00106       // - either the user should care of order of nodes or
00107       // - the user should use a service method arranging nodes if he
00108       //   don't want or can't to do it by him-self
00109       // The method below works OK only with planar faces and convex polyhedrones
00110       //
00111       // double a[3];
00112       // double b[3];
00113       // double c[3];
00114       // grid->GetPoints()->GetPoint(nodeIds[k], a);
00115       // grid->GetPoints()->GetPoint(nodeIds[k + 1], b);
00116       // grid->GetPoints()->GetPoint(nodeIds[k + 2], c);
00117       // bool isFaceForward = this->isForward(a, b, c, center);
00118       //MESSAGE("isFaceForward " << i << " " << isFaceForward);
00119       const vtkIdType *facePts = &nodeIds[k];
00120       //if (isFaceForward)
00121         for (int n = 0; n < nf; n++)
00122           ptIds.push_back(facePts[n]);
00123       // else
00124       //   for (int n = nf - 1; n >= 0; n--)
00125       //     ptIds.push_back(facePts[n]);
00126       k += nf;
00127     }
00128   myVtkID = grid->InsertNextLinkedCell(VTK_POLYHEDRON, nbFaces, &ptIds[0]);
00129   mesh->setMyModified();
00130 }
00131 //#endif
00132 
00133 bool SMDS_VtkVolume::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
00134 {
00135   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
00136   vtkIdType npts = 0;
00137   vtkIdType* pts = 0;
00138   grid->GetCellPoints(myVtkID, npts, pts);
00139   if (nbNodes != npts)
00140     {
00141       MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes);
00142       return false;
00143     }
00144   for (int i = 0; i < nbNodes; i++)
00145     {
00146       pts[i] = nodes[i]->getVtkId();
00147     }
00148   SMDS_Mesh::_meshList[myMeshId]->setMyModified();
00149   return true;
00150 }
00151 
00156 bool SMDS_VtkVolume::vtkOrder(const SMDS_MeshNode* nodes[], const int nbNodes)
00157 {
00158   if (nbNodes != this->NbNodes())
00159     {
00160       MESSAGE("vtkOrder, wrong number of nodes " << nbNodes << " instead of "<< this->NbNodes());
00161       return false;
00162     }
00163   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
00164   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
00165   const std::vector<int>& interlace = SMDS_MeshCell::toVtkOrder( VTKCellType( aVtkType ));
00166   if ( !interlace.empty() )
00167   {
00168     ASSERT( interlace.size() == nbNodes );
00169     std::vector<const SMDS_MeshNode*> initNodes( nodes, nodes+nbNodes );
00170     for ( size_t i = 0; i < interlace.size(); ++i )
00171       nodes[i] = initNodes[ interlace[i] ];
00172   }
00173   return true;
00174 }
00175 
00176 SMDS_VtkVolume::~SMDS_VtkVolume()
00177 {
00178 }
00179 
00180 void SMDS_VtkVolume::Print(ostream & OS) const
00181 {
00182   OS << "volume <" << GetID() << "> : ";
00183 }
00184 
00185 int SMDS_VtkVolume::NbFaces() const
00186 {
00187   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
00188   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
00189   int nbFaces = 4;
00190   switch (aVtkType)
00191   {
00192     case VTK_TETRA:
00193     case VTK_QUADRATIC_TETRA:
00194       nbFaces = 4;
00195       break;
00196     case VTK_PYRAMID:
00197     case VTK_WEDGE:
00198     case VTK_QUADRATIC_PYRAMID:
00199     case VTK_QUADRATIC_WEDGE:
00200       nbFaces = 5;
00201       break;
00202     case VTK_HEXAHEDRON:
00203     case VTK_QUADRATIC_HEXAHEDRON:
00204     case VTK_TRIQUADRATIC_HEXAHEDRON:
00205       nbFaces = 6;
00206       break;
00207     case VTK_POLYHEDRON:
00208       {
00209         vtkIdType nFaces = 0;
00210         vtkIdType* ptIds = 0;
00211         grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
00212         nbFaces = nFaces;
00213         break;
00214       }
00215     case VTK_HEXAGONAL_PRISM:
00216       nbFaces = 8;
00217       break;
00218     default:
00219       MESSAGE("invalid volume type")
00220       ;
00221       nbFaces = 0;
00222       break;
00223   }
00224   return nbFaces;
00225 }
00226 
00227 int SMDS_VtkVolume::NbNodes() const
00228 {
00229   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
00230   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
00231   int nbPoints = 0;
00232   if (aVtkType != VTK_POLYHEDRON)
00233     {
00234       nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints();
00235     }
00236   else
00237     {
00238       vtkIdType nFaces = 0;
00239       vtkIdType* ptIds = 0;
00240       grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
00241       int id = 0;
00242       for (int i = 0; i < nFaces; i++)
00243         {
00244           int nodesInFace = ptIds[id];
00245           nbPoints += nodesInFace;
00246           id += (nodesInFace + 1);
00247         }
00248     }
00249   return nbPoints;
00250 }
00251 
00252 int SMDS_VtkVolume::NbEdges() const
00253 {
00254   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
00255   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
00256   int nbEdges = 6;
00257   switch (aVtkType)
00258   {
00259     case VTK_TETRA:
00260     case VTK_QUADRATIC_TETRA:
00261       nbEdges = 6;
00262       break;
00263     case VTK_PYRAMID:
00264     case VTK_QUADRATIC_PYRAMID:
00265       nbEdges = 8;
00266       break;
00267     case VTK_WEDGE:
00268     case VTK_QUADRATIC_WEDGE:
00269       nbEdges = 9;
00270       break;
00271     case VTK_HEXAHEDRON:
00272     case VTK_QUADRATIC_HEXAHEDRON:
00273     case VTK_TRIQUADRATIC_HEXAHEDRON:
00274       nbEdges = 12;
00275       break;
00276     case VTK_POLYHEDRON:
00277       {
00278         vtkIdType nFaces = 0;
00279         vtkIdType* ptIds = 0;
00280         grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
00281         nbEdges = 0;
00282         int id = 0;
00283         for (int i = 0; i < nFaces; i++)
00284           {
00285             int edgesInFace = ptIds[id];
00286             id += (edgesInFace + 1);
00287             nbEdges += edgesInFace;
00288           }
00289         nbEdges = nbEdges / 2;
00290         break;
00291       }
00292     case VTK_HEXAGONAL_PRISM:
00293       nbEdges = 18;
00294       break;
00295     default:
00296       MESSAGE("invalid volume type")
00297       ;
00298       nbEdges = 0;
00299       break;
00300   }
00301   return nbEdges;
00302 }
00303 
00307 int SMDS_VtkVolume::NbFaceNodes(const int face_ind) const
00308 {
00309   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
00310   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
00311   int nbNodes = 0;
00312   if (aVtkType == VTK_POLYHEDRON)
00313     {
00314       vtkIdType nFaces = 0;
00315       vtkIdType* ptIds = 0;
00316       grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
00317       int id = 0;
00318       for (int i = 0; i < nFaces; i++)
00319         {
00320           int nodesInFace = ptIds[id];
00321           id += (nodesInFace + 1);
00322           if (i == face_ind - 1)
00323             {
00324               nbNodes = nodesInFace;
00325               break;
00326             }
00327         }
00328     }
00329   return nbNodes;
00330 }
00331 
00336 const SMDS_MeshNode* SMDS_VtkVolume::GetFaceNode(const int face_ind, const int node_ind) const
00337 {
00338   SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId];
00339   vtkUnstructuredGrid* grid = mesh->getGrid();
00340   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
00341   const SMDS_MeshNode* node = 0;
00342   if (aVtkType == VTK_POLYHEDRON)
00343     {
00344       vtkIdType nFaces = 0;
00345       vtkIdType* ptIds = 0;
00346       grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
00347       int id = 0;
00348       for (int i = 0; i < nFaces; i++)
00349         {
00350           int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace]
00351           if (i == face_ind - 1) // first face is number 1
00352             {
00353               if ((node_ind > 0) && (node_ind <= nodesInFace))
00354                 node = mesh->FindNodeVtk(ptIds[id + node_ind]); // ptIds[id+1] : first node
00355               break;
00356             }
00357           id += (nodesInFace + 1);
00358         }
00359     }
00360   return node;
00361 }
00362 
00366 std::vector<int> SMDS_VtkVolume::GetQuantities() const
00367 {
00368   vector<int> quantities;
00369   quantities.clear();
00370   SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId];
00371   vtkUnstructuredGrid* grid = mesh->getGrid();
00372   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
00373   if (aVtkType == VTK_POLYHEDRON)
00374     {
00375       vtkIdType nFaces = 0;
00376       vtkIdType* ptIds = 0;
00377       grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
00378       int id = 0;
00379       for (int i = 0; i < nFaces; i++)
00380         {
00381           int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace]
00382           quantities.push_back(nodesInFace);
00383           id += (nodesInFace + 1);
00384         }
00385     }
00386   return quantities;
00387 }
00388 
00389 SMDS_ElemIteratorPtr SMDS_VtkVolume::elementsIterator(SMDSAbs_ElementType type) const
00390 {
00391   switch (type)
00392   {
00393     case SMDSAbs_Node:
00394       {
00395         SMDSAbs_EntityType aType = this->GetEntityType();
00396         if (aType == SMDSEntity_Polyhedra)
00397           return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorPolyH(SMDS_Mesh::_meshList[myMeshId], myVtkID, aType));
00398         else
00399           return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, aType));
00400       }
00401     default:
00402       MESSAGE("ERROR : Iterator not implemented");
00403       return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL);
00404   }
00405 }
00406 
00407 SMDS_ElemIteratorPtr SMDS_VtkVolume::nodesIteratorToUNV() const
00408 {
00409   return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
00410 }
00411 
00412 SMDS_ElemIteratorPtr SMDS_VtkVolume::interlacedNodesElemIterator() const
00413 {
00414   return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
00415 }
00416 
00417 SMDSAbs_ElementType SMDS_VtkVolume::GetType() const
00418 {
00419   return SMDSAbs_Volume;
00420 }
00421 
00427 const SMDS_MeshNode* SMDS_VtkVolume::GetNode(const int ind) const
00428 {
00429   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
00430   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
00431   vtkIdType npts, *pts;
00432   grid->GetCellPoints( this->myVtkID, npts, pts );
00433   const std::vector<int>& interlace = SMDS_MeshCell::fromVtkOrder( VTKCellType( aVtkType ));
00434   return SMDS_Mesh::_meshList[myMeshId]->FindNodeVtk( pts[ interlace.empty() ? ind : interlace[ind]] );
00435 }
00436 
00437 bool SMDS_VtkVolume::IsQuadratic() const
00438 {
00439   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
00440   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
00441   // TODO quadratic polyhedrons ?
00442   switch (aVtkType)
00443   {
00444     case VTK_QUADRATIC_TETRA:
00445     case VTK_QUADRATIC_PYRAMID:
00446     case VTK_QUADRATIC_WEDGE:
00447     case VTK_QUADRATIC_HEXAHEDRON:
00448     case VTK_TRIQUADRATIC_HEXAHEDRON:
00449       return true;
00450       break;
00451     default:
00452       return false;
00453   }
00454 }
00455 
00456 bool SMDS_VtkVolume::IsPoly() const
00457 {
00458   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
00459   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
00460   return (aVtkType == VTK_POLYHEDRON);
00461 }
00462 
00463 bool SMDS_VtkVolume::IsMediumNode(const SMDS_MeshNode* node) const
00464 {
00465   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
00466   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
00467   int rankFirstMedium = 0;
00468   switch (aVtkType)
00469   {
00470     case VTK_QUADRATIC_TETRA:
00471       rankFirstMedium = 4; // medium nodes are of rank 4 to 9
00472       break;
00473     case VTK_QUADRATIC_PYRAMID:
00474       rankFirstMedium = 5; // medium nodes are of rank 5 to 12
00475       break;
00476     case VTK_QUADRATIC_WEDGE:
00477       rankFirstMedium = 6; // medium nodes are of rank 6 to 14
00478       break;
00479     case VTK_QUADRATIC_HEXAHEDRON:
00480     case VTK_TRIQUADRATIC_HEXAHEDRON:
00481       rankFirstMedium = 8; // medium nodes are of rank 8 to 19
00482       break;
00483     default:
00484       return false;
00485   }
00486   vtkIdType npts = 0;
00487   vtkIdType* pts = 0;
00488   grid->GetCellPoints(myVtkID, npts, pts);
00489   vtkIdType nodeId = node->getVtkId();
00490   for (int rank = 0; rank < npts; rank++)
00491     {
00492       if (pts[rank] == nodeId)
00493         {
00494           if (rank < rankFirstMedium)
00495             return false;
00496           else
00497             return true;
00498         }
00499     }
00500   //throw SALOME_Exception(LOCALIZED("node does not belong to this element"));
00501   MESSAGE("======================================================");
00502   MESSAGE("= IsMediumNode: node does not belong to this element =");
00503   MESSAGE("======================================================");
00504   return false;
00505 }
00506 
00507 int SMDS_VtkVolume::NbCornerNodes() const
00508 {
00509   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
00510   int            nbN = grid->GetCell(myVtkID)->GetNumberOfPoints();
00511   vtkIdType aVtkType = grid->GetCellType(myVtkID);
00512   switch (aVtkType)
00513   {
00514   case VTK_QUADRATIC_TETRA:         return 4;
00515   case VTK_QUADRATIC_PYRAMID:       return 5;
00516   case VTK_QUADRATIC_WEDGE:         return 6;
00517   case VTK_QUADRATIC_HEXAHEDRON:
00518   case VTK_TRIQUADRATIC_HEXAHEDRON: return 8;
00519   default:;
00520   }
00521   return nbN;
00522 }
00523 
00524 SMDSAbs_EntityType SMDS_VtkVolume::GetEntityType() const
00525 {
00526   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
00527   vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
00528 
00529   SMDSAbs_EntityType aType = SMDSEntity_Tetra;
00530   switch (aVtkType)
00531   {
00532     case VTK_TETRA:
00533       aType = SMDSEntity_Tetra;
00534       break;
00535     case VTK_PYRAMID:
00536       aType = SMDSEntity_Pyramid;
00537       break;
00538     case VTK_WEDGE:
00539       aType = SMDSEntity_Penta;
00540       break;
00541     case VTK_HEXAHEDRON:
00542       aType = SMDSEntity_Hexa;
00543       break;
00544     case VTK_QUADRATIC_TETRA:
00545       aType = SMDSEntity_Quad_Tetra;
00546       break;
00547     case VTK_QUADRATIC_PYRAMID:
00548       aType = SMDSEntity_Quad_Pyramid;
00549       break;
00550     case VTK_QUADRATIC_WEDGE:
00551       aType = SMDSEntity_Quad_Penta;
00552       break;
00553     case VTK_QUADRATIC_HEXAHEDRON:
00554       aType = SMDSEntity_Quad_Hexa;
00555       break;
00556     case VTK_TRIQUADRATIC_HEXAHEDRON:
00557       aType = SMDSEntity_TriQuad_Hexa;
00558       break;
00559     case VTK_HEXAGONAL_PRISM:
00560       aType = SMDSEntity_Hexagonal_Prism;
00561       break;
00562 //#ifdef VTK_HAVE_POLYHEDRON
00563     case VTK_POLYHEDRON:
00564       aType = SMDSEntity_Polyhedra;
00565       break;
00566 //#endif
00567     default:
00568       aType = SMDSEntity_Polyhedra;
00569       break;
00570   }
00571   return aType;
00572 }
00573 
00574 vtkIdType SMDS_VtkVolume::GetVtkType() const
00575 {
00576   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
00577   vtkIdType aType = grid->GetCellType(myVtkID);
00578   return aType;
00579 }
00580 
00581 void SMDS_VtkVolume::gravityCenter(SMDS_UnstructuredGrid* grid,
00582                                    const vtkIdType *      nodeIds,
00583                                    int                    nbNodes,
00584                                    double*                result)
00585 {
00586   for (int j = 0; j < 3; j++)
00587     result[j] = 0;
00588   if (nbNodes <= 0)
00589     return;
00590   for (int i = 0; i < nbNodes; i++)
00591     {
00592       double *coords = grid->GetPoint(nodeIds[i]);
00593       for (int j = 0; j < 3; j++)
00594         result[j] += coords[j];
00595     }
00596   for (int j = 0; j < 3; j++)
00597     result[j] = result[j] / nbNodes;
00598   //MESSAGE("center " << result[0] << " " << result[1] << " "  << result[2]);
00599   return;
00600 }
00601 
00602 bool SMDS_VtkVolume::isForward(double* a, double* b, double* c, double* d)
00603 {
00604   double u[3], v[3], w[3];
00605   for (int j = 0; j < 3; j++)
00606     {
00607       //MESSAGE("a,b,c,d " << a[j] << " " << b[j] << " " << c[j] << " " << d[j]);
00608       u[j] = b[j] - a[j];
00609       v[j] = c[j] - a[j];
00610       w[j] = d[j] - a[j];
00611       //MESSAGE("u,v,w " << u[j] << " " << v[j] << " " << w[j]);
00612     }
00613   double prodmixte = (u[1]*v[2] - u[2]*v[1]) * w[0]
00614                    + (u[2]*v[0] - u[0]*v[2]) * w[1]
00615                    + (u[0]*v[1] - u[1]*v[0]) * w[2];
00616   return (prodmixte < 0);
00617 }
00618 
00622 int SMDS_VtkVolume::NbUniqueNodes() const
00623 {
00624   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
00625   return grid->GetCell(myVtkID)->GetNumberOfPoints();
00626 }
00627 
00631 SMDS_ElemIteratorPtr SMDS_VtkVolume::uniqueNodesIterator() const
00632 {
00633   MESSAGE("uniqueNodesIterator");
00634   return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
00635 }