]> SALOME platform Git repositories - modules/smesh.git/commitdiff
Salome HOME
first version of this file needed for the Netgen integration in the SMESH
authornadir <nadir>
Thu, 16 Oct 2003 13:08:16 +0000 (13:08 +0000)
committernadir <nadir>
Thu, 16 Oct 2003 13:08:16 +0000 (13:08 +0000)
Engine.

adm_local/unix/config_files/check_Netgen.m4 [new file with mode: 0644]
resources/mesh_algo_tetra.png [new file with mode: 0644]
resources/mesh_tree_algo_tetra.png [new file with mode: 0644]
src/NETGEN/Makefile.in [new file with mode: 0644]
src/SMESH/SMESH_Tetra_3D.cxx [new file with mode: 0644]
src/SMESH/SMESH_Tetra_3D.hxx [new file with mode: 0644]
src/SMESH_I/SMESH_Tetra_3D_i.cxx [new file with mode: 0644]
src/SMESH_I/SMESH_Tetra_3D_i.hxx [new file with mode: 0644]

diff --git a/adm_local/unix/config_files/check_Netgen.m4 b/adm_local/unix/config_files/check_Netgen.m4
new file mode 100644 (file)
index 0000000..2322d14
--- /dev/null
@@ -0,0 +1,122 @@
+AC_DEFUN([CHECK_NETGEN],[
+
+AC_REQUIRE([AC_PROG_CXX])dnl
+AC_REQUIRE([AC_PROG_CXXCPP])dnl
+
+AC_CHECKING(for Netgen Libraries)
+
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+
+AC_ARG_WITH(netgen,
+           --with-netgen=DIR root directory path of NETGEN installation,
+           WITHNETGEN="yes",WITHNETGEN="no")
+
+NETGEN_INCLUDES=""
+NETGEN_LIBS=""
+
+Netgen_ok=no
+
+if test "$WITHNETGEN" = yes; then
+
+  echo
+  echo -------------------------------------------------
+  echo You are about to choose to use somehow the
+  echo Netgen Library to generate Tetrahedric mesh.
+  echo
+  echo WARNING
+  echo -------
+  echo You should then be sure to have a Netgen Library
+  echo compiled without -DOPENGL compilation option and
+  echo to have the object nglib.o in your library
+  echo libnginterface.a. If it is not the case recompile
+  echo the Netgen distribution accordingly.
+  echo ask your system administrator
+  echo 
+  echo
+  echo -------------------------------------------------
+  echo
+
+  NETGEN_HOME=$withval
+
+  if test "$NETGEN_HOME"; then
+    NETGEN_INCLUDES="-I$NETGEN_HOME/include"
+    NETGEN_LIBS_DIR="$NETGEN_HOME/lib/LINUX"
+    NETGEN_LIBS="-L$NETGEN_LIBS_DIR"
+  fi
+
+  CPPFLAGS_old="$CPPFLAGS"
+  CPPFLAGS="$NETGEN_INCLUDES $CPPFLAGS"
+  CXXFLAGS_old="$CXXFLAGS"
+  CXXFLAGS="$NETGEN_INCLUDES $CXXFLAGS"
+
+  AC_MSG_CHECKING(for Netgen header file)
+
+  AC_CHECK_HEADER(nglib.h,Netgen_ok=yes,Netgen_ok=no)
+  CPPFLAGS="$CPPFLAGS_old"
+  CXXFLAGS="$CXXFLAGS_old"
+
+  if test "$WITHNETGEN" = "yes";then
+    NETGEN_LIBS="-L. -lNETGEN"
+
+    AC_MSG_CHECKING(for Netgen libraries)
+
+    CPPFLAGS_old="$CPPFLAGS"
+    CPPFLAGS="$NETGEN_INCLUDES $CPPFLAGS"
+    CXXFLAGS_old="$CXXFLAGS"
+    CXXFLAGS="$NETGEN_INCLUDES $CXXFLAGS"
+
+    LDFLAGS_old="$LDFLAGS"
+    LDFLAGS="$NETGEN_LIBS $LDFLAGS"
+
+    AC_TRY_COMPILE(#include <iostream.h>
+#include <fstream.h>
+#include "nglib.h"
+,Ng_Init();
+ Ng_Exit();,Netgen_ok=yes;ar x "$NETGEN_LIBS_DIR"/libnginterface.a;
+            ar x "$NETGEN_LIBS_DIR"/libcsg.a;
+            ar x "$NETGEN_LIBS_DIR"/libgprim.a;
+            ar x "$NETGEN_LIBS_DIR"/libmesh.a;
+            ar x "$NETGEN_LIBS_DIR"/libopti.a;
+            ar x "$NETGEN_LIBS_DIR"/libgen.a;
+            ar x "$NETGEN_LIBS_DIR"/libla.a;
+            ar x "$NETGEN_LIBS_DIR"/libstlgeom.a;
+            ar x "$NETGEN_LIBS_DIR"/libgeom2d.a;
+            "$CXX" -shared linopt.o bfgs.o linsearch.o global.o bisect.o meshtool.o refine.o ruler3.o improve3.o adfront3.o tetrarls.o prism2rls.o pyramidrls.o pyramid2rls.o netrule3.o ruler2.o meshclass.o improve2.o adfront2.o netrule2.o triarls.o geomsearch.o secondorder.o meshtype.o parser3.o quadrls.o specials.o parser2.o meshing2.o meshing3.o meshfunc.o localh.o improve2gen.o delaunay.o boundarylayer.o msghandler.o meshfunc2d.o smoothing2.o smoothing3.o topology.o curvedelems.o clusters.o zrefine.o ngexception.o geomtest3d.o geom2d.o geom3d.o adtree.o transform3d.o geomfuncs.o polynomial.o densemat.o vector.o basemat.o sparsmat.o algprim.o brick.o manifold.o bspline2d.o meshsurf.o csgeom.o polyhedra.o curve2d.o singularref.o edgeflw.o solid.o explicitcurve2d.o specpoin.o gencyl.o revolution.o genmesh.o spline3d.o surface.o identify.o triapprox.o meshstlsurface.o stlline.o stltopology.o stltool.o stlgeom.o stlgeomchart.o stlgeommesh.o table.o optmem.o spbita2d.o hashtabl.o sort.o flags.o seti.o bitarray.o array.o symbolta.o mystring.o moveablemem.o spline2d.o splinegeometry2.o ngnewdelete.o nglib.o -o libNETGEN.so;
+            rm -rf adfront2.o adfront3.o adtree.o algprim.o array.o basemat.o bfgs.o bisect.o bitarray.o boundarylayer.o brick.o bspline2d.o clusters.o csgeom.o csgparser.o curve2d.o curvedelems.o delaunay.o densemat.o dynamicmem.o edgeflw.o explicitcurve2d.o extrusion.o flags.o gencyl.o genmesh.o geom2dmesh.o geom2d.o geom3d.o geomfuncs.o geomsearch.o geomtest3d.o global.o hashtabl.o hprefinement.o identify.o importsolution.o improve2gen.o improve2.o improve3.o linopt.o linsearch.o localh.o manifold.o meshclass.o meshfunc2d.o meshfunc.o meshing2.o meshing3.o meshstlsurface.o meshsurf.o meshtool.o meshtype.o moveablemem.o msghandler.o mystring.o netrule2.o netrule3.o ngexception.o nglib.o ngnewdelete.o optmem.o parser2.o parser3.o parthreads.o polyhedra.o polynomial.o prism2rls.o pyramid2rls.o pyramidrls.o quadrls.o readuser.o refine.o revolution.o ruler2.o ruler3.o secondorder.o seti.o singularref.o smoothing2.o smoothing3.o solid.o sort.o sparsmat.o spbita2d.o specials.o specpoin.o spline2d.o spline3d.o splinegeometry2.o stlgeomchart.o stlgeommesh.o stlgeom.o stlline.o stltool.o stltopology.o surface.o symbolta.o table.o tetrarls.o topology.o transform3d.o triapprox.o triarls.o vector.o writeabaqus.o writediffpack.o writefeap.o writefluent.o writepermas.o writetecplot.o writetochnog.o writeuser.o wuchemnitz.o zrefine.o,
+            Netgen_ok=no)
+
+    AC_CACHE_VAL(salome_netgen_lib,[
+                 AC_TRY_LINK(
+#include <iostream.h>
+#include <fstream.h>
+#include "nglib.h"
+,Ng_Init();
+ Ng_Exit();,
+    eval "salome_netgen_lib=yes";rm -rf libNETGEN.so,eval "salome_netgen_lib=no";rm -rf libNETGEN.so)
+  ])
+  Netgen_ok="$salome_netgen_lib"
+
+
+    LDFLAGS="$LDFLAGS_old"
+    CPPFLAGS="$CPPFLAGS_old"
+    CXXFLAGS="$CXXFLAGS_old"
+  fi
+
+
+if test "x$Netgen_ok" = xno ; then
+  AC_MSG_RESULT(no)
+  AC_MSG_WARN(Netgen libraries not found or not properly installed)
+else
+  AC_MSG_RESULT(yes)
+  NETGEN_LIBS="-lNETGEN"
+fi
+fi
+AC_SUBST(NETGEN_INCLUDES)
+AC_SUBST(NETGEN_LIBS)
+AC_SUBST(NETGEN_LIBS_DIR)
+AC_SUBST(WITHNETGEN)
+
+AC_LANG_RESTORE
+
+])dnl
diff --git a/resources/mesh_algo_tetra.png b/resources/mesh_algo_tetra.png
new file mode 100644 (file)
index 0000000..87e50a8
Binary files /dev/null and b/resources/mesh_algo_tetra.png differ
diff --git a/resources/mesh_tree_algo_tetra.png b/resources/mesh_tree_algo_tetra.png
new file mode 100644 (file)
index 0000000..cb75b7e
Binary files /dev/null and b/resources/mesh_tree_algo_tetra.png differ
diff --git a/src/NETGEN/Makefile.in b/src/NETGEN/Makefile.in
new file mode 100644 (file)
index 0000000..7185fce
--- /dev/null
@@ -0,0 +1,152 @@
+# -* Makefile *- 
+#
+# Author : Nadir Bouhamou (CEA)
+# Module : SMESH
+# Date : 10/10/2003
+#
+#
+
+# source path
+top_srcdir=@top_srcdir@
+top_builddir=../..
+srcdir=@srcdir@
+VPATH=.:@srcdir@
+
+@COMMENCE@
+
+# Libraries targets
+LIB = libNETGEN.la
+
+# additionnal information to compil and link file
+CPPFLAGS += -DSOLIDGEOM -DLINUX $(OCC_INCLUDES)
+CXXFLAGS += -DSOLIDGEOM -DLINUX $(OCC_CXXFLAGS)
+
+LDFLAGS += $(OCC_LIBS) -lg2c
+
+NETGEN_LIBS_DIR=@NETGEN_LIBS_DIR@
+
+LIB_OBJ_O = linopt.o \
+       bfgs.o \
+        linsearch.o \
+       global.o \
+       bisect.o \
+       meshtool.o \
+       refine.o \
+       ruler3.o \
+       improve3.o \
+       adfront3.o \
+       tetrarls.o \
+       prism2rls.o \
+       pyramidrls.o \
+       pyramid2rls.o \
+       netrule3.o \
+       ruler2.o \
+       meshclass.o \
+       improve2.o \
+       adfront2.o \
+       netrule2.o \
+       triarls.o \
+       geomsearch.o \
+       secondorder.o \
+       meshtype.o \
+       parser3.o \
+       quadrls.o \
+       specials.o \
+       parser2.o \
+       meshing2.o \
+       meshing3.o \
+       meshfunc.o \
+       localh.o \
+       improve2gen.o \
+       delaunay.o \
+       boundarylayer.o \
+       msghandler.o \
+       meshfunc2d.o \
+       smoothing2.o \
+       smoothing3.o \
+       topology.o \
+       curvedelems.o \
+       clusters.o \
+       zrefine.o \
+       ngexception.o \
+       geomtest3d.o \
+       geom2d.o \
+       geom3d.o \
+       adtree.o \
+       transform3d.o \
+       geomfuncs.o \
+       polynomial.o \
+       densemat.o \
+       vector.o \
+       basemat.o \
+       sparsmat.o \
+       algprim.o \
+       brick.o \
+       manifold.o \
+       bspline2d.o \
+       meshsurf.o \
+       csgeom.o \
+       polyhedra.o \
+       curve2d.o \
+       singularref.o \
+       edgeflw.o \
+       solid.o \
+       explicitcurve2d.o \
+       specpoin.o \
+       gencyl.o \
+       revolution.o \
+       genmesh.o \
+       spline3d.o \
+       surface.o \
+       identify.o \
+       triapprox.o \
+       meshstlsurface.o \
+       stlline.o \
+       stltopology.o \
+       stltool.o \
+       stlgeom.o \
+       stlgeomchart.o \
+       stlgeommesh.o \
+       table.o \
+       optmem.o \
+       spbita2d.o \
+       hashtabl.o \
+       sort.o \
+       flags.o \
+       seti.o \
+       bitarray.o \
+       array.o \
+       symbolta.o \
+       mystring.o \
+       moveablemem.o \
+       spline2d.o \
+       splinegeometry2.o \
+       ngnewdelete.o \
+       nglib.o
+
+$(LIB_OBJ_O):
+       ar x $(NETGEN_LIBS_DIR)/libnginterface.a
+       ar x $(NETGEN_LIBS_DIR)/libcsg.a
+       ar x $(NETGEN_LIBS_DIR)/libgprim.a
+       ar x $(NETGEN_LIBS_DIR)/libmesh.a
+       ar x $(NETGEN_LIBS_DIR)/libopti.a
+       ar x $(NETGEN_LIBS_DIR)/libgen.a
+       ar x $(NETGEN_LIBS_DIR)/libla.a
+       ar x $(NETGEN_LIBS_DIR)/libstlgeom.a
+       ar x $(NETGEN_LIBS_DIR)/libgeom2d.a
+       rm -rf sgparser.o hprefinement.o parthreads.o writediffpack.o writepermas.o writeuser.o dynamicmem.o importsolution.o readuser.o writefeap.o writetecplot.o wuchemnitz.o extrusion.o writeabaqus.o writefluent.o writetochnog.o csgparser.o geom2dmesh.o
+
+LIB_OBJ_LO = $(LIB_OBJ_O:%.o=%.lo)
+
+#implicits rules
+
+.o.lo:
+       ln -s $< $@ || true
+
+@CONCLUDE@
+
+$(LIB): $(LIB_OBJ_O) $(LIB_OBJ_LO)
+       @$(LT) --mode=link $(CXX) -rpath $(libdir) -o $@ $(CXXFLAGS) $(LIB_OBJ_LO) $(LDFLAGS) $(LIBS)
+
+mostlyclean: cleandep
+       -$(RM) $(LIB_OBJ_O) $(LIB_OBJ_LO)
diff --git a/src/SMESH/SMESH_Tetra_3D.cxx b/src/SMESH/SMESH_Tetra_3D.cxx
new file mode 100644 (file)
index 0000000..4392d18
--- /dev/null
@@ -0,0 +1,1227 @@
+//=============================================================================
+// File      : SMESH_Tetra_3D.cxx
+// Created   : lundi 27 Janvier 2003
+// Author    : Nadir BOUHAMOU (CEA)
+// Project   : SALOME
+// Copyright : CEA 2003
+// $Header$
+//=============================================================================
+using namespace std;
+
+#include "SMESH_Tetra_3D.hxx"
+#include "SMESH_MEFISTO_2D.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_Mesh.hxx"
+
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_FacePosition.hxx"
+
+#include <TopExp.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TColStd_ListIteratorOfListOfInteger.hxx>
+
+#include <BRep_Tool.hxx>
+#include <Geom_Surface.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom2d_Curve.hxx>
+
+#include "utilities.h"
+
+/*
+  Netgen include files
+*/
+
+#include "nglib.h"
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+SMESH_Tetra_3D::SMESH_Tetra_3D(int hypId, int studyId,
+                            SMESH_Gen* gen)
+  : SMESH_3D_Algo(hypId, studyId, gen)
+{
+  MESSAGE("SMESH_Tetra_3D::SMESH_Tetra_3D");
+  _name = "Tetra_3D";
+//   _shapeType = TopAbs_SOLID;
+  _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);// 1 bit /shape type
+//   MESSAGE("_shapeType octal " << oct << _shapeType);
+  _compatibleHypothesis.push_back("MaxElementVolume");
+
+  _maxElementVolume = 0.;
+
+  _hypMaxElementVolume = NULL;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+SMESH_Tetra_3D::~SMESH_Tetra_3D()
+{
+  MESSAGE("SMESH_Tetra_3D::~SMESH_Tetra_3D");
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+bool SMESH_Tetra_3D::CheckHypothesis(SMESH_Mesh& aMesh,
+                                    const TopoDS_Shape& aShape)
+{
+  MESSAGE("SMESH_Tetra_3D::CheckHypothesis");
+
+  _hypMaxElementVolume = NULL;
+
+  list<const SMESHDS_Hypothesis*>::const_iterator itl;
+  const SMESHDS_Hypothesis* theHyp;
+
+  const list<const SMESHDS_Hypothesis*>& hyps = GetUsedHypothesis(aMesh, aShape);
+  int nbHyp = hyps.size();
+  if (nbHyp != 1) return false;  // only one compatible hypothesis allowed
+
+  itl = hyps.begin();
+  theHyp = (*itl);
+
+  string hypName = theHyp->GetName();
+  int hypId = theHyp->GetID();
+  SCRUTE(hypName);
+
+  bool isOk = false;
+
+  if (hypName == "MaxElementVolume")
+    {
+      _hypMaxElementVolume = static_cast<const SMESH_MaxElementVolume*> (theHyp);
+      ASSERT(_hypMaxElementVolume);
+      _maxElementVolume = _hypMaxElementVolume->GetMaxVolume();
+      isOk =true;
+    }
+
+  return isOk;
+}
+
+//=============================================================================
+/*!
+ *Here we are going to use the NETGEN mesher
+ */
+//=============================================================================
+
+bool SMESH_Tetra_3D::Compute(SMESH_Mesh& aMesh,
+                            const TopoDS_Shape& aShape)
+  throw (SALOME_Exception)
+{
+  MESSAGE("SMESH_Tetra_3D::Compute with maxElmentsize = " << _maxElementVolume);
+
+  bool isOk = false;
+  SMESHDS_Mesh* meshDS = aMesh.GetMeshDS();
+  SMESH_subMesh* theSubMesh = aMesh.GetSubMesh(aShape);
+  //const Handle(SMESHDS_SubMesh)& subMeshDS = theSubMesh->GetSubMeshDS();
+
+  map<int, const SMDS_MeshNode*> netgenToDS;
+
+  MESSAGE("SMESH_Tetra_3D::Compute Checking the mesh Faces");
+
+  // check if all faces were meshed by a triangle mesher (here MESFISTO_2D)
+
+  vector<SMESH_subMesh*> meshFaces;
+  vector<TopoDS_Shape> shapeFaces;
+
+  for (TopExp_Explorer exp(aShape,TopAbs_FACE);exp.More();exp.Next())
+    {
+      TopoDS_Shape aShapeFace = exp.Current();
+      SMESH_subMesh* aSubMesh = aMesh.GetSubMeshContaining(exp.Current());
+      ASSERT (aSubMesh);
+      int internal_size = meshFaces.size();
+      int index = 0;
+      for (int i = 0;i<internal_size;i++)
+       {
+         if (aSubMesh == meshFaces[i]) index = 1;
+       }
+      if (index == 0) meshFaces.push_back(aSubMesh);
+
+      internal_size = shapeFaces.size();
+      index = 0;
+      for (int i = 0;i<internal_size;i++)
+       {
+         if (aShapeFace == shapeFaces[i]) index = 1;
+       }
+      if (index == 0) shapeFaces.push_back(aShapeFace);
+    }
+
+  int numberOfFaces = meshFaces.size();
+  int numberOfShapeFaces = shapeFaces.size();
+
+  SCRUTE(numberOfFaces);
+  SCRUTE(numberOfShapeFaces);
+
+  MESSAGE("---");
+
+  int NbTotOfTria = 0;
+  int NbTotOfNodesFaces = 0;
+
+  for (int i=0; i<numberOfFaces; i++)
+    {
+      TopoDS_Shape aShapeFace = meshFaces[i]->GetSubShape();
+      TopoDS_Shape aFace = shapeFaces[i];
+      SMESH_Algo* algoFace = _gen->GetAlgo(aMesh, aShapeFace);
+      string algoFaceName = algoFace->GetName();
+      SCRUTE(algoFaceName);
+      if (algoFaceName != "MEFISTO_2D")
+       {
+         SCRUTE(algoFaceName);
+         ASSERT(0);
+         return false;
+       }
+
+      bool orientationMeshFace = (aFace.Orientation() == aShapeFace.Orientation());
+
+      const SMESHDS_SubMesh* aSubMeshDSFace = meshFaces[i]->GetSubMeshDS();
+      SCRUTE(aSubMeshDSFace);
+
+      int nbNodes = aSubMeshDSFace->NbNodes();
+      NbTotOfNodesFaces += nbNodes;
+      int nbTria = aSubMeshDSFace->NbElements();
+      NbTotOfTria += nbTria;
+      int index = 0;
+
+      MESSAGE("SMESH_Tetra_3D::Compute The mesh Face " << (i+1) << " has " << nbNodes << " face internal Nodes, " << nbTria << " triangles");
+
+      SCRUTE(orientationMeshFace);
+
+      if (orientationMeshFace)
+       {
+         MESSAGE("The mesh and face have the same orientation");
+       }
+      else
+       {
+         MESSAGE("The mesh and face have different orientations");
+       }
+
+      SMDS_Iterator<const SMDS_MeshNode *> * iteratorNodes = aSubMeshDSFace->GetNodes();
+      SCRUTE(nbNodes);
+      index = 0;
+      while(iteratorNodes->more())
+       {
+         index++;
+         const SMDS_MeshNode * node = iteratorNodes->next();
+         int nodeId = node->GetID();
+         double nodeX = node->X();
+         double nodeY = node->Y();
+         double nodeZ = node->Z();
+         MESSAGE("NODE -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ);
+       }
+      delete iteratorNodes;
+
+      SCRUTE(index);
+
+      SMDS_Iterator<const SMDS_MeshElement *> * iteratorTriangle = aSubMeshDSFace->GetElements();
+
+      SCRUTE(nbTria);
+      index = 0;
+      while(iteratorTriangle->more())
+       {
+         index++;
+         const SMDS_MeshElement * triangle = iteratorTriangle->next();
+         int triangleId = triangle->GetID();
+
+         SMDS_Iterator<const SMDS_MeshElement *> * triangleNodesIt = triangle->nodesIterator();
+
+         int triangleNode1 = (triangleNodesIt->next())->GetID();
+         int triangleNode2 = (triangleNodesIt->next())->GetID();
+         int triangleNode3 = (triangleNodesIt->next())->GetID();
+
+         MESSAGE("TRIANGLE -> ID = " << triangleId << " N1 = " << triangleNode1 << " N2 = " << triangleNode2 << " N3 = " << triangleNode3);
+
+       }
+      delete iteratorTriangle;
+
+      SCRUTE(index);
+    }
+
+  SCRUTE(NbTotOfTria);
+  SCRUTE(NbTotOfNodesFaces);
+
+  MESSAGE("SMESH_Tetra_3D::Compute Checking the mesh Edges");
+
+  // check if all edges were meshed by a edge mesher (here Regular_1D)
+
+  vector<SMESH_subMesh*> meshEdges;
+  for (TopExp_Explorer exp(aShape,TopAbs_EDGE);exp.More();exp.Next())
+    {
+      SMESH_subMesh* aSubMesh = aMesh.GetSubMeshContaining(exp.Current());
+      ASSERT (aSubMesh);
+      int internal_size = meshEdges.size();
+      int index = 0;
+      for (int i = 0;i<internal_size;i++)
+       {
+         if (aSubMesh == meshEdges[i]) index = 1;
+       }
+      if (index == 0) meshEdges.push_back(aSubMesh);
+    }
+
+  int numberOfEdges = meshEdges.size();
+  SCRUTE(numberOfEdges);
+
+  MESSAGE("---");
+
+  int NbTotOfNodesEdges = 0;
+  int NbTotOfSegs = 0;
+
+  for (int i=0; i<numberOfEdges; i++)
+    {
+      TopoDS_Shape aShapeEdge = meshEdges[i]->GetSubShape();
+      SMESH_Algo* algoEdge = _gen->GetAlgo(aMesh, aShapeEdge);
+      string algoEdgeName = algoEdge->GetName();
+      SCRUTE(algoEdgeName);
+      if (algoEdgeName != "Regular_1D")
+       {
+         SCRUTE(algoEdgeName);
+         ASSERT(0);
+         return false;
+       }
+
+      const SMESHDS_SubMesh* aSubMeshDSEdge = meshEdges[i]->GetSubMeshDS();
+      SCRUTE(aSubMeshDSEdge);
+
+      int nbNodes = aSubMeshDSEdge->NbNodes();
+      NbTotOfNodesEdges += nbNodes;
+      int nbSegs = aSubMeshDSEdge->NbElements();
+      NbTotOfSegs += nbSegs;
+
+      MESSAGE("SMESH_Tetra_3D::Compute The mesh Edge " << (i+1) << " has " << nbNodes << " edge internal Nodes, " << nbSegs << " segments");
+
+      SMDS_Iterator<const SMDS_MeshNode *> * iteratorNodes = aSubMeshDSEdge->GetNodes();
+      SCRUTE(nbNodes);
+      int index = 0;
+      while(iteratorNodes->more())
+       {
+         index++;
+         const SMDS_MeshNode * node = iteratorNodes->next();
+         int nodeId = node->GetID();
+         double nodeX = node->X();
+         double nodeY = node->Y();
+         double nodeZ = node->Z();
+         MESSAGE("NODE -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ);
+       }
+      delete iteratorNodes;
+
+      SCRUTE(index);
+    }
+
+  SCRUTE(NbTotOfNodesEdges);
+  SCRUTE(NbTotOfSegs);
+
+  MESSAGE("SMESH_Tetra_3D::Compute Checking the mesh Vertices");
+
+  vector<SMESH_subMesh*> meshVertices;
+  for (TopExp_Explorer exp(aShape,TopAbs_VERTEX);exp.More();exp.Next())
+    {
+      SMESH_subMesh* aSubMesh = aMesh.GetSubMeshContaining(exp.Current());
+      ASSERT (aSubMesh);
+      int internal_size = meshVertices.size();
+      int index = 0;
+      for (int i = 0;i<internal_size;i++)
+       {
+         if (aSubMesh == meshVertices[i]) index = 1;
+       }
+      if (index == 0) meshVertices.push_back(aSubMesh);
+    }
+
+  int numberOfVertices = meshVertices.size();
+  SCRUTE(numberOfVertices);
+
+  MESSAGE("---");
+
+  int NbTotOfNodesVertices = 0;
+
+  for (int i=0; i<numberOfVertices; i++)
+    {
+      TopoDS_Shape aShapeVertex = meshVertices[i]->GetSubShape();
+
+      const SMESHDS_SubMesh * aSubMeshDSVertex = meshVertices[i]->GetSubMeshDS();
+      SCRUTE(aSubMeshDSVertex);
+
+      int nbNodes = aSubMeshDSVertex->NbNodes();
+      NbTotOfNodesVertices += nbNodes;
+
+      MESSAGE("SMESH_Tetra_3D::Compute The mesh Vertex " << (i+1) << " has " << nbNodes << " Nodes");
+
+      SMDS_Iterator<const SMDS_MeshNode *> * iteratorNodes = aSubMeshDSVertex->GetNodes();
+      SCRUTE(nbNodes);
+      int index = 0;
+      while(iteratorNodes->more())
+       {
+         index++;
+         const SMDS_MeshNode * node = iteratorNodes->next();
+         int nodeId = node->GetID();
+         double nodeX = node->X();
+         double nodeY = node->Y();
+         double nodeZ = node->Z();
+         MESSAGE("NODE -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ);
+       }
+      delete iteratorNodes;
+
+      SCRUTE(index);
+    }
+
+  SCRUTE(NbTotOfNodesVertices);
+
+  MESSAGE("SMESH_Tetra_3D::Compute --> Analysis of all shell mesh");
+
+  vector<SMESH_subMesh*> meshShells;
+  TopoDS_Shell aShell;
+
+  for (TopExp_Explorer exp(aShape,TopAbs_SHELL);exp.More();exp.Next())
+    {
+      SMESH_subMesh* aSubMesh = aMesh.GetSubMesh(exp.Current());
+      ASSERT(aSubMesh);
+      SCRUTE(aSubMesh);
+      aShell = TopoDS::Shell(exp.Current());
+      meshShells.push_back(aSubMesh);
+    }
+
+  int numberOfShells = meshShells.size();
+  SCRUTE(numberOfShells);
+
+  if (numberOfShells == 1)
+    {
+      MESSAGE("SMESH_Tetra_3D::Compute Only one shell --> generation of the mesh using directly Netgen");
+
+      /*
+       Prepare the Netgen surface mesh from the SMESHDS
+      */
+
+      MESSAGE("SMESH_Tetra_3D::Compute Prepare the Netgen surface mesh from the SMESHDS");
+
+      int spaceDimension = 3;
+      int nbNodesByTri = 3;
+      int nbNodesByTetra = 4;
+
+      int Netgen_NbOfNodes = NbTotOfNodesFaces +
+                            NbTotOfNodesEdges +
+                            NbTotOfNodesVertices;
+      int Netgen_NbOfTria = NbTotOfTria;
+      int Netgen_param2ndOrder = 0;
+      double Netgen_paramFine = 1.;
+      double Netgen_paramSize = _maxElementVolume;
+
+      SCRUTE(Netgen_NbOfNodes);
+      SCRUTE(Netgen_NbOfTria);
+
+      double * Netgen_Coordinates = new double [spaceDimension*
+                                               Netgen_NbOfNodes];
+      int * listNodeCoresNetgenSmesh = new int [Netgen_NbOfNodes];
+      int * Netgen_Connectivity = new int [nbNodesByTri*Netgen_NbOfTria];
+      double * Netgen_point = new double [spaceDimension];
+      int * Netgen_triangle = new int [nbNodesByTri];
+      int * Netgen_tetrahedron = new int [nbNodesByTetra];
+
+      for (int i=0; i<Netgen_NbOfTria; i++)
+       {
+         for (int j=0; j<nbNodesByTri; j++)
+           Netgen_Connectivity[i*nbNodesByTri+j] = 0;
+       }
+
+      double bigNumber = 1.e20;
+
+      for (int i=0; i<Netgen_NbOfNodes; i++)
+       {
+         listNodeCoresNetgenSmesh[i] = 0;
+         for (int j=0; j<spaceDimension; j++)
+           Netgen_Coordinates[i*spaceDimension+j] = bigNumber;
+       }
+
+      int indexNodes = 0;
+      for (int i=0; i<numberOfVertices; i++)
+       {
+         const SMESHDS_SubMesh * aSubMeshDSVertex =
+           meshVertices[i]->GetSubMeshDS();
+
+//       const TColStd_ListOfInteger& indEltNodes =
+//         aSubMeshDSVertex->GetIDNodes();
+
+//       TColStd_ListIteratorOfListOfInteger itNodes(indEltNodes);
+
+//       for (; itNodes.More(); itNodes.Next())
+//         {
+//           int nodeId = itNodes.Value();
+//           Handle (SMDS_MeshElement) elt = meshDS->FindNode(nodeId);
+//           Handle (SMDS_MeshNode) node = meshDS->GetNode(1, elt);
+//           //MESSAGE("NODE -> ID = " << node->GetID() << " X = " << node->X() << " Y = " << node->Y() << " Z = " << node->Z());
+//           listNodeCoresNetgenSmesh[indexNodes] = node->GetID();
+//           int index = indexNodes*spaceDimension;
+//           Netgen_Coordinates[index] = node->X();
+//           Netgen_Coordinates[index+1] = node->Y();
+//           Netgen_Coordinates[index+2] = node->Z();
+//           indexNodes++;
+//         }
+
+         SMDS_Iterator<const SMDS_MeshNode *> * iteratorNodes = aSubMeshDSVertex->GetNodes();
+
+         while(iteratorNodes->more())
+           {
+             const SMDS_MeshNode * node = iteratorNodes->next();
+             int nodeId = node->GetID();
+             double nodeX = node->X();
+             double nodeY = node->Y();
+             double nodeZ = node->Z();
+             MESSAGE("NODE -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ);
+             listNodeCoresNetgenSmesh[indexNodes] = nodeId;
+             int index = indexNodes*spaceDimension;
+             Netgen_Coordinates[index] = nodeX;
+             Netgen_Coordinates[index+1] = nodeY;
+             Netgen_Coordinates[index+2] = nodeZ;
+             netgenToDS[indexNodes] = node;
+             indexNodes++;
+           }
+         delete iteratorNodes;
+       }
+
+      for (int i=0; i<numberOfEdges; i++)
+       {
+         const SMESHDS_SubMesh *  aSubMeshDSEdge =
+           meshEdges[i]->GetSubMeshDS();
+
+//       const TColStd_ListOfInteger& indEltNodes =
+//         aSubMeshDSEdge->GetIDNodes();
+
+//       TColStd_ListIteratorOfListOfInteger itNodes(indEltNodes);
+
+//       for (; itNodes.More(); itNodes.Next())
+//         {
+//           int nodeId = itNodes.Value();
+//           Handle (SMDS_MeshElement) elt = meshDS->FindNode(nodeId);
+//           Handle (SMDS_MeshNode) node = meshDS->GetNode1, elt);
+//           //MESSAGE("NODE -> ID = " << node->GetID() << " X = " << node->X() << " Y = " << node->Y() << " Z = " << node->Z());
+//           listNodeCoresNetgenSmesh[indexNodes] = node->GetID();
+//           int index = indexNodes*spaceDimension;
+//           Netgen_Coordinates[index] = node->X();
+//           Netgen_Coordinates[index+1] = node->Y();
+//           Netgen_Coordinates[index+2] = node->Z();
+//           indexNodes++;
+//         }
+
+         SMDS_Iterator<const SMDS_MeshNode *> * iteratorNodes = aSubMeshDSEdge->GetNodes();
+
+         while(iteratorNodes->more())
+           {
+             const SMDS_MeshNode * node = iteratorNodes->next();
+             int nodeId = node->GetID();
+             double nodeX = node->X();
+             double nodeY = node->Y();
+             double nodeZ = node->Z();
+             MESSAGE("NODE -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ);
+             listNodeCoresNetgenSmesh[indexNodes] = node->GetID();
+             int index = indexNodes*spaceDimension;
+             Netgen_Coordinates[index] = node->X();
+             Netgen_Coordinates[index+1] = node->Y();
+             Netgen_Coordinates[index+2] = node->Z();
+             netgenToDS[indexNodes] = node;
+             indexNodes++;
+           }
+         delete iteratorNodes;
+       }
+
+      for (int i=0; i<numberOfFaces; i++)
+       {
+         const SMESHDS_SubMesh * aSubMeshDSFace =
+           meshFaces[i]->GetSubMeshDS();
+
+//       const TColStd_ListOfInteger& indEltNodes =
+//         aSubMeshDSFace->GetIDNodes();
+
+//       TColStd_ListIteratorOfListOfInteger itNodes(indEltNodes);
+
+//       for (; itNodes.More(); itNodes.Next())
+//         {
+//           int nodeId = itNodes.Value();
+//           Handle (SMDS_MeshElement) elt = meshDS->FindNode(nodeId);
+//           Handle (SMDS_MeshNode) node = meshDS->GetNode(1, elt);
+//           //MESSAGE("NODE -> ID = " << node->GetID() << " X = " << node->X() << " Y = " << node->Y() << " Z = " << node->Z());
+//           listNodeCoresNetgenSmesh[indexNodes] = nodeId;
+//           int index = indexNodes*spaceDimension;
+//           Netgen_Coordinates[index] = nodeX;
+//           Netgen_Coordinates[index+1] = nodeY;
+//           Netgen_Coordinates[index+2] = nodeZ;
+//           indexNodes++;
+//         }
+
+         SMDS_Iterator<const SMDS_MeshNode *> * iteratorNodes = aSubMeshDSFace->GetNodes();
+
+         while(iteratorNodes->more())
+           {
+             const SMDS_MeshNode * node = iteratorNodes->next();
+             int nodeId = node->GetID();
+             double nodeX = node->X();
+             double nodeY = node->Y();
+             double nodeZ = node->Z();
+             MESSAGE("NODE -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ);
+             listNodeCoresNetgenSmesh[indexNodes] = nodeId;
+             int index = indexNodes*spaceDimension;
+             Netgen_Coordinates[index] = nodeX;
+             Netgen_Coordinates[index+1] = nodeY;
+             Netgen_Coordinates[index+2] = nodeZ;
+             netgenToDS[indexNodes] = node;
+             indexNodes++;
+           }
+         delete iteratorNodes;
+       }
+
+      SCRUTE(indexNodes);
+
+      for (int i=0; i<Netgen_NbOfNodes; i++)
+       {
+         ASSERT(listNodeCoresNetgenSmesh[i] != 0);
+
+         for (int j=0; j<Netgen_NbOfNodes && j!=i; j++)
+           ASSERT(listNodeCoresNetgenSmesh[i] != listNodeCoresNetgenSmesh[j]);
+
+         for (int j=0; j<spaceDimension; j++)
+           ASSERT(Netgen_Coordinates[i*spaceDimension+j] != bigNumber);
+       }
+
+      int indexTrias = 0;
+      for (int i=0; i<numberOfFaces; i++)
+       {
+         const SMESHDS_SubMesh * aSubMeshDSFace =
+           meshFaces[i]->GetSubMeshDS();
+
+         TopoDS_Shape aFace = shapeFaces[i];
+
+//       const TColStd_ListOfInteger& indEltTria =
+//         aSubMeshDSFace->GetIDElements();
+
+         SMDS_Iterator<const SMDS_MeshElement *> * iteratorTriangle = aSubMeshDSFace->GetElements();
+
+         TopoDS_Shape aShapeFace = meshFaces[i]->GetSubShape();
+
+         bool orientationMeshFace = (aFace.Orientation() == aShapeFace.Orientation());
+
+         SCRUTE(orientationMeshFace);
+
+         if (orientationMeshFace)
+           {
+             MESSAGE("The mesh and face have the same orientation");
+
+//           for (TColStd_ListIteratorOfListOfInteger itTrias(indEltTria); itTrias.More(); itTrias.Next())
+//             {
+//               int triangleId = itTrias.Value();
+//               Handle (SMDS_MeshElement) elt = meshDS->FindElement(triangleId);
+//               int index = indexTrias*nbNodesByTri;
+//               int N1 = elt->GetConnection(1);
+//               int N2 = elt->GetConnection(2);
+//               int N3 = elt->GetConnection(3);
+
+//               int N1New = 0;
+//               int N2New = 0;
+//               int N3New = 0;
+
+//               for (int j=0; j<Netgen_NbOfNodes; j++)
+//                 {
+//                   int jp1 = j+1;
+
+//                   if (N1 == listNodeCoresNetgenSmesh[j])
+//                     N1New = jp1;
+//                   else if (N2 == listNodeCoresNetgenSmesh[j])
+//                     N2New = jp1;
+//                   else if (N3 == listNodeCoresNetgenSmesh[j])
+//                     N3New = jp1;
+//                 }
+
+//               N1 = N1New;
+//               N2 = N2New;
+//               N3 = N3New;
+
+//               Netgen_Connectivity[index] = N1;
+//               Netgen_Connectivity[index+1] = N2;
+//               Netgen_Connectivity[index+2] = N3;
+//               indexTrias++;
+//             }
+
+             while(iteratorTriangle->more())
+               {
+                 const SMDS_MeshElement * triangle = iteratorTriangle->next();
+                 int triangleId = triangle->GetID();
+
+                 SMDS_Iterator<const SMDS_MeshElement *> * triangleNodesIt = triangle->nodesIterator();
+
+                 int triangleNode1 = (triangleNodesIt->next())->GetID();
+                 int triangleNode2 = (triangleNodesIt->next())->GetID();
+                 int triangleNode3 = (triangleNodesIt->next())->GetID();
+
+                 MESSAGE("TRIANGLE -> ID = " << triangleId << " N1 = " << triangleNode1 << " N2 = " << triangleNode2 << " N3 = " << triangleNode3);
+
+                 int N1New = 0;
+                 int N2New = 0;
+                 int N3New = 0;
+                 int index = indexTrias*nbNodesByTri;
+
+                 for (int j=0; j<Netgen_NbOfNodes; j++)
+                   {
+                     int jp1 = j+1;
+
+                     if (triangleNode1 == listNodeCoresNetgenSmesh[j])
+                       N1New = jp1;
+                     else if (triangleNode2 == listNodeCoresNetgenSmesh[j])
+                       N2New = jp1;
+                     else if (triangleNode3 == listNodeCoresNetgenSmesh[j])
+                       N3New = jp1;
+                   }
+
+                 triangleNode1 = N1New;
+                 triangleNode2 = N2New;
+                 triangleNode3 = N3New;
+
+                 Netgen_Connectivity[index] = triangleNode1;
+                 Netgen_Connectivity[index+1] = triangleNode2;
+                 Netgen_Connectivity[index+2] = triangleNode3;
+
+                 indexTrias++;
+               }
+             delete iteratorTriangle;
+           }
+         else
+           {
+             MESSAGE("The mesh and face have different orientations");
+
+//           for (TColStd_ListIteratorOfListOfInteger itTrias(indEltTria); itTrias.More(); itTrias.Next())
+//             {
+//               int triangleId = itTrias.Value();
+//               Handle (SMDS_MeshElement) elt = meshDS->FindElement(triangleId);
+//               int index = indexTrias*nbNodesByTri;
+//               int N1 = elt->GetConnection(1);
+//               int N2 = elt->GetConnection(3);
+//               int N3 = elt->GetConnection(2);
+
+//               int N1New = 0;
+//               int N2New = 0;
+//               int N3New = 0;
+
+//               for (int j=0; j<Netgen_NbOfNodes; j++)
+//                 {
+//                   int jp1 = j+1;
+
+//                   if (N1 == listNodeCoresNetgenSmesh[j])
+//                     N1New = jp1;
+//                   else if (N2 == listNodeCoresNetgenSmesh[j])
+//                     N2New = jp1;
+//                   else if (N3 == listNodeCoresNetgenSmesh[j])
+//                     N3New = jp1;
+//                 }
+
+//               N1 = N1New;
+//               N2 = N2New;
+//               N3 = N3New;
+
+//               Netgen_Connectivity[index] = N1;
+//               Netgen_Connectivity[index+1] = N2;
+//               Netgen_Connectivity[index+2] = N3;
+//               indexTrias++;
+//             }
+
+             while(iteratorTriangle->more())
+               {
+                 const SMDS_MeshElement * triangle = iteratorTriangle->next();
+                 int triangleId = triangle->GetID();
+
+                 SMDS_Iterator<const SMDS_MeshElement *> * triangleNodesIt = triangle->nodesIterator();
+
+                 int triangleNode1 = (triangleNodesIt->next())->GetID();
+                 int triangleNode3 = (triangleNodesIt->next())->GetID();
+                 int triangleNode2 = (triangleNodesIt->next())->GetID();
+
+                 MESSAGE("TRIANGLE -> ID = " << triangleId << " N1 = " << triangleNode1 << " N2 = " << triangleNode2 << " N3 = " << triangleNode3);
+
+                 int N1New = 0;
+                 int N2New = 0;
+                 int N3New = 0;
+                 int index = indexTrias*nbNodesByTri;
+
+                 for (int j=0; j<Netgen_NbOfNodes; j++)
+                   {
+                     int jp1 = j+1;
+
+                     if (triangleNode1 == listNodeCoresNetgenSmesh[j])
+                       N1New = jp1;
+                     else if (triangleNode2 == listNodeCoresNetgenSmesh[j])
+                       N2New = jp1;
+                     else if (triangleNode3 == listNodeCoresNetgenSmesh[j])
+                       N3New = jp1;
+                   }
+
+                 triangleNode1 = N1New;
+                 triangleNode2 = N2New;
+                 triangleNode3 = N3New;
+
+                 Netgen_Connectivity[index] = triangleNode1;
+                 Netgen_Connectivity[index+1] = triangleNode2;
+                 Netgen_Connectivity[index+2] = triangleNode3;
+
+                 indexTrias++;
+               }
+             delete iteratorTriangle;
+           }
+       }
+
+      SCRUTE(indexTrias);
+
+      int * nodesUsed = new int[Netgen_NbOfNodes];
+
+      for (int i=0; i<Netgen_NbOfNodes; i++) nodesUsed[i] = 0;
+
+      for (int i=0; i<Netgen_NbOfTria; i++)
+       for (int j=0; j<nbNodesByTri; j++)
+         {
+           int Nij = Netgen_Connectivity[i*nbNodesByTri+j];
+
+           ASSERT((Nij>=1) && (Nij<=Netgen_NbOfNodes));
+
+           nodesUsed[Nij-1] = 1;
+           Netgen_Connectivity[i*nbNodesByTri+j] = Nij;
+         }
+
+      for (int i=0; i<Netgen_NbOfNodes; i++)
+       {
+         ASSERT(nodesUsed[i] != 0);
+       }
+
+      delete [] nodesUsed;
+
+      /*
+       Feed the Netgen surface mesh
+      */
+
+      MESSAGE("SMESH_Tetra_3D::Compute Feed the Netgen surface mesh");
+
+      Ng_Mesh * Netgen_mesh;
+
+      Ng_Init();
+
+      Netgen_mesh = Ng_NewMesh();
+
+      Ng_Meshing_Parameters Netgen_param;
+
+      for (int i=0; i<Netgen_NbOfNodes; i++)
+       {
+         for (int j=0; j<spaceDimension; j++)
+           Netgen_point[j] = Netgen_Coordinates[i*spaceDimension+j];
+
+         Ng_AddPoint(Netgen_mesh, Netgen_point);
+       }
+
+      for (int i=0; i<Netgen_NbOfTria; i++)
+       {
+         for (int j=0; j<nbNodesByTri; j++)
+           Netgen_triangle[j] = Netgen_Connectivity[i*nbNodesByTri+j];
+
+         Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle);
+       }
+
+      SCRUTE(Netgen_paramSize);
+
+      Netgen_param.secondorder = Netgen_param2ndOrder;
+      Netgen_param.fineness = Netgen_paramFine;
+      Netgen_param.maxh = Netgen_paramSize;
+
+      /*
+       Generate the volume mesh
+      */
+
+      MESSAGE("SMESH_Tetra_3D::Compute Generate the volume mesh");
+
+      SCRUTE(Netgen_NbOfNodes);
+      SCRUTE(Netgen_NbOfTria);
+
+      SCRUTE(Ng_GetNP(Netgen_mesh));
+      SCRUTE(Ng_GetNE(Netgen_mesh));
+      SCRUTE(Ng_GetNSE(Netgen_mesh));
+
+      ASSERT(Netgen_NbOfNodes == Ng_GetNP(Netgen_mesh));
+      ASSERT(Ng_GetNE(Netgen_mesh) == 0);
+      ASSERT(Netgen_NbOfTria == Ng_GetNSE(Netgen_mesh));
+
+      Ng_Result status;
+
+      status = Ng_GenerateVolumeMesh(Netgen_mesh, &Netgen_param);
+
+      int Netgen_NbOfNodesNew = Ng_GetNP(Netgen_mesh);
+
+      int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh);
+
+      SCRUTE(Netgen_NbOfNodesNew);
+
+      SCRUTE(Netgen_NbOfTetra);
+
+      if ((status != NG_OK) ||
+         (Netgen_NbOfNodesNew <= Netgen_NbOfNodes) ||
+         (Netgen_NbOfTetra <= 0))
+       {
+         MESSAGE("SMESH_Tetra_3D::Compute The Volume Mesh Generation has failed ...");
+         SCRUTE(status);
+
+         /*
+           Free the memory needed by to generate the Netgen Mesh
+         */
+
+         MESSAGE("SMESH_Tetra_3D::Compute Free the memory needed by to generate the Netgen Mesh");
+
+         delete [] Netgen_Coordinates;
+         delete [] Netgen_Connectivity;
+         delete [] Netgen_point;
+         delete [] Netgen_triangle;
+         delete [] Netgen_tetrahedron;
+
+         delete [] listNodeCoresNetgenSmesh;
+
+         Ng_DeleteMesh(Netgen_mesh);
+         Ng_Exit();
+
+         return false;
+       }
+
+      MESSAGE("SMESH_Tetra_3D::Compute End of Volume Mesh Generation");
+      SCRUTE(status);
+
+      double * Netgen_CoordinatesNew = new double [spaceDimension*Netgen_NbOfNodesNew];
+      int * Netgen_ConnectivityNew = new int [nbNodesByTetra*Netgen_NbOfTetra];
+
+      for (int i=0; i<Netgen_NbOfNodesNew; i++)
+       {
+         Ng_GetPoint(Netgen_mesh, (i+1), Netgen_point);
+
+         for (int j=0; j<spaceDimension; j++)
+           Netgen_CoordinatesNew[i*spaceDimension+j] = Netgen_point[j];
+       }
+
+      for (int i=0; i<Netgen_NbOfNodes; i++)
+       for (int j=0; j<spaceDimension; j++)
+         ASSERT(Netgen_CoordinatesNew[i*spaceDimension+j] == Netgen_Coordinates[i*spaceDimension+j])
+
+      for (int i=0; i<Netgen_NbOfTetra; i++)
+       {
+         Ng_GetVolumeElement(Netgen_mesh, (i+1), Netgen_tetrahedron);
+
+         for (int j=0; j<nbNodesByTetra; j++)
+           Netgen_ConnectivityNew[i*nbNodesByTetra+j] = Netgen_tetrahedron[j];
+       }
+
+      /*
+       Feed back the SMESHDS with the generated Nodes and Volume Elements
+      */
+
+      MESSAGE("SMESH_Tetra_3D::Compute Feed back the SMESHDS with the generated Nodes and Volume Elements");
+
+      int NbTotOfNodesShell = Netgen_NbOfNodesNew - Netgen_NbOfNodes;
+
+      SCRUTE(NbTotOfNodesShell);
+
+      int * listNodeShellCoresNetgenSmesh = new int [NbTotOfNodesShell];
+
+      for (int i=0; i<NbTotOfNodesShell; i++)
+       listNodeShellCoresNetgenSmesh[i] = 0;
+
+      MESSAGE("SMESH_Tetra_3D::Compute --> Adding the New Nodes to SMESHDS");
+
+      for (int i=0; i<NbTotOfNodesShell; i++)
+       {
+         int index = (i+Netgen_NbOfNodes)*spaceDimension;
+
+//       int myNodeId = meshDS->AddNode(Netgen_CoordinatesNew[index],
+//                                      Netgen_CoordinatesNew[index+1],
+//                                      Netgen_CoordinatesNew[index+2]);
+
+//       Handle (SMDS_MeshElement) elt = meshDS->FindNode(myNodeId);
+//       Handle (SMDS_MeshNode) node = meshDS->GetNode(1, elt);
+
+         SMDS_MeshNode * node =
+           meshDS->AddNode(Netgen_CoordinatesNew[index],
+                           Netgen_CoordinatesNew[index+1],
+                           Netgen_CoordinatesNew[index+2]);
+
+         meshDS->SetNodeInVolume(node, aShell);
+
+         index = i+Netgen_NbOfNodes;
+         netgenToDS[index] = node;
+
+         listNodeShellCoresNetgenSmesh[i] = node->GetID();
+       }
+
+      SCRUTE(Netgen_NbOfNodesNew);
+      
+      SCRUTE(netgenToDS.size());
+
+      for (int i=0; i<NbTotOfNodesShell; i++)
+       {
+         ASSERT(listNodeShellCoresNetgenSmesh[i] != 0);
+
+         for (int j=0; j<NbTotOfNodesShell && j!=i; j++)
+           ASSERT(listNodeShellCoresNetgenSmesh[i] != listNodeShellCoresNetgenSmesh[j]);
+       }
+
+      MESSAGE("SMESH_Tetra_3D::Compute --> Adding the New elements (Tetrahedrons) to the SMESHDS");
+
+      for (int i=0; i<Netgen_NbOfTetra; i++)
+       {
+         int index = i*nbNodesByTetra;
+         int tetraNode1 = Netgen_ConnectivityNew[index];
+         int tetraNode2 = Netgen_ConnectivityNew[index+1];
+         int tetraNode3 = Netgen_ConnectivityNew[index+2];
+         int tetraNode4 = Netgen_ConnectivityNew[index+3];
+
+         MESSAGE("SMESH_Tetra_3D::Compute --> Tetrahedron generated" << i << " with N1 = " << tetraNode1 << " N2 = " << tetraNode2 << " N3 = " << tetraNode3 << " N4 = " << tetraNode4);
+
+         const SMDS_MeshNode * node1 = netgenToDS[tetraNode1-1];
+         const SMDS_MeshNode * node2 = netgenToDS[tetraNode2-1];
+         const SMDS_MeshNode * node3 = netgenToDS[tetraNode3-1];
+         const SMDS_MeshNode * node4 = netgenToDS[tetraNode4-1];
+
+         int nodeId = node1->GetID();
+         double nodeX = node1->X();
+         double nodeY = node1->Y();
+         double nodeZ = node1->Z();
+         MESSAGE("NODE 1 -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ);
+
+          nodeId = node2->GetID();
+         nodeX = node2->X();
+         nodeY = node2->Y();
+         nodeZ = node2->Z();
+         MESSAGE("NODE 2 -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ);
+
+         nodeId = node3->GetID();
+         nodeX = node3->X();
+         nodeY = node3->Y();
+         nodeZ = node3->Z();
+         MESSAGE("NODE 3 -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ);
+
+         nodeId = node4->GetID();
+         nodeX = node4->X();
+         nodeY = node4->Y();
+         nodeZ = node4->Z();
+         MESSAGE("NODE 4 -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ);
+
+         index = tetraNode1;
+         if (index <= Netgen_NbOfNodes)
+           tetraNode1 = listNodeCoresNetgenSmesh[index-1];
+         else
+           tetraNode1 = listNodeShellCoresNetgenSmesh[index-Netgen_NbOfNodes-1];
+
+         index = tetraNode2;
+         if (index <= Netgen_NbOfNodes)
+           tetraNode2 = listNodeCoresNetgenSmesh[index-1];
+         else
+           tetraNode2 = listNodeShellCoresNetgenSmesh[index-Netgen_NbOfNodes-1];
+
+         index = tetraNode3;
+         if (index <= Netgen_NbOfNodes)
+           tetraNode3 = listNodeCoresNetgenSmesh[index-1];
+         else
+           tetraNode3 = listNodeShellCoresNetgenSmesh[index-Netgen_NbOfNodes-1];
+
+         index = tetraNode4;
+         if (index <= Netgen_NbOfNodes)
+           tetraNode4 = listNodeCoresNetgenSmesh[index-1];
+         else
+           tetraNode4 = listNodeShellCoresNetgenSmesh[index-Netgen_NbOfNodes-1];
+
+//       int tetraId = meshDS->AddVolume(nodeId1,nodeId2,nodeId3,nodeId4);
+
+//       Handle (SMDS_MeshElement) elt = meshDS->FindElement(tetraId);
+
+         MESSAGE("SMESH_Tetra_3D::Compute Add Volume");
+
+         SMDS_MeshVolume * elt =
+           meshDS->AddVolume(node1,node2,node3,node4);
+
+         MESSAGE("SMESH_Tetra_3D::Compute SetMeshElementOnShape");
+
+         meshDS->SetMeshElementOnShape(elt, aShell);
+       }
+
+      /*
+       Free the memory needed by to generate the Netgen Mesh
+      */
+
+      MESSAGE("SMESH_Tetra_3D::Compute Free the memory needed by to generate the Netgen Mesh");
+
+      delete [] Netgen_Coordinates;
+      delete [] Netgen_Connectivity;
+      delete [] Netgen_CoordinatesNew;
+      delete [] Netgen_ConnectivityNew;
+      delete [] Netgen_point;
+      delete [] Netgen_triangle;
+      delete [] Netgen_tetrahedron;
+
+      delete [] listNodeCoresNetgenSmesh;
+      delete [] listNodeShellCoresNetgenSmesh;
+
+      Ng_DeleteMesh(Netgen_mesh);
+      Ng_Exit();
+
+      /*
+       Verification
+      */
+
+      {
+       MESSAGE("SMESH_Tetra_3D::Compute Verification of the Shell mesh");
+
+       TopoDS_Shape aShapeShell = meshShells[0]->GetSubShape();
+       SMESH_Algo* algoShell = _gen->GetAlgo(aMesh, aShapeShell);
+       string algoShellName = algoShell->GetName();
+       SCRUTE(algoShellName);
+       if (algoShellName != "Tetra_3D")
+         {
+           SCRUTE(algoShellName);
+           ASSERT(0);
+           return false;
+         }
+
+       const SMESHDS_SubMesh * aSubMeshDSShell = meshShells[0]->GetSubMeshDS();
+       SCRUTE(&aSubMeshDSShell);
+
+       int nbNodes = aSubMeshDSShell->NbNodes();
+       int nbTetra = aSubMeshDSShell->NbElements();
+
+       MESSAGE("SMESH_Tetra_3D::Compute The mesh Shell has " << nbNodes << " shell internal Nodes, " << nbTetra << " tetrahedrons");
+
+//     const TColStd_ListOfInteger& indEltNodes = aSubMeshDSShell->GetIDNodes();
+
+       SMDS_Iterator<const SMDS_MeshNode *> * iteratorNodes = aSubMeshDSShell->GetNodes();
+
+       SCRUTE(nbNodes);
+
+//     SCRUTE(indEltNodes.Extent());
+
+//     TColStd_ListIteratorOfListOfInteger itNodes(indEltNodes);
+
+       int index;
+
+       index = 0;
+
+//     for (; itNodes.More(); itNodes.Next())
+//       {
+//         index++;
+//         int nodeId = itNodes.Value();
+//         Handle (SMDS_MeshElement) elt = meshDS->FindNode(nodeId);
+//         Handle (SMDS_MeshNode) node = meshDS->GetNode(1, elt);
+//         MESSAGE("NODE -> ID = " << node->GetID() << " X = " << node->X() << " Y = " << node->Y() << " Z = " << node->Z());
+//       }
+//     SCRUTE(index);
+
+       while(iteratorNodes->more())
+         {
+           index++;
+           const SMDS_MeshNode * node = iteratorNodes->next();
+           int nodeId = node->GetID();
+           double nodeX = node->X();
+           double nodeY = node->Y();
+           double nodeZ = node->Z();
+           MESSAGE("NODE -> ID = " << nodeId << " X = " << nodeX << " Y = " << nodeY << " Z = " << nodeZ);
+         }
+       delete iteratorNodes;
+
+       SCRUTE(index);
+
+       SMDS_Iterator<const SMDS_MeshElement *> * iteratorTetra = aSubMeshDSShell->GetElements();
+
+//     const TColStd_ListOfInteger& indEltTetra = aSubMeshDSShell->GetIDElements();
+
+       SCRUTE(nbTetra);
+
+//     SCRUTE(indEltTetra.Extent());
+
+//     TColStd_ListIteratorOfListOfInteger itTetras(indEltTetra);
+
+//     index = 0;
+//     for (; itTetras.More(); itTetras.Next())
+//       {
+//         index++;
+//         int tetraId = itTetras.Value();
+//         Handle (SMDS_MeshElement) elt = meshDS->FindElement(tetraId);
+//         MESSAGE("TETRAHEDRON -> ID = " << elt->GetID() << " N1 = " << elt->GetConnection(1) << " N2 = " << elt->GetConnection(2) << " N3 = " << elt->GetConnection(3) << " N4 = " << elt->GetConnection(4));
+//       }
+
+       index = 0;
+       while(iteratorTetra->more())
+         {
+           index++;
+           const SMDS_MeshElement * tetra = iteratorTetra->next();
+           int tetraId = tetra->GetID();
+
+           SMDS_Iterator<const SMDS_MeshElement *> * tetraNodesIt = tetra->nodesIterator();
+
+           int tetraNode1 = (tetraNodesIt->next())->GetID();
+           int tetraNode2 = (tetraNodesIt->next())->GetID();
+           int tetraNode3 = (tetraNodesIt->next())->GetID();
+           int tetraNode4 = (tetraNodesIt->next())->GetID();
+
+           MESSAGE("TETRAHEDRON -> ID = " << tetraId << " N1 = " << tetraNode1 << " N2 = " << tetraNode2 << " N3 = " << tetraNode3 << " N4 = " << tetraNode4);
+
+         }
+       delete iteratorTetra;
+
+       SCRUTE(index);
+      }
+    }
+  else
+    {
+      SCRUTE(numberOfShells);
+      MESSAGE("SMESH_Tetra_3D::Compute ERROR More than one shell ????? ");
+      return false;
+    }
+
+  return true;
+}
+
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+ostream & SMESH_Tetra_3D::SaveTo(ostream & save)
+{
+  return save << this;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+istream & SMESH_Tetra_3D::LoadFrom(istream & load)
+{
+  return load >> (*this);
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+ostream & operator << (ostream & save, SMESH_Tetra_3D & hyp)
+{
+  return save;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+istream & operator >> (istream & load, SMESH_Tetra_3D & hyp)
+{
+  return load;
+}
diff --git a/src/SMESH/SMESH_Tetra_3D.hxx b/src/SMESH/SMESH_Tetra_3D.hxx
new file mode 100644 (file)
index 0000000..ad7caf4
--- /dev/null
@@ -0,0 +1,42 @@
+//=============================================================================
+// File      : SMESH_Tetra_3D.hxx
+// Created   : lundi 27 Janvier 2003
+// Author    : Nadir BOUHAMOU (CEA)
+// Project   : SALOME
+// Copyright : CEA 2003
+// $Header$
+//=============================================================================
+
+#ifndef _SMESH_TETRA_3D_HXX_
+#define _SMESH_TETRA_3D_HXX_
+
+#include "SMESH_3D_Algo.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_MaxElementVolume.hxx"
+#include "Utils_SALOME_Exception.hxx"
+
+class SMESH_Tetra_3D: public SMESH_3D_Algo
+{
+public:
+  SMESH_Tetra_3D(int hypId, int studyId, SMESH_Gen* gen);
+  virtual ~SMESH_Tetra_3D();
+
+  virtual bool CheckHypothesis(SMESH_Mesh& aMesh,
+                              const TopoDS_Shape& aShape);
+
+  virtual bool Compute(SMESH_Mesh& aMesh,
+                      const TopoDS_Shape& aShape)
+    throw (SALOME_Exception);
+
+  ostream & SaveTo(ostream & save);
+  istream & LoadFrom(istream & load);
+  friend ostream & operator << (ostream & save, SMESH_Tetra_3D & hyp);
+  friend istream & operator >> (istream & load, SMESH_Tetra_3D & hyp);
+
+protected:
+  double _maxElementVolume;
+
+  const SMESH_MaxElementVolume* _hypMaxElementVolume;
+};
+
+#endif
diff --git a/src/SMESH_I/SMESH_Tetra_3D_i.cxx b/src/SMESH_I/SMESH_Tetra_3D_i.cxx
new file mode 100644 (file)
index 0000000..9e1fa75
--- /dev/null
@@ -0,0 +1,60 @@
+//=============================================================================
+// File      : SMESH_Tetra_3D_i.cxx
+// Created   : Jeudi 31 Janvier 2003
+// Author    : Nadir Bouhamou CEA
+// Project   : SALOME
+// Copyright : CEA 2003
+// $Header$
+//=============================================================================
+using namespace std;
+
+#include "SMESH_Tetra_3D_i.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_HypothesisFactory.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+SMESH_Tetra_3D_i::SMESH_Tetra_3D_i(const char* anHyp,
+                                  int studyId,
+                                  ::SMESH_Gen* genImpl)
+{
+  MESSAGE("SMESH_Tetra_3D_i::SMESH_Tetra_3D_i");
+  _genImpl = genImpl;
+  ::SMESH_Tetra_3D* impl 
+      = new ::SMESH_Tetra_3D(_genImpl->_hypothesisFactory.GetANewId(),
+                            studyId,
+                            genImpl);
+  SetImpl(impl);
+  _baseImpl = _impl;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+SMESH_Tetra_3D_i::~SMESH_Tetra_3D_i()
+{
+  MESSAGE("SMESH_Tetra_3D_i::~SMESH_Tetra_3D_i");
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+void SMESH_Tetra_3D_i::SetImpl(::SMESH_Tetra_3D* impl)
+{
+  MESSAGE("SMESH_Tetra_3D_i::SetImpl");
+  SMESH_3D_Algo_i::SetImpl(impl);
+  _impl = impl;
+}
diff --git a/src/SMESH_I/SMESH_Tetra_3D_i.hxx b/src/SMESH_I/SMESH_Tetra_3D_i.hxx
new file mode 100644 (file)
index 0000000..8a62597
--- /dev/null
@@ -0,0 +1,36 @@
+//=============================================================================
+// File      : SMESH_Tetra_3D_i.hxx
+// Created   : Jeudi 31 Janvier 2003
+// Author    : Nadir Bouhamou CEA
+// Project   : SALOME
+// Copyright : CEA 2003
+// $Header$
+//=============================================================================
+#ifndef _SMESH_TETRA_3D_I_HXX_
+#define _SMESH_TETRA_3D_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_3D_Algo_i.hxx"
+
+#include "SMESH_Tetra_3D.hxx"
+
+class SMESH_Tetra_3D_i:
+  public POA_SMESH::SMESH_Tetra_3D,
+  public SMESH_3D_Algo_i
+{
+public:
+  SMESH_Tetra_3D_i(const char* anHyp,
+                  int studyId,
+                  ::SMESH_Gen* genImpl);
+
+  virtual ~SMESH_Tetra_3D_i();
+
+protected:
+  virtual void SetImpl(::SMESH_Tetra_3D* impl);
+
+  ::SMESH_Tetra_3D* _impl;
+};
+
+#endif