Salome HOME
merge from branch BR_SMDS_MEMIMP 29 nov 2010
authorprascle <prascle>
Mon, 29 Nov 2010 13:20:53 +0000 (13:20 +0000)
committerprascle <prascle>
Mon, 29 Nov 2010 13:20:53 +0000 (13:20 +0000)
146 files changed:
adm_local/unix/config_files/check_f77.m4 [new file with mode: 0644]
adm_local/unix/config_files/check_qwt.m4 [new file with mode: 0644]
clean_configure
doc/salome/gui/SMESH/images/image94.gif [new file with mode: 0755]
doc/salome/gui/SMESH/static/header.html [new file with mode: 0755]
doc/salome/tui/doxyfile.in
doc/salome/tui/images/application.gif [new file with mode: 0644]
doc/salome/tui/images/logocorp.gif [new file with mode: 0755]
doc/salome/tui/static/myheader.html [new file with mode: 0755]
idl/SMESH_MeshEditor.idl
src/Controls/Makefile.am
src/Controls/SMESH_Controls.cxx
src/DriverDAT/Makefile.am
src/DriverMED/DriverMED_Family.cxx
src/DriverMED/DriverMED_Family.h
src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx
src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx
src/DriverMED/Makefile.am
src/DriverSTL/Makefile.am
src/DriverUNV/DriverUNV_R_SMDS_Mesh.cxx
src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx
src/DriverUNV/Makefile.am
src/OBJECT/Makefile.am
src/OBJECT/SMESH_Actor.cxx
src/OBJECT/SMESH_ActorUtils.cxx
src/OBJECT/SMESH_Object.cxx
src/OBJECT/SMESH_Object.h
src/OBJECT/SMESH_ObjectDef.h
src/OBJECT/SMESH_vtkPVUpdateSuppressor.cxx [new file with mode: 0644]
src/OBJECT/SMESH_vtkPVUpdateSuppressor.h [new file with mode: 0644]
src/SMDS/Makefile.am
src/SMDS/Notes [new file with mode: 0644]
src/SMDS/ObjectPool.hxx [new file with mode: 0644]
src/SMDS/SMDS_Downward.cxx [new file with mode: 0644]
src/SMDS/SMDS_Downward.hxx [new file with mode: 0644]
src/SMDS/SMDS_EdgePosition.cxx
src/SMDS/SMDS_EdgePosition.hxx
src/SMDS/SMDS_FaceOfEdges.cxx
src/SMDS/SMDS_FaceOfEdges.hxx
src/SMDS/SMDS_FaceOfNodes.cxx
src/SMDS/SMDS_FacePosition.cxx
src/SMDS/SMDS_FacePosition.hxx
src/SMDS/SMDS_LinearEdge.cxx [new file with mode: 0644]
src/SMDS/SMDS_LinearEdge.hxx [new file with mode: 0644]
src/SMDS/SMDS_Mesh.cxx
src/SMDS/SMDS_Mesh.hxx
src/SMDS/SMDS_Mesh0DElement.cxx
src/SMDS/SMDS_Mesh0DElement.hxx
src/SMDS/SMDS_MeshCell.cxx [new file with mode: 0644]
src/SMDS/SMDS_MeshCell.hxx [new file with mode: 0644]
src/SMDS/SMDS_MeshEdge.cxx
src/SMDS/SMDS_MeshEdge.hxx
src/SMDS/SMDS_MeshElement.cxx
src/SMDS/SMDS_MeshElement.hxx
src/SMDS/SMDS_MeshElementIDFactory.cxx
src/SMDS/SMDS_MeshElementIDFactory.hxx
src/SMDS/SMDS_MeshFace.cxx
src/SMDS/SMDS_MeshFace.hxx
src/SMDS/SMDS_MeshIDFactory.cxx
src/SMDS/SMDS_MeshIDFactory.hxx
src/SMDS/SMDS_MeshNode.cxx
src/SMDS/SMDS_MeshNode.hxx
src/SMDS/SMDS_MeshNodeIDFactory.cxx [new file with mode: 0644]
src/SMDS/SMDS_MeshNodeIDFactory.hxx [new file with mode: 0644]
src/SMDS/SMDS_MeshVolume.cxx
src/SMDS/SMDS_MeshVolume.hxx
src/SMDS/SMDS_PolygonalFaceOfNodes.cxx
src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx
src/SMDS/SMDS_Position.cxx
src/SMDS/SMDS_Position.hxx
src/SMDS/SMDS_QuadraticEdge.cxx
src/SMDS/SMDS_QuadraticEdge.hxx
src/SMDS/SMDS_QuadraticFaceOfNodes.cxx
src/SMDS/SMDS_QuadraticVolumeOfNodes.cxx
src/SMDS/SMDS_SpacePosition.cxx
src/SMDS/SMDS_SpacePosition.hxx
src/SMDS/SMDS_UnstructuredGrid.cxx [new file with mode: 0644]
src/SMDS/SMDS_UnstructuredGrid.hxx [new file with mode: 0644]
src/SMDS/SMDS_VertexPosition.cxx
src/SMDS/SMDS_VertexPosition.hxx
src/SMDS/SMDS_VolumeOfFaces.cxx
src/SMDS/SMDS_VolumeOfFaces.hxx
src/SMDS/SMDS_VolumeOfNodes.cxx
src/SMDS/SMDS_VolumeOfNodes.hxx
src/SMDS/SMDS_VolumeTool.cxx
src/SMDS/SMDS_VolumeTool.hxx
src/SMDS/SMDS_VtkCellIterator.cxx [new file with mode: 0644]
src/SMDS/SMDS_VtkCellIterator.hxx [new file with mode: 0644]
src/SMDS/SMDS_VtkEdge.cxx [new file with mode: 0644]
src/SMDS/SMDS_VtkEdge.hxx [new file with mode: 0644]
src/SMDS/SMDS_VtkFace.cxx [new file with mode: 0644]
src/SMDS/SMDS_VtkFace.hxx [new file with mode: 0644]
src/SMDS/SMDS_VtkVolume.cxx [new file with mode: 0644]
src/SMDS/SMDS_VtkVolume.hxx [new file with mode: 0644]
src/SMDS/chrono.cxx [new file with mode: 0644]
src/SMDS/chrono.hxx [new file with mode: 0644]
src/SMESH/Makefile.am
src/SMESH/SMESH_Algo.cxx
src/SMESH/SMESH_Gen.cxx
src/SMESH/SMESH_Gen.hxx
src/SMESH/SMESH_Hypothesis.cxx
src/SMESH/SMESH_MeshEditor.cxx
src/SMESH/SMESH_MeshEditor.hxx
src/SMESH/SMESH_MesherHelper.cxx
src/SMESH/SMESH_OctreeNode.cxx
src/SMESH/SMESH_OctreeNode.hxx
src/SMESH/SMESH_Pattern.cxx
src/SMESH/SMESH_subMesh.hxx
src/SMESH/memoire.h [new file with mode: 0644]
src/SMESHClient/Makefile.am
src/SMESHClient/SMESH_Client.cxx
src/SMESHDS/Makefile.am
src/SMESHDS/SMESHDS_Mesh.cxx
src/SMESHDS/SMESHDS_Mesh.hxx
src/SMESHDS/SMESHDS_Script.cxx
src/SMESHDS/SMESHDS_SubMesh.cxx
src/SMESHDS/SMESHDS_SubMesh.hxx
src/SMESHGUI/SMESHGUI.cxx
src/SMESHGUI/SMESHGUI_ComputeDlg.cxx
src/SMESHGUI/SMESHGUI_VTKUtils.cxx
src/SMESHGUI/SMESHGUI_VTKUtils.h
src/SMESH_I/Makefile.am
src/SMESH_I/SMESH_Gen_i.cxx
src/SMESH_I/SMESH_MeshEditor_i.cxx
src/SMESH_I/SMESH_MeshEditor_i.hxx
src/SMESH_I/SMESH_Mesh_i.cxx
src/SMESH_I/SMESH_Pattern_i.cxx
src/SMESH_SWIG/SMESH_AdvancedEditor.py
src/SMESH_SWIG/SMESH_mechanic_editor.py
src/SMESH_SWIG/smeshDC.py
src/StdMeshers/Makefile.am
src/StdMeshers/StdMeshers_CompositeHexa_3D.cxx
src/StdMeshers/StdMeshers_FaceSide.cxx
src/StdMeshers/StdMeshers_Hexa_3D.cxx
src/StdMeshers/StdMeshers_Import_1D.cxx
src/StdMeshers/StdMeshers_Import_1D2D.cxx
src/StdMeshers/StdMeshers_MEFISTO_2D.cxx
src/StdMeshers/StdMeshers_Penta_3D.cxx
src/StdMeshers/StdMeshers_Prism_3D.cxx
src/StdMeshers/StdMeshers_ProjectionUtils.cxx
src/StdMeshers/StdMeshers_Projection_2D.cxx
src/StdMeshers/StdMeshers_Projection_3D.cxx
src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx
src/StdMeshers/StdMeshers_QuadToTriaAdaptor.hxx
src/StdMeshers/StdMeshers_Quadrangle_2D.cxx
src/StdMeshers_I/Makefile.am

diff --git a/adm_local/unix/config_files/check_f77.m4 b/adm_local/unix/config_files/check_f77.m4
new file mode 100644 (file)
index 0000000..e03c6c1
--- /dev/null
@@ -0,0 +1,29 @@
+dnl  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+dnl
+dnl  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+dnl  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+dnl
+dnl  This library is free software; you can redistribute it and/or
+dnl  modify it under the terms of the GNU Lesser General Public
+dnl  License as published by the Free Software Foundation; either
+dnl  version 2.1 of the License.
+dnl
+dnl  This library is distributed in the hope that it will be useful,
+dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+dnl  Lesser General Public License for more details.
+dnl
+dnl  You should have received a copy of the GNU Lesser General Public
+dnl  License along with this library; if not, write to the Free Software
+dnl  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+dnl
+dnl  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+dnl
+AC_DEFUN([CHECK_F77],[
+
+AC_PROG_F77
+
+AC_F77_LIBRARY_LDFLAGS
+AC_F77_WRAPPERS
+
+])dnl
diff --git a/adm_local/unix/config_files/check_qwt.m4 b/adm_local/unix/config_files/check_qwt.m4
new file mode 100644 (file)
index 0000000..736c5b5
--- /dev/null
@@ -0,0 +1,187 @@
+dnl  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+dnl
+dnl  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+dnl  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+dnl
+dnl  This library is free software; you can redistribute it and/or
+dnl  modify it under the terms of the GNU Lesser General Public
+dnl  License as published by the Free Software Foundation; either
+dnl  version 2.1 of the License.
+dnl
+dnl  This library is distributed in the hope that it will be useful,
+dnl  but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+dnl  Lesser General Public License for more details.
+dnl
+dnl  You should have received a copy of the GNU Lesser General Public
+dnl  License along with this library; if not, write to the Free Software
+dnl  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+dnl
+dnl  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+dnl
+AC_DEFUN([CHECK_QWT],[
+AC_REQUIRE([CHECK_QT])dnl
+AC_REQUIRE([AC_LINKER_OPTIONS])dnl
+
+AC_CHECKING(for qwt)
+
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+
+qwt_ok=yes
+
+dnl where is qwt ?
+
+AC_ARG_WITH(qwt,
+    [  --with-qwt=DIR     directory path to QWT installation ],
+    [QWTHOME="$withval"
+      AC_MSG_RESULT("select $withval as path to QWT")
+    ])
+
+AC_ARG_WITH(qwt_inc,
+    [  --with-qwt_inc=DIR   directory path to QWT includes ],
+    [QWT_INCDIR="$withval"
+      AC_MSG_RESULT("select $withval as path to QWT includes")
+    ])
+
+libqwt_name=qwt
+if test -z $QWTHOME; then
+  AC_MSG_RESULT(QWTHOME not defined)
+  AC_MSG_NOTICE(Trying native Qwt...)
+  exist_ok=no  
+  if test "x$exist_ok" = "xno"; then
+     for d in /usr /usr/local ; do
+        for extension in qwt-qt4 qwt; do
+           AC_CHECK_FILE(${d}/lib${LIB_LOCATION_SUFFIX}/lib${extension}.so,exist_ok=yes,exist_ok=no)
+           if test "x$exist_ok" = "xyes"; then
+              QWTHOME=$d
+              AC_MSG_RESULT(lib${extension}.so detected in $d/lib)
+              libqwt_name=${extension}
+              dnl  break, libqwt-qt4.so is choosen before libqwt.so since it is surely the Qt4 version.
+              break
+           fi
+        done
+        if test "x$exist_ok" = "xyes"; then
+           break
+        fi
+     done
+  fi
+  if test "x$exist_ok" = "xno"; then
+     for d in `echo $LD_LIBRARY_PATH | sed -e "s/:/ /g"` ; do
+        if test -f $d/libqwt.so ; then
+           AC_MSG_RESULT(libqwt.so detected in $d)
+           QWTHOME=$d
+           QWTHOME=`echo ${QWTHOME} | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"`
+           exist_ok=yes
+           break
+        fi
+     done
+  fi
+  if test "x$exist_ok" = "xyes"; then
+     if test -z $QWT_INCDIR; then
+        QWT_INCDIR=$QWTHOME"/include/qwt-qt4"
+        if test ! -f $QWT_INCDIR/qwt.h ; then
+          QWT_INCDIR=/usr/include/qwt
+        fi
+        if test ! -f $QWT_INCDIR/qwt.h ; then
+          QWT_INCDIR=$QWTHOME"/include"
+        fi
+        if test ! -f $QWT_INCDIR/qwt.h ; then
+          QWT_INCDIR=/usr/lib/qt4/include/qwt
+        fi
+        if test ! -f $QWT_INCDIR/qwt.h ; then
+          QWT_INCDIR=/usr/include/qwt-qt4
+        fi
+     fi
+  else
+     qwt_ok=no
+  fi
+else
+  AC_MSG_NOTICE(Trying Qwt from $QWTHOME ...)
+  if test -z $QWT_INCDIR; then
+     QWT_INCDIR="$QWTHOME/include"
+  fi           
+fi
+
+if test "x$qwt_ok" = xno -o ! -d "$QWTHOME" ; then
+  AC_MSG_RESULT(no)
+  AC_MSG_WARN(qwt not found)
+  qwt_ok=no
+else
+  CPPFLAGS_old=$CPPFLAGS
+  CPPFLAGS="$CPPFLAGS $QT_INCLUDES -I$QWT_INCDIR"
+
+  AC_CHECK_HEADER(qwt.h,qwt_ok=yes,qwt_ok=no) 
+  CPPFLAGS=$CPPFLAGS_old
+
+  AC_MSG_CHECKING(include of qwt headers)
+
+  if test "x$qwt_ok" = xno ; then
+    AC_MSG_RESULT(no)
+    AC_MSG_WARN(qwt not found)
+  else
+    AC_MSG_RESULT(yes)
+    QWT_INCLUDES=-I$QWT_INCDIR
+  fi
+
+  #
+  # test Qwt libraries
+  #
+  if test "x$qwt_ok" = "xyes" ; then
+    AC_MSG_CHECKING(linking qwt library)
+
+    LIBS_old=$LIBS
+    LIBS="$LIBS $QT_LIBS"
+    if test "x$QWTHOME" = "x/usr" ; then
+      LIBS="$LIBS -l${libqwt_name}"
+    else
+      LIBS="$LIBS -L$QWTHOME/lib -l${libqwt_name}"
+    fi
+
+    CXXFLAGS_old=$CXXFLAGS
+    CXXFLAGS="$CXXFLAGS $QT_INCLUDES $QWT_INCLUDES"
+
+    AC_CACHE_VAL(salome_cv_lib_qwt,[
+      AC_TRY_LINK(
+#include <QApplication>
+#include <qwt_plot.h>
+,     int n;
+      char **s;
+      QApplication a(n, s);
+      QwtPlot p;
+      p.resize( 600, 400 );
+      p.show();
+      a.exec();,
+      eval "salome_cv_lib_qwt=yes",eval "salome_cv_lib_qwt=no")
+    ])
+    qwt_ok="$salome_cv_lib_qwt"
+
+    if  test "x$qwt_ok" = "xno" ; then
+      AC_MSG_RESULT(unable to link with qwt library)
+      AC_MSG_RESULT(QWTHOME environment variable may be wrong)
+    else
+      AC_MSG_RESULT(yes)
+      if test "x$QWTHOME" = "x/usr" ; then
+        QWT_LIBS=" -l${libqwt_name}"
+      else
+        QWT_LIBS="-L$QWTHOME/lib -l${libqwt_name}"
+      fi
+    fi
+
+    LIBS=$LIBS_old
+    CXXFLAGS=$CXXFLAGS_old
+  fi
+fi
+
+AC_SUBST(QWT_INCLUDES)
+AC_SUBST(QWT_LIBS)
+
+AC_LANG_RESTORE
+
+AC_MSG_RESULT(for qwt: $qwt_ok)
+
+# Save cache
+AC_CACHE_SAVE
+
+])dnl
+dnl
index 05e43a7ff9b6b6fb9e039fdca0de0bb6ffbae5a8..be3f7f1afa1d59a6322d8d69ec6504aa95134782 100755 (executable)
@@ -28,6 +28,9 @@ find bin -name Makefile.in | xargs rm -f
 find doc -name Makefile.in | xargs rm -f
 find idl -name Makefile.in | xargs rm -f
 find resources -name Makefile.in | xargs rm -f
+find salome_adm -name Makefile.in | xargs rm -f
 find adm_local -name Makefile.in | xargs rm -f
 find src -name Makefile.in | xargs rm -f
 rm -f Makefile.in
+cd adm_local/unix/config_files
+rm -f config.* depcomp install-sh l*.m4 ltmain.sh missing py-compile
diff --git a/doc/salome/gui/SMESH/images/image94.gif b/doc/salome/gui/SMESH/images/image94.gif
new file mode 100755 (executable)
index 0000000..7313f5d
Binary files /dev/null and b/doc/salome/gui/SMESH/images/image94.gif differ
diff --git a/doc/salome/gui/SMESH/static/header.html b/doc/salome/gui/SMESH/static/header.html
new file mode 100755 (executable)
index 0000000..a70a95e
--- /dev/null
@@ -0,0 +1,12 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <title>$title</title>
+   <link href="doxygen.css" rel="stylesheet" type="text/css">
+</head>
+<hr>
+<center>
+SALOME documentation central
+</center>
+<hr>
index 2279c3fc51c180a318eb37e0a4a280e1d9f521cd..56d3277d55b54480fa01b39fc4341298d8a45ffa 100755 (executable)
@@ -31,7 +31,7 @@ CREATE_SUBDIRS         = NO
 OUTPUT_LANGUAGE        = English
 USE_WINDOWS_ENCODING   = NO
 BRIEF_MEMBER_DESC      = YES
-REPEAT_BRIEF           = NO
+REPEAT_BRIEF           = YES
 ABBREVIATE_BRIEF       = 
 ALWAYS_DETAILED_SEC    = YES
 INLINE_INHERITED_MEMB  = YES
@@ -40,6 +40,7 @@ STRIP_FROM_PATH        = @top_srcdir@ @top_builddir@
 STRIP_FROM_INC_PATH    = 
 SHORT_NAMES            = NO
 JAVADOC_AUTOBRIEF      = YES
+QT_AUTOBRIEF           = YES
 MULTILINE_CPP_IS_BRIEF = NO
 DETAILS_AT_TOP         = NO
 INHERIT_DOCS           = YES
@@ -69,7 +70,7 @@ CASE_SENSE_NAMES       = YES
 HIDE_SCOPE_NAMES       = NO
 SHOW_INCLUDE_FILES     = YES
 INLINE_INFO            = YES
-SORT_MEMBER_DOCS       = NO
+SORT_MEMBER_DOCS       = YES
 SORT_BRIEF_DOCS        = NO
 SORT_BY_SCOPE_NAME     = NO
 GENERATE_TODOLIST      = YES
@@ -91,7 +92,7 @@ WARN_IF_UNDOCUMENTED   = YES
 WARN_IF_DOC_ERROR      = YES
 WARN_NO_PARAMDOC       = NO
 WARN_FORMAT            = "$file:$line: $text"
-WARN_LOGFILE           =
+WARN_LOGFILE           = log.txt
 
 #---------------------------------------------------------------------------
 # configuration options related to the input files
@@ -117,19 +118,19 @@ FILTER_SOURCE_FILES    = YES
 #---------------------------------------------------------------------------
 # configuration options related to source browsing
 #---------------------------------------------------------------------------
-SOURCE_BROWSER         = NO
-INLINE_SOURCES         = NO
+SOURCE_BROWSER         = YES
+INLINE_SOURCES         = YES
 STRIP_CODE_COMMENTS    = YES
-REFERENCED_BY_RELATION = NO
+REFERENCED_BY_RELATION = YES
 REFERENCES_RELATION    = YES
-USE_HTAGS              = NO
+#USE_HTAGS              = NO
 VERBATIM_HEADERS       = YES
 
 #---------------------------------------------------------------------------
 # configuration options related to the alphabetical class index
 #---------------------------------------------------------------------------
 ALPHABETICAL_INDEX     = YES
-COLS_IN_ALPHA_INDEX    = 3
+COLS_IN_ALPHA_INDEX    = 2
 IGNORE_PREFIX          = 
 
 #---------------------------------------------------------------------------
@@ -146,11 +147,11 @@ GENERATE_HTMLHELP      = NO
 CHM_FILE               = 
 HHC_LOCATION           = 
 GENERATE_CHI           = NO
-BINARY_TOC             = YES
-TOC_EXPAND             = YES
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
 DISABLE_INDEX          = NO
 ENUM_VALUES_PER_LINE   = 4
-GENERATE_TREEVIEW      = NO
+GENERATE_TREEVIEW      = YES
 TREEVIEW_WIDTH         = 250
 
 #---------------------------------------------------------------------------
@@ -213,14 +214,14 @@ PERLMOD_MAKEVAR_PREFIX =
 # Configuration options related to the preprocessor   
 #---------------------------------------------------------------------------
 ENABLE_PREPROCESSING   = YES
-MACRO_EXPANSION        = NO
+MACRO_EXPANSION        = YES
 EXPAND_ONLY_PREDEF     = NO
 SEARCH_INCLUDES        = YES
 INCLUDE_PATH           = 
 INCLUDE_FILE_PATTERNS  = 
 PREDEFINED             = 
 EXPAND_AS_DEFINED      = 
-SKIP_FUNCTION_MACROS   = NO
+SKIP_FUNCTION_MACROS   = YES
 
 #---------------------------------------------------------------------------
 # Configuration::additions related to external references   
@@ -239,23 +240,23 @@ HIDE_UNDOC_RELATIONS   = NO
 HAVE_DOT               = YES
 CLASS_GRAPH            = YES
 COLLABORATION_GRAPH    = NO
-GROUP_GRAPHS           = NO
+GROUP_GRAPHS           = YES
 UML_LOOK               = NO
 TEMPLATE_RELATIONS     = YES
 INCLUDE_GRAPH          = YES
-INCLUDED_BY_GRAPH      = NO
+INCLUDED_BY_GRAPH      = YES
 CALL_GRAPH             = NO
 GRAPHICAL_HIERARCHY    = YES
 DIRECTORY_GRAPH        = YES
-DOT_IMAGE_FORMAT       = jpg
+DOT_IMAGE_FORMAT       = png
 DOT_PATH               = 
 DOTFILE_DIRS           = 
 MAX_DOT_GRAPH_WIDTH    = 1024
-MAX_DOT_GRAPH_HEIGHT   = 1200
-MAX_DOT_GRAPH_DEPTH    = 0
+MAX_DOT_GRAPH_HEIGHT   = 1024
+MAX_DOT_GRAPH_DEPTH    = 1000
 DOT_TRANSPARENT        = NO
 DOT_MULTI_TARGETS      = NO
-GENERATE_LEGEND        = NO
+GENERATE_LEGEND        = YES
 DOT_CLEANUP            = YES
 
 #---------------------------------------------------------------------------
diff --git a/doc/salome/tui/images/application.gif b/doc/salome/tui/images/application.gif
new file mode 100644 (file)
index 0000000..0b05d5c
Binary files /dev/null and b/doc/salome/tui/images/application.gif differ
diff --git a/doc/salome/tui/images/logocorp.gif b/doc/salome/tui/images/logocorp.gif
new file mode 100755 (executable)
index 0000000..7697e08
Binary files /dev/null and b/doc/salome/tui/images/logocorp.gif differ
diff --git a/doc/salome/tui/static/myheader.html b/doc/salome/tui/static/myheader.html
new file mode 100755 (executable)
index 0000000..d2efb75
--- /dev/null
@@ -0,0 +1,13 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.73 [en] (WinNT; I) [Netscape]">
+   <title>Main Page</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css">
+<link href="tabs.css" rel="stylesheet" type="text/css">
+</head>
+<body>
+&nbsp;
+</body>
+</html>
index c010980be7c1d91457cfe57f33a88a64a03fdbd1..acc18fad3448cf24a9db698c4e36e2bfe5f88c4a 100644 (file)
@@ -929,6 +929,19 @@ module SMESH
      */
     boolean Make2DMeshFrom3D();
 
+    /*!
+     * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
+     * The list of groups must describe a partition of the mesh volumes.
+     * The nodes of the internal faces at the boundaries of the groups are doubled.
+     * In option, the internal faces are replaced by flat elements.
+     * Triangles are transformed in prisms, and quadrangles in hexahedrons.
+     * \param theDomains - list of groups of volumes
+     * \param createJointElems - if TRUE, create the elements
+     * \return TRUE if operation has been completed successfully, FALSE otherwise
+     */
+    boolean DoubleNodesOnGroupBoundaries( in ListOfGroups theDomains,
+                                          in boolean createJointElems );
+
     /*!
      * \brief Creates missing boundary elements
      *  \param elements - elements whose boundary is to be checked
index 9401c6d72f68710001dd4f354f0c970afc5b56d6..57e9551ce45480153ad3dbcf69a167ddca7155dd 100644 (file)
@@ -43,6 +43,7 @@ dist_SMESHControls_SOURCES = \
 # additionnal information to compil and link file
 libSMESHControls_la_CPPFLAGS = \
        $(CAS_CPPFLAGS) \
+        $(VTK_INCLUDES) \
        $(BOOST_CPPFLAGS) \
        $(KERNEL_CXXFLAGS) \
        -I$(srcdir)/../SMDS \
index 5238b982f3c55ee99f83bf4048d2096b2f866e3c..198ea8da423e4742a3197bc86f5c27fedac1b6e6 100644 (file)
@@ -250,11 +250,11 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem,
   if ( anElem->IsQuadratic() ) {
     switch ( anElem->GetType() ) {
     case SMDSAbs_Edge:
-      anIter = static_cast<const SMDS_QuadraticEdge*>
+      anIter = dynamic_cast<const SMDS_VtkEdge*>
         (anElem)->interlacedNodesElemIterator();
       break;
     case SMDSAbs_Face:
-      anIter = static_cast<const SMDS_QuadraticFaceOfNodes*>
+      anIter = dynamic_cast<const SMDS_VtkFace*>
         (anElem)->interlacedNodesElemIterator();
       break;
     default:
@@ -1622,10 +1622,10 @@ void Length2D::GetValues(TValues& theValues){
     const SMDS_MeshFace* anElem = anIter->next();
 
     if(anElem->IsQuadratic()) {
-      const SMDS_QuadraticFaceOfNodes* F =
-        static_cast<const SMDS_QuadraticFaceOfNodes*>(anElem);
+      const SMDS_VtkFace* F =
+        dynamic_cast<const SMDS_VtkFace*>(anElem);
       // use special nodes iterator
-      SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+      SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator();
       long aNodeId[4];
       gp_Pnt P[4];
 
@@ -1819,7 +1819,7 @@ void MultiConnection2D::GetValues(MValues& theValues){
     const SMDS_MeshFace* anElem = anIter->next();
     SMDS_ElemIteratorPtr aNodesIter;
     if ( anElem->IsQuadratic() )
-      aNodesIter = static_cast<const SMDS_QuadraticFaceOfNodes*>
+      aNodesIter = dynamic_cast<const SMDS_VtkFace*>
         (anElem)->interlacedNodesElemIterator();
     else
       aNodesIter = anElem->nodesIterator();
@@ -1978,7 +1978,7 @@ bool FreeEdges::IsSatisfy( long theId )
 
   SMDS_ElemIteratorPtr anIter;
   if ( aFace->IsQuadratic() ) {
-    anIter = static_cast<const SMDS_QuadraticFaceOfNodes*>
+    anIter = dynamic_cast<const SMDS_VtkFace*>
       (aFace)->interlacedNodesElemIterator();
   }
   else {
@@ -2047,7 +2047,7 @@ void FreeEdges::GetBoreders(TBorders& theBorders)
     long anElemId = anElem->GetID();
     SMDS_ElemIteratorPtr aNodesIter;
     if ( anElem->IsQuadratic() )
-      aNodesIter = static_cast<const SMDS_QuadraticFaceOfNodes*>(anElem)->
+      aNodesIter = static_cast<const SMDS_VtkFace*>(anElem)->
         interlacedNodesElemIterator();
     else
       aNodesIter = anElem->nodesIterator();
@@ -3225,7 +3225,7 @@ void ManifoldPart::expandBoundary
 void ManifoldPart::getFacesByLink( const ManifoldPart::Link& theLink,
                                    ManifoldPart::TVectorOfFacePtr& theFaces ) const
 {
-  SMDS_Mesh::SetOfFaces aSetOfFaces;
+  std::set<SMDS_MeshCell *> aSetOfFaces;
   // take all faces that shared first node
   SMDS_ElemIteratorPtr anItr = theLink.myNode1->facesIterator();
   for ( ; anItr->more(); )
@@ -3233,7 +3233,7 @@ void ManifoldPart::getFacesByLink( const ManifoldPart::Link& theLink,
     SMDS_MeshFace* aFace = (SMDS_MeshFace*)anItr->next();
     if ( !aFace )
       continue;
-    aSetOfFaces.Add( aFace );
+    aSetOfFaces.insert( aFace );
   }
   // take all faces that shared second node
   anItr = theLink.myNode2->facesIterator();
@@ -3241,7 +3241,7 @@ void ManifoldPart::getFacesByLink( const ManifoldPart::Link& theLink,
   for ( ; anItr->more(); )
   {
     SMDS_MeshFace* aFace = (SMDS_MeshFace*)anItr->next();
-    if ( aSetOfFaces.Contains( aFace ) )
+    if ( aSetOfFaces.count( aFace ) )
       theFaces.push_back( aFace );
   }
 }
index 7d5ddc8ad6d50d2463db50c8282b8ff486c9f6cc..4d701ec2deb4c1e0464684b440e3b74307509976 100644 (file)
@@ -56,6 +56,7 @@ dist_DAT_Test_SOURCES = \
 libMeshDriverDAT_la_CPPFLAGS = \
        $(KERNEL_CXXFLAGS) \
        $(CAS_CPPFLAGS) \
+        $(VTK_INCLUDES) \
        $(BOOST_CPPFLAGS) \
        -I$(srcdir)/../Driver \
        -I$(srcdir)/../SMDS \
index 4d0f73ec59c0c693742b1dd1ce832861a91d93eb..0f0f5709f16081b703d189d197962b372de27705 100644 (file)
@@ -24,6 +24,7 @@
 //  File   : DriverMED_Family.cxx
 //  Author : Julia DOROVSKIKH
 //  Module : SMESH
+//  $Header$
 //
 #include "DriverMED_Family.h"
 #include "MED_Factory.hxx"
index a05e99b5955a8b9371276edf2d41408adce458a3..8110e56de4a240950af37563736476164322a624 100644 (file)
@@ -24,6 +24,7 @@
 //  File   : DriverMED_Family.hxx
 //  Author : Julia DOROVSKIKH
 //  Module : SMESH
+//  $Header$
 //
 #ifndef _INCLUDE_DRIVERMED_FAMILY
 #define _INCLUDE_DRIVERMED_FAMILY
index 5b425f212c6981eaf66fcbc50876f758a53aa834..c679edd9bca473f2612d5a372ec83245abeeefe8 100644 (file)
@@ -40,7 +40,7 @@
 #include <stdlib.h>
 
 #ifdef _DEBUG_
-static int MYDEBUG = 0;
+static int MYDEBUG = 1;
 //#define _DEXCEPT_
 #else
 static int MYDEBUG = 0;
@@ -161,9 +161,11 @@ DriverMED_R_SMESHDS_Mesh
           if(anIsNodeNum) {
             aNode = myMesh->AddNodeWithID
               (aCoords[0],aCoords[1],aCoords[2],aNodeInfo->GetElemNum(iElem));
+            //MESSAGE("AddNodeWithID " << aNodeInfo->GetElemNum(iElem));
           } else {
-            aNode = myMesh->AddNode
-              (aCoords[0],aCoords[1],aCoords[2]);
+            aNode = myMesh->AddNodeWithID
+              (aCoords[0],aCoords[1],aCoords[2], iElem+1);
+            //MESSAGE("AddNode " << aNode->GetID());
           }
           //cout<<aNode->GetID()<<": "<<aNode->X()<<", "<<aNode->Y()<<", "<<aNode->Z()<<endl;
 
@@ -225,12 +227,14 @@ DriverMED_R_SMESHDS_Mesh
                   if(anIsElemNum){
                     TInt anElemId = aPolygoneInfo->GetElemNum(iElem);
                     anElement = myMesh->AddPolygonalFaceWithID(aNodeIds,anElemId);
+                    //MESSAGE("AddPolygonalFaceWithID " << anElemId);
                   }
                   if(!anElement){
                     vector<const SMDS_MeshNode*> aNodes(aNbConn);
                     for(TInt iConn = 0; iConn < aNbConn; iConn++)
                       aNodes[iConn] = FindNode(myMesh,aNodeIds[iConn]);
                     anElement = myMesh->AddPolygonalFace(aNodes);
+                    //MESSAGE("AddPolygonalFace " << anElement->GetID());
                     isRenum = anIsElemNum;
                   }
 #ifndef _DEXCEPT_
@@ -270,21 +274,35 @@ DriverMED_R_SMESHDS_Mesh
                 typedef MED::TVector<int> TQuantities;
                 TQuantities aQuantities(aNbFaces);
                 TInt aNbNodes = aPolyedreInfo->GetNbNodes(iElem);
+                //MESSAGE("--- aNbNodes " << aNbNodes);
                 TNodeIds aNodeIds(aNbNodes);
                 for(TInt iFace = 0, iNode = 0; iFace < aNbFaces; iFace++){
+                  //MESSAGE("--- iface " << aNbFaces << " " << iFace);
                   MED::TCConnSlice aConnSlice = aConnSliceArr[iFace];
                   TInt aNbConn = aConnSlice.size();
                   aQuantities[iFace] = aNbConn;
 #ifdef _EDF_NODE_IDS_
+                  //MESSAGE(anIsNodeNum);
                   if(anIsNodeNum)
                     for(TInt iConn = 0; iConn < aNbConn; iConn++)
-                      aNodeIds[iNode++] = aNodeInfo->GetElemNum(aConnSlice[iConn] - 1);
+                      {
+                      //MESSAGE("iConn " << iConn << " aConnSlice[iConn] " << aConnSlice[iConn]);
+                      aNodeIds[iNode] = aNodeInfo->GetElemNum(aConnSlice[iConn] - 1);
+                      //MESSAGE("aNodeIds[" << iNode << "]=" << aNodeIds[iNode]);
+                      iNode++;
+                      }
                   else
                     for(TInt iConn = 0; iConn < aNbConn; iConn++)
+                      {
+                      //MESSAGE("iConn " << iConn);
                       aNodeIds[iNode++] = aConnSlice[iConn];
+                      }
 #else
                   for(TInt iConn = 0; iConn < aNbConn; iConn++)
+                    {
+                    //MESSAGE("iConn " << iConn);
                     aNodeIds[iNode++] = aConnSlice[iConn];
+                    }
 #endif          
                 }
 
@@ -298,12 +316,14 @@ DriverMED_R_SMESHDS_Mesh
                   if(anIsElemNum){
                     TInt anElemId = aPolyedreInfo->GetElemNum(iElem);
                     anElement = myMesh->AddPolyhedralVolumeWithID(aNodeIds,aQuantities,anElemId);
+                    //MESSAGE("AddPolyhedralVolumeWithID " << anElemId);
                   }
                   if(!anElement){
                     vector<const SMDS_MeshNode*> aNodes(aNbNodes);
                     for(TInt iConn = 0; iConn < aNbNodes; iConn++)
                       aNodes[iConn] = FindNode(myMesh,aNodeIds[iConn]);
                     anElement = myMesh->AddPolyhedralVolume(aNodes,aQuantities);
+                    //MESSAGE("AddPolyhedralVolume " << anElement->GetID());
                     isRenum = anIsElemNum;
                   }
 #ifndef _DEXCEPT_
@@ -378,10 +398,10 @@ DriverMED_R_SMESHDS_Mesh
                   anIsValidConnect = true;
 #ifndef _DEXCEPT_
                 }catch(const std::exception& exc){
-                  //INFOS("Follow exception was cought:\n\t"<<exc.what());
+                  INFOS("Following exception was caught:\n\t"<<exc.what());
                   aResult = DRS_FAIL;
                 }catch(...){
-                  //INFOS("Unknown exception was cought !!!");
+                  INFOS("Unknown exception was cought !!!");
                   aResult = DRS_FAIL;
                 }
 #endif          
@@ -552,7 +572,7 @@ DriverMED_R_SMESHDS_Mesh
                     break;
                   case ePYRA13:
                     aNbNodes = 13;
-                    // There is some differnce between SMDS and MED
+                    // There is some difference between SMDS and MED
                     if(anIsElemNum)
                       anElement = myMesh->AddVolumeWithID(aNodeIds[0], aNodeIds[1],
                                                           aNodeIds[2], aNodeIds[3],
@@ -693,13 +713,18 @@ DriverMED_R_SMESHDS_Mesh
                     }
                     break;
                   }
-
+//                  if (anIsElemNum) {
+//                    MESSAGE("add element with id " << aCellInfo->GetElemNum(iElem));
+//                  }
+//                  else {
+//                    MESSAGE("add element "<< anElement->GetID());
+//                  }
 #ifndef _DEXCEPT_
                 }catch(const std::exception& exc){
-                  //INFOS("Follow exception was cought:\n\t"<<exc.what());
+                  INFOS("The following exception was caught:\n\t"<<exc.what());
                   aResult = DRS_FAIL;
                 }catch(...){
-                  //INFOS("Unknown exception was cought !!!");
+                  INFOS("Unknown exception was caught !!!");
                   aResult = DRS_FAIL;
                 }
 #endif          
@@ -727,13 +752,15 @@ DriverMED_R_SMESHDS_Mesh
     }
 #ifndef _DEXCEPT_
   }catch(const std::exception& exc){
-    INFOS("Follow exception was cought:\n\t"<<exc.what());
+    INFOS("The following exception was caught:\n\t"<<exc.what());
     aResult = DRS_FAIL;
   }catch(...){
-    INFOS("Unknown exception was cought !!!");
+    INFOS("Unknown exception was caught !!!");
     aResult = DRS_FAIL;
   }
 #endif
+  if (myMesh)
+    myMesh->compactMesh();
   if(MYDEBUG) MESSAGE("Perform - aResult status = "<<aResult);
   return aResult;
 }
@@ -756,10 +783,10 @@ list<string> DriverMED_R_SMESHDS_Mesh::GetMeshNames(Status& theStatus)
       }
     }
   }catch(const std::exception& exc){
-    INFOS("Follow exception was cought:\n\t"<<exc.what());
+    INFOS("Following exception was caught:\n\t"<<exc.what());
     theStatus = DRS_FAIL;
   }catch(...){
-    INFOS("Unknown exception was cought !!!");
+    INFOS("Unknown exception was caught !!!");
     theStatus = DRS_FAIL;
   }
 
@@ -944,6 +971,9 @@ bool DriverMED_R_SMESHDS_Mesh::buildMeshGrille(const MED::PWrapper& theWrapper,
     for(MED::TInt iDim=0;iDim<aMeshDim;iDim++)
       aCoords[(int)iDim] = aMEDNodeCoord[(int)iDim];
     aNode = myMesh->AddNodeWithID(aCoords[0],aCoords[1],aCoords[2],(int)iNode);
+    if (!aNode) {
+      EXCEPTION(runtime_error,"buildMeshGrille Error. Node not created! "<<(int)iNode);
+    }
 
     if((aGrilleInfo->myFamNumNode).size() > 0){
       TInt aFamNum = aGrilleInfo->GetFamNumNode(iNode);
@@ -999,7 +1029,9 @@ bool DriverMED_R_SMESHDS_Mesh::buildMeshGrille(const MED::PWrapper& theWrapper,
     default:
       break;
     }
-    
+    if (!anElement) {
+      EXCEPTION(runtime_error,"buildMeshGrille Error. Element not created! "<<iCell);
+    }
     if((aGrilleInfo->myFamNum).size() > 0){
       TInt aFamNum = aGrilleInfo->GetFamNum(iCell);
       if ( checkFamilyID ( aFamily, aFamNum )){
index d44e27675bb8f39d19d0416a4d17358af9043876..cbd619696da068d29553a0ede1b8be789a883c85 100644 (file)
@@ -622,6 +622,7 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
                                              nbElemInfo.NbHexas( ORDER_QUADRATIC ),
                                              SMDSAbs_Volume));
     if ( polyTypesSupported ) {
+      //MESSAGE("polyTypesSupported");
       aTElemTypeDatas.push_back( TElemTypeData(anEntity,
                                                ePOLYEDRE,
                                                nbElemInfo.NbPolyhedrons(),
@@ -738,18 +739,21 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
       // ----------------
       else if (aElemTypeData->_geomType == ePOLYEDRE )
       {
+        //MESSAGE("_geomType == ePOLYEDRE");
         if ( nbPolyhedronNodes == 0 ) {
           // Count nb of nodes
           while ( const SMDS_MeshElement* anElem = elemIterator->next() ) {
-            const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
-              dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>( anElem );
-            if ( aPolyedre ) {
+              const SMDS_VtkVolume *aPolyedre = dynamic_cast<const SMDS_VtkVolume*>(anElem);
+              if ( aPolyedre && aPolyedre->IsPoly()) {
               nbPolyhedronNodes += aPolyedre->NbNodes();
               nbPolyhedronFaces += aPolyedre->NbFaces();
               if ( ++iElem == aElemTypeData->_nbElems )
                 break;
             }
           }
+          //MESSAGE("nbPolyhedronNodes=" << nbPolyhedronNodes);
+          //MESSAGE("nbPolyhedronFaces=" << nbPolyhedronFaces);
+          //MESSAGE("_nbElems="<< aElemTypeData->_nbElems);
         }
         else {
           // Store in med file
@@ -771,19 +775,22 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
           TInt iFace = 0, iNode = 0;
           while ( const SMDS_MeshElement* anElem = elemIterator->next() )
           {
-            const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
-              dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>( anElem );
+            const SMDS_VtkVolume *aPolyedre = dynamic_cast<const SMDS_VtkVolume*>(anElem);
             if ( !aPolyedre )
               continue;
-
+            if ( !aPolyedre->IsPoly() )
+              continue;
+            //MESSAGE("index[" << iElem << "]=" << index[iElem] << " iElem=" << iElem);
             // index
             TInt aNbFaces = aPolyedre->NbFaces();
             index[ iElem+1 ] = index[ iElem ] + aNbFaces;
+            //MESSAGE("index[" << iElem+1 << "]=" << index[iElem+1] << " iElem=" << iElem);
 
             // face index
             for (TInt f = 1; f <= aNbFaces; ++f, ++iFace ) {
               int aNbFaceNodes = aPolyedre->NbFaceNodes( f );
               faces[ iFace+1 ] = faces[ iFace ] + aNbFaceNodes;
+              //MESSAGE("faces[" << iFace+1 << "]=" << faces[iFace+1] << " iFace=" << iFace);
             }
             // connectivity
             SMDS_ElemIteratorPtr nodeIt = anElem->nodesIterator();
@@ -791,8 +798,10 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
               const SMDS_MeshElement* aNode = nodeIt->next();
 #ifdef _EDF_NODE_IDS_
               conn[ iNode ] = aNodeIdMap[aNode->GetID()];
+              //MESSAGE("conn["<< iNode << "]=" << conn[iNode] << " aNode->GetID()=" << aNode->GetID());
 #else
               conn[ iNode ] = aNode->GetID();
+              //MESSAGE("conn["<< iNode << "]=" << conn[iNode]);
 #endif
               ++iNode;
             }
@@ -868,11 +877,11 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
 
   }
   catch(const std::exception& exc) {
-    INFOS("Follow exception was cought:\n\t"<<exc.what());
+    INFOS("The following exception was caught:\n\t"<<exc.what());
     throw;
   }
   catch(...) {
-    INFOS("Unknown exception was cought !!!");
+    INFOS("Unknown exception was caught !!!");
     throw;
   }
 
index 834008b582c30f5e7e0f06cd4f0fa14985b6bab8..e9db01b300202e55699a9f93c2b577006af5623e 100644 (file)
@@ -61,6 +61,7 @@ libMeshDriverMED_la_CPPFLAGS = \
        @HDF5_INCLUDES@ \
        $(KERNEL_CXXFLAGS) \
        $(CAS_CPPFLAGS) \
+        $(VTK_INCLUDES) \
        $(BOOST_CPPFLAGS) \
        -I$(srcdir)/../Driver \
        -I$(srcdir)/../SMDS \
index 1b9c8ded4d2b6c915ad1bfb2788026cdd34ea3a5..b067fd4cbad212c57b3f38dcf8e6958006d8aecd 100644 (file)
@@ -50,6 +50,7 @@ dist_STL_Test_SOURCES = \
 libMeshDriverSTL_la_CPPFLAGS = \
        $(KERNEL_CXXFLAGS) \
        $(CAS_CPPFLAGS) \
+        $(VTK_INCLUDES) \
        $(BOOST_CPPFLAGS) \
        -I$(srcdir)/../Driver \
        -I$(srcdir)/../SMDS
index 24150eeda41d13b8ceef0f078128ef4db97c508a..666bd5e13bedd51c62ff941dd2e8d1df49ed6f59 100644 (file)
@@ -37,7 +37,7 @@ using namespace std;
 
 
 #ifdef _DEBUG_
-static int MYDEBUG = 0;
+static int MYDEBUG = 1;
 #else
 static int MYDEBUG = 0;
 #endif
@@ -65,6 +65,7 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
       for(; anIter != aDataSet2411.end(); anIter++){
         const TNodeLab& aLabel = anIter->first;
         const TRecord& aRec = anIter->second;
+        //MESSAGE("AddNodeWithID " << aLabel << " " << aRec.coord[0] << " " << aRec.coord[1] << " " << aRec.coord[2]);
         myMesh->AddNodeWithID(aRec.coord[0],aRec.coord[1],aRec.coord[2],aLabel);
       }
     }
@@ -82,11 +83,13 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
         if(IsBeam(aRec.fe_descriptor_id)) {
           switch ( aRec.node_labels.size() ) {
           case 2: // edge with two nodes
+            //MESSAGE("add edge " << aLabel << " " << aRec.node_labels[0] << " " << aRec.node_labels[1]);
             anElement = myMesh->AddEdgeWithID(aRec.node_labels[0],
                                               aRec.node_labels[1],
                                               aLabel);
             break;
           case 3: // quadratic edge (with 3 nodes)
+            //MESSAGE("add edge " << aLabel << " " << aRec.node_labels[0] << " " << aRec.node_labels[1] << " " << aRec.node_labels[2]);
             anElement = myMesh->AddEdgeWithID(aRec.node_labels[0],
                                               aRec.node_labels[2],
                                               aRec.node_labels[1],
@@ -94,6 +97,7 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
           }
         }
         else if(IsFace(aRec.fe_descriptor_id)) {
+          //MESSAGE("add face " << aLabel);
           switch(aRec.fe_descriptor_id){
           case 41: // Plane Stress Linear Triangle      
           case 51: // Plane Strain Linear Triangle      
@@ -113,6 +117,7 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
           case 72: //  Membrane Parabolic Triangle           
           case 82: //  Axisymetric Solid Parabolic Triangle  
           case 92: //  Thin Shell Parabolic Triangle         
+            //MESSAGE("add face " << aLabel << " " << aRec.node_labels[0] << " " << aRec.node_labels[1] << " " << aRec.node_labels[2] << " " << aRec.node_labels[3] << " " << aRec.node_labels[4] << " " << aRec.node_labels[5]);
             anElement = myMesh->AddFaceWithID(aRec.node_labels[0],
                                               aRec.node_labels[2],
                                               aRec.node_labels[4],
@@ -154,6 +159,7 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
           }
         }
         else if(IsVolume(aRec.fe_descriptor_id)){
+          //MESSAGE("add volume " << aLabel);
           switch(aRec.fe_descriptor_id){
             
           case 111: // Solid Linear Tetrahedron - TET4
@@ -377,5 +383,7 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform()
   catch(...){
     INFOS("Unknown exception was cought !!!");
   }
+  if (myMesh)
+    myMesh->compactMesh();
   return aResult;
 }
index cf7778300ca677beb810a70466de94f0d09c4395..ffa50cbe7d5f82522b734e86bd320d5f17283fbf 100644 (file)
@@ -99,12 +99,10 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform()
           TRecord aRec;
           aRec.node_labels.reserve(aNbNodes);
           SMDS_ElemIteratorPtr aNodesIter;
+          aNodesIter = anElem->nodesIteratorToUNV();
           if( anElem->IsQuadratic() ) {
-            aNodesIter = static_cast<const SMDS_QuadraticEdge* >
-              ( anElem )->interlacedNodesElemIterator();
             aRec.fe_descriptor_id = 22;
           } else {
-            aNodesIter = anElem->nodesIterator();
             aRec.fe_descriptor_id = 11;
           }
           for(; aNodesIter->more();){
@@ -126,11 +124,7 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform()
           TRecord aRec;
           aRec.node_labels.reserve(aNbNodes);
           SMDS_ElemIteratorPtr aNodesIter;
-          if( anElem->IsQuadratic() )
-            aNodesIter = static_cast<const SMDS_QuadraticFaceOfNodes* >
-              ( anElem )->interlacedNodesElemIterator();
-          else
-            aNodesIter = anElem->nodesIterator();
+          aNodesIter = anElem->nodesIteratorToUNV();
           for(; aNodesIter->more();){
             const SMDS_MeshElement* aNode = aNodesIter->next();
             aRec.node_labels.push_back(aNode->GetID());
@@ -164,72 +158,59 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform()
           TElementLab aLabel = anElem->GetID();
 
           int aNbNodes = anElem->NbNodes();
-          SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
+          //MESSAGE("aNbNodes="<<aNbNodes);
+          SMDS_ElemIteratorPtr aNodesIter;
+          aNodesIter = anElem->nodesIteratorToUNV();
           if ( anElem->IsPoly() ) {
-            if ( const SMDS_PolyhedralVolumeOfNodes* ph =
-                 dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem))
+            MESSAGE("anElem->IsPoly");
+            if ( const SMDS_VtkVolume* ph =
+                 dynamic_cast<const SMDS_VtkVolume*> (anElem))
             {
               aNbNodes = ph->NbUniqueNodes();
               aNodesIter = ph->uniqueNodesIterator();
             }
           }
-          aConnect.resize(aNbNodes);
-          GetConnect(aNodesIter,aConnect);
 
           int anId = -1;
-          int* aConn = NULL;
           switch(aNbNodes){
           case 4: {
-            static int anIds[] = {0,2,1,3};
-            aConn = anIds;
             anId = 111;
             break;
           }
           case 6: {
-            static int anIds[] = {0,2,1,3,5,4};
-            aConn = anIds;
             anId = 112;
             break;
           }
           case 8: {
-            static int anIds[] = {0,3,2,1,4,7,6,5};
-            aConn = anIds;
             anId = 115;
             break;
           }
           case 10: {
-            static int anIds[] = {0,4,2,9,5,3, 1,6,8, 7};
-            aConn = anIds;
             anId = 118;
             break;
           }
           case 13: {
-            static int anIds[] = {0,6,4,2,7,5,3,1,8,11,10,9,12};
-            aConn = anIds;
             anId = 114;
             break;
           }
           case 15: {
-            static int anIds[] = {0,4,2,9,13,11,5,3,1,14,12,10,6,8,7};
-            aConn = anIds;
             anId = 113;
             break;
           }
           case 20: {
-            static int anIds[] = {0,6, 4,2, 12,18,16,14,7, 5, 3, 1, 19,17,15,13,8, 11,10,9};
-            aConn = anIds;
             anId = 116;
             break;
           }
           default:
             continue;
           }
-          if(aConn){
+          if(anId>0){
             TRecord aRec;
             aRec.fe_descriptor_id = anId;
-            aRec.node_labels.resize(aNbNodes);
-            for(int aNodeId = 0; aNodeId < aNbNodes; aNodeId++){
-              aRec.node_labels[aConn[aNodeId]] = aConnect[aNodeId];
+            aRec.node_labels.reserve(aNbNodes);
+            for(; aNodesIter->more();){
+              const SMDS_MeshElement* aNode = aNodesIter->next();
+              aRec.node_labels.push_back(aNode->GetID());
             }
             aDataSet2412.insert(TDataSet::value_type(aLabel,aRec));
           }
index 982afe8cff10a89e4b6768c1cebd40137c979eb0..4fa349f3f198d07608fa11c4dcf5215b910de7c6 100644 (file)
@@ -69,6 +69,7 @@ libMeshDriverUNV_la_CPPFLAGS = \
        $(CAS_CPPFLAGS) \
        $(CORBA_CXXFLAGS) \
         $(CORBA_INCLUDES) \
+        $(VTK_INCLUDES) \
        $(BOOST_CPPFLAGS) \
        -I$(srcdir)/../Driver \
        -I$(srcdir)/../SMDS \
index 219350562eb68a338e600df0604beb9d7c1eeb91..88dd738fde9076d5222de75aa6f92281ff8d3284 100644 (file)
@@ -37,7 +37,6 @@ salomeinclude_HEADERS = \
        SMESH_FaceOrientationFilter.h \
        SMESH_ScalarBarActor.h
 
-
 # Libraries targets
 
 lib_LTLIBRARIES = libSMESHObject.la
index 4afc7f4ca903bc6cd7b1f92f0c6dab13de7efe29..4b4f432ffb958531bc5751f5683eb0e8491acc75 100644 (file)
@@ -30,6 +30,7 @@
 #include "SMESH_DeviceActor.h"
 #include "SMESH_ObjectDef.h"
 #include "SMESH_ControlsDef.hxx"
+#include "SMDS_UnstructuredGrid.hxx"
 #include "SMESH_ScalarBarActor.h"
 #include "VTKViewer_CellCenters.h"
 #include "VTKViewer_ExtractUnstructuredGrid.h"
@@ -82,7 +83,7 @@
 #ifdef _DEBUG_
 static int MYDEBUG = 1;
 #else
-static int MYDEBUG = 0;
+static int MYDEBUG = 1;
 #endif
 
 static int aLineWidthInc = 2;
@@ -198,6 +199,10 @@ SMESH_ActorDef::SMESH_ActorDef()
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
   aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
   aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
+//#ifdef VTK_HAVE_POLYHEDRON
+  MESSAGE("RegisterCellsWithType(VTK_POLYHEDRON)");
+  aFilter->RegisterCellsWithType(VTK_POLYHEDRON);
+//#endif
 
   //Definition 1D device of the actor
   //---------------------------------
@@ -1359,6 +1364,9 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode)
     aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON);
     aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
     aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
+//#ifdef VTK_HAVE_POLYHEDRON
+    aFilter->RegisterCellsWithType(VTK_POLYHEDRON);
+//#endif
     
     aHightFilter->RegisterCellsWithType(VTK_TETRA);
     aHightFilter->RegisterCellsWithType(VTK_VOXEL);
@@ -1370,6 +1378,9 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode)
     aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
     aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
     aHightFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
+//#ifdef VTK_HAVE_POLYHEDRON
+    aHightFilter->RegisterCellsWithType(VTK_POLYHEDRON);
+//#endif
   }
   aFilter->Update();
   if (MYDEBUG) MESSAGE(aFilter->GetOutput()->GetNumberOfCells());
index 6808e145e1c668b6aecff46a237e1835cf05fd7b..899e413ec23266f1896593cd895ae906e5ebde98 100644 (file)
@@ -29,6 +29,7 @@
 #include "utilities.h"
 
 #include <vtkUnstructuredGrid.h>
+#include <vtkXMLUnstructuredGridWriter.h>
 #include <vtkUnstructuredGridWriter.h>
 
 #ifdef _DEBUG_
@@ -73,9 +74,10 @@ namespace SMESH
   WriteUnstructuredGrid(vtkUnstructuredGrid* theGrid, 
                         const char* theFileName)
   {
-    vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
+    vtkXMLUnstructuredGridWriter* aWriter = vtkXMLUnstructuredGridWriter::New();
     aWriter->SetFileName(theFileName);
     aWriter->SetInput(theGrid);
+    aWriter->SetDataModeToAscii();
     if(theGrid->GetNumberOfCells()){
       aWriter->Write();
     }
index 480a0fe3fa8f61d76ce405dc8aeb7a80cee9a82b..709847e9c34cf51738456857e9e203c62293beb6 100644 (file)
@@ -64,8 +64,8 @@ using namespace std;
 #endif
 
 #ifdef _DEBUG_
-static int MYDEBUG = 0;
-static int MYDEBUGWITHFILES = 0;
+static int MYDEBUG = 1;
+static int MYDEBUGWITHFILES = 1;
 #else
 static int MYDEBUG = 0;
 static int MYDEBUGWITHFILES = 0;
@@ -133,11 +133,14 @@ static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
 //=================================================================================
 SMESH_VisualObjDef::SMESH_VisualObjDef()
 {
+  MESSAGE("---------------------------------------------SMESH_VisualObjDef::SMESH_VisualObjDef");
   myGrid = vtkUnstructuredGrid::New();
+  myLocalGrid = false;
 }
 SMESH_VisualObjDef::~SMESH_VisualObjDef()
 {
-  if ( MYDEBUG )
+  MESSAGE("---------------------------------------------SMESH_VisualObjDef::~SMESH_VisualObjDef");
+  //if ( MYDEBUG )
     MESSAGE( "~SMESH_MeshObj - myGrid->GetReferenceCount() = " << myGrid->GetReferenceCount() );
   myGrid->Delete();
 }
@@ -148,32 +151,53 @@ SMESH_VisualObjDef::~SMESH_VisualObjDef()
 //=================================================================================
 vtkIdType SMESH_VisualObjDef::GetNodeObjId( int theVTKID )
 {
-  TMapOfIds::const_iterator i = myVTK2SMDSNodes.find(theVTKID);
-  return i == myVTK2SMDSNodes.end() ? -1 : i->second;
+       if (myLocalGrid)
+       {
+               TMapOfIds::const_iterator i = myVTK2SMDSNodes.find(theVTKID);
+               return i == myVTK2SMDSNodes.end() ? -1 : i->second;
+       }
+  return this->GetMesh()->FindNodeVtk(theVTKID)->GetID();
 }
 
 vtkIdType SMESH_VisualObjDef::GetNodeVTKId( int theObjID )
 {
-  TMapOfIds::const_iterator i = mySMDS2VTKNodes.find(theObjID);
-  return i == mySMDS2VTKNodes.end() ? -1 : i->second;
+       if (myLocalGrid)
+       {
+               TMapOfIds::const_iterator i = mySMDS2VTKNodes.find(theObjID);
+    return i == mySMDS2VTKNodes.end() ? -1 : i->second;
+       }
+  return this->GetMesh()->FindNode(theObjID)->getVtkId();
 }
 
 vtkIdType SMESH_VisualObjDef::GetElemObjId( int theVTKID )
 {
-  TMapOfIds::const_iterator i = myVTK2SMDSElems.find(theVTKID);
-  return i == myVTK2SMDSElems.end() ? -1 : i->second;
+       if (myLocalGrid)
+       {
+               TMapOfIds::const_iterator i = myVTK2SMDSElems.find(theVTKID);
+               return i == myVTK2SMDSElems.end() ? -1 : i->second;
+       }
+  return this->GetMesh()->fromVtkToSmds(theVTKID);
 }
 
 vtkIdType SMESH_VisualObjDef::GetElemVTKId( int theObjID )
 {
-  TMapOfIds::const_iterator i = mySMDS2VTKElems.find(theObjID);
-  return i == mySMDS2VTKElems.end() ? -1 : i->second;
+       if (myLocalGrid)
+       {
+               TMapOfIds::const_iterator i = mySMDS2VTKElems.find(theObjID);
+               return i == mySMDS2VTKElems.end() ? -1 : i->second;
+       }
+  return this->GetMesh()->FindElement(theObjID)->getVtkId();
+  //return this->GetMesh()->fromSmdsToVtk(theObjID);
 }
 
 //=================================================================================
 // function : SMESH_VisualObjDef::createPoints
 // purpose  : Create points from nodes
 //=================================================================================
+/*! fills a vtkPoints structure for a submesh.
+ *  fills a std::list of SMDS_MeshElements*, then extract the points.
+ *  fills also conversion id maps between SMDS and VTK.
+ */
 void SMESH_VisualObjDef::createPoints( vtkPoints* thePoints )
 {
   if ( thePoints == 0 )
@@ -182,7 +206,7 @@ void SMESH_VisualObjDef::createPoints( vtkPoints* thePoints )
   TEntityList aNodes;
   vtkIdType nbNodes = GetEntities( SMDSAbs_Node, aNodes );
   thePoints->SetNumberOfPoints( nbNodes );
-  
+
   int nbPoints = 0;
 
   TEntityList::const_iterator anIter;
@@ -207,52 +231,70 @@ void SMESH_VisualObjDef::createPoints( vtkPoints* thePoints )
 // function : buildPrs
 // purpose  : create VTK cells( fill unstructured grid )
 //=================================================================================
-void SMESH_VisualObjDef::buildPrs()
+void SMESH_VisualObjDef::buildPrs(bool buildGrid)
 {
-  try 
+  MESSAGE("----------------------------------------------------------SMESH_VisualObjDef::buildPrs " << buildGrid);
+  if (buildGrid)
   {
-    mySMDS2VTKNodes.clear();
-    myVTK2SMDSNodes.clear();
-    mySMDS2VTKElems.clear();
-    myVTK2SMDSElems.clear();
-    
-    if ( IsNodePrs() )
-      buildNodePrs();
-    else
-      buildElemPrs();
+       myLocalGrid = true;
+       try
+       {
+               mySMDS2VTKNodes.clear();
+               myVTK2SMDSNodes.clear();
+               mySMDS2VTKElems.clear();
+               myVTK2SMDSElems.clear();
+
+               if ( IsNodePrs() )
+                       buildNodePrs();
+               else
+                       buildElemPrs();
+       }
+       catch(...)
+       {
+               mySMDS2VTKNodes.clear();
+               myVTK2SMDSNodes.clear();
+               mySMDS2VTKElems.clear();
+               myVTK2SMDSElems.clear();
+
+               myGrid->SetPoints( 0 );
+               myGrid->SetCells( 0, 0, 0, 0, 0 );
+               throw;
+       }
   }
-  catch(...)
+  else
   {
-    mySMDS2VTKNodes.clear();
-    myVTK2SMDSNodes.clear();
-    mySMDS2VTKElems.clear();
-    myVTK2SMDSElems.clear();
-
-    myGrid->SetPoints( 0 );
-    myGrid->SetCells( 0, 0, 0 );
-    throw;
+       myLocalGrid = false;
+       if (!GetMesh()->isCompacted())
+         {
+           MESSAGE("*** buildPrs ==> compactMesh!");
+           GetMesh()->compactMesh();
+         }
+       vtkUnstructuredGrid *theGrid = GetMesh()->getGrid();
+       myGrid->ShallowCopy(theGrid);
+       //MESSAGE(myGrid->GetReferenceCount());
+       //MESSAGE( "Update - myGrid->GetNumberOfCells() = "<<myGrid->GetNumberOfCells() );
+       //MESSAGE( "Update - myGrid->GetNumberOfPoints() = "<<myGrid->GetNumberOfPoints() );
+       if( MYDEBUGWITHFILES ) SMESH::WriteUnstructuredGrid( myGrid,"buildPrs.vtu" );
   }
-  
-  if( MYDEBUG ) MESSAGE( "Update - myGrid->GetNumberOfCells() = "<<myGrid->GetNumberOfCells() );
-  if( MYDEBUGWITHFILES ) SMESH::WriteUnstructuredGrid( myGrid,"/tmp/buildPrs" );
 }
 
 //=================================================================================
 // function : buildNodePrs
 // purpose  : create VTK cells for nodes
 //=================================================================================
+
 void SMESH_VisualObjDef::buildNodePrs()
 {
   // PAL16631: without swap, bad_alloc is not thrown but hung up and crash instead,
   // so check remaining memory size for safety
-  SMDS_Mesh::CheckMemory(); // PAL16631
+  // SMDS_Mesh::CheckMemory(); // PAL16631
   vtkPoints* aPoints = vtkPoints::New();
   createPoints( aPoints );
-  SMDS_Mesh::CheckMemory();
+  // SMDS_Mesh::CheckMemory();
   myGrid->SetPoints( aPoints );
   aPoints->Delete();
 
-  myGrid->SetCells( 0, 0, 0 );
+  myGrid->SetCells( 0, 0, 0, 0, 0 );
 }
 
 //=================================================================================
@@ -288,12 +330,12 @@ namespace{
 void SMESH_VisualObjDef::buildElemPrs()
 {
   // Create points
-  
+
   vtkPoints* aPoints = vtkPoints::New();
   createPoints( aPoints );
   myGrid->SetPoints( aPoints );
   aPoints->Delete();
-    
+
   if ( MYDEBUG )
     MESSAGE("Update - myGrid->GetNumberOfPoints() = "<<myGrid->GetNumberOfPoints());
 
@@ -311,7 +353,7 @@ void SMESH_VisualObjDef::buildElemPrs()
 
   // PAL16631: without swap, bad_alloc is not thrown but hung up and crash instead,
   // so check remaining memory size for safety
-  SMDS_Mesh::CheckMemory(); // PAL16631
+  // SMDS_Mesh::CheckMemory(); // PAL16631
 
   vtkIdType aCellsSize =  2 * nbEnts[ SMDSAbs_0DElement ] + 3 * nbEnts[ SMDSAbs_Edge ];
 
@@ -328,7 +370,7 @@ void SMESH_VisualObjDef::buildElemPrs()
 
   vtkIdType aNbCells = nbEnts[ SMDSAbs_0DElement ] + nbEnts[ SMDSAbs_Edge ] +
                        nbEnts[ SMDSAbs_Face ] + nbEnts[ SMDSAbs_Volume ];
-  
+
   if ( MYDEBUG )
     MESSAGE( "Update - aNbCells = "<<aNbCells<<"; aCellsSize = "<<aCellsSize );
 
@@ -337,13 +379,13 @@ void SMESH_VisualObjDef::buildElemPrs()
   vtkCellArray* aConnectivity = vtkCellArray::New();
   aConnectivity->Allocate( aCellsSize, 0 );
 
-  SMDS_Mesh::CheckMemory(); // PAL16631
+  // SMDS_Mesh::CheckMemory(); // PAL16631
 
   vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
   aCellTypesArray->SetNumberOfComponents( 1 );
   aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
 
-  SMDS_Mesh::CheckMemory(); // PAL16631
+  // SMDS_Mesh::CheckMemory(); // PAL16631
 
   vtkIdList *anIdList = vtkIdList::New();
   vtkIdType iElem = 0;
@@ -351,7 +393,7 @@ void SMESH_VisualObjDef::buildElemPrs()
   TConnect aConnect;
   aConnect.reserve(VTK_CELL_SIZE);
 
-  SMDS_Mesh::CheckMemory(); // PAL16631
+  // SMDS_Mesh::CheckMemory(); // PAL16631
 
   for ( int i = 0; i <= 3; i++ ) // iterate through 0d elements, edges, faces and volumes
   {
@@ -380,8 +422,8 @@ void SMESH_VisualObjDef::buildElemPrs()
           // Convertions connectivities from SMDS to VTK
           if (anElem->IsPoly() && aNbNodes > 3) { // POLYEDRE
 
-            if ( const SMDS_PolyhedralVolumeOfNodes* ph =
-                 dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem))
+            if ( const SMDS_VtkVolume* ph =
+                 dynamic_cast<const SMDS_VtkVolume*> (anElem))
             {
               aNbNodes = GetConnect(ph->uniqueNodesIterator(),aConnect);
               anIdList->SetNumberOfIds( aNbNodes );
@@ -454,29 +496,29 @@ void SMESH_VisualObjDef::buildElemPrs()
         iElem++;
       }
     }
-    SMDS_Mesh::CheckMemory(); // PAL16631
+    // SMDS_Mesh::CheckMemory(); // PAL16631
   }
 
   // Insert cells in grid
-  
+
   VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
   aCellLocationsArray->SetNumberOfComponents( 1 );
   aCellLocationsArray->SetNumberOfTuples( aNbCells );
-  
-  SMDS_Mesh::CheckMemory(); // PAL16631
+
+  // SMDS_Mesh::CheckMemory(); // PAL16631
 
   aConnectivity->InitTraversal();
   for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
     aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
 
   myGrid->SetCells( aCellTypesArray, aCellLocationsArray,aConnectivity );
-  
+
   aCellLocationsArray->Delete();
   aCellTypesArray->Delete();
   aConnectivity->Delete();
   anIdList->Delete();
 
-  SMDS_Mesh::CheckMemory(); // PAL16631
+  // SMDS_Mesh::CheckMemory(); // PAL16631
 }
 
 //=================================================================================
@@ -521,12 +563,20 @@ bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId,
   return true;
 }
 
+vtkUnstructuredGrid* SMESH_VisualObjDef::GetUnstructuredGrid()
+{
+       //MESSAGE("SMESH_VisualObjDef::GetUnstructuredGrid " << myGrid);
+       return myGrid;
+}
+
+
 //=================================================================================
 // function : IsValid
 // purpose  : Return true if there are some entities
 //=================================================================================
 bool SMESH_VisualObjDef::IsValid() const
 {
+       //MESSAGE("SMESH_VisualObjDef::IsValid");
   return GetNbEntities(SMDSAbs_Node) > 0      || 
          GetNbEntities(SMDSAbs_0DElement) > 0 || 
          GetNbEntities(SMDSAbs_Edge) > 0      || 
@@ -546,6 +596,7 @@ bool SMESH_VisualObjDef::IsValid() const
 SMESH_MeshObj::SMESH_MeshObj(SMESH::SMESH_Mesh_ptr theMesh):
   myClient(SalomeApp_Application::orb(),theMesh)
 {
+       myEmptyGrid = 0;
   if ( MYDEBUG ) 
     MESSAGE("SMESH_MeshObj - this = "<<this<<"; theMesh->_is_nil() = "<<theMesh->_is_nil());
 }
@@ -567,13 +618,31 @@ SMESH_MeshObj::~SMESH_MeshObj()
 bool SMESH_MeshObj::Update( int theIsClear )
 {
   // Update SMDS_Mesh on client part
+  MESSAGE("SMESH_MeshObj::Update " << this);
   if ( myClient.Update(theIsClear) || GetUnstructuredGrid()->GetNumberOfPoints()==0) {
+    MESSAGE("buildPrs");
     buildPrs();  // Fill unstructured grid
     return true;
   }
   return false;
 }
 
+bool SMESH_MeshObj::NulData()
+{
+       MESSAGE ("SMESH_MeshObj::NulData() ==================================================================================");
+       if (!myEmptyGrid)
+       {
+         myEmptyGrid = SMDS_UnstructuredGrid::New();
+         myEmptyGrid->Initialize();
+         myEmptyGrid->Allocate();
+         vtkPoints* points = vtkPoints::New();
+         points->SetNumberOfPoints(0);
+         myEmptyGrid->SetPoints( points );
+         points->Delete();
+         myEmptyGrid->BuildLinks();
+       }
+       myGrid->ShallowCopy(myEmptyGrid);
+}
 //=================================================================================
 // function : GetElemDimension
 // purpose  : Get dimension of element
@@ -740,8 +809,9 @@ void SMESH_SubMeshObj::UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunc
 //=================================================================================
 bool SMESH_SubMeshObj::Update( int theIsClear )
 {
+       MESSAGE("SMESH_SubMeshObj::Update " << this)
   bool changed = myMeshObj->Update( theIsClear );
-  buildPrs();
+  buildPrs(true);
   return changed;
 }
 
index 37a7ff63bf6e4da3d7f375041ad88deb1689f02c..160901d836f819f9a8a40bbcd169700e2e185124 100644 (file)
@@ -56,6 +56,7 @@ class SMESHOBJECT_EXPORT SMESH_VisualObj
 {
 public:
   virtual bool Update( int theIsClear = true ) = 0;
+  virtual bool NulData() = 0;
   virtual void UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor ) = 0;
   virtual int GetElemDimension( const int theObjId ) = 0;
 
index de41e1628cc9eed475a1250d209a1f18c232f90b..f8aec86be3f0d974c018ea1eb799212e5d314efa 100644 (file)
@@ -62,6 +62,7 @@ public:
   virtual                   ~SMESH_VisualObjDef();
   
   virtual bool              Update( int theIsClear = true ) = 0;
+  virtual bool              NulData() {return 0; };
   virtual void              UpdateFunctor( const SMESH::Controls::FunctorPtr& theFunctor ) = 0;
   virtual int               GetElemDimension( const int theObjId ) = 0;
 
@@ -77,7 +78,7 @@ public:
                                           int&      theNodeId1,
                                           int&      theNodeId2 ) const;
 
-  virtual vtkUnstructuredGrid* GetUnstructuredGrid() { return myGrid; }
+  virtual vtkUnstructuredGrid* GetUnstructuredGrid();
   
   virtual vtkIdType         GetNodeObjId( int theVTKID );
   virtual vtkIdType         GetNodeVTKId( int theObjID );
@@ -87,16 +88,17 @@ public:
 protected:
 
   void                      createPoints( vtkPoints* );
-  void                      buildPrs();
+  void                      buildPrs(bool buildGrid = false);
   void                      buildNodePrs();
   void                      buildElemPrs();
   
-private:                                   
+//private:
 
   TMapOfIds                 mySMDS2VTKNodes;
   TMapOfIds                 myVTK2SMDSNodes;
   TMapOfIds                 mySMDS2VTKElems;
   TMapOfIds                 myVTK2SMDSElems;
+  bool                      myLocalGrid;
 
   vtkUnstructuredGrid*      myGrid;
 };
@@ -115,6 +117,7 @@ public:
   virtual                   ~SMESH_MeshObj();
   
   virtual bool              Update( int theIsClear = true );
+  virtual bool              NulData();
   
   virtual int               GetNbEntities( const SMDSAbs_ElementType) const;
   virtual int               GetEntities( const SMDSAbs_ElementType, TEntityList& ) const;
@@ -129,6 +132,7 @@ public:
 
 protected:
   SMESH_Client              myClient;
+  vtkUnstructuredGrid*      myEmptyGrid;
 };
 
 
diff --git a/src/OBJECT/SMESH_vtkPVUpdateSuppressor.cxx b/src/OBJECT/SMESH_vtkPVUpdateSuppressor.cxx
new file mode 100644 (file)
index 0000000..bbab763
--- /dev/null
@@ -0,0 +1,230 @@
+/*=========================================================================
+
+ Program:   ParaView
+ Module:    $RCSfile$
+
+ Copyright (c) Kitware, Inc.
+ All rights reserved.
+ See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.  See the above copyright notice for more information.
+
+ =========================================================================*/
+#include "SMESH_vtkPVUpdateSuppressor.h"
+
+#include "vtkAlgorithmOutput.h"
+#include "vtkCollection.h"
+#include "vtkCommand.h"
+#include "vtkCompositeDataPipeline.h"
+#include "vtkDataObject.h"
+#include "vtkDemandDrivenPipeline.h"
+#include "vtkInformation.h"
+#include "vtkInformationDoubleVectorKey.h"
+#include "vtkInformationExecutivePortKey.h"
+#include "vtkInformationVector.h"
+#include "vtkObjectFactory.h"
+#include "vtkPolyData.h"
+//#include "vtkProcessModule.h"
+#include "vtkSmartPointer.h"
+#include "vtkUnstructuredGrid.h"
+//#include "vtkUpdateSuppressorPipeline.h"
+
+#include <vtkstd/map>
+
+#ifdef MYDEBUG
+# define vtkMyDebug(x)\
+    cout << x;
+#else
+# define vtkMyDebug(x)
+#endif
+
+vtkCxxRevisionMacro(vtkPVUpdateSuppressor, "$Revision$")
+;
+vtkStandardNewMacro(vtkPVUpdateSuppressor)
+;
+//----------------------------------------------------------------------------
+vtkPVUpdateSuppressor::vtkPVUpdateSuppressor()
+{
+  this->UpdatePiece = 0;
+  this->UpdateNumberOfPieces = 1;
+
+  this->UpdateTime = 0.0;
+  this->UpdateTimeInitialized = false;
+
+  this->Enabled = 1;
+
+  //  vtkProcessModule* pm = vtkProcessModule::GetProcessModule();
+  //
+  //  if (pm)
+  //    {
+  //    this->UpdateNumberOfPieces = pm->GetNumberOfLocalPartitions();
+  //    this->UpdatePiece = pm->GetPartitionId();
+  //    }
+}
+
+//----------------------------------------------------------------------------
+vtkPVUpdateSuppressor::~vtkPVUpdateSuppressor()
+{
+}
+
+//----------------------------------------------------------------------------
+void vtkPVUpdateSuppressor::SetUpdateTime(double utime)
+{
+  this->UpdateTimeInitialized = true;
+  if (this->UpdateTime != utime)
+    {
+      this->Modified();
+      this->UpdateTime = utime;
+    }
+}
+
+//----------------------------------------------------------------------------
+void vtkPVUpdateSuppressor::SetEnabled(int enable)
+{
+  if (this->Enabled == enable)
+    {
+      return;
+    }
+  this->Enabled = enable;
+  this->Modified();
+  //  vtkUpdateSuppressorPipeline* executive =
+  //    vtkUpdateSuppressorPipeline::SafeDownCast(this->GetExecutive());
+  //  if (executive)
+  //    {
+  //    executive->SetEnabled(enable);
+  //    }
+}
+
+//----------------------------------------------------------------------------
+void vtkPVUpdateSuppressor::ForceUpdate()
+{
+  // Make sure that output type matches input type
+  this->UpdateInformation();
+
+  vtkDataObject *input = this->GetInput();
+  if (input == 0)
+    {
+      vtkErrorMacro("No valid input.");
+      return;
+    }
+  vtkDataObject *output = this->GetOutput();
+
+  // int fixme; // I do not like this hack.  How can we get rid of it?
+  // Assume the input is the collection filter.
+  // Client needs to modify the collection filter because it is not
+  // connected to a pipeline.
+  vtkAlgorithm *source = input->GetProducerPort()->GetProducer();
+  if (source && (source->IsA("vtkMPIMoveData")
+      || source->IsA("vtkCollectPolyData") || source->IsA("vtkM2NDuplicate")
+      || source->IsA("vtkM2NCollect")
+      || source->IsA("vtkOrderedCompositeDistributor")
+      || source->IsA("vtkClientServerMoveData")))
+    {
+      source->Modified();
+    }
+
+  vtkInformation* info = input->GetPipelineInformation();
+  vtkStreamingDemandDrivenPipeline
+      * sddp =
+          vtkStreamingDemandDrivenPipeline::SafeDownCast(
+                                                         vtkExecutive::PRODUCER()->GetExecutive(
+                                                                                                info));
+  if (sddp)
+    {
+      sddp->SetUpdateExtent(info, this->UpdatePiece,
+                            this->UpdateNumberOfPieces, 0);
+    }
+  else
+    {
+      input->SetUpdatePiece(this->UpdatePiece);
+      input->SetUpdateNumberOfPieces(this->UpdateNumberOfPieces);
+      input->SetUpdateGhostLevel(0);
+    } vtkMyDebug("ForceUpdate ");
+  if (this->UpdateTimeInitialized)
+    {
+      info->Set(vtkCompositeDataPipeline::UPDATE_TIME_STEPS(),
+                &this->UpdateTime, 1);
+      vtkMyDebug(this->UpdateTime);
+    } vtkMyDebug(endl);
+
+  input->Update();
+  // Input may have changed, we obtain the pointer again.
+  input = this->GetInput();
+
+  output->ShallowCopy(input);
+  this->PipelineUpdateTime.Modified();
+}
+
+//----------------------------------------------------------------------------
+vtkExecutive* vtkPVUpdateSuppressor::CreateDefaultExecutive()
+{
+  vtkUpdateSuppressorPipeline* executive = vtkUpdateSuppressorPipeline::New();
+  executive->SetEnabled(this->Enabled);
+  return executive;
+}
+
+//----------------------------------------------------------------------------
+int vtkPVUpdateSuppressor::RequestDataObject(
+                                             vtkInformation* vtkNotUsed(reqInfo),
+                                             vtkInformationVector** inputVector,
+                                             vtkInformationVector* outputVector)
+{
+  vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
+  if (!inInfo)
+    {
+      return 0;
+    }
+
+  vtkDataObject *input = inInfo->Get(vtkDataObject::DATA_OBJECT());
+  if (input)
+    {
+      // for each output
+      for (int i = 0; i < this->GetNumberOfOutputPorts(); ++i)
+        {
+          vtkInformation* outInfo = outputVector->GetInformationObject(i);
+          vtkDataObject *output = outInfo->Get(vtkDataObject::DATA_OBJECT());
+
+          if (!output || !output->IsA(input->GetClassName()))
+            {
+              vtkDataObject* newOutput = input->NewInstance();
+              newOutput->SetPipelineInformation(outInfo);
+              newOutput->Delete();
+              this->GetOutputPortInformation(i)->Set(
+                                                     vtkDataObject::DATA_EXTENT_TYPE(),
+                                                     newOutput->GetExtentType());
+            }
+        }
+      return 1;
+    }
+  return 0;
+
+}
+
+//----------------------------------------------------------------------------
+int vtkPVUpdateSuppressor::RequestData(vtkInformation* vtkNotUsed(reqInfo),
+                                       vtkInformationVector** inputVector,
+                                       vtkInformationVector* outputVector)
+{
+  // RequestData is only called by its executive when 
+  // (Enabled==off) and thus acting as a passthrough filter
+  vtkInformation *outInfo = outputVector->GetInformationObject(0);
+  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
+  vtkDataObject *input = inInfo->Get(vtkDataObject::DATA_OBJECT());
+  vtkDataObject *output = outInfo->Get(vtkDataObject::DATA_OBJECT());
+
+  output->ShallowCopy(input);
+  return 1;
+}
+
+//----------------------------------------------------------------------------
+void vtkPVUpdateSuppressor::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+  os << indent << "UpdatePiece: " << this->UpdatePiece << endl;
+  os << indent << "UpdateNumberOfPieces: " << this->UpdateNumberOfPieces
+      << endl;
+  os << indent << "Enabled: " << this->Enabled << endl;
+  os << indent << "UpdateTime: " << this->UpdateTime << endl;
+}
diff --git a/src/OBJECT/SMESH_vtkPVUpdateSuppressor.h b/src/OBJECT/SMESH_vtkPVUpdateSuppressor.h
new file mode 100644 (file)
index 0000000..4cd0624
--- /dev/null
@@ -0,0 +1,98 @@
+/*=========================================================================
+
+ Program:   ParaView
+ Module:    $RCSfile$
+
+ Copyright (c) Kitware, Inc.
+ All rights reserved.
+ See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE.  See the above copyright notice for more information.
+
+ =========================================================================*/
+// .NAME vtkPVUpdateSuppressor - prevents propagation of update
+// .SECTION Description 
+// vtkPVUpdateSuppressor now uses the vtkProcessModule singleton to set up the
+// default values for UpdateNumberOfPieces and UpdatePiece, so we no longer have
+// to set the default values (in most cases).
+// .SECTION See Also
+// vtkPVCacheKeeper vtkUpdateSuppressorPipeline
+
+#ifndef __vtkPVUpdateSuppressor_h
+#define __vtkPVUpdateSuppressor_h
+
+#include "vtkDataObjectAlgorithm.h"
+
+class VTK_EXPORT vtkPVUpdateSuppressor: public vtkDataObjectAlgorithm
+{
+public:
+vtkTypeRevisionMacro(vtkPVUpdateSuppressor,vtkDataObjectAlgorithm)
+  ;
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  // Description:
+  // Construct with user-specified implicit function.
+  static vtkPVUpdateSuppressor *New();
+
+  // Description:
+  // Force update on the input.
+  virtual void ForceUpdate();
+
+  // Description:
+  // Set number of pieces and piece on the data.
+  // This causes the filter to ingore the request from the output.
+  // It is here because the user may not have celled update on the output
+  // before calling force update (it is an easy fix).
+  vtkSetMacro(UpdatePiece, int)
+  ;
+  vtkGetMacro(UpdatePiece, int)
+  ;
+  vtkSetMacro(UpdateNumberOfPieces, int)
+  ;
+  vtkGetMacro(UpdateNumberOfPieces, int)
+  ;
+
+  // Description:
+  // Get/Set if the update suppressor is enabled. If the update suppressor 
+  // is not enabled, it won't supress any updates. Enabled by default.
+  void SetEnabled(int);
+  vtkGetMacro(Enabled, int)
+  ;
+
+  // Description:
+  // Get/Set the update time that is sent up the pipeline.
+  void SetUpdateTime(double utime);
+  vtkGetMacro(UpdateTime, double)
+  ;
+
+protected:
+  vtkPVUpdateSuppressor();
+  ~vtkPVUpdateSuppressor();
+
+  int RequestDataObject(vtkInformation* request,
+                        vtkInformationVector **inputVector,
+                        vtkInformationVector *outputVector);
+  int RequestData(vtkInformation* request, vtkInformationVector **inputVector,
+                  vtkInformationVector *outputVector);
+
+  int UpdatePiece;
+  int UpdateNumberOfPieces;
+  double UpdateTime;
+
+  bool UpdateTimeInitialized;
+
+  int Enabled;
+
+  vtkTimeStamp PipelineUpdateTime;
+
+  // Create a default executive.
+  virtual vtkExecutive* CreateDefaultExecutive();
+
+private:
+  vtkPVUpdateSuppressor(const vtkPVUpdateSuppressor&); // Not implemented.
+  void operator=(const vtkPVUpdateSuppressor&); // Not implemented.
+};
+
+#endif
index 869c6677ce71f57ae4132368443632243e868b83..c4dd2bf11c7c77be9e3e16169f712a3c5ba065d1 100644 (file)
@@ -27,6 +27,8 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
 # header files 
 salomeinclude_HEADERS = \
+    chrono.hxx \
+       ObjectPool.hxx \
        SMDS_TypeOfPosition.hxx \
        SMDSAbs_ElementType.hxx \
        SMDS_EdgePosition.hxx \
@@ -34,13 +36,17 @@ salomeinclude_HEADERS = \
        SMDS_FacePosition.hxx \
        SMDS_Mesh.hxx \
        SMDS_Mesh0DElement.hxx \
+       SMDS_LinearEdge.hxx \
        SMDS_MeshEdge.hxx \
        SMDS_MeshElement.hxx \
+       SMDS_MeshElement.cxx \
        SMDS_MeshElementIDFactory.hxx \
+       SMDS_MeshCell.hxx \
        SMDS_MeshFace.hxx \
        SMDS_MeshGroup.hxx \
        SMDS_MeshIDFactory.hxx \
        SMDS_MeshNode.hxx \
+       SMDS_MeshNodeIDFactory.hxx \
        SMDS_MeshObject.hxx \
        SMDS_MeshVolume.hxx \
        SMDS_Position.hxx \
@@ -50,6 +56,10 @@ salomeinclude_HEADERS = \
        SMDS_IteratorOfElements.hxx \
        SMDS_VolumeOfFaces.hxx \
        SMDS_VolumeOfNodes.hxx \
+       SMDS_VtkEdge.hxx \
+       SMDS_VtkFace.hxx \
+       SMDS_VtkVolume.hxx \
+       SMDS_VtkCellIterator.hxx \
        SMDS_PolyhedralVolumeOfNodes.hxx \
        SMDS_FaceOfEdges.hxx \
        SMDS_FaceOfNodes.hxx \
@@ -61,6 +71,8 @@ salomeinclude_HEADERS = \
        SMDS_SetIterator.hxx \
        SMESH_SMDS.hxx \
        SMDS_MeshInfo.hxx \
+       SMDS_UnstructuredGrid.hxx \
+       SMDS_Downward.hxx \
        SMDS_StdIterator.hxx
 
 
@@ -68,8 +80,10 @@ salomeinclude_HEADERS = \
 
 lib_LTLIBRARIES = libSMDS.la
 dist_libSMDS_la_SOURCES = \
+    chrono.cxx \
        SMDS_MeshObject.cxx \
        SMDS_MeshElement.cxx \
+       SMDS_MeshCell.cxx \
        SMDS_Position.cxx \
        SMDS_EdgePosition.cxx \
        SMDS_FacePosition.cxx \
@@ -77,9 +91,11 @@ dist_libSMDS_la_SOURCES = \
        SMDS_VertexPosition.cxx \
        SMDS_MeshNode.cxx \
        SMDS_Mesh0DElement.cxx \
+       SMDS_LinearEdge.cxx \
        SMDS_MeshEdge.cxx \
        SMDS_MeshFace.cxx \
        SMDS_MeshVolume.cxx \
+       SMDS_MeshNodeIDFactory.cxx \
        SMDS_MeshElementIDFactory.cxx \
        SMDS_MeshGroup.cxx \
        SMDS_MeshIDFactory.cxx \
@@ -87,6 +103,10 @@ dist_libSMDS_la_SOURCES = \
        SMDS_IteratorOfElements.cxx \
        SMDS_VolumeOfFaces.cxx \
        SMDS_VolumeOfNodes.cxx \
+       SMDS_VtkEdge.cxx \
+       SMDS_VtkFace.cxx \
+       SMDS_VtkVolume.cxx \
+       SMDS_VtkCellIterator.cxx \
        SMDS_PolyhedralVolumeOfNodes.cxx \
        SMDS_FaceOfEdges.cxx \
        SMDS_FaceOfNodes.cxx \
@@ -94,15 +114,19 @@ dist_libSMDS_la_SOURCES = \
        SMDS_VolumeTool.cxx \
        SMDS_QuadraticEdge.cxx \
        SMDS_QuadraticFaceOfNodes.cxx \
-       SMDS_QuadraticVolumeOfNodes.cxx
+       SMDS_QuadraticVolumeOfNodes.cxx \
+       SMDS_UnstructuredGrid.cxx \
+       SMDS_Downward.cxx
 
 # additionnal information to compil and link file
 libSMDS_la_CPPFLAGS = \
        $(KERNEL_CXXFLAGS) \
        $(CAS_CPPFLAGS) \
+        $(VTK_INCLUDES) \
        $(BOOST_CPPFLAGS)
 
 libSMDS_la_LDFLAGS  = \
+       $(VTK_LIBS) \
        $(KERNEL_LDFLAGS) -lSALOMELocalTrace \
        $(CAS_KERNEL)
 
diff --git a/src/SMDS/Notes b/src/SMDS/Notes
new file mode 100644 (file)
index 0000000..830ffb5
--- /dev/null
@@ -0,0 +1,235 @@
+--> Branche V6_main
+
+Problemes en cours
+==================
+- a faire
++ en cours, OK mais perfectible
+* OK
+
++ visualisation de groupe (type d'element): on voit tout le maillage, mais le groupe est OK
+  creation d'une structure vtkUnstructuredGrid locale : iteration un peu lourde, et pas de partage avec la structure du maillage (pas evident)
+- inversion d'un volume (tetra): exception
+- script de creation de noeuds et d'elements: OK, mais pas compatible avec version precedente (numerotation noeuds differente)
++ affichage numeros noeuds: numeros en trop sur (O,0,0) pas systematique, trouver la condition (enlever dans vtkUnstructuredGrid ?)
+  ==> purge systematique noeuds et cellules en trop dans compactage grid.
++ gestion du mode embedded mal faite lors d'un script python : journal commandes intempestif
+- affichage des noeuds apres changement lineaire <--> quadratique à l'IHM : pas pris en compte, alors que maillage OK,
+  mais script OK
+  ==> cassé apres mode embedded ou elimination noeuds en trop ?
+- extrusion elements 2D along a path : affichage apres calcul pas toujours OK (filaire)
+- branche git a ouvrir pour merge avec V5_1_4_BR tag V5_1_4rc1
+
+A tester, non pris en compte
+============================
+- engine standalone
+- polyedres (attendre vtk)
+
+
+=============================== Hypothese de refonte de l'API de SMDS
+
+n'utiliser que vtkUnstructuredGrid, ne pas avor d'objets SMDS_MeshElement mais seulement des index de vtkUnstructuredGrid.
+2987 usages de SMDS_MeshNodes
+810            SMDS_MeshElement
+...
+==> en dernier ressort, lourd
+================================================================================
+
+Essai a API SMDS a peu pres constante
+=====================================
+
+SMDS_Mesh
+  static vector<SMDS_Mesh*> _meshList;     --> retrouver un SMDS_Mesh
+  vtkUnstructuredGrid*      myGrid;
+
+  vector<SMDS_MeshNode *>   myNodes;       --> meme index que dans le pointSet de myGrid
+  vector<SMDS_MeshCell *>   myCells;       --> index = ID client, pas le meme index que dans le cellTypes de myGrid (ID vtk)
+
+
+
+SMDS_MeshElement
+  int myID;                                --> index dans la structure geree par SMDS_Mesh
+  int myMeshId;                            --> pour retrouver SMDS_Mesh* dans _meshList
+  int myShapeId;                           --> pour retrouver la subShape
+                                                         
+
+SMDS_MeshNode: SMDS_MeshElement
+  SMDS_PositionPtr myPosition;             -->  A REVOIR : objet position dans la shape geom
+  ##vector<int> myInverseElements;         -->  SUPPRIME : pour retrouver les elements, vtkCellLinks
+
+
+SMDS_MeshCell: SMDS_MeshElement            --> generique pour tous les elements (cells)
+  int myVtkID                              --> A SUPPRIMER
+
+SMDS_MeshVolume: SMDS_MeshCell
+
+SMDS_VolumeOfNodes: SMDS_MeshVolume        --> Garder temporairement, utilisation dans StdMesher et SMDS_VolumeTool
+  const SMDS_MeshNode **myNodes;           --> Couteux
+  int                 myNbNodes;           -->  ""
+
+SMDS_VolumeVtkNodes: SMDS_MeshVolume       --> Utiliser systematiquement dans SMDS,
+                                           --> IMPLEMENTER.
+
+
+SMDS_MeshElementIDFactory: SMDS_MeshNodeIDFactory
+  vector<int> myIDElements; // index = ID client, value = ID vtk  --> A SUPPRIMER, ne sert que dans SMDS_MeshElementIDFactory
+  vector<int> myVtkIndex;   // index = ID vtk, value = ID client  --> A REPORTER dans SMDS_Mesh
+
+
+
+
+========= TODO ============
+
+enlever vtkId de SMDS_MeshCell, utiliser SMDS_MeshElementIDFactory.
+
+ajouter ID dans SMDS_Mesh::createTriangle 
+verifier ID dans SMDS_Mesh::Find*OrCreate
+
+===================================================
+occupation memoire cube 100*100*100 sans affichage
+NOTES:
+- sur Debian Sarge 64 bits, les mesures malloc_stat() semblent coherentes
+  avec une mesure externe globale(recherche du passage en swap du process).
+- sur Ubuntu 9.10 64 bits, les mesures malloc_stat() donnent des resultats bizarres (surestimation ?),
+  mais la mesure avec l'outil KDE de surveillance systeme est OK avec la recherche du swap.
+
+
+Reference : V513 Debian Sarge 64 bits: --> 463 - 33 = 430 Mo
+-------------------------------------
+Total (incl. mmap):
+system bytes     =   43757568
+in use bytes     =   32909584 = 33M
+max mmap regions =         41
+max mmap bytes   =   16371712
+----
+Total (incl. mmap):
+system bytes     =  464670720
+in use bytes     =  463105120 = 463M
+max mmap regions =         47
+max mmap bytes   =   28188672
+
+Debian Sarge 64 bits, vtkUnstructuredGrid nodes et hexa, 4 janvier 2010 --> 512 - 41 = 471M
+-----------------------------------
+
+Total (incl. mmap):
+system bytes     =   52133888
+in use bytes     =   41340320 : 41M
+max mmap regions =         72
+max mmap bytes   =   24625152
+----
+Total (incl. mmap):
+system bytes     =  520560640
+in use bytes     =  518735584 : 512M
+max mmap regions =         88
+max mmap bytes   =  198385664
+
+idem avec pool SMDS_MeshNodes --> 483 -33 = 450M
+-----------------------------
+Total (incl. mmap):
+system bytes     =   43696128
+in use bytes     =   32915184 : 33M 
+max mmap regions =         41
+max mmap bytes   =   16371712
+----
+Total (incl. mmap):
+system bytes     =  484806656
+in use bytes     =  482980992 : 483M
+max mmap regions =         58
+max mmap bytes   =  184557568
+
+idem ci-dessus + pool SMDS_VolumeVtkNodes --> 475 -33 = 442M (git: add ObjectPool.hxx)
+-----------------------------------------
+
+Total (incl. mmap):
+system bytes     =   43200512
+in use bytes     =   32908576 : 33M
+max mmap regions =         41
+max mmap bytes   =   16371712
+----
+Total (incl. mmap):
+system bytes     =  478068736
+in use bytes     =  475144400 : 475M
+max mmap regions =         59
+max mmap bytes   =  184692736
+
+remplacement SMDS_PositionPtr: (boost::shared_ptr<SMDS_Position> --> SMDS_Position*) --> 436 - 35 = 401M (git SMDS_Position)
+------------------------------------------------------------------------------------
+Total (incl. mmap):
+system bytes     =   45408256
+in use bytes     =   35097680 : 35M
+max mmap regions =         47
+max mmap bytes   =   18116608
+----
+Total (incl. mmap):
+system bytes     =  438935552
+in use bytes     =  436116560 : 436M
+max mmap regions =         65
+max mmap bytes   =  186437632
+
+simplification SMDS_SpacePosition (pas de double[3]) --> 418 -33 = 385M (git SMDS_SpacePosition)
+----------------------------------------------------
+Total (incl. mmap):
+system bytes     =   42582016
+in use bytes     =   32883552 : 33M
+max mmap regions =         41
+max mmap bytes   =   16371712
+----
+Total (incl. mmap):
+system bytes     =  421728256
+in use bytes     =  418378000 : 418M
+max mmap regions =         58
+max mmap bytes   =  183640064
+
+sizeof(SMDS_MeshElement) 16
+sizeof(SMDS_MeshNode) 24
+sizeof(SMDS_MeshCell) 24
+sizeof(SMDS_VolumeVtkNodes) 24
+sizeof(SMDS_Position) 16
+sizeof(SMDS_SpacePosition) 16
+
+impact d'un int en plus dans SMDS_MeshElement --> 426 - 33 = 393M
+---------------------------------------------
+
+sizeof(SMDS_MeshElement) 24
+sizeof(SMDS_MeshNode) 32       --> on retrouve bien les 8M
+sizeof(SMDS_MeshCell) 24
+sizeof(SMDS_VolumeVtkNodes) 24
+sizeof(SMDS_Position) 16
+sizeof(SMDS_SpacePosition) 16
+
+Total (incl. mmap):
+system bytes     =   43192320
+in use bytes     =   32681088 : 33M
+max mmap regions =         41
+max mmap bytes   =   16371712
+----
+Total (incl. mmap):
+system bytes     =  429334528
+in use bytes     =  426424576 : 426M
+max mmap regions =         59
+max mmap bytes   =  184692736
+
+remplacement std::set par std::vector dans SMESHDS_SubMesh --> 347 - 35 = 312M
+----------------------------------------------------------
+sizeof(SMDS_MeshElement) 24
+sizeof(SMDS_MeshNode) 32
+sizeof(SMDS_MeshCell) 24
+sizeof(SMDS_VolumeVtkNodes) 24
+sizeof(SMDS_Position) 16
+sizeof(SMDS_SpacePosition) 16
+
+Total (incl. mmap):
+system bytes     =   45404160
+in use bytes     =   35132160 --> 35M
+max mmap regions =         49
+max mmap bytes   =   17723392
+----
+Total (incl. mmap):
+system bytes     =  349831168
+in use bytes     =  346885424 --> 347M
+max mmap regions =         73
+max mmap bytes   =  204148736
+
+Ce resultat est coherent avec une recherche de swap sur une machine a 8Go de memoire:
+Cube a 270**3 mailles (~20M mailles) --> 6.2 Go (idem Debian Sarge et Ubuntu 9.10, 64 bits)
+Le meme avec V5.1.3 --> 14 Go (swap)
+
diff --git a/src/SMDS/ObjectPool.hxx b/src/SMDS/ObjectPool.hxx
new file mode 100644 (file)
index 0000000..6e2fc1d
--- /dev/null
@@ -0,0 +1,115 @@
+#ifndef _OBJECTPOOL_HXX_
+#define _OBJECTPOOL_HXX_
+
+#include <vector>
+#include <stack>
+#include <iostream>
+
+template<class X> class ObjectPool
+{
+
+private:
+  std::vector<X*> _chunkList;
+  std::vector<bool> _freeList;
+  int _nextFree;
+  int _maxAvail;
+  int _chunkSize;
+
+  int getNextFree()
+  {
+    for (int i = _nextFree; i < _maxAvail; i++)
+      if (_freeList[i] == true)
+        {
+          return i;
+          break;
+        }
+    return _maxAvail;
+  }
+
+  void checkDelete(int chunkId)
+  {
+    int i0 = _chunkSize * chunkId;
+    int i1 = _chunkSize * (chunkId + 1);
+    for (int i = i0; i < i1; i++)
+      if (_freeList[i] == false)
+        return;
+    std::cerr << "a chunk to delete" << std::endl;
+    // compactage des vecteurs un peu lourd, pas necessaire
+    //X* chunk = _chunkList[chunkId];
+    //delete [] chunk;
+  }
+
+public:
+  ObjectPool(int nblk)
+  {
+    _chunkSize = nblk;
+    _nextFree = 0;
+    _maxAvail = 0;
+    _chunkList.clear();
+    _freeList.clear();
+  }
+
+  virtual ~ObjectPool()
+  {
+    for (int i = 0; i < _chunkList.size(); i++)
+      delete[] _chunkList[i];
+  }
+
+  X* getNew()
+  {
+    X *obj = 0;
+    _nextFree = getNextFree();
+    if (_nextFree == _maxAvail)
+      {
+        X* newChunk = new X[_chunkSize];
+        _chunkList.push_back(newChunk);
+        _freeList.insert(_freeList.end(), _chunkSize, true);
+        _maxAvail += _chunkSize;
+        _freeList[_nextFree] = false;
+        obj = newChunk; // &newChunk[0];
+      }
+    else
+      {
+        int chunkId = _nextFree / _chunkSize;
+        int rank = _nextFree - chunkId * _chunkSize;
+        _freeList[_nextFree] = false;
+        obj = _chunkList[chunkId] + rank; // &_chunkList[chunkId][rank];
+      }
+    //obj->init();
+    return obj;
+  }
+
+  void destroy(X* obj)
+  {
+    long adrobj = (long) (obj);
+    for (int i = 0; i < _chunkList.size(); i++)
+      {
+        X* chunk = _chunkList[i];
+        long adrmin = (long) (chunk);
+        if (adrobj < adrmin)
+          continue;
+        long adrmax = (long) (chunk + _chunkSize);
+        if (adrobj >= adrmax)
+          continue;
+        int rank = (adrobj - adrmin) / sizeof(X);
+        int toFree = i * _chunkSize + rank;
+        _freeList[toFree] = true;
+        if (toFree < _nextFree)
+          _nextFree = toFree;
+        //obj->clean();
+        //checkDelete(i); compactage non fait
+        break;
+      }
+  }
+
+  //  void destroy(int toFree)
+  //  {
+  //    // no control 0<= toFree < _freeList.size()
+  //    _freeList[toFree] = true;
+  //    if (toFree < _nextFree)
+  //      _nextFree = toFree;
+  //  }
+
+};
+
+#endif
diff --git a/src/SMDS/SMDS_Downward.cxx b/src/SMDS/SMDS_Downward.cxx
new file mode 100644 (file)
index 0000000..f735c82
--- /dev/null
@@ -0,0 +1,1981 @@
+/*
+ * SMDS_Downward.cxx
+ *
+ *  Created on: Jun 3, 2010
+ *      Author: prascle
+ */
+
+#include "SMDS_Downward.hxx"
+#include "SMDS_Mesh.hxx"
+#include "utilities.h"
+
+#include <vtkCellType.h>
+#include <vtkCellLinks.h>
+
+#include <map>
+
+using namespace std;
+
+// ---------------------------------------------------------------------------
+
+vector<int> SMDS_Downward::_cellDimension;
+
+/*! get the dimension of a cell (1,2,3 for 1D, 2D 3D) given the vtk cell type
+ *
+ * @param cellType vtk cell type @see vtkCellType.h
+ * @return 1,2 or 3
+ */
+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);
+      _cellDimension[VTK_LINE] = 1;
+      _cellDimension[VTK_QUADRATIC_EDGE] = 1;
+      _cellDimension[VTK_TRIANGLE] = 2;
+      _cellDimension[VTK_QUADRATIC_TRIANGLE] = 2;
+      _cellDimension[VTK_QUAD] = 2;
+      _cellDimension[VTK_QUADRATIC_QUAD] = 2;
+      _cellDimension[VTK_TETRA] = 3;
+      _cellDimension[VTK_QUADRATIC_TETRA] = 3;
+      _cellDimension[VTK_HEXAHEDRON] = 3;
+      _cellDimension[VTK_QUADRATIC_HEXAHEDRON] = 3;
+      _cellDimension[VTK_WEDGE] = 3;
+      _cellDimension[VTK_QUADRATIC_WEDGE] = 3;
+      _cellDimension[VTK_PYRAMID] = 3;
+      _cellDimension[VTK_QUADRATIC_PYRAMID] = 3;
+    }
+}
+
+SMDS_Downward::~SMDS_Downward()
+{
+}
+
+/*! Give or create an entry for downward connectivity structure relative to a cell.
+ * If the entry already exists, just return its id, otherwise, create it.
+ * The internal storage memory is allocated if needed.
+ * The SMDS_UnstructuredGrid::_cellIdToDownId vector is completed for vtkUnstructuredGrid cells.
+ * @param vtkId for a vtkUnstructuredGrid cell  or -1 (default) for a created downward cell.
+ * @return the rank in downward[vtkType] structure.
+ */
+int SMDS_Downward::addCell(int vtkId)
+{
+  int localId = -1;
+  if (vtkId >= 0)
+    localId = _grid->CellIdToDownId(vtkId);
+  if (localId >= 0)
+    return localId;
+
+  localId = this->_maxId;
+  this->_maxId++;
+  this->allocate(_maxId);
+  if (vtkId >= 0)
+    {
+      this->_vtkCellIds[localId] = vtkId;
+      _grid->setCellIdToDownId(vtkId, localId);
+    }
+  this->initCell(localId);
+  return localId;
+}
+
+/*! generic method do nothing. see derived methods
+ *
+ * @param cellId
+ */
+void SMDS_Downward::initCell(int cellId)
+{
+}
+
+/*! Get the number of downward entities associated to a cell (always the same for a given vtk type of cell)
+ *
+ * @param cellId not used here.
+ * @return
+ */
+int SMDS_Downward::getNumberOfDownCells(int cellId)
+{
+  return _nbDownCells;
+}
+
+/*! get a pointer on the downward entities id's associated to a cell.
+ * @see SMDS_Downward::getNumberOfDownCells for the number of downward entities.
+ * @see SMDS_Downward::getDownTypes for the vtk cell types associated to the downward entities.
+ * @param cellId index of the cell in the downward structure relative to a given vtk cell type.
+ * @return table of downward entities id's.
+ */
+const int* SMDS_Downward::getDownCells(int cellId)
+{
+  //ASSERT((cellId >=0) && (cellId < _maxId));
+  return &_cellIds[_nbDownCells * cellId];
+}
+
+/*! get a list of vtk cell types associated to downward entities of a given cell, in the same order
+ * than the downward entities id's list (@see SMDS_Downward::getDownCells).
+ *
+ * @param cellId index of the cell in the downward structure relative to a vtk cell type.
+ * @return table of downward entities types.
+ */
+const unsigned char* SMDS_Downward::getDownTypes(int cellId)
+{
+  return &_cellTypes[0];
+}
+
+/*! add a downward entity of dimension n-1 (cell or node) to a given cell.
+ * Actual implementation is done in derived methods.
+ * @param cellId index of the parent cell (dimension n) in the downward structure relative to a vtk cell type.
+ * @param lowCellId index of the children cell to add (dimension n-1)
+ * @param aType vtk cell type of the cell to add (needed to find the SMDS_Downward structure containing the cell to add).
+ */
+void SMDS_Downward::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  ASSERT(0); // must be re-implemented in derived class
+}
+
+/*! add a downward entity of dimension n+1 to a given cell.
+ * Actual implementation is done in derived methods.
+ * @param cellId index of the children cell (dimension n) in the downward structure relative to a vtk cell type.
+ * @param upCellId index of the parent cell to add (dimension n+1)
+ * @param aType vtk cell type of the cell to add (needed to find the SMDS_Downward structure containing the cell to add).
+ */
+void SMDS_Downward::addUpCell(int cellId, int upCellId, unsigned char aType)
+{
+  ASSERT(0); // must be re-implemented in derived class
+}
+
+int SMDS_Downward::getNodeSet(int cellId, int* nodeSet)
+{
+  return 0;
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_Down1D::SMDS_Down1D(SMDS_UnstructuredGrid *grid, int nbDownCells) :
+  SMDS_Downward(grid, nbDownCells)
+{
+  _upCellIdsVector.clear();
+  _upCellTypesVector.clear();
+  _upCellIds.clear();
+  _upCellTypes.clear();
+  _upCellIndex.clear();
+}
+
+SMDS_Down1D::~SMDS_Down1D()
+{
+}
+
+/*! clear vectors used to reference 2D cells containing the edge
+ *
+ * @param cellId
+ */
+void SMDS_Down1D::initCell(int cellId)
+{
+  _upCellIdsVector[cellId].clear();
+  _upCellTypesVector[cellId].clear();
+}
+
+/*! Resize the downward connectivity storage vector if needed.
+ *
+ * @param nbElems total number of elements of the same type required
+ */
+void SMDS_Down1D::allocate(int nbElems)
+{
+  if (nbElems >= _vtkCellIds.size())
+    {
+      _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1);
+      _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1);
+      _upCellIdsVector.resize(nbElems + SMDS_Mesh::chunkSize);
+      _upCellTypesVector.resize(nbElems + SMDS_Mesh::chunkSize);
+    }
+}
+
+void SMDS_Down1D::compactStorage()
+{
+  _cellIds.resize(_nbDownCells * _maxId);
+  _vtkCellIds.resize(_maxId);
+
+  int sizeUpCells = 0;
+  for (int i = 0; i < _maxId; i++)
+    sizeUpCells += _upCellIdsVector[i].size();
+  _upCellIds.resize(sizeUpCells, -1);
+  _upCellTypes.resize(sizeUpCells);
+  _upCellIndex.resize(_maxId + 1, -1); // id and types of rank i correspond to [ _upCellIndex[i], _upCellIndex[i+1] [
+  int current = 0;
+  for (int i = 0; i < _maxId; i++)
+    {
+      _upCellIndex[i] = current;
+      for (int j = 0; j < _upCellIdsVector[i].size(); j++)
+        {
+          _upCellIds[current] = _upCellIdsVector[i][j];
+          _upCellTypes[current] = _upCellTypesVector[i][j];
+          current++;
+        }
+    }
+  _upCellIndex[_maxId] = current;
+
+  _upCellIdsVector.clear();
+  _upCellTypesVector.clear();
+}
+
+void SMDS_Down1D::addUpCell(int cellId, int upCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0) && (cellId < _maxId));
+  int nbFaces = _upCellIdsVector[cellId].size();
+  for (int i = 0; i < nbFaces; i++)
+    {
+      if ((_upCellIdsVector[cellId][i] == upCellId) && (_upCellTypesVector[cellId][i] == aType))
+        {
+          return; // already done
+        }
+    }
+  _upCellIdsVector[cellId].push_back(upCellId);
+  _upCellTypesVector[cellId].push_back(aType);
+}
+
+int SMDS_Down1D::getNumberOfUpCells(int cellId)
+{
+  //ASSERT((cellId >=0) && (cellId < _maxId));
+  return _upCellIndex[cellId + 1] - _upCellIndex[cellId];
+}
+
+const int* SMDS_Down1D::getUpCells(int cellId)
+{
+  //ASSERT((cellId >=0) && (cellId < _maxId));
+  return &_upCellIds[_upCellIndex[cellId]];
+}
+
+const unsigned char* SMDS_Down1D::getUpTypes(int cellId)
+{
+  //ASSERT((cellId >=0) && (cellId < _maxId));
+  return &_upCellTypes[_upCellIndex[cellId]];
+}
+
+void SMDS_Down1D::getNodeIds(int cellId, std::set<int>& nodeSet)
+{
+  for (int i = 0; i < _nbDownCells; i++)
+    nodeSet.insert(_cellIds[_nbDownCells * cellId + i]);
+}
+
+int SMDS_Down1D::getNodeSet(int cellId, int* nodeSet)
+{
+  for (int i = 0; i < _nbDownCells; i++)
+    nodeSet[i] = _cellIds[_nbDownCells * cellId + i];
+  return _nbDownCells;
+}
+
+void SMDS_Down1D::setNodes(int cellId, int vtkId)
+{
+  vtkIdType npts = 0;
+  vtkIdType *pts; // will refer to the point id's of the face
+  _grid->GetCellPoints(vtkId, npts, pts);
+  // MESSAGE(vtkId << " " << npts << "  " << _nbDownCells);
+  //ASSERT(npts == _nbDownCells);
+  for (int i = 0; i < npts; i++)
+    {
+      _cellIds[_nbDownCells * cellId + i] = pts[i];
+    }
+}
+
+void SMDS_Down1D::setNodes(int cellId, const int* nodeIds)
+{
+  //ASSERT(nodeIds.size() == _nbDownCells);
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      _cellIds[_nbDownCells * cellId + i] = nodeIds[i];
+    }
+}
+
+/*! Build the list of vtkUnstructuredGrid cells containing the edge.
+ * We keep in the list the cells that contains all the nodes, we keep only volumes and faces.
+ * @param cellId id of the edge in the downward structure
+ * @param vtkIds vector of vtk id's
+ * @return number of vtk cells (size of vector)
+ */
+int SMDS_Down1D::computeVtkCells(int cellId, std::vector<int>& vtkIds)
+{
+  vtkIds.clear();
+
+  // --- find all the cells the points belong to, and how many of the points belong to a given cell
+
+  int *pts = &_cellIds[_nbDownCells * cellId];
+  int ncells = this->computeVtkCells(pts, vtkIds);
+  return ncells;
+}
+
+/*! Build the list of vtkUnstructuredGrid cells containing the edge.
+ *
+ * @param pts list of points id's defining an edge
+ * @param vtkIds vector of vtk id's
+ * @return number of vtk cells (size of vector)
+ */
+int SMDS_Down1D::computeVtkCells(int *pts, std::vector<int>& vtkIds)
+{
+
+  // --- find all the cells the points belong to, and how many of the points belong to a given cell
+
+  int cellIds[1000];
+  int cellCnt[1000];
+  int cnt = 0;
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      vtkIdType point = pts[i];
+      int numCells = _grid->GetLinks()->GetNcells(point);
+      vtkIdType *cells = _grid->GetLinks()->GetCells(point);
+      for (int j = 0; j < numCells; j++)
+        {
+          int vtkCellId = cells[j];
+          bool found = false;
+          for (int k = 0; k < cnt; k++)
+            {
+              if (cellIds[k] == vtkCellId)
+                {
+                  cellCnt[k] += 1;
+                  found = true;
+                  break;
+                }
+            }
+          if (!found)
+            {
+              cellIds[cnt] = vtkCellId;
+              cellCnt[cnt] = 1;
+              // TODO ASSERT(cnt<1000);
+              cnt++;
+            }
+        }
+    }
+
+  // --- find the face and volume cells: they contains all the points and are of type volume or face
+
+  int ncells = 0;
+  for (int i = 0; i < cnt; i++)
+    {
+      if (cellCnt[i] == _nbDownCells)
+        {
+          int vtkElemId = cellIds[i];
+          int vtkType = _grid->GetCellType(vtkElemId);
+          if (SMDS_Downward::getCellDimension(vtkType) > 1)
+            {
+              vtkIds.push_back(vtkElemId);
+              ncells++;
+            }
+        }
+    }
+
+  return ncells;
+}
+
+/*! Build the list of downward faces from a list of vtk cells.
+ *
+ * @param cellId id of the edge in the downward structure
+ * @param vtkIds vector of vtk id's
+ * @param downFaces vector of face id's in downward structures
+ * @param downTypes vector of face types
+ * @return number of downward faces
+ */
+int SMDS_Down1D::computeFaces(int cellId, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes)
+{
+  int *pts = &_cellIds[_nbDownCells * cellId];
+  int nbFaces = this->computeFaces(pts, vtkIds, nbcells, downFaces, downTypes);
+  return nbFaces;
+}
+
+/*! Build the list of downward faces from a list of vtk cells.
+ *
+ * @param pts list of points id's defining an edge
+ * @param vtkIds vector of vtk id's
+ * @param downFaces vector of face id's in downward structures
+ * @param downTypes vector of face types
+ * @return number of downward faces
+ */
+int SMDS_Down1D::computeFaces(int* pts, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes)
+{
+  int cnt = 0;
+  for (int i = 0; i < nbcells; i++)
+    {
+      int vtkId = vtkIds[i];
+      int vtkType = _grid->GetCellType(vtkId);
+      if (SMDS_Downward::getCellDimension(vtkType) == 2)
+        {
+          int faceId = _grid->CellIdToDownId(vtkId);
+          downFaces[cnt] = faceId;
+          downTypes[cnt] = vtkType;
+          cnt++;
+        }
+      else
+        {
+          int volId = _grid->CellIdToDownId(vtkId);
+          SMDS_Downward * downvol = _grid->getDownArray(vtkType);
+          const int *downIds = downvol->getDownCells(volId);
+          const unsigned char* downTypesVol = downvol->getDownTypes(volId);
+          int nbFaces = downvol->getNumberOfDownCells(volId);
+          const int* faceIds = downvol->getDownCells(volId);
+          for (int n = 0; n < nbFaces; n++)
+            {
+              SMDS_Down2D *downFace = static_cast<SMDS_Down2D*> (_grid->getDownArray(downTypesVol[n]));
+              bool isInFace = downFace->isInFace(faceIds[n], pts, _nbDownCells);
+              if (isInFace)
+                {
+                  bool alreadySet = false;
+                  for (int k = 0; k < cnt; k++)
+                    if (faceIds[n] == downFaces[k])
+                      {
+                        alreadySet = true;
+                        break;
+                      }
+                  if (!alreadySet)
+                    {
+                      downFaces[cnt] = faceIds[n];
+                      downTypes[cnt] = downTypesVol[n];
+                      cnt++;
+                    }
+                }
+            }
+        }
+    }
+  return cnt;
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_Down2D::SMDS_Down2D(SMDS_UnstructuredGrid *grid, int nbDownCells) :
+  SMDS_Downward(grid, nbDownCells)
+{
+  _upCellIds.clear();
+  _upCellTypes.clear();
+  _tempNodes.clear();
+  _nbNodes = 0;
+}
+
+SMDS_Down2D::~SMDS_Down2D()
+{
+}
+
+int SMDS_Down2D::getNumberOfUpCells(int cellId)
+{
+  int nbup = 0;
+  if (_upCellIds[2 * cellId] >= 0)
+    nbup++;
+  if (_upCellIds[2 * cellId + 1] >= 0)
+    nbup++;
+  return nbup;
+}
+
+const int* SMDS_Down2D::getUpCells(int cellId)
+{
+  //ASSERT((cellId >=0) && (cellId < _maxId));
+  return &_upCellIds[2 * cellId];
+}
+
+const unsigned char* SMDS_Down2D::getUpTypes(int cellId)
+{
+  //ASSERT((cellId >=0) && (cellId < _maxId));
+  return &_upCellTypes[2 * cellId];
+}
+
+void SMDS_Down2D::getNodeIds(int cellId, std::set<int>& nodeSet)
+{
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      int downCellId = _cellIds[_nbDownCells * cellId + i];
+      unsigned char cellType = _cellTypes[i];
+      this->_grid->getDownArray(cellType)->getNodeIds(downCellId, nodeSet);
+    }
+}
+
+/*! Find in vtkUnstructuredGrid the volumes containing a face already stored in vtkUnstructuredGrid.
+ * Search the volumes containing a face, to store the info in SMDS_Down2D for later uses
+ * with SMDS_Down2D::getUpCells and SMDS_Down2D::getUpTypes.
+ * A face belongs to 0, 1 or 2 volumes, identified by their id in vtkUnstructuredGrid.
+ * @param cellId the face cell id in vkUnstructuredGrid
+ * @param ids a couple of vtkId, initialized at -1 (no parent volume)
+ * @return number of volumes (0, 1 or 2)
+ */
+int SMDS_Down2D::computeVolumeIds(int cellId, int* ids)
+{
+  // --- find point id's of the face
+
+  vtkIdType npts = 0;
+  vtkIdType *pts; // will refer to the point id's of the face
+  _grid->GetCellPoints(cellId, npts, pts);
+  vector<int> nodes;
+  for (int i = 0; i < npts; i++)
+    nodes.push_back(pts[i]);
+  int nvol = this->computeVolumeIdsFromNodesFace(&nodes[0], npts, ids);
+  return nvol;
+}
+
+/*! Find in vtkUnstructuredGrid the volumes containing a face described by it's nodes
+ * Search the volumes containing a face, to store the info in SMDS_Down2D for later uses
+ * with SMDS_Down2D::getUpCells and SMDS_Down2D::getUpTypes.
+ * A face belongs to 0, 1 or 2 volumes, identified by their id in vtkUnstructuredGrid.
+ * @param faceByNodes
+ * @param ids a couple of vtkId, initialized at -1 (no parent volume)
+ * @return number of volumes (0, 1 or 2)
+ */
+int SMDS_Down2D::computeVolumeIds(ElemByNodesType& faceByNodes, int* ids)
+{
+  int nvol = this->computeVolumeIdsFromNodesFace(&faceByNodes.nodeIds[0], faceByNodes.nbNodes, ids);
+  return nvol;
+}
+
+/*! Find in vtkUnstructuredGrid the volumes containing a face described by it's nodes
+ * Search the volumes containing a face, to store the info in SMDS_Down2D for later uses
+ * with SMDS_Down2D::getUpCells and SMDS_Down2D::getUpTypes.
+ * A face belongs to 0, 1 or 2 volumes, identified by their id in vtkUnstructuredGrid.
+ * @param pts array of vtk node id's
+ * @param npts number of nodes
+ * @param ids
+ * @return number of volumes (0, 1 or 2)
+ */
+int SMDS_Down2D::computeVolumeIdsFromNodesFace(int* pts, int npts, int* ids)
+{
+
+  // --- find all the cells the points belong to, and how many of the points belong to a given cell
+
+  int cellIds[1000];
+  int cellCnt[1000];
+  int cnt = 0;
+  for (int i = 0; i < npts; i++)
+    {
+      vtkIdType point = pts[i];
+      int numCells = _grid->GetLinks()->GetNcells(point);
+      //MESSAGE("cells pour " << i << " " << numCells);
+      vtkIdType *cells = _grid->GetLinks()->GetCells(point);
+      for (int j = 0; j < numCells; j++)
+        {
+          int vtkCellId = cells[j];
+          bool found = false;
+          for (int k = 0; k < cnt; k++)
+            {
+              if (cellIds[k] == vtkCellId)
+                {
+                  cellCnt[k] += 1;
+                  found = true;
+                  break;
+                }
+            }
+          if (!found)
+            {
+              cellIds[cnt] = vtkCellId;
+              cellCnt[cnt] = 1;
+              // TODO ASSERT(cnt<1000);
+              cnt++;
+            }
+        }
+    }
+
+  // --- find the volume cells: they contains all the points and are of type volume
+
+  int nvol = 0;
+  for (int i = 0; i < cnt; i++)
+    {
+      //MESSAGE("cell " << cellIds[i] << " points " << cellCnt[i]);
+      if (cellCnt[i] == npts)
+        {
+          int vtkElemId = cellIds[i];
+          int vtkType = _grid->GetCellType(vtkElemId);
+          if (SMDS_Downward::getCellDimension(vtkType) == 3)
+            {
+              ids[nvol] = vtkElemId; // store the volume id in given vector
+              nvol++;
+            }
+        }
+      if (nvol == 2)
+        break;
+    }
+
+  return nvol;
+}
+
+void SMDS_Down2D::setTempNodes(int cellId, int vtkId)
+{
+  vtkIdType npts = 0;
+  vtkIdType *pts; // will refer to the point id's of the face
+  _grid->GetCellPoints(vtkId, npts, pts);
+  // MESSAGE(vtkId << " " << npts << "  " << _nbNodes);
+  //ASSERT(npts == _nbNodes);
+  for (int i = 0; i < npts; i++)
+    {
+      _tempNodes[_nbNodes * cellId + i] = pts[i];
+    }
+}
+
+void SMDS_Down2D::setTempNodes(int cellId, ElemByNodesType& faceByNodes)
+{
+  for (int i = 0; i < faceByNodes.nbNodes; i++)
+    _tempNodes[_nbNodes * cellId + i] = faceByNodes.nodeIds[i];
+}
+
+/*! Find if all the nodes belongs to the face.
+ *
+ * @param cellId the face cell Id
+ * @param nodeSet set of node id's to be found in the face list of nodes
+ * @return
+ */
+bool SMDS_Down2D::isInFace(int cellId, int *pts, int npts)
+{
+  int nbFound = 0;
+  int *nodes = &_tempNodes[_nbNodes * cellId];
+  for (int j = 0; j < npts; j++)
+    {
+      int point = pts[j];
+      for (int i = 0; i < _nbNodes; i++)
+        {
+          if (nodes[i] == point)
+            {
+              nbFound++;
+              break;
+            }
+        }
+    }
+  return (nbFound == npts);
+}
+
+/*! Resize the downward connectivity storage vector if needed.
+ *
+ * @param nbElems total number of elements of the same type required
+ */
+void SMDS_Down2D::allocate(int nbElems)
+{
+  if (nbElems >= _vtkCellIds.size())
+    {
+      _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1);
+      _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1);
+      _upCellIds.resize(2 * (nbElems + SMDS_Mesh::chunkSize), -1);
+      _upCellTypes.resize(2 * (nbElems + SMDS_Mesh::chunkSize), -1);
+      _tempNodes.resize(_nbNodes * (nbElems + SMDS_Mesh::chunkSize), -1);
+    }
+}
+
+void SMDS_Down2D::compactStorage()
+{
+  _cellIds.resize(_nbDownCells * _maxId);
+  _upCellIds.resize(2 * _maxId);
+  _upCellTypes.resize(2 * _maxId);
+  _vtkCellIds.resize(_maxId);
+  _tempNodes.clear();
+}
+
+void SMDS_Down2D::addUpCell(int cellId, int upCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0)&& (cellId < _maxId));
+  int *vols = &_upCellIds[2 * cellId];
+  unsigned char *types = &_upCellTypes[2 * cellId];
+  for (int i = 0; i < 2; i++)
+    {
+      if (vols[i] < 0)
+        {
+          vols[i] = upCellId; // use non affected volume
+          types[i] = aType;
+          return;
+        }
+      if ((vols[i] == upCellId) && (types[i] == aType)) // already done
+        return;
+    }
+  ASSERT(0);
+}
+
+int SMDS_Down2D::getNodeSet(int cellId, int* nodeSet)
+{
+  for (int i = 0; i < _nbNodes; i++)
+    nodeSet[i] = _tempNodes[_nbNodes * cellId + i];
+  return _nbNodes;
+}
+
+int SMDS_Down2D::FindEdgeByNodes(int cellId, ElemByNodesType& edgeByNodes)
+{
+  int *edges = &_cellIds[_nbDownCells * cellId];
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      if ((edges[i] >= 0) && (edgeByNodes.vtkType == _cellTypes[i]))
+        {
+          int nodeSet[3];
+          int npts = this->_grid->getDownArray(edgeByNodes.vtkType)->getNodeSet(edges[i], nodeSet);
+          bool found = false;
+          for (int j = 0; j < npts; j++)
+            {
+              int point = edgeByNodes.nodeIds[j];
+              found = false;
+              for (int k = 0; k < npts; k++)
+                {
+                  if (nodeSet[k] == point)
+                    {
+                      found = true;
+                      break;
+                    }
+                }
+              if (!found)
+                break;
+            }
+          if (found)
+            return edges[i];
+        }
+    }
+  return -1;
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_Down3D::SMDS_Down3D(SMDS_UnstructuredGrid *grid, int nbDownCells) :
+  SMDS_Downward(grid, nbDownCells)
+{
+}
+
+SMDS_Down3D::~SMDS_Down3D()
+{
+}
+
+void SMDS_Down3D::allocate(int nbElems)
+{
+  if (nbElems >= _vtkCellIds.size())
+    {
+      _cellIds.resize(_nbDownCells * (nbElems + SMDS_Mesh::chunkSize), -1);
+      _vtkCellIds.resize(nbElems + SMDS_Mesh::chunkSize, -1);
+    }
+}
+
+void SMDS_Down3D::compactStorage()
+{
+  // nothing to do, size was known before
+}
+
+int SMDS_Down3D::getNumberOfUpCells(int cellId)
+{
+  return 0;
+}
+
+const int* SMDS_Down3D::getUpCells(int cellId)
+{
+  return 0;
+}
+
+const unsigned char* SMDS_Down3D::getUpTypes(int cellId)
+{
+  return 0;
+}
+
+void SMDS_Down3D::getNodeIds(int cellId, std::set<int>& nodeSet)
+{
+  int vtkId = this->_vtkCellIds[cellId];
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(vtkId, npts, nodes);
+  for (int i = 0; i < npts; i++)
+    nodeSet.insert(nodes[i]);
+}
+
+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++)
+    {
+      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;
+            }
+
+          int nodeSet[10];
+          int npts = this->_grid->getDownArray(faceByNodes.vtkType)->getNodeSet(faces[i], nodeSet);
+          if (npts != npoints)
+            continue; // skip this face
+          bool found = false;
+          for (int j = 0; j < npts; j++)
+            {
+              int point = faceByNodes.nodeIds[j];
+              found = false;
+              for (int k = 0; k < npts; k++)
+                {
+                  if (nodeSet[k] == point)
+                    {
+                      found = true;
+                      break; // point j is in the 2 faces, skip remaining k values
+                    }
+                }
+              if (!found)
+                break; // point j is not in the 2 faces, skip the remaining tests
+            }
+          if (found)
+            return faces[i];
+        }
+    }
+  return -1;
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownEdge::SMDS_DownEdge(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down1D(grid, 2)
+{
+  _cellTypes.push_back(VTK_VERTEX);
+  _cellTypes.push_back(VTK_VERTEX);
+}
+
+SMDS_DownEdge::~SMDS_DownEdge()
+{
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownQuadEdge::SMDS_DownQuadEdge(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down1D(grid, 3)
+{
+  _cellTypes.push_back(VTK_VERTEX);
+  _cellTypes.push_back(VTK_VERTEX);
+  _cellTypes.push_back(VTK_VERTEX);
+}
+
+SMDS_DownQuadEdge::~SMDS_DownQuadEdge()
+{
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownTriangle::SMDS_DownTriangle(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down2D(grid, 3)
+{
+  _cellTypes.push_back(VTK_LINE);
+  _cellTypes.push_back(VTK_LINE);
+  _cellTypes.push_back(VTK_LINE);
+  _nbNodes = 3;
+}
+
+SMDS_DownTriangle::~SMDS_DownTriangle()
+{
+}
+
+void SMDS_DownTriangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes)
+{
+  int *nodes = &_tempNodes[_nbNodes * cellId];
+  edgesWithNodes.nbElems = 3;
+
+  edgesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  edgesWithNodes.elems[0].nodeIds[1] = nodes[1];
+  edgesWithNodes.elems[0].nbNodes = 2;
+  edgesWithNodes.elems[0].vtkType = VTK_LINE;
+
+  edgesWithNodes.elems[1].nodeIds[0] = nodes[1];
+  edgesWithNodes.elems[1].nodeIds[1] = nodes[2];
+  edgesWithNodes.elems[1].nbNodes = 2;
+  edgesWithNodes.elems[1].vtkType = VTK_LINE;
+
+  edgesWithNodes.elems[2].nodeIds[0] = nodes[2];
+  edgesWithNodes.elems[2].nodeIds[1] = nodes[0];
+  edgesWithNodes.elems[2].nbNodes = 2;
+  edgesWithNodes.elems[2].vtkType = VTK_LINE;
+}
+
+void SMDS_DownTriangle::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0)&& (cellId < _maxId));
+  //ASSERT(aType == VTK_LINE);
+  int *faces = &_cellIds[_nbDownCells * cellId];
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      if (faces[i] < 0)
+        {
+          faces[i] = lowCellId;
+          return;
+        }
+      if (faces[i] == lowCellId)
+        return;
+    }
+  ASSERT(0);
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownQuadTriangle::SMDS_DownQuadTriangle(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down2D(grid, 3)
+{
+  _cellTypes.push_back(VTK_QUADRATIC_EDGE);
+  _cellTypes.push_back(VTK_QUADRATIC_EDGE);
+  _cellTypes.push_back(VTK_QUADRATIC_EDGE);
+  _nbNodes = 6;
+}
+
+SMDS_DownQuadTriangle::~SMDS_DownQuadTriangle()
+{
+}
+
+void SMDS_DownQuadTriangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes)
+{
+  int *nodes = &_tempNodes[_nbNodes * cellId];
+  edgesWithNodes.nbElems = 3;
+
+  edgesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  edgesWithNodes.elems[0].nodeIds[1] = nodes[1];
+  edgesWithNodes.elems[0].nodeIds[2] = nodes[3];
+  edgesWithNodes.elems[0].nbNodes = 3;
+  edgesWithNodes.elems[0].vtkType = VTK_QUADRATIC_EDGE;
+
+  edgesWithNodes.elems[1].nodeIds[0] = nodes[1];
+  edgesWithNodes.elems[1].nodeIds[1] = nodes[2];
+  edgesWithNodes.elems[1].nodeIds[2] = nodes[4];
+  edgesWithNodes.elems[1].nbNodes = 3;
+  edgesWithNodes.elems[1].vtkType = VTK_QUADRATIC_EDGE;
+
+  edgesWithNodes.elems[2].nodeIds[0] = nodes[2];
+  edgesWithNodes.elems[2].nodeIds[1] = nodes[0];
+  edgesWithNodes.elems[2].nodeIds[2] = nodes[5];
+  edgesWithNodes.elems[2].nbNodes = 3;
+  edgesWithNodes.elems[2].vtkType = VTK_QUADRATIC_EDGE;
+}
+
+void SMDS_DownQuadTriangle::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0)&& (cellId < _maxId));
+  //ASSERT(aType == VTK_QUADRATIC_EDGE);
+  int *faces = &_cellIds[_nbDownCells * cellId];
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      if (faces[i] < 0)
+        {
+          faces[i] = lowCellId;
+          return;
+        }
+      if (faces[i] == lowCellId)
+        return;
+    }
+  ASSERT(0);
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownQuadrangle::SMDS_DownQuadrangle(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down2D(grid, 4)
+{
+  _cellTypes.push_back(VTK_LINE);
+  _cellTypes.push_back(VTK_LINE);
+  _cellTypes.push_back(VTK_LINE);
+  _cellTypes.push_back(VTK_LINE);
+  _nbNodes = 4;
+}
+
+SMDS_DownQuadrangle::~SMDS_DownQuadrangle()
+{
+}
+
+void SMDS_DownQuadrangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes)
+{
+  int *nodes = &_tempNodes[_nbNodes * cellId];
+  edgesWithNodes.nbElems = 4;
+
+  edgesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  edgesWithNodes.elems[0].nodeIds[1] = nodes[1];
+  edgesWithNodes.elems[0].nbNodes = 2;
+  edgesWithNodes.elems[0].vtkType = VTK_LINE;
+
+  edgesWithNodes.elems[1].nodeIds[0] = nodes[1];
+  edgesWithNodes.elems[1].nodeIds[1] = nodes[2];
+  edgesWithNodes.elems[1].nbNodes = 2;
+  edgesWithNodes.elems[1].vtkType = VTK_LINE;
+
+  edgesWithNodes.elems[2].nodeIds[0] = nodes[2];
+  edgesWithNodes.elems[2].nodeIds[1] = nodes[3];
+  edgesWithNodes.elems[2].nbNodes = 2;
+  edgesWithNodes.elems[2].vtkType = VTK_LINE;
+
+  edgesWithNodes.elems[3].nodeIds[0] = nodes[3];
+  edgesWithNodes.elems[3].nodeIds[1] = nodes[0];
+  edgesWithNodes.elems[3].nbNodes = 2;
+  edgesWithNodes.elems[3].vtkType = VTK_LINE;
+}
+
+void SMDS_DownQuadrangle::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0)&& (cellId < _maxId));
+  //ASSERT(aType == VTK_LINE);
+  int *faces = &_cellIds[_nbDownCells * cellId];
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      if (faces[i] < 0)
+        {
+          faces[i] = lowCellId;
+          return;
+        }
+      if (faces[i] == lowCellId)
+        return;
+    }
+  ASSERT(0);
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownQuadQuadrangle::SMDS_DownQuadQuadrangle(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down2D(grid, 4)
+{
+  _cellTypes.push_back(VTK_QUADRATIC_EDGE);
+  _cellTypes.push_back(VTK_QUADRATIC_EDGE);
+  _cellTypes.push_back(VTK_QUADRATIC_EDGE);
+  _cellTypes.push_back(VTK_QUADRATIC_EDGE);
+  _nbNodes = 8;
+}
+
+SMDS_DownQuadQuadrangle::~SMDS_DownQuadQuadrangle()
+{
+}
+
+void SMDS_DownQuadQuadrangle::computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes)
+{
+  int *nodes = &_tempNodes[_nbNodes * cellId];
+  edgesWithNodes.nbElems = 4;
+
+  edgesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  edgesWithNodes.elems[0].nodeIds[1] = nodes[1];
+  edgesWithNodes.elems[0].nodeIds[2] = nodes[4];
+  edgesWithNodes.elems[0].nbNodes = 3;
+  edgesWithNodes.elems[0].vtkType = VTK_QUADRATIC_EDGE;
+
+  edgesWithNodes.elems[1].nodeIds[0] = nodes[1];
+  edgesWithNodes.elems[1].nodeIds[1] = nodes[2];
+  edgesWithNodes.elems[1].nodeIds[2] = nodes[5];
+  edgesWithNodes.elems[1].nbNodes = 3;
+  edgesWithNodes.elems[1].vtkType = VTK_QUADRATIC_EDGE;
+
+  edgesWithNodes.elems[2].nodeIds[0] = nodes[2];
+  edgesWithNodes.elems[2].nodeIds[1] = nodes[3];
+  edgesWithNodes.elems[2].nodeIds[2] = nodes[6];
+  edgesWithNodes.elems[2].nbNodes = 3;
+  edgesWithNodes.elems[2].vtkType = VTK_QUADRATIC_EDGE;
+
+  edgesWithNodes.elems[3].nodeIds[0] = nodes[3];
+  edgesWithNodes.elems[3].nodeIds[1] = nodes[0];
+  edgesWithNodes.elems[3].nodeIds[2] = nodes[7];
+  edgesWithNodes.elems[3].nbNodes = 3;
+  edgesWithNodes.elems[3].vtkType = VTK_QUADRATIC_EDGE;
+}
+
+void SMDS_DownQuadQuadrangle::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0)&& (cellId < _maxId));
+  //ASSERT(aType == VTK_QUADRATIC_EDGE);
+  int *faces = &_cellIds[_nbDownCells * cellId];
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      if (faces[i] < 0)
+        {
+          faces[i] = lowCellId;
+          return;
+        }
+      if (faces[i] == lowCellId)
+        return;
+    }
+  ASSERT(0);
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownTetra::SMDS_DownTetra(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down3D(grid, 4)
+{
+  _cellTypes.push_back(VTK_TRIANGLE);
+  _cellTypes.push_back(VTK_TRIANGLE);
+  _cellTypes.push_back(VTK_TRIANGLE);
+  _cellTypes.push_back(VTK_TRIANGLE);
+}
+
+SMDS_DownTetra::~SMDS_DownTetra()
+{
+}
+
+void SMDS_DownTetra::getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes)
+{
+  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[12] = { 0, 1, 2, 0, 1, 3, 0, 2, 3, 1, 2, 3 };
+  for (int k = 0; k < 4; 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;
+        }
+    }
+  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_DownTetra::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0)&& (cellId < _maxId));
+  //ASSERT(aType == VTK_TRIANGLE);
+  int *faces = &_cellIds[_nbDownCells * cellId];
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      if (faces[i] < 0)
+        {
+          faces[i] = lowCellId;
+          return;
+        }
+      if (faces[i] == lowCellId)
+        return;
+    }
+  ASSERT(0);
+}
+
+/*! Create a list of faces described by a vtk Type and  an ordered set of Node Id's
+ * The linear tetrahedron is defined by four points.
+ * @see vtkTetra.h in Filtering.
+ * @param cellId volumeId in vtkUnstructuredGrid
+ * @param facesWithNodes vector of face descriptors to be filled
+ */
+void SMDS_DownTetra::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
+{
+  // --- find point id's of the volume
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(cellId, npts, nodes);
+
+  // --- create all the ordered list of node id's for each face
+
+  facesWithNodes.nbElems = 4;
+
+  facesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[0].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[0].nodeIds[2] = nodes[2];
+  facesWithNodes.elems[0].nbNodes = 3;
+  facesWithNodes.elems[0].vtkType = VTK_TRIANGLE;
+
+  facesWithNodes.elems[1].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[1].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[1].nodeIds[2] = nodes[3];
+  facesWithNodes.elems[1].nbNodes = 3;
+  facesWithNodes.elems[1].vtkType = VTK_TRIANGLE;
+
+  facesWithNodes.elems[2].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[2].nodeIds[1] = nodes[2];
+  facesWithNodes.elems[2].nodeIds[2] = nodes[3];
+  facesWithNodes.elems[2].nbNodes = 3;
+  facesWithNodes.elems[2].vtkType = VTK_TRIANGLE;
+
+  facesWithNodes.elems[3].nodeIds[0] = nodes[1];
+  facesWithNodes.elems[3].nodeIds[1] = nodes[2];
+  facesWithNodes.elems[3].nodeIds[2] = nodes[3];
+  facesWithNodes.elems[3].nbNodes = 3;
+  facesWithNodes.elems[3].vtkType = VTK_TRIANGLE;
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownQuadTetra::SMDS_DownQuadTetra(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down3D(grid, 4)
+{
+  _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
+  _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
+  _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
+  _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
+}
+
+SMDS_DownQuadTetra::~SMDS_DownQuadTetra()
+{
+}
+
+void SMDS_DownQuadTetra::getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes)
+{
+  // TODO
+}
+
+void SMDS_DownQuadTetra::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0)&& (cellId < _maxId));
+  //ASSERT(aType == VTK_QUADRATIC_TRIANGLE);
+  int *faces = &_cellIds[_nbDownCells * cellId];
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      if (faces[i] < 0)
+        {
+          faces[i] = lowCellId;
+          return;
+        }
+      if (faces[i] == lowCellId)
+        return;
+    }
+  ASSERT(0);
+}
+
+/*! Create a list of faces described by a vtk Type and  an ordered set of Node Id's
+ * The ordering of the ten points defining the quadratic tetrahedron cell is point id's (0-3,4-9)
+ * where id's 0-3 are the four tetrahedron vertices;
+ * and point id's 4-9 are the mid-edge nodes between (0,1), (1,2), (2,0), (0,3), (1,3), and (2,3).
+ * @see vtkQuadraticTetra.h in Filtering.
+ * @param cellId volumeId in vtkUnstructuredGrid
+ * @param facesWithNodes vector of face descriptors to be filled
+ */
+void SMDS_DownQuadTetra::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
+{
+  // --- find point id's of the volume
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(cellId, npts, nodes);
+
+  // --- create all the ordered list of node id's for each face
+
+  facesWithNodes.nbElems = 4;
+
+  facesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[0].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[0].nodeIds[2] = nodes[2];
+  facesWithNodes.elems[0].nodeIds[3] = nodes[4];
+  facesWithNodes.elems[0].nodeIds[4] = nodes[5];
+  facesWithNodes.elems[0].nodeIds[5] = nodes[6];
+  facesWithNodes.elems[0].nbNodes = 6;
+  facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_TRIANGLE;
+
+  facesWithNodes.elems[1].nodeIds[0] = nodes[0];
+  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].nbNodes = 6;
+  facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_TRIANGLE;
+
+  facesWithNodes.elems[2].nodeIds[0] = nodes[0];
+  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].nbNodes = 6;
+  facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_TRIANGLE;
+
+  facesWithNodes.elems[3].nodeIds[0] = nodes[1];
+  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].nbNodes = 6;
+  facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE;
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownPyramid::SMDS_DownPyramid(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down3D(grid, 5)
+{
+  _cellTypes.push_back(VTK_QUAD);
+  _cellTypes.push_back(VTK_TRIANGLE);
+  _cellTypes.push_back(VTK_TRIANGLE);
+  _cellTypes.push_back(VTK_TRIANGLE);
+  _cellTypes.push_back(VTK_TRIANGLE);
+}
+
+SMDS_DownPyramid::~SMDS_DownPyramid()
+{
+}
+
+void SMDS_DownPyramid::getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes)
+{
+  // TODO
+}
+
+void SMDS_DownPyramid::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0) && (cellId < _maxId));
+  int *faces = &_cellIds[_nbDownCells * cellId];
+  if (aType == VTK_QUAD)
+    {
+      if (faces[0] < 0)
+        {
+          faces[0] = lowCellId;
+          return;
+        }
+      if (faces[0] == lowCellId)
+        return;
+    }
+  else
+    {
+      //ASSERT(aType == VTK_TRIANGLE);
+      for (int i = 1; i < _nbDownCells; i++)
+        {
+          if (faces[i] < 0)
+            {
+              faces[i] = lowCellId;
+              return;
+            }
+          if (faces[i] == lowCellId)
+            return;
+        }
+    }
+  ASSERT(0);
+}
+
+/*! Create a list of faces described by a vtk Type and  an ordered set of Node Id's
+ * The pyramid is defined by the five points (0-4) where (0,1,2,3) is the base of the pyramid which,
+ * using the right hand rule, forms a quadrilateral whose normal points in the direction of the
+ * pyramid apex at vertex #4.
+ * @see vtkPyramid.h in Filtering.
+ * @param cellId volumeId in vtkUnstructuredGrid
+ * @param facesWithNodes vector of face descriptors to be filled
+ */
+void SMDS_DownPyramid::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
+{
+  // --- find point id's of the volume
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(cellId, npts, nodes);
+
+  // --- create all the ordered list of node id's for each face
+
+  facesWithNodes.nbElems = 5;
+
+  facesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[0].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[0].nodeIds[2] = nodes[2];
+  facesWithNodes.elems[0].nodeIds[3] = nodes[3];
+  facesWithNodes.elems[0].nbNodes = 4;
+  facesWithNodes.elems[0].vtkType = VTK_QUAD;
+
+  facesWithNodes.elems[1].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[1].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[1].nodeIds[2] = nodes[4];
+  facesWithNodes.elems[1].nbNodes = 3;
+  facesWithNodes.elems[1].vtkType = VTK_TRIANGLE;
+
+  facesWithNodes.elems[2].nodeIds[0] = nodes[1];
+  facesWithNodes.elems[2].nodeIds[1] = nodes[2];
+  facesWithNodes.elems[2].nodeIds[2] = nodes[4];
+  facesWithNodes.elems[2].nbNodes = 3;
+  facesWithNodes.elems[2].vtkType = VTK_TRIANGLE;
+
+  facesWithNodes.elems[3].nodeIds[0] = nodes[2];
+  facesWithNodes.elems[3].nodeIds[1] = nodes[3];
+  facesWithNodes.elems[3].nodeIds[2] = nodes[4];
+  facesWithNodes.elems[3].nbNodes = 3;
+  facesWithNodes.elems[3].vtkType = VTK_TRIANGLE;
+
+  facesWithNodes.elems[4].nodeIds[0] = nodes[3];
+  facesWithNodes.elems[4].nodeIds[1] = nodes[0];
+  facesWithNodes.elems[4].nodeIds[2] = nodes[4];
+  facesWithNodes.elems[4].nbNodes = 3;
+  facesWithNodes.elems[4].vtkType = VTK_TRIANGLE;
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownQuadPyramid::SMDS_DownQuadPyramid(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down3D(grid, 5)
+{
+  _cellTypes.push_back(VTK_QUADRATIC_QUAD);
+  _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
+  _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
+  _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
+  _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
+}
+
+SMDS_DownQuadPyramid::~SMDS_DownQuadPyramid()
+{
+}
+
+void SMDS_DownQuadPyramid::getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes)
+{
+  // TODO
+}
+
+void SMDS_DownQuadPyramid::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0) && (cellId < _maxId));
+  int *faces = &_cellIds[_nbDownCells * cellId];
+  if (aType == VTK_QUADRATIC_QUAD)
+    {
+      if (faces[0] < 0)
+        {
+          faces[0] = lowCellId;
+          return;
+        }
+      if (faces[0] == lowCellId)
+        return;
+    }
+  else
+    {
+      //ASSERT(aType == VTK_QUADRATIC_TRIANGLE);
+      for (int i = 1; i < _nbDownCells; i++)
+        {
+          if (faces[i] < 0)
+            {
+              faces[i] = lowCellId;
+              return;
+            }
+          if (faces[i] == lowCellId)
+            return;
+        }
+    }
+  ASSERT(0);
+}
+
+/*! Create a list of faces described by a vtk Type and  an ordered set of Node Id's
+ * The ordering of the thirteen points defining the quadratic pyramid cell is point id's (0-4,5-12)
+ * where point id's 0-4 are the five corner vertices of the pyramid; followed
+ * by eight mid-edge nodes (5-12). Note that these mid-edge nodes lie on the edges defined by
+ * 5(0,1), 6(1,2), 7(2,3), 8(3,0), 9(0,4), 10(1,4), 11(2,4), 12(3,4).
+ * @see vtkQuadraticPyramid.h in Filtering.
+ * @param cellId volumeId in vtkUnstructuredGrid
+ * @param facesWithNodes vector of face descriptors to be filled
+ */
+void SMDS_DownQuadPyramid::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
+{
+  // --- find point id's of the volume
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(cellId, npts, nodes);
+
+  // --- create all the ordered list of node id's for each face
+
+  facesWithNodes.nbElems = 5;
+
+  facesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[0].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[0].nodeIds[2] = nodes[2];
+  facesWithNodes.elems[0].nodeIds[3] = nodes[3];
+  facesWithNodes.elems[0].nodeIds[4] = nodes[5];
+  facesWithNodes.elems[0].nodeIds[5] = nodes[6];
+  facesWithNodes.elems[0].nodeIds[6] = nodes[7];
+  facesWithNodes.elems[0].nodeIds[7] = nodes[8];
+  facesWithNodes.elems[0].nbNodes = 8;
+  facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD;
+
+  facesWithNodes.elems[1].nodeIds[0] = nodes[0];
+  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].nbNodes = 6;
+  facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_TRIANGLE;
+
+  facesWithNodes.elems[2].nodeIds[0] = nodes[1];
+  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].nbNodes = 6;
+  facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_TRIANGLE;
+
+  facesWithNodes.elems[3].nodeIds[0] = nodes[2];
+  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].nbNodes = 6;
+  facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE;
+
+  facesWithNodes.elems[4].nodeIds[0] = nodes[3];
+  facesWithNodes.elems[4].nodeIds[1] = nodes[0];
+  facesWithNodes.elems[4].nodeIds[2] = nodes[4];
+  facesWithNodes.elems[4].nodeIds[3] = nodes[8];
+  facesWithNodes.elems[4].nodeIds[4] = nodes[9];
+  facesWithNodes.elems[4].nodeIds[5] = nodes[12];
+  facesWithNodes.elems[4].nbNodes = 6;
+  facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_TRIANGLE;
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownPenta::SMDS_DownPenta(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down3D(grid, 5)
+{
+  _cellTypes.push_back(VTK_QUAD);
+  _cellTypes.push_back(VTK_QUAD);
+  _cellTypes.push_back(VTK_QUAD);
+  _cellTypes.push_back(VTK_TRIANGLE);
+  _cellTypes.push_back(VTK_TRIANGLE);
+}
+
+SMDS_DownPenta::~SMDS_DownPenta()
+{
+}
+
+void SMDS_DownPenta::getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes)
+{
+  // TODO
+}
+
+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++)
+      {
+        if (faces[i] < 0)
+          {
+            faces[i] = lowCellId;
+            return;
+          }
+        if (faces[i] == lowCellId)
+          return;
+      }
+  else
+    {
+      //ASSERT(aType == VTK_TRIANGLE);
+      for (int i = 2; i < _nbDownCells; i++)
+        {
+          if (faces[i] < 0)
+            {
+              faces[i] = lowCellId;
+              return;
+            }
+          if (faces[i] == lowCellId)
+            return;
+        }
+    }
+  ASSERT(0);
+}
+
+/*! Create a list of faces described by a vtk Type and  an ordered set of Node Id's.
+ * A wedge or pentahedron consists of two triangular and three quadrilateral faces
+ * and is defined by the six points (0-5) where (0,1,2) is the base of the wedge which,
+ * using the right hand rule, forms a triangle whose normal points outward
+ * (away from the triangular face (3,4,5)).
+ * @see vtkWedge.h in Filtering
+ * @param cellId volumeId in vtkUnstructuredGrid
+ * @param facesWithNodes vector of face descriptors to be filled
+ */
+void SMDS_DownPenta::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
+{
+  // --- find point id's of the volume
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(cellId, npts, nodes);
+
+  // --- create all the ordered list of node id's for each face
+
+  facesWithNodes.nbElems = 5;
+
+  facesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[0].nodeIds[1] = nodes[2];
+  facesWithNodes.elems[0].nodeIds[2] = nodes[5];
+  facesWithNodes.elems[0].nodeIds[3] = nodes[3];
+  facesWithNodes.elems[0].nbNodes = 4;
+  facesWithNodes.elems[0].vtkType = VTK_QUAD;
+
+  facesWithNodes.elems[1].nodeIds[0] = nodes[1];
+  facesWithNodes.elems[1].nodeIds[1] = nodes[2];
+  facesWithNodes.elems[1].nodeIds[2] = nodes[5];
+  facesWithNodes.elems[1].nodeIds[3] = nodes[4];
+  facesWithNodes.elems[1].nbNodes = 4;
+  facesWithNodes.elems[1].vtkType = VTK_QUAD;
+
+  facesWithNodes.elems[2].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[2].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[2].nodeIds[2] = nodes[4];
+  facesWithNodes.elems[2].nodeIds[3] = nodes[3];
+  facesWithNodes.elems[2].nbNodes = 4;
+  facesWithNodes.elems[2].vtkType = VTK_QUAD;
+
+  facesWithNodes.elems[3].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[3].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[3].nodeIds[2] = nodes[2];
+  facesWithNodes.elems[3].nbNodes = 3;
+  facesWithNodes.elems[3].vtkType = VTK_TRIANGLE;
+
+  facesWithNodes.elems[4].nodeIds[0] = nodes[3];
+  facesWithNodes.elems[4].nodeIds[1] = nodes[4];
+  facesWithNodes.elems[4].nodeIds[2] = nodes[5];
+  facesWithNodes.elems[4].nbNodes = 3;
+  facesWithNodes.elems[4].vtkType = VTK_TRIANGLE;
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownQuadPenta::SMDS_DownQuadPenta(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down3D(grid, 5)
+{
+  _cellTypes.push_back(VTK_QUADRATIC_QUAD);
+  _cellTypes.push_back(VTK_QUADRATIC_QUAD);
+  _cellTypes.push_back(VTK_QUADRATIC_QUAD);
+  _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
+  _cellTypes.push_back(VTK_QUADRATIC_TRIANGLE);
+}
+
+SMDS_DownQuadPenta::~SMDS_DownQuadPenta()
+{
+}
+
+void SMDS_DownQuadPenta::getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes)
+{
+  // TODO
+}
+
+void SMDS_DownQuadPenta::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0) && (cellId < _maxId));
+  int *faces = &_cellIds[_nbDownCells * cellId];
+  if (aType == VTK_QUADRATIC_QUAD)
+    for (int i = 0; i < 2; i++)
+      {
+        if (faces[i] < 0)
+          {
+            faces[i] = lowCellId;
+            return;
+          }
+        if (faces[i] == lowCellId)
+          return;
+      }
+  else
+    {
+      //ASSERT(aType == VTK_QUADRATIC_TRIANGLE);
+      for (int i = 2; i < _nbDownCells; i++)
+        {
+          if (faces[i] < 0)
+            {
+              faces[i] = lowCellId;
+              return;
+            }
+          if (faces[i] == lowCellId)
+            return;
+        }
+    }
+  ASSERT(0);
+}
+
+/*! Create a list of faces described by a vtk Type and  an ordered set of Node Id's
+ * The quadratic wedge (or pentahedron) is defined by fifteen points.
+ * The ordering of the fifteen points defining the cell is point id's (0-5,6-14)
+ * where point id's 0-5 are the six corner vertices of the wedge, followed by
+ * nine mid-edge nodes (6-14). Note that these mid-edge nodes lie on the edges defined by
+ * (0,1), (1,2), (2,0), (3,4), (4,5), (5,3), (0,3), (1,4), (2,5).
+ * @see vtkQuadraticWedge.h in Filtering
+ * @param cellId volumeId in vtkUnstructuredGrid
+ * @param facesWithNodes vector of face descriptors to be filled
+ */
+void SMDS_DownQuadPenta::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
+{
+  // --- find point id's of the volume
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(cellId, npts, nodes);
+
+  // --- create all the ordered list of node id's for each face
+
+  facesWithNodes.nbElems = 5;
+
+  facesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[0].nodeIds[1] = nodes[2];
+  facesWithNodes.elems[0].nodeIds[2] = nodes[5];
+  facesWithNodes.elems[0].nodeIds[3] = nodes[3];
+  facesWithNodes.elems[0].nodeIds[4] = nodes[8];
+  facesWithNodes.elems[0].nodeIds[5] = nodes[14];
+  facesWithNodes.elems[0].nodeIds[6] = nodes[11];
+  facesWithNodes.elems[0].nodeIds[7] = nodes[12];
+  facesWithNodes.elems[0].nbNodes = 8;
+  facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD;
+
+  facesWithNodes.elems[1].nodeIds[0] = nodes[1];
+  facesWithNodes.elems[1].nodeIds[1] = nodes[2];
+  facesWithNodes.elems[1].nodeIds[2] = nodes[5];
+  facesWithNodes.elems[1].nodeIds[3] = nodes[4];
+  facesWithNodes.elems[1].nodeIds[4] = nodes[7];
+  facesWithNodes.elems[1].nodeIds[5] = nodes[14];
+  facesWithNodes.elems[1].nodeIds[6] = nodes[10];
+  facesWithNodes.elems[1].nodeIds[7] = nodes[13];
+  facesWithNodes.elems[1].nbNodes = 8;
+  facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_QUAD;
+
+  facesWithNodes.elems[2].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[2].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[2].nodeIds[2] = nodes[4];
+  facesWithNodes.elems[2].nodeIds[3] = nodes[3];
+  facesWithNodes.elems[2].nodeIds[4] = nodes[6];
+  facesWithNodes.elems[2].nodeIds[5] = nodes[13];
+  facesWithNodes.elems[2].nodeIds[6] = nodes[9];
+  facesWithNodes.elems[2].nodeIds[7] = nodes[12];
+  facesWithNodes.elems[2].nbNodes = 8;
+  facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_QUAD;
+
+  facesWithNodes.elems[3].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[3].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[3].nodeIds[2] = nodes[2];
+  facesWithNodes.elems[3].nodeIds[3] = nodes[6];
+  facesWithNodes.elems[3].nodeIds[4] = nodes[7];
+  facesWithNodes.elems[3].nodeIds[5] = nodes[8];
+  facesWithNodes.elems[3].nbNodes = 6;
+  facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_TRIANGLE;
+
+  facesWithNodes.elems[4].nodeIds[0] = nodes[3];
+  facesWithNodes.elems[4].nodeIds[1] = nodes[4];
+  facesWithNodes.elems[4].nodeIds[2] = nodes[5];
+  facesWithNodes.elems[4].nodeIds[3] = nodes[9];
+  facesWithNodes.elems[4].nodeIds[4] = nodes[10];
+  facesWithNodes.elems[4].nodeIds[5] = nodes[11];
+  facesWithNodes.elems[4].nbNodes = 6;
+  facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_TRIANGLE;
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownHexa::SMDS_DownHexa(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down3D(grid, 6)
+{
+  _cellTypes.push_back(VTK_QUAD);
+  _cellTypes.push_back(VTK_QUAD);
+  _cellTypes.push_back(VTK_QUAD);
+  _cellTypes.push_back(VTK_QUAD);
+  _cellTypes.push_back(VTK_QUAD);
+  _cellTypes.push_back(VTK_QUAD);
+}
+
+SMDS_DownHexa::~SMDS_DownHexa()
+{
+}
+
+void SMDS_DownHexa::getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes)
+{
+  // TODO
+}
+
+void SMDS_DownHexa::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0)&& (cellId < _maxId));
+  int *faces = &_cellIds[_nbDownCells * cellId];
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      if (faces[i] < 0)
+        {
+          faces[i] = lowCellId;
+          return;
+        }
+      if (faces[i] == lowCellId)
+        return;
+    }
+  ASSERT(0);
+  // MESSAGE("-------------------------------------> trop de faces ! " << cellId << " " << lowCellId);
+}
+
+/*! Create a list of faces described by a vtk Type and  an ordered set of Node Id's
+ * The hexahedron is defined by the eight points (0-7), where (0,1,2,3) is the base
+ * of the hexahedron which, using the right hand rule, forms a quadrilateral whose normal
+ * points in the direction of the opposite face (4,5,6,7).
+ * @see vtkHexahedron.h in Filtering
+ * @param cellId volumeId in vtkUnstructuredGrid
+ * @param facesWithNodes vector of face descriptors to be filled
+ */
+void SMDS_DownHexa::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
+{
+  // --- find point id's of the volume
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(cellId, npts, nodes);
+
+  // --- create all the ordered list of node id's for each face
+
+  facesWithNodes.nbElems = 6;
+
+  facesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[0].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[0].nodeIds[2] = nodes[2];
+  facesWithNodes.elems[0].nodeIds[3] = nodes[3];
+  facesWithNodes.elems[0].nbNodes = 4;
+  facesWithNodes.elems[0].vtkType = VTK_QUAD;
+
+  facesWithNodes.elems[1].nodeIds[0] = nodes[4];
+  facesWithNodes.elems[1].nodeIds[1] = nodes[5];
+  facesWithNodes.elems[1].nodeIds[2] = nodes[6];
+  facesWithNodes.elems[1].nodeIds[3] = nodes[7];
+  facesWithNodes.elems[1].nbNodes = 4;
+  facesWithNodes.elems[1].vtkType = VTK_QUAD;
+
+  facesWithNodes.elems[2].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[2].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[2].nodeIds[2] = nodes[5];
+  facesWithNodes.elems[2].nodeIds[3] = nodes[4];
+  facesWithNodes.elems[2].nbNodes = 4;
+  facesWithNodes.elems[2].vtkType = VTK_QUAD;
+
+  facesWithNodes.elems[3].nodeIds[0] = nodes[1];
+  facesWithNodes.elems[3].nodeIds[1] = nodes[2];
+  facesWithNodes.elems[3].nodeIds[2] = nodes[6];
+  facesWithNodes.elems[3].nodeIds[3] = nodes[5];
+  facesWithNodes.elems[3].nbNodes = 4;
+  facesWithNodes.elems[3].vtkType = VTK_QUAD;
+
+  facesWithNodes.elems[4].nodeIds[0] = nodes[2];
+  facesWithNodes.elems[4].nodeIds[1] = nodes[6];
+  facesWithNodes.elems[4].nodeIds[2] = nodes[7];
+  facesWithNodes.elems[4].nodeIds[3] = nodes[3];
+  facesWithNodes.elems[4].nbNodes = 4;
+  facesWithNodes.elems[4].vtkType = VTK_QUAD;
+
+  facesWithNodes.elems[5].nodeIds[0] = nodes[3];
+  facesWithNodes.elems[5].nodeIds[1] = nodes[7];
+  facesWithNodes.elems[5].nodeIds[2] = nodes[4];
+  facesWithNodes.elems[5].nodeIds[3] = nodes[0];
+  facesWithNodes.elems[5].nbNodes = 4;
+  facesWithNodes.elems[5].vtkType = VTK_QUAD;
+}
+
+// ---------------------------------------------------------------------------
+
+SMDS_DownQuadHexa::SMDS_DownQuadHexa(SMDS_UnstructuredGrid *grid) :
+  SMDS_Down3D(grid, 6)
+{
+  _cellTypes.push_back(VTK_QUADRATIC_QUAD);
+  _cellTypes.push_back(VTK_QUADRATIC_QUAD);
+  _cellTypes.push_back(VTK_QUADRATIC_QUAD);
+  _cellTypes.push_back(VTK_QUADRATIC_QUAD);
+  _cellTypes.push_back(VTK_QUADRATIC_QUAD);
+  _cellTypes.push_back(VTK_QUADRATIC_QUAD);
+}
+
+SMDS_DownQuadHexa::~SMDS_DownQuadHexa()
+{
+}
+
+void SMDS_DownQuadHexa::getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes)
+{
+  // TODO
+}
+
+void SMDS_DownQuadHexa::addDownCell(int cellId, int lowCellId, unsigned char aType)
+{
+  //ASSERT((cellId >=0)&& (cellId < _maxId));
+  int *faces = &_cellIds[_nbDownCells * cellId];
+  for (int i = 0; i < _nbDownCells; i++)
+    {
+      if (faces[i] < 0)
+        {
+          faces[i] = lowCellId;
+          return;
+        }
+      if (faces[i] == lowCellId)
+        return;
+    }
+  ASSERT(0);
+}
+
+/*! Create a list of faces described by a vtk Type and  an ordered set of Node Id's
+ * The ordering of the twenty points defining the quadratic hexahedron cell is point id's (0-7,8-19)
+ * where point id's 0-7 are the eight corner vertices of the cube, followed by twelve mid-edge nodes (8-19).
+ * Note that these mid-edge nodes lie on the edges defined by
+ * (0,1), (1,2), (2,3), (3,0), (4,5), (5,6), (6,7), (7,4), (0,4), (1,5), (2,6), (3,7).
+ * @see vtkQuadraticHexahedron.h in Filtering
+ * @param cellId volumeId in vtkUnstructuredGrid
+ * @param facesWithNodes vector of face descriptors to be filled
+ */
+void SMDS_DownQuadHexa::computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes)
+{
+  // --- find point id's of the volume
+
+  vtkIdType npts = 0;
+  vtkIdType *nodes; // will refer to the point id's of the volume
+  _grid->GetCellPoints(cellId, npts, nodes);
+
+  // --- create all the ordered list of node id's for each face
+
+  facesWithNodes.nbElems = 6;
+
+  facesWithNodes.elems[0].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[0].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[0].nodeIds[2] = nodes[2];
+  facesWithNodes.elems[0].nodeIds[3] = nodes[3];
+  facesWithNodes.elems[0].nodeIds[4] = nodes[8];
+  facesWithNodes.elems[0].nodeIds[5] = nodes[9];
+  facesWithNodes.elems[0].nodeIds[6] = nodes[10];
+  facesWithNodes.elems[0].nodeIds[7] = nodes[11];
+  facesWithNodes.elems[0].nbNodes = 8;
+  facesWithNodes.elems[0].vtkType = VTK_QUADRATIC_QUAD;
+
+  facesWithNodes.elems[1].nodeIds[0] = nodes[4];
+  facesWithNodes.elems[1].nodeIds[1] = nodes[5];
+  facesWithNodes.elems[1].nodeIds[2] = nodes[6];
+  facesWithNodes.elems[1].nodeIds[3] = nodes[7];
+  facesWithNodes.elems[1].nodeIds[4] = nodes[12];
+  facesWithNodes.elems[1].nodeIds[5] = nodes[13];
+  facesWithNodes.elems[1].nodeIds[6] = nodes[14];
+  facesWithNodes.elems[1].nodeIds[7] = nodes[15];
+  facesWithNodes.elems[1].nbNodes = 8;
+  facesWithNodes.elems[1].vtkType = VTK_QUADRATIC_QUAD;
+
+  facesWithNodes.elems[2].nodeIds[0] = nodes[0];
+  facesWithNodes.elems[2].nodeIds[1] = nodes[1];
+  facesWithNodes.elems[2].nodeIds[2] = nodes[5];
+  facesWithNodes.elems[2].nodeIds[3] = nodes[4];
+  facesWithNodes.elems[2].nodeIds[4] = nodes[8];
+  facesWithNodes.elems[2].nodeIds[5] = nodes[17];
+  facesWithNodes.elems[2].nodeIds[6] = nodes[12];
+  facesWithNodes.elems[2].nodeIds[7] = nodes[16];
+  facesWithNodes.elems[2].nbNodes = 8;
+  facesWithNodes.elems[2].vtkType = VTK_QUADRATIC_QUAD;
+
+  facesWithNodes.elems[3].nodeIds[0] = nodes[1];
+  facesWithNodes.elems[3].nodeIds[1] = nodes[2];
+  facesWithNodes.elems[3].nodeIds[2] = nodes[6];
+  facesWithNodes.elems[3].nodeIds[3] = nodes[5];
+  facesWithNodes.elems[3].nodeIds[4] = nodes[9];
+  facesWithNodes.elems[3].nodeIds[5] = nodes[18];
+  facesWithNodes.elems[3].nodeIds[6] = nodes[13];
+  facesWithNodes.elems[3].nodeIds[7] = nodes[17];
+  facesWithNodes.elems[3].nbNodes = 8;
+  facesWithNodes.elems[3].vtkType = VTK_QUADRATIC_QUAD;
+
+  facesWithNodes.elems[4].nodeIds[0] = nodes[2];
+  facesWithNodes.elems[4].nodeIds[1] = nodes[6];
+  facesWithNodes.elems[4].nodeIds[2] = nodes[7];
+  facesWithNodes.elems[4].nodeIds[3] = nodes[3];
+  facesWithNodes.elems[4].nodeIds[4] = nodes[18];
+  facesWithNodes.elems[4].nodeIds[5] = nodes[14];
+  facesWithNodes.elems[4].nodeIds[6] = nodes[19];
+  facesWithNodes.elems[4].nodeIds[7] = nodes[10];
+  facesWithNodes.elems[4].nbNodes = 8;
+  facesWithNodes.elems[4].vtkType = VTK_QUADRATIC_QUAD;
+
+  facesWithNodes.elems[5].nodeIds[0] = nodes[3];
+  facesWithNodes.elems[5].nodeIds[1] = nodes[7];
+  facesWithNodes.elems[5].nodeIds[2] = nodes[4];
+  facesWithNodes.elems[5].nodeIds[3] = nodes[0];
+  facesWithNodes.elems[5].nodeIds[4] = nodes[19];
+  facesWithNodes.elems[5].nodeIds[5] = nodes[15];
+  facesWithNodes.elems[5].nodeIds[6] = nodes[16];
+  facesWithNodes.elems[5].nodeIds[7] = nodes[11];
+  facesWithNodes.elems[5].nbNodes = 8;
+  facesWithNodes.elems[5].vtkType = VTK_QUADRATIC_QUAD;
+}
+
+// ---------------------------------------------------------------------------
+
diff --git a/src/SMDS/SMDS_Downward.hxx b/src/SMDS/SMDS_Downward.hxx
new file mode 100644 (file)
index 0000000..d9b12a0
--- /dev/null
@@ -0,0 +1,363 @@
+/*
+ * SMDS_Downward.hxx
+ *
+ *  Created on: Jun 3, 2010
+ *      Author: prascle
+ */
+
+#ifndef SMDS_DOWNWARD_HXX_
+#define SMDS_DOWNWARD_HXX_
+
+#include "SMDS_UnstructuredGrid.hxx"
+
+#include <vector>
+#include <set>
+
+typedef struct
+{
+  int nodeIds[8]; //!< max number of nodes in a face or edge: quad quad = 8
+  int nbNodes;
+  unsigned char vtkType;
+} ElemByNodesType; // TODO resize for polyhedrons
+
+typedef struct
+{
+  ElemByNodesType elems[6]; //!< max number of faces in a volume or edges in a face : hexahedron = 6
+  int nbElems;
+} ListElemByNodesType; // TODO resize for polyhedrons
+
+class DownIdType
+{
+public:
+  DownIdType(int a, unsigned char b) :
+    cellId(a), cellType(b)
+  {
+  }
+  int cellId;
+  unsigned char cellType;
+};
+
+struct DownIdCompare
+{
+  bool operator ()(const DownIdType e1, const DownIdType e2) const
+  {
+    if (e1.cellId == e2.cellId)
+      return (e1.cellType < e2.cellType);
+    else
+      return (e1.cellId < e2.cellId);
+  }
+};
+
+class SMDS_Downward
+{
+  friend class SMDS_UnstructuredGrid;
+  friend class SMDS_Down2D;
+  friend class SMDS_Down3D;
+public:
+  virtual int getNumberOfDownCells(int cellId);
+  virtual const int* getDownCells(int cellId);
+  virtual const unsigned char* getDownTypes(int cellId);
+  virtual int getNumberOfUpCells(int cellId) = 0;
+  virtual const int* getUpCells(int cellId) = 0;
+  virtual const unsigned char* getUpTypes(int cellId) = 0;
+  virtual void getNodeIds(int cellId, std::set<int>& nodeSet) = 0;
+  int getVtkCellId(int cellId)
+  {
+    return _vtkCellIds[cellId];
+  }
+  int getMaxId()
+  {
+    return _maxId;
+  }
+  static int getCellDimension(unsigned char cellType);
+protected:
+  SMDS_Downward(SMDS_UnstructuredGrid *grid, int nbDownCells);
+  ~SMDS_Downward();
+  int addCell(int vtkId = -1);
+  virtual void initCell(int cellId);
+  virtual void allocate(int nbElems) = 0;
+  virtual void compactStorage() = 0;
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's
+  virtual void addUpCell(int cellId, int upCellId, unsigned char aType); //!< Id's are downward connectivity id's
+  virtual int getNodeSet(int cellId, int* nodeSet);
+
+  SMDS_UnstructuredGrid* _grid;
+  int _maxId;
+  int _nbDownCells; //!< the same number for all cells of a derived class
+  std::vector<int> _cellIds; //!< growing size: all the down cell id's, size = _maxId * _nbDownCells
+  std::vector<int> _vtkCellIds; //!< growing size: size = _maxId, either vtkId or -1
+  std::vector<unsigned char> _cellTypes; //!< fixed size: the same vector for all cells of a derived class
+
+  static std::vector<int> _cellDimension; //!< conversion table: type --> dimension
+};
+
+class SMDS_Down1D: public SMDS_Downward
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+  virtual int getNumberOfUpCells(int cellId);
+  virtual const int* getUpCells(int cellId);
+  virtual const unsigned char* getUpTypes(int cellId);
+  virtual void getNodeIds(int cellId, std::set<int>& nodeSet);
+protected:
+  SMDS_Down1D(SMDS_UnstructuredGrid *grid, int nbDownCells);
+  ~SMDS_Down1D();
+  virtual void initCell(int cellId);
+  virtual void allocate(int nbElems);
+  virtual void compactStorage();
+  virtual void addUpCell(int cellId, int upCellId, unsigned char aType); //!< Id's are downward connectivity id's
+  virtual int getNodeSet(int cellId, int* nodeSet);
+  void setNodes(int cellId, int vtkId);
+  void setNodes(int cellId, const int* nodeIds);
+  int computeVtkCells(int cellId, std::vector<int>& vtkIds);
+  int computeVtkCells(int* pts, std::vector<int>& vtkIds);
+  int computeFaces(int cellId, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes);
+  int computeFaces(int* pts, int* vtkIds, int nbcells, int* downFaces, unsigned char* downTypes);
+
+  std::vector<std::vector<int> > _upCellIdsVector; //!< the number of faces sharing an edge is not known
+  std::vector<std::vector<unsigned char> > _upCellTypesVector; //!< the number of faces sharing an edge is not known
+  std::vector<int> _upCellIds; //!< compacted storage after connectivity calculation
+  std::vector<unsigned char> _upCellTypes; //!< compacted storage after connectivity calculation
+  std::vector<int> _upCellIndex; //!< compacted storage after connectivity calculation
+};
+
+class SMDS_Down2D: public SMDS_Downward
+{
+  friend class SMDS_UnstructuredGrid;
+  friend class SMDS_Down1D;
+public:
+  virtual int getNumberOfUpCells(int cellId);
+  virtual const int* getUpCells(int cellId);
+  virtual const unsigned char* getUpTypes(int cellId);
+  virtual void getNodeIds(int cellId, std::set<int>& nodeSet);
+protected:
+  SMDS_Down2D(SMDS_UnstructuredGrid *grid, int nbDownCells);
+  ~SMDS_Down2D();
+  virtual void allocate(int nbElems);
+  virtual void compactStorage();
+  virtual void addUpCell(int cellId, int upCellId, unsigned char aType);
+  virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) = 0;
+  virtual int getNodeSet(int cellId, int* nodeSet);
+  int computeVolumeIds(int cellId, int* ids);
+  int computeVolumeIds(ElemByNodesType& faceByNodes, int* ids);
+  int computeVolumeIdsFromNodesFace(int* nodes, int nbNodes, int* ids);
+  void setTempNodes(int cellId, int vtkId);
+  void setTempNodes(int cellId, ElemByNodesType& faceByNodes);
+  bool isInFace(int cellId, int *pts, int npts);
+  int FindEdgeByNodes(int cellId, ElemByNodesType& edgeByNodes);
+
+  std::vector<int> _upCellIds; //!< 2 volumes max. per face
+  std::vector<unsigned char> _upCellTypes; //!< 2 volume types per face
+  std::vector<int> _tempNodes; //!< temporary storage of nodes, until downward connectivity completion
+  int _nbNodes; //!< number of nodes in a face
+};
+
+class SMDS_Down3D: public SMDS_Downward
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+  virtual int getNumberOfUpCells(int cellId);
+  virtual const int* getUpCells(int cellId);
+  virtual const unsigned char* getUpTypes(int cellId);
+  virtual void getNodeIds(int cellId, std::set<int>& nodeSet);
+  virtual void getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes) = 0;
+protected:
+  SMDS_Down3D(SMDS_UnstructuredGrid *grid, int nbDownCells);
+  ~SMDS_Down3D();
+  virtual void allocate(int nbElems);
+  virtual void compactStorage();
+  virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes) = 0;
+  int FindFaceByNodes(int cellId, ElemByNodesType& faceByNodes);
+};
+
+class SMDS_DownEdge: public SMDS_Down1D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+protected:
+  SMDS_DownEdge(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownEdge();
+};
+
+class SMDS_DownQuadEdge: public SMDS_Down1D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+protected:
+  SMDS_DownQuadEdge(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownQuadEdge();
+};
+
+class SMDS_DownTriangle: public SMDS_Down2D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+protected:
+  SMDS_DownTriangle(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownTriangle();
+  virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes);
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's
+};
+
+class SMDS_DownQuadTriangle: public SMDS_Down2D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+protected:
+  SMDS_DownQuadTriangle(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownQuadTriangle();
+  virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes);
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's
+};
+
+class SMDS_DownQuadrangle: public SMDS_Down2D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+protected:
+  SMDS_DownQuadrangle(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownQuadrangle();
+  virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes);
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's
+};
+
+class SMDS_DownQuadQuadrangle: public SMDS_Down2D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+protected:
+  SMDS_DownQuadQuadrangle(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownQuadQuadrangle();
+  virtual void computeEdgesWithNodes(int cellId, ListElemByNodesType& edgesWithNodes);
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType); //!< Id's are downward connectivity id's
+};
+
+//class SMDS_DownPolygon: public SMDS_Down2D
+//{
+//public:
+//  SMDS_DownPolygon(SMDS_UnstructuredGrid *grid);
+//  ~SMDS_DownPolygon();
+//protected:
+//};
+
+//class SMDS_DownQuadPolygon: public SMDS_Down2D
+//{
+//public:
+//  SMDS_DownQuadPolygon(SMDS_UnstructuredGrid *grid);
+//  ~SMDS_DownQuadPolygon();
+//protected:
+//};
+
+class SMDS_DownTetra: public SMDS_Down3D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+  virtual void getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes);
+protected:
+  SMDS_DownTetra(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownTetra();
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType);
+  virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes);
+};
+
+class SMDS_DownQuadTetra: public SMDS_Down3D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+  virtual void getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes);
+protected:
+  SMDS_DownQuadTetra(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownQuadTetra();
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType);
+  virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes);
+};
+
+class SMDS_DownPyramid: public SMDS_Down3D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+  virtual void getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes);
+protected:
+  SMDS_DownPyramid(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownPyramid();
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType);
+  virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes);
+};
+
+class SMDS_DownQuadPyramid: public SMDS_Down3D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+  virtual void getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes);
+protected:
+  SMDS_DownQuadPyramid(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownQuadPyramid();
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType);
+  virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes);
+};
+
+class SMDS_DownPenta: public SMDS_Down3D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+  virtual void getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes);
+protected:
+  SMDS_DownPenta(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownPenta();
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType);
+  virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes);
+};
+
+class SMDS_DownQuadPenta: public SMDS_Down3D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+  virtual void getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes);
+protected:
+  SMDS_DownQuadPenta(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownQuadPenta();
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType);
+  virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes);
+};
+
+class SMDS_DownHexa: public SMDS_Down3D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+  virtual void getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes);
+protected:
+  SMDS_DownHexa(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownHexa();
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType);
+  virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes);
+};
+
+class SMDS_DownQuadHexa: public SMDS_Down3D
+{
+  friend class SMDS_UnstructuredGrid;
+public:
+  virtual void getOrderedNodesOfFace(int cellId, std::vector<int>& orderedNodes);
+protected:
+  SMDS_DownQuadHexa(SMDS_UnstructuredGrid *grid);
+  ~SMDS_DownQuadHexa();
+  virtual void addDownCell(int cellId, int lowCellId, unsigned char aType);
+  virtual void computeFacesWithNodes(int cellId, ListElemByNodesType& facesWithNodes);
+};
+
+//class SMDS_DownPolyhedra: public SMDS_Down3D
+//{
+//public:
+//  SMDS_DownPolyhedra(SMDS_UnstructuredGrid *grid);
+//  ~SMDS_DownPolyhedra();
+//protected:
+//};
+
+//class SMDS_DownQuadPolyhedra: public SMDS_Down3D
+//{
+//public:
+//  SMDS_DownQuadPolyhedra(SMDS_UnstructuredGrid *grid);
+//  ~SMDS_DownQuadPolyhedra();
+//protected:
+//};
+
+#endif /* SMDS_DOWNWARD_HXX_ */
index 76df7471cece45eb03079d535e031a97bc4b7eae..1f96b7483c1c92a80a5e779adcc200ff82825003 100644 (file)
@@ -36,32 +36,22 @@ using namespace std;
 //purpose  : 
 //=======================================================================
 
-SMDS_EdgePosition::SMDS_EdgePosition(const int aEdgeId,
-        const double aUParam):SMDS_Position(aEdgeId), myUParameter(aUParam)
+SMDS_EdgePosition::SMDS_EdgePosition(const double aUParam): myUParameter(aUParam)
 {
-}
-
-//=======================================================================
-//function : Coords
-//purpose  : 
-//=======================================================================
-
-const double *SMDS_EdgePosition::Coords() const
-{
-        static double origin[]={0,0,0};
-        MESSAGE("SMDS_EdgePosition::Coords not implemented");
-        return origin;
+  //MESSAGE("********************************* SMDS_EdgePosition " << myUParameter);
 }
 
 /**
 */
 SMDS_TypeOfPosition SMDS_EdgePosition::GetTypeOfPosition() const
 {
+  //MESSAGE("###################################### SMDS_EdgePosition::GetTypeOfPosition");
         return SMDS_TOP_EDGE;
 }
 
 void SMDS_EdgePosition::SetUParameter(double aUparam)
 {
+  //MESSAGE("############################### SMDS_EdgePosition::SetUParameter " << aUparam);
         myUParameter = aUparam;
 }
 
@@ -72,5 +62,6 @@ void SMDS_EdgePosition::SetUParameter(double aUparam)
 
 double SMDS_EdgePosition::GetUParameter() const 
 {
+  //MESSAGE("########################## SMDS_EdgePosition::GetUParameter " << myUParameter);
         return myUParameter;
 }
index 8c2148dfe55abc93944cc51cffacfeadc1724ada..dc4afa983b9bfc9fdfda81545b02bc37c5106f7c 100644 (file)
@@ -35,8 +35,7 @@ class SMDS_EXPORT SMDS_EdgePosition:public SMDS_Position
 {
 
   public:
-        SMDS_EdgePosition(const int aEdgeId=0, const double aUParam=0);
-        const virtual double * Coords() const;
+        SMDS_EdgePosition(const double aUParam=0);
         SMDS_TypeOfPosition GetTypeOfPosition() const;
         void SetUParameter(double aUparam);
         double GetUParameter() const;
index 2d545861d5177a1a3d26f3ff8638b39d9cf33041..c02ad1a2bf4d4a84e85725303752b15fa487e6ad 100644 (file)
@@ -29,6 +29,7 @@
 #include "SMDS_FaceOfEdges.hxx"
 #include "SMDS_IteratorOfElements.hxx"
 #include "SMDS_MeshNode.hxx"
+#include "utilities.h"
 
 using namespace std;
 
@@ -111,6 +112,7 @@ SMDS_FaceOfEdges::SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1,
                                    const SMDS_MeshEdge* edge2,
                                    const SMDS_MeshEdge* edge3)
 {
+  //MESSAGE("****************************************************** SMDS_FaceOfEdges");
         myNbEdges = 3;
         myEdges[0]=edge1;
         myEdges[1]=edge2;
@@ -123,6 +125,7 @@ SMDS_FaceOfEdges::SMDS_FaceOfEdges(const SMDS_MeshEdge* edge1,
                                    const SMDS_MeshEdge* edge3,
                                    const SMDS_MeshEdge* edge4)
 {
+  //MESSAGE("****************************************************** SMDS_FaceOfEdges");
         myNbEdges = 4;
         myEdges[0]=edge1;
         myEdges[1]=edge2;
index 91acdb17a3bb434417ca8b13318304755f92bd87..bb757e852c5462b26a038ea27ccc99e477f5054a 100644 (file)
@@ -20,7 +20,7 @@
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
-//  SMESH SMDS : implementaion of Salome mesh data structure
+//  SMESH SMDS : implementation of Salome mesh data structure
 //
 #ifndef _SMDS_FaceOfEdges_HeaderFile
 #define _SMDS_FaceOfEdges_HeaderFile
@@ -48,6 +48,7 @@ class SMDS_EXPORT SMDS_FaceOfEdges:public SMDS_MeshFace
                 
         SMDSAbs_ElementType GetType() const;
         virtual SMDSAbs_EntityType   GetEntityType() const;
+        virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) {return false;};
         int NbNodes() const;
         int NbEdges() const;
         int NbFaces() const;
index d92a89a3ef58cdcf21f661646a10d2cd172e6d4c..ce99398ca2e5908b2925514276bfdd69ae5ffa8f 100644 (file)
@@ -133,6 +133,7 @@ SMDS_FaceOfNodes::SMDS_FaceOfNodes(const SMDS_MeshNode* node1,
                                    const SMDS_MeshNode* node2,
                                    const SMDS_MeshNode* node3)
 {
+  //MESSAGE("******************************************************* SMDS_FaceOfNodes");
         myNbNodes = 3;
         myNodes[0]=node1;
         myNodes[1]=node2;
@@ -145,6 +146,7 @@ SMDS_FaceOfNodes::SMDS_FaceOfNodes(const SMDS_MeshNode* node1,
                                    const SMDS_MeshNode* node3,
                                    const SMDS_MeshNode* node4)
 {
+  //MESSAGE("******************************************************* SMDS_FaceOfNodes");
         myNbNodes = 4;
         myNodes[0]=node1;
         myNodes[1]=node2;
index da93899b627f8d61c620f13f464db77aaf6e869a..01421cb6f0bd1050565c67f74d19ac8020a9779e 100644 (file)
@@ -36,23 +36,11 @@ using namespace std;
 //purpose  : 
 //=======================================================================
 
-SMDS_FacePosition::SMDS_FacePosition(const int aEdgeId,
-                                     const double aUParam,
+SMDS_FacePosition::SMDS_FacePosition(const double aUParam,
                                      const double aVParam)
-  :SMDS_Position(aEdgeId),
-   myUParameter(aUParam),myVParameter(aVParam)
+   : myUParameter(aUParam),myVParameter(aVParam)
 {
-}
-
-//=======================================================================
-//function : Coords
-//purpose  : 
-//=======================================================================
-const double *SMDS_FacePosition::Coords() const
-{
-        static double origin[]={0,0,0};
-        MESSAGE("SMDS_EdgePosition::Coords not implemented");
-        return origin;
+  //MESSAGE("******************************************************** SMDS_FacePosition");
 }
 
 /**
index 1b8967dc077779ce56c7c2705eec4901c266b73f..4efb606842460eb0237097737cae8d5324b4e702 100644 (file)
@@ -35,9 +35,7 @@ class SMDS_EXPORT SMDS_FacePosition:public SMDS_Position
 {
 
   public:
-        SMDS_FacePosition(int aFaceId=0, double aUParam=0,
-                double aVParam=0);
-        const virtual double * Coords() const;
+        SMDS_FacePosition(double aUParam=0, double aVParam=0);
         SMDS_TypeOfPosition GetTypeOfPosition() const;
         void SetUParameter(double aUparam);
         void SetVParameter(double aVparam);
diff --git a/src/SMDS/SMDS_LinearEdge.cxx b/src/SMDS/SMDS_LinearEdge.cxx
new file mode 100644 (file)
index 0000000..7bb1ea2
--- /dev/null
@@ -0,0 +1,163 @@
+//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  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
+//
+//  SMESH SMDS : implementaion of Salome mesh data structure
+//  File   : SMDS_LinearEdge.cxx
+//  Author : Jean-Michel BOULCOURT
+//  Module : SMESH
+//
+#ifdef _MSC_VER
+#pragma warning(disable:4786)
+#endif
+
+#include "SMDS_LinearEdge.hxx"
+#include "SMDS_IteratorOfElements.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "utilities.h"
+
+using namespace std;
+
+//=======================================================================
+//function : SMDS_LinearEdge
+//purpose  : 
+//=======================================================================
+
+SMDS_LinearEdge::SMDS_LinearEdge(const SMDS_MeshNode * node1,
+                                 const SMDS_MeshNode * node2)
+{
+  //MESSAGE("SMDS_LinearEdge " << GetID());
+  myNodes[0] = node1;
+  myNodes[1] = node2;
+}
+
+//=======================================================================
+//function : Print
+//purpose  : 
+//=======================================================================
+
+void SMDS_LinearEdge::Print(ostream & OS) const
+{
+  OS << "edge <" << GetID() << "> : (" << myNodes[0] << " , " << myNodes[1]
+      << ") " << endl;
+}
+
+int SMDS_LinearEdge::NbNodes() const
+{
+  return 2;
+}
+
+int SMDS_LinearEdge::NbEdges() const
+{
+  return 1;
+}
+
+class SMDS_LinearEdge_MyNodeIterator: public SMDS_ElemIterator
+{
+  const SMDS_MeshNode * const * myNodes;
+  int myIndex;
+public:
+  SMDS_LinearEdge_MyNodeIterator(const SMDS_MeshNode * const * nodes) :
+    myNodes(nodes), myIndex(0)
+  {
+  }
+
+  bool more()
+  {
+    return myIndex < 2;
+  }
+
+  const SMDS_MeshElement* next()
+  {
+    myIndex++;
+    return myNodes[myIndex - 1];
+  }
+};
+
+SMDS_ElemIteratorPtr SMDS_LinearEdge::elementsIterator(SMDSAbs_ElementType type) const
+{
+  switch (type)
+  {
+    case SMDSAbs_Edge:
+      return SMDS_MeshElement::elementsIterator(SMDSAbs_Edge);
+    case SMDSAbs_Node:
+      return SMDS_ElemIteratorPtr(new SMDS_LinearEdge_MyNodeIterator(myNodes));
+    default:
+      return SMDS_ElemIteratorPtr(
+                                  new SMDS_IteratorOfElements(
+                                                              this,
+                                                              type,
+                                                              SMDS_ElemIteratorPtr(
+                                                                                   new SMDS_LinearEdge_MyNodeIterator(
+                                                                                                                      myNodes))));
+  }
+}
+
+bool operator<(const SMDS_LinearEdge & e1, const SMDS_LinearEdge & e2)
+{
+  int id11 = e1.myNodes[0]->getVtkId();
+  int id21 = e2.myNodes[0]->getVtkId();
+  int id12 = e1.myNodes[1]->getVtkId();
+  int id22 = e2.myNodes[1]->getVtkId();
+  int tmp;
+
+  if (id11 >= id12)
+    {
+      tmp = id11;
+      id11 = id12;
+      id12 = tmp;
+    }
+  if (id21 >= id22)
+    {
+      tmp = id21;
+      id21 = id22;
+      id22 = tmp;
+    }
+
+  if (id11 < id21)
+    return true;
+  else if (id11 == id21)
+    return (id21 < id22);
+  else
+    return false;
+}
+
+/*!
+ * \brief Return node by its index
+ * \param ind - node index
+ * \retval const SMDS_MeshNode* - the node
+ */
+const SMDS_MeshNode* SMDS_LinearEdge::GetNode(const int ind) const
+{
+  return myNodes[ind];
+}
+
+//=======================================================================
+//function : ChangeNodes
+//purpose  : 
+//=======================================================================
+
+bool SMDS_LinearEdge::ChangeNodes(const SMDS_MeshNode * node1,
+                                  const SMDS_MeshNode * node2)
+{
+  myNodes[0] = node1;
+  myNodes[1] = node2;
+  return true;
+}
diff --git a/src/SMDS/SMDS_LinearEdge.hxx b/src/SMDS/SMDS_LinearEdge.hxx
new file mode 100644 (file)
index 0000000..e7c66d7
--- /dev/null
@@ -0,0 +1,69 @@
+//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  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
+//
+//  SMESH SMDS : implementaion of Salome mesh data structure
+//  File   : SMDS_LinearEdge.hxx
+//  Module : SMESH
+//
+#ifndef _SMDS_LinearEdge_HeaderFile
+#define _SMDS_LinearEdge_HeaderFile
+
+#include "SMESH_SMDS.hxx"
+
+#include "SMDS_MeshEdge.hxx"
+#include <iostream>
+
+class SMDS_EXPORT SMDS_LinearEdge: public SMDS_MeshEdge
+{
+
+public:
+  SMDS_LinearEdge(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2);
+  bool ChangeNodes(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2);
+  void Print(std::ostream & OS) const;
+
+  virtual SMDSAbs_EntityType GetEntityType() const
+  {
+    return SMDSEntity_Edge;
+  }
+  virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
+  {
+    return false;
+  }
+  int NbNodes() const;
+  int NbEdges() const;
+  friend bool operator<(const SMDS_LinearEdge& e1, const SMDS_LinearEdge& e2);
+
+  /*!
+   * \brief Return node by its index
+   * \param ind - node index
+   * \retval const SMDS_MeshNode* - the node
+   */
+  virtual const SMDS_MeshNode* GetNode(const int ind) const;
+
+protected:
+  SMDS_ElemIteratorPtr
+  elementsIterator(SMDSAbs_ElementType type) const;
+
+protected:
+  const SMDS_MeshNode* myNodes[3];
+
+};
+#endif
index d3d41b135bc4faa4a3eec9041dd6659a41b48278..d6f7e1813f23d8b5d56944b27b7e4cc3ccfdcb3a 100644 (file)
@@ -20,7 +20,7 @@
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
-//  SMESH SMDS : implementaion of Salome mesh data structure
+//  SMESH SMDS : implementation of Salome mesh data structure
 //
 #ifdef _MSC_VER
 #pragma warning(disable:4786)
 #include "SMDS_QuadraticEdge.hxx"
 #include "SMDS_QuadraticFaceOfNodes.hxx"
 #include "SMDS_QuadraticVolumeOfNodes.hxx"
+#include "SMDS_SpacePosition.hxx"
+#include "SMDS_UnstructuredGrid.hxx"
+
+#include <vtkUnstructuredGrid.h>
+#include <vtkUnstructuredGridWriter.h>
+#include <vtkUnsignedCharArray.h>
+#include <vtkCell.h>
+#include <vtkCellLinks.h>
+#include <vtkIdList.h>
 
 #include <algorithm>
 #include <map>
+#include <iostream>
+#include <fstream>
 using namespace std;
 
 #ifndef WIN32
 #include <sys/sysinfo.h>
 #endif
 
-// number of added entitis to check memory after
+// number of added entities to check memory after
 #define CHECKMEMORY_INTERVAL 1000
 
+vector<SMDS_Mesh*> SMDS_Mesh::_meshList = vector<SMDS_Mesh*>();
+int SMDS_Mesh::chunkSize = 1024;
+
+
 //================================================================================
 /*!
  * \brief Raise an exception if free memory (ram+swap) too low
@@ -105,11 +120,45 @@ int SMDS_Mesh::CheckMemory(const bool doNotRaise) throw (std::bad_alloc)
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_Mesh::SMDS_Mesh()
         :myParent(NULL),
-        myNodeIDFactory(new SMDS_MeshElementIDFactory()),
-        myElementIDFactory(new SMDS_MeshElementIDFactory()),
-        myHasConstructionEdges(false), myHasConstructionFaces(false),
-        myHasInverseElements(true)
-{
+         myNodeIDFactory(new SMDS_MeshNodeIDFactory()),
+         myElementIDFactory(new SMDS_MeshElementIDFactory()),
+         myHasConstructionEdges(false), myHasConstructionFaces(false),
+         myHasInverseElements(true),
+         myNodeMin(0), myNodeMax(0),
+         myNodePool(0), myEdgePool(0), myFacePool(0), myVolumePool(0),
+         myModified(false), myModifTime(0), myCompactTime(0),
+         xmin(0), xmax(0), ymin(0), ymax(0), zmin(0), zmax(0)
+{
+  myMeshId = _meshList.size();         // --- index of the mesh to push back in the vector
+  MESSAGE("myMeshId=" << myMeshId);
+  MESSAGE("sizeof(SMDS_MeshElement) " << sizeof(SMDS_MeshElement) );
+  MESSAGE("sizeof(SMDS_MeshNode) " << sizeof(SMDS_MeshNode) );
+  MESSAGE("sizeof(SMDS_MeshCell) " << sizeof(SMDS_MeshCell) );
+  MESSAGE("sizeof(SMDS_VtkVolume) " << sizeof(SMDS_VtkVolume) );
+  MESSAGE("sizeof(SMDS_Position) " << sizeof(SMDS_Position) );
+  MESSAGE("sizeof(SMDS_SpacePosition) " << sizeof(SMDS_SpacePosition) );
+  myNodeIDFactory->SetMesh(this);
+  myElementIDFactory->SetMesh(this);
+  _meshList.push_back(this);
+  myNodePool = new ObjectPool<SMDS_MeshNode>(SMDS_Mesh::chunkSize);
+  myEdgePool = new ObjectPool<SMDS_VtkEdge>(SMDS_Mesh::chunkSize);
+  myFacePool = new ObjectPool<SMDS_VtkFace>(SMDS_Mesh::chunkSize);
+  myVolumePool = new ObjectPool<SMDS_VtkVolume>(SMDS_Mesh::chunkSize);
+
+  myNodes.clear();
+  myCells.clear();
+  //myCellIdSmdsToVtk.clear();
+  myCellIdVtkToSmds.clear();
+  myGrid = SMDS_UnstructuredGrid::New();
+  myGrid->setSMDS_mesh(this);
+  myGrid->Initialize();
+  myGrid->Allocate();
+  vtkPoints* points = vtkPoints::New();
+  points->SetNumberOfPoints(SMDS_Mesh::chunkSize);
+  myGrid->SetPoints( points );
+  points->Delete();
+  myGrid->BuildLinks();
+  this->Modified();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -119,9 +168,13 @@ SMDS_Mesh::SMDS_Mesh()
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_Mesh::SMDS_Mesh(SMDS_Mesh * parent)
         :myParent(parent), myNodeIDFactory(parent->myNodeIDFactory),
-        myElementIDFactory(parent->myElementIDFactory),
-        myHasConstructionEdges(false), myHasConstructionFaces(false),
-        myHasInverseElements(true)
+         myElementIDFactory(parent->myElementIDFactory),
+         myHasConstructionEdges(false), myHasConstructionFaces(false),
+         myHasInverseElements(true),
+         myNodePool(parent->myNodePool),
+         myEdgePool(parent->myEdgePool),
+         myFacePool(parent->myFacePool),
+         myVolumePool(parent->myVolumePool)
 {
 }
 
@@ -157,11 +210,25 @@ SMDS_MeshNode * SMDS_Mesh::AddNodeWithID(double x, double y, double z, int ID)
   // find the MeshNode corresponding to ID
   const SMDS_MeshElement *node = myNodeIDFactory->MeshElement(ID);
   if(!node){
-    if ( myNodes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-    SMDS_MeshNode * node=new SMDS_MeshNode(x, y, z);
-    myNodes.Add(node);
+    // TODO ID < 1
+    if (ID <= 0)
+      {
+        MESSAGE("=============>  Bad Node Id: " << ID);
+        ID = myNodeIDFactory->GetFreeID();
+      }
+    myNodeIDFactory->adjustMaxId(ID);
+    SMDS_MeshNode * node = myNodePool->getNew();
+    node->init(ID, myMeshId, 0, x, y, z);
+    if (ID >= myNodes.size())
+    {
+        myNodes.resize(ID+SMDS_Mesh::chunkSize, 0);
+        MESSAGE(" ------------------ myNodes resize " << ID << " --> " << ID+SMDS_Mesh::chunkSize);
+    }
+    myNodes[ID] = node;
     myNodeIDFactory->BindID(ID,node);
     myInfo.myNbNodes++;
+    myModified = true;
+    this->adjustBoundingBox(x, y, z);
     return node;
   }else
     return NULL;
@@ -198,13 +265,14 @@ SMDS_Mesh0DElement* SMDS_Mesh::Add0DElementWithID(const SMDS_MeshNode * n, int I
 {
   if (!n) return 0;
 
-  if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
-
+  //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
+  //MESSAGE("Add0DElementWithID" << ID)
   SMDS_Mesh0DElement * el0d = new SMDS_Mesh0DElement(n);
   if (myElementIDFactory->BindID(ID, el0d)) {
     SMDS_MeshNode *node = const_cast<SMDS_MeshNode*>(n);
-    node->AddInverseElement(el0d);
-    my0DElements.Add(el0d);
+    //node->AddInverseElement(el0d);// --- fait avec BindID
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = el0d;
     myInfo.myNb0DElements++;
     return el0d;
   }
@@ -251,24 +319,33 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
                                         int ID)
 {
   if ( !n1 || !n2 ) return 0;
+  SMDS_MeshEdge * edge = 0;
 
-  if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  // --- retreive nodes ID
+  vector<vtkIdType> nodeIds;
+  nodeIds.clear();
+  nodeIds.push_back(n1->getVtkId());
+  nodeIds.push_back(n2->getVtkId());
 
-  SMDS_MeshEdge * edge=new SMDS_MeshEdge(n1,n2);
-  if(myElementIDFactory->BindID(ID, edge)) {
-    SMDS_MeshNode *node1,*node2;
-    node1=const_cast<SMDS_MeshNode*>(n1);
-    node2=const_cast<SMDS_MeshNode*>(n2);
-    node1->AddInverseElement(edge);
-    node2->AddInverseElement(edge);
-    myEdges.Add(edge);
-    myInfo.myNbEdges++;
-    return edge;
-  }
-  else {
-    delete edge;
-    return NULL;
-  }
+  SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
+  edgevtk->init(nodeIds, this);
+  if (!this->registerElement(ID,edgevtk))
+    {
+      this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
+      myEdgePool->destroy(edgevtk);
+      return 0;
+    }
+  edge = edgevtk;
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = edge;
+  myInfo.myNbEdges++;
+
+//  if (edge && !registerElement(ID, edge))
+//  {
+//    RemoveElement(edge, false);
+//    edge = NULL;
+//  }
+  return edge;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -305,12 +382,13 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
                                         const SMDS_MeshNode * n3,
                                         int ID)
 {
-  SMDS_MeshFace * face=createTriangle(n1, n2, n3);
+  //MESSAGE("AddFaceWithID " << ID)
+  SMDS_MeshFace * face=createTriangle(n1, n2, n3, ID);
 
-  if (face && !registerElement(ID, face)) {
-    RemoveElement(face, false);
-    face = NULL;
-  }
+//  if (face && !registerElement(ID, face)) {
+//    RemoveElement(face, false);
+//    face = NULL;
+//  }
   return face;
 }
 
@@ -356,12 +434,13 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
                                         const SMDS_MeshNode * n4,
                                         int ID)
 {
-  SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4);
+  //MESSAGE("AddFaceWithID " << ID);
+  SMDS_MeshFace * face=createQuadrangle(n1, n2, n3, n4, ID);
 
-  if (face && !registerElement(ID, face)) {
-    RemoveElement(face, false);
-    face = NULL;
-  }
+//  if (face && !registerElement(ID, face)) {
+//    RemoveElement(face, false);
+//    face = NULL;
+//  }
   return face;
 }
 
@@ -376,7 +455,8 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
 {
   if (!hasConstructionEdges())
     return NULL;
-  return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
+     //MESSAGE("AddFaceWithID");
+ return AddFaceWithID(e1,e2,e3, myElementIDFactory->GetFreeID());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -392,15 +472,18 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
     return NULL;
   if ( !e1 || !e2 || !e3 ) return 0;
 
-  if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  MESSAGE("AddFaceWithID" << ID);
 
   SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3);
-  myFaces.Add(face);
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = face;
   myInfo.myNbTriangles++;
 
   if (!registerElement(ID, face)) {
-    RemoveElement(face, false);
-    face = NULL;
+    registerElement(myElementIDFactory->GetFreeID(), face);
+    //RemoveElement(face, false);
+    //face = NULL;
   }
   return face;
 }
@@ -417,7 +500,8 @@ SMDS_MeshFace* SMDS_Mesh::AddFace(const SMDS_MeshEdge * e1,
 {
   if (!hasConstructionEdges())
     return NULL;
-  return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
+     //MESSAGE("AddFaceWithID" );
+ return AddFaceWithID(e1,e2,e3,e4, myElementIDFactory->GetFreeID());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -432,16 +516,19 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshEdge * e1,
 {
   if (!hasConstructionEdges())
     return NULL;
+  MESSAGE("AddFaceWithID" << ID);
   if ( !e1 || !e2 || !e3 || !e4 ) return 0;
-  if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   SMDS_MeshFace * face = new SMDS_FaceOfEdges(e1,e2,e3,e4);
-  myFaces.Add(face);
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = face;
   myInfo.myNbQuadrangles++;
 
   if (!registerElement(ID, face))
   {
-    RemoveElement(face, false);
-    face = NULL;
+    registerElement(myElementIDFactory->GetFreeID(), face);
+    //RemoveElement(face, false);
+    //face = NULL;
   }
   return face;
 }
@@ -457,6 +544,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
                                       const SMDS_MeshNode * n4)
 {
   int ID = myElementIDFactory->GetFreeID();
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, ID);
   if(v==NULL) myElementIDFactory->ReleaseID(ID);
   return v;
@@ -475,6 +563,7 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
                                              int idnode4,
                                              int ID)
 {
+    //MESSAGE("AddVolumeWithID" << ID);
   SMDS_MeshNode *node1, *node2, *node3, *node4;
   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
@@ -496,16 +585,18 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n4,
                                             int ID)
 {
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshVolume* volume = 0;
   if ( !n1 || !n2 || !n3 || !n4) return volume;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   if(hasConstructionFaces()) {
     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
     SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n4);
     SMDS_MeshFace * f3=FindFaceOrCreate(n1,n3,n4);
     SMDS_MeshFace * f4=FindFaceOrCreate(n2,n3,n4);
     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
-    myVolumes.Add(volume);
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbTetras++;
   }
   else if(hasConstructionEdges()) {
@@ -513,15 +604,32 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     return NULL;
   }
   else {
-    volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4);
-    myVolumes.Add(volume);
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(n1->getVtkId());
+    nodeIds.push_back(n3->getVtkId()); // order SMDS-->VTK
+    nodeIds.push_back(n2->getVtkId());
+    nodeIds.push_back(n4->getVtkId());
+
+    SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+    volvtk->init(nodeIds, this);
+    if (!this->registerElement(ID,volvtk))
+      {
+        this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+        myVolumePool->destroy(volvtk);
+        return 0;
+      }
+    volume = volvtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbTetras++;
   }
 
-  if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
-  }
+//  if (!registerElement(ID, volume)) {
+//    RemoveElement(volume, false);
+//    volume = NULL;
+//  }
   return volume;
 }
 
@@ -538,6 +646,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
                                       const SMDS_MeshNode * n5)
 {
   int ID = myElementIDFactory->GetFreeID();
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, ID);
   if(v==NULL) myElementIDFactory->ReleaseID(ID);
   return v;
@@ -558,6 +667,7 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
                                              int idnode5,
                                              int ID)
 {
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5;
   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
@@ -582,16 +692,18 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n5,
                                             int ID)
 {
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshVolume* volume = 0;
   if ( !n1 || !n2 || !n3 || !n4 || !n5) return volume;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   if(hasConstructionFaces()) {
     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
     SMDS_MeshFace * f2=FindFaceOrCreate(n1,n2,n5);
     SMDS_MeshFace * f3=FindFaceOrCreate(n2,n3,n5);
     SMDS_MeshFace * f4=FindFaceOrCreate(n3,n4,n5);
     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4);
-    myVolumes.Add(volume);
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbPyramids++;
   }
   else if(hasConstructionEdges()) {
@@ -599,15 +711,33 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     return NULL;
   }
   else {
-    volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5);
-    myVolumes.Add(volume);
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(n1->getVtkId());
+    nodeIds.push_back(n4->getVtkId());
+    nodeIds.push_back(n3->getVtkId());
+    nodeIds.push_back(n2->getVtkId());
+    nodeIds.push_back(n5->getVtkId());
+
+    SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+    volvtk->init(nodeIds, this);
+    if (!this->registerElement(ID,volvtk))
+      {
+        this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+        myVolumePool->destroy(volvtk);
+        return 0;
+      }
+    volume = volvtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbPyramids++;
   }
 
-  if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
-  }
+//  if (!registerElement(ID, volume)) {
+//    RemoveElement(volume, false);
+//    volume = NULL;
+//  }
   return volume;
 }
 
@@ -625,6 +755,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
                                       const SMDS_MeshNode * n6)
 {
   int ID = myElementIDFactory->GetFreeID();
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, ID);
   if(v==NULL) myElementIDFactory->ReleaseID(ID);
   return v;
@@ -646,6 +777,7 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
                                              int idnode6,
                                              int ID)
 {
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6;
   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
@@ -672,9 +804,10 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n6,
                                             int ID)
 {
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshVolume* volume = 0;
   if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6) return volume;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   if(hasConstructionFaces()) {
     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3);
     SMDS_MeshFace * f2=FindFaceOrCreate(n4,n5,n6);
@@ -682,7 +815,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     SMDS_MeshFace * f4=FindFaceOrCreate(n2,n5,n6,n3);
     SMDS_MeshFace * f5=FindFaceOrCreate(n3,n6,n4,n1);
     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
-    myVolumes.Add(volume);
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbPrisms++;
   }
   else if(hasConstructionEdges()) {
@@ -690,15 +824,34 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     return NULL;
   }
   else {
-    volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6);
-    myVolumes.Add(volume);
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(n1->getVtkId());
+    nodeIds.push_back(n2->getVtkId());
+    nodeIds.push_back(n3->getVtkId());
+    nodeIds.push_back(n4->getVtkId());
+    nodeIds.push_back(n5->getVtkId());
+    nodeIds.push_back(n6->getVtkId());
+
+    SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+    volvtk->init(nodeIds, this);
+    if (!this->registerElement(ID,volvtk))
+      {
+        this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+        myVolumePool->destroy(volvtk);
+        return 0;
+      }
+    volume = volvtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbPrisms++;
   }
 
-  if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
-  }
+//  if (!registerElement(ID, volume)) {
+//    RemoveElement(volume, false);
+//    volume = NULL;
+//  }
   return volume;
 }
 
@@ -718,7 +871,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshNode * n1,
                                       const SMDS_MeshNode * n8)
 {
   int ID = myElementIDFactory->GetFreeID();
-  SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
+     //MESSAGE("AddVolumeWithID " << ID);
+ SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, ID);
   if(v==NULL) myElementIDFactory->ReleaseID(ID);
   return v;
 }
@@ -741,6 +895,7 @@ SMDS_MeshVolume * SMDS_Mesh::AddVolumeWithID(int idnode1,
                                              int idnode8,
                                              int ID)
 {
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshNode *node1, *node2, *node3, *node4, *node5, *node6, *node7, *node8;
   node1 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode1);
   node2 = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(idnode2);
@@ -774,9 +929,10 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                                             const SMDS_MeshNode * n8,
                                             int ID)
 {
+    //MESSAGE("AddVolumeWithID " << ID);
   SMDS_MeshVolume* volume = 0;
   if ( !n1 || !n2 || !n3 || !n4 || !n5 || !n6 || !n7 || !n8) return volume;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   if(hasConstructionFaces()) {
     SMDS_MeshFace * f1=FindFaceOrCreate(n1,n2,n3,n4);
     SMDS_MeshFace * f2=FindFaceOrCreate(n5,n6,n7,n8);
@@ -785,7 +941,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     SMDS_MeshFace * f5=FindFaceOrCreate(n2,n3,n7,n6);
     SMDS_MeshFace * f6=FindFaceOrCreate(n3,n4,n8,n7);
     volume=new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
-    myVolumes.Add(volume);
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbHexas++;
   }
   else if(hasConstructionEdges()) {
@@ -793,16 +950,36 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     return NULL;
   }
   else {
-//    volume=new SMDS_HexahedronOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
-    volume=new SMDS_VolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8);
-    myVolumes.Add(volume);
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(n1->getVtkId());
+    nodeIds.push_back(n4->getVtkId());
+    nodeIds.push_back(n3->getVtkId());
+    nodeIds.push_back(n2->getVtkId());
+    nodeIds.push_back(n5->getVtkId());
+    nodeIds.push_back(n8->getVtkId());
+    nodeIds.push_back(n7->getVtkId());
+    nodeIds.push_back(n6->getVtkId());
+
+    SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+    volvtk->init(nodeIds, this);
+    if (!this->registerElement(ID,volvtk))
+      {
+        this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+        myVolumePool->destroy(volvtk);
+        return 0;
+      }
+    volume = volvtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = volume;
     myInfo.myNbHexas++;
   }
-
-  if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
-  }
+//  if (!registerElement(ID, volume)) {
+//    RemoveElement(volume, false);
+//    volume = NULL;
+//  }
   return volume;
 }
 
@@ -816,6 +993,7 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
                                       const SMDS_MeshFace * f3,
                                       const SMDS_MeshFace * f4)
 {
+    //MESSAGE("AddVolumeWithID");
   if (!hasConstructionFaces())
     return NULL;
   return AddVolumeWithID(f1,f2,f3,f4, myElementIDFactory->GetFreeID());
@@ -833,17 +1011,20 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
                                             const SMDS_MeshFace * f4,
                                             int ID)
 {
+  MESSAGE("AddVolumeWithID" << ID);
   if (!hasConstructionFaces())
     return NULL;
   if ( !f1 || !f2 || !f3 || !f4) return 0;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4);
-  myVolumes.Add(volume);
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = volume;
   myInfo.myNbTetras++;
 
   if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
+    registerElement(myElementIDFactory->GetFreeID(), volume);
+    //RemoveElement(volume, false);
+    //volume = NULL;
   }
   return volume;
 }
@@ -859,7 +1040,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
                                       const SMDS_MeshFace * f4,
                                       const SMDS_MeshFace * f5)
 {
-  if (!hasConstructionFaces())
+     //MESSAGE("AddVolumeWithID");
+ if (!hasConstructionFaces())
     return NULL;
   return AddVolumeWithID(f1,f2,f3,f4,f5, myElementIDFactory->GetFreeID());
 }
@@ -877,17 +1059,20 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
                                             const SMDS_MeshFace * f5,
                                             int ID)
 {
+  MESSAGE("AddVolumeWithID" << ID);
   if (!hasConstructionFaces())
     return NULL;
   if ( !f1 || !f2 || !f3 || !f4 || !f5) return 0;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5);
-  myVolumes.Add(volume);
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = volume;
   myInfo.myNbPyramids++;
 
   if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
+    registerElement(myElementIDFactory->GetFreeID(), volume);
+    //RemoveElement(volume, false);
+    //volume = NULL;
   }
   return volume;
 }
@@ -904,7 +1089,8 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolume(const SMDS_MeshFace * f1,
                                       const SMDS_MeshFace * f5,
                                       const SMDS_MeshFace * f6)
 {
-  if (!hasConstructionFaces())
+     //MESSAGE("AddVolumeWithID" );
+ if (!hasConstructionFaces())
     return NULL;
   return AddVolumeWithID(f1,f2,f3,f4,f5,f6, myElementIDFactory->GetFreeID());
 }
@@ -923,17 +1109,20 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
                                             const SMDS_MeshFace * f6,
                                             int ID)
 {
+  MESSAGE("AddVolumeWithID" << ID);
   if (!hasConstructionFaces())
     return NULL;
   if ( !f1 || !f2 || !f3 || !f4 || !f5 || !f6) return 0;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   SMDS_MeshVolume * volume = new SMDS_VolumeOfFaces(f1,f2,f3,f4,f5,f6);
-  myVolumes.Add(volume);
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = volume;
   myInfo.myNbPrisms++;
 
   if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
+    registerElement(myElementIDFactory->GetFreeID(), volume);
+    //RemoveElement(volume, false);
+    //volume = NULL;
   }
   return volume;
 }
@@ -964,26 +1153,51 @@ SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
 {
   SMDS_MeshFace * face;
 
-  if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  //if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   if (hasConstructionEdges())
-  {
-    MESSAGE("Error : Not implemented");
-    return NULL;
-  }
+    {
+      MESSAGE("Error : Not implemented");
+      return NULL;
+    }
   else
-  {
-    for ( int i = 0; i < nodes.size(); ++i )
-      if ( !nodes[ i ] ) return 0;
-    face = new SMDS_PolygonalFaceOfNodes(nodes);
-    myFaces.Add(face);
-    myInfo.myNbPolygons++;
-  }
+    {
+//#ifdef VTK_HAVE_POLYHEDRON
+    MESSAGE("AddPolygonalFaceWithID vtk " << ID);
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    vector<const SMDS_MeshNode*>::iterator it = nodes.begin();
+    for ( ; it != nodes.end(); ++it)
+      nodeIds.push_back((*it)->getVtkId());
+
+    SMDS_VtkFace *facevtk = myFacePool->getNew();
+    facevtk->initPoly(nodeIds, this);
+    if (!this->registerElement(ID,facevtk))
+      {
+        this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
+        myFacePool->destroy(facevtk);
+        return 0;
+      }
+    face = facevtk;
+//#else
+//    MESSAGE("AddPolygonalFaceWithID smds " << ID);
+//     for ( int i = 0; i < nodes.size(); ++i )
+//      if ( !nodes[ i ] ) return 0;
+//      face = new SMDS_PolygonalFaceOfNodes(nodes);
+//#endif
+      adjustmyCellsCapacity(ID);
+      myCells[ID] = face;
+      myInfo.myNbPolygons++;
+    }
 
-  if (!registerElement(ID, face)) {
-    RemoveElement(face, false);
-    face = NULL;
-  }
-  return face;
+//#ifndef VTK_HAVE_POLYHEDRON
+//  if (!registerElement(ID, face))
+//    {
+//      registerElement(myElementIDFactory->GetFreeID(), face);
+//      //RemoveElement(face, false);
+//      //face = NULL;
+//    }
+//#endif
+ return face;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1026,28 +1240,58 @@ SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
 SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
                             (vector<const SMDS_MeshNode*> nodes,
                              vector<int>                  quantities,
-                             const int                         ID)
+                             const int                    ID)
 {
   SMDS_MeshVolume* volume;
-  if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-  if (hasConstructionFaces()) {
-    MESSAGE("Error : Not implemented");
-    return NULL;
-  } else if (hasConstructionEdges()) {
-    MESSAGE("Error : Not implemented");
-    return NULL;
-  } else {
-    for ( int i = 0; i < nodes.size(); ++i )
-      if ( !nodes[ i ] ) return 0;
-    volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
-    myVolumes.Add(volume);
-    myInfo.myNbPolyhedrons++;
-  }
+  //if ( myVolumes.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+  if (hasConstructionFaces())
+    {
+      MESSAGE("Error : Not implemented");
+      return NULL;
+    }
+  else if (hasConstructionEdges())
+    {
+      MESSAGE("Error : Not implemented");
+      return NULL;
+    }
+  else
+    {
+//#ifdef VTK_HAVE_POLYHEDRON
+      MESSAGE("AddPolyhedralVolumeWithID vtk " << ID);
+      vector<vtkIdType> nodeIds;
+      nodeIds.clear();
+      vector<const SMDS_MeshNode*>::iterator it = nodes.begin();
+      for (; it != nodes.end(); ++it)
+        nodeIds.push_back((*it)->getVtkId());
+
+      SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+      volvtk->initPoly(nodeIds, quantities, this);
+      if (!this->registerElement(ID, volvtk))
+        {
+          this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+          myVolumePool->destroy(volvtk);
+          return 0;
+        }
+      volume = volvtk;
+//#else
+//      MESSAGE("AddPolyhedralVolumeWithID smds " << ID);
+//      for ( int i = 0; i < nodes.size(); ++i )
+//      if ( !nodes[ i ] ) return 0;
+//      volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
+//#endif
+      adjustmyCellsCapacity(ID);
+      myCells[ID] = volume;
+      myInfo.myNbPolyhedrons++;
+    }
 
-  if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
-  }
+//#ifndef VTK_HAVE_POLYHEDRON
+//  if (!registerElement(ID, volume))
+//    {
+//      registerElement(myElementIDFactory->GetFreeID(), volume);
+//      //RemoveElement(volume, false);
+//      //volume = NULL;
+//    }
+//#endif
   return volume;
 }
 
@@ -1066,41 +1310,139 @@ SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
   return v;
 }
 
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIds(const std::vector<int>& vtkNodeIds)
+{
+  int ID = myElementIDFactory->GetFreeID();
+  SMDS_MeshVolume * v = SMDS_Mesh::AddVolumeFromVtkIdsWithID(vtkNodeIds, ID);
+  if (v == NULL) myElementIDFactory->ReleaseID(ID);
+  return v;
+}
+
+SMDS_MeshVolume* SMDS_Mesh::AddVolumeFromVtkIdsWithID(const std::vector<int>& vtkNodeIds, const int ID)
+{
+  SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+  volvtk->init(vtkNodeIds, this);
+  if (!this->registerElement(ID,volvtk))
+    {
+      this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+      myVolumePool->destroy(volvtk);
+      return 0;
+    }
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = volvtk;
+  vtkIdType aVtkType = volvtk->GetVtkType();
+  switch (aVtkType)
+  {
+    case VTK_TETRA:
+      myInfo.myNbTetras++;
+      break;
+    case VTK_PYRAMID:
+      myInfo.myNbPyramids++;
+      break;
+    case VTK_WEDGE:
+      myInfo.myNbPrisms++;
+      break;
+    case VTK_HEXAHEDRON:
+      myInfo.myNbHexas++;
+      break;
+    case VTK_QUADRATIC_TETRA:
+      myInfo.myNbQuadTetras++;
+      break;
+    case VTK_QUADRATIC_PYRAMID:
+      myInfo.myNbQuadPyramids++;
+      break;
+    case VTK_QUADRATIC_WEDGE:
+      myInfo.myNbQuadPrisms++;
+      break;
+    case VTK_QUADRATIC_HEXAHEDRON:
+      myInfo.myNbQuadHexas++;
+      break;
+//#ifdef VTK_HAVE_POLYHEDRON
+    case VTK_POLYHEDRON:
+      myInfo.myNbPolyhedrons++;
+      break;
+//#endif
+    default:
+      myInfo.myNbPolyhedrons++;
+      break;
+  }
+  return volvtk;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 /// Registers element with the given ID, maintains inverse connections
 ///////////////////////////////////////////////////////////////////////////////
-bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element)
+bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement* element)
 {
-  if (myElementIDFactory->BindID(ID, element)) {
-    SMDS_ElemIteratorPtr it = element->nodesIterator();
-    while (it->more()) {
-      SMDS_MeshNode *node = static_cast<SMDS_MeshNode*>
-        (const_cast<SMDS_MeshElement*>(it->next()));
-      node->AddInverseElement(element);
-    }
-    return true;
+  //MESSAGE("registerElement " << ID);
+  if ((ID >=0) && (ID < myCells.size()) && myCells[ID]) // --- already bound
+  {
+    MESSAGE(" ------------------ already bound "<< ID << " " << myCells[ID]->getVtkId());
+    return false;
   }
-  return false;
+
+  element->myID = ID;
+  element->myMeshId = myMeshId;
+
+  SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(element);
+  MYASSERT(cell);
+  int vtkId = cell->getVtkId();  
+  if (vtkId == -1)
+    vtkId = myElementIDFactory->SetInVtkGrid(element);
+
+  if (vtkId >= myCellIdVtkToSmds.size()) // --- resize local vector
+  {
+    MESSAGE(" --------------------- resize myCellIdVtkToSmds " << vtkId << " --> " << vtkId + SMDS_Mesh::chunkSize);
+    myCellIdVtkToSmds.resize(vtkId + SMDS_Mesh::chunkSize, -1);
+  }
+  myCellIdVtkToSmds[vtkId] = ID;
+
+  myElementIDFactory->updateMinMax(ID);
+  return true;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-/// Return the node whose ID is 'ID'.
+/// Return the node whose SMDS ID is 'ID'.
 ///////////////////////////////////////////////////////////////////////////////
 const SMDS_MeshNode * SMDS_Mesh::FindNode(int ID) const
 {
-  return (const SMDS_MeshNode *)myNodeIDFactory->MeshElement(ID);
+  if (ID < 1 || ID >= myNodes.size())
+  {
+    MESSAGE("------------------------------------------------------------------------- ");
+    MESSAGE("----------------------------------- bad ID " << ID << " " << myNodes.size());
+    MESSAGE("------------------------------------------------------------------------- ");
+    return 0;
+  }
+  return (const SMDS_MeshNode *)myNodes[ID];
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-///Create a triangle and add it to the current mesh. This methode do not bind a
+/// Return the node whose VTK ID is 'vtkId'.
+///////////////////////////////////////////////////////////////////////////////
+const SMDS_MeshNode * SMDS_Mesh::FindNodeVtk(int vtkId) const
+{
+  // TODO if needed use mesh->nodeIdFromVtkToSmds
+  if (vtkId < 0 || vtkId >= (myNodes.size() -1))
+  {
+    MESSAGE("------------------------------------------------------------------------- ");
+    MESSAGE("---------------------------- bad VTK ID " << vtkId << " " << myNodes.size());
+    MESSAGE("------------------------------------------------------------------------- ");
+    return 0;
+  }
+  return (const SMDS_MeshNode *)myNodes[vtkId+1];
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///Create a triangle and add it to the current mesh. This method do not bind an
 ///ID to the create triangle.
 ///////////////////////////////////////////////////////////////////////////////
 SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
                                           const SMDS_MeshNode * node2,
-                                          const SMDS_MeshNode * node3)
+                                          const SMDS_MeshNode * node3,
+                                          int ID)
 {
   if ( !node1 || !node2 || !node3) return 0;
-  if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+//  if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   if(hasConstructionEdges())
   {
     SMDS_MeshEdge *edge1, *edge2, *edge3;
@@ -1108,15 +1450,35 @@ SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
     edge2=FindEdgeOrCreate(node2,node3);
     edge3=FindEdgeOrCreate(node3,node1);
 
+    //int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
     SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3);
-    myFaces.Add(face);
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = face;
     myInfo.myNbTriangles++;
     return face;
   }
   else
   {
-    SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3);
-    myFaces.Add(face);
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(node1->getVtkId());
+    nodeIds.push_back(node2->getVtkId());
+    nodeIds.push_back(node3->getVtkId());
+
+    SMDS_MeshFace * face = 0;
+    SMDS_VtkFace *facevtk = myFacePool->getNew();
+    facevtk->init(nodeIds, this); // put in vtkUnstructuredGrid
+    if (!this->registerElement(ID,facevtk))
+      {
+        this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
+        myFacePool->destroy(facevtk);
+        return 0;
+      }
+    face = facevtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = face;
+    //MESSAGE("createTriangle " << ID << " " << face);
     myInfo.myNbTriangles++;
     return face;
   }
@@ -1129,12 +1491,14 @@ SMDS_MeshFace * SMDS_Mesh::createTriangle(const SMDS_MeshNode * node1,
 SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
                                             const SMDS_MeshNode * node2,
                                             const SMDS_MeshNode * node3,
-                                            const SMDS_MeshNode * node4)
+                                            const SMDS_MeshNode * node4,
+                                            int ID)
 {
   if ( !node1 || !node2 || !node3 || !node4 ) return 0;
-  if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+//  if ( myFaces.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
   if(hasConstructionEdges())
   {
+      //MESSAGE("createQuadrangle hasConstructionEdges "<< ID);
     SMDS_MeshEdge *edge1, *edge2, *edge3, *edge4;
     edge1=FindEdgeOrCreate(node1,node2);
     edge2=FindEdgeOrCreate(node2,node3);
@@ -1142,14 +1506,33 @@ SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
     edge4=FindEdgeOrCreate(node4,node1);
 
     SMDS_MeshFace * face = new SMDS_FaceOfEdges(edge1,edge2,edge3,edge4);
-    myFaces.Add(face);
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = face;
     myInfo.myNbQuadrangles++;
     return face;
   }
   else
   {
-    SMDS_MeshFace * face = new SMDS_FaceOfNodes(node1,node2,node3,node4);
-    myFaces.Add(face);
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(node1->getVtkId());
+    nodeIds.push_back(node2->getVtkId());
+    nodeIds.push_back(node3->getVtkId());
+    nodeIds.push_back(node4->getVtkId());
+
+    SMDS_MeshFace * face = 0;
+    SMDS_VtkFace *facevtk = myFacePool->getNew();
+    facevtk->init(nodeIds, this);
+    if (!this->registerElement(ID,facevtk))
+      {
+        this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
+        myFacePool->destroy(facevtk);
+        return 0;
+      }
+    face = facevtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = face;
     myInfo.myNbQuadrangles++;
     return face;
   }
@@ -1161,6 +1544,7 @@ SMDS_MeshFace * SMDS_Mesh::createQuadrangle(const SMDS_MeshNode * node1,
 
 void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
 {
+    MESSAGE("RemoveNode");
         RemoveElement(node, true);
 }
 
@@ -1170,6 +1554,7 @@ void SMDS_Mesh::RemoveNode(const SMDS_MeshNode * node)
 
 void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
 {
+    MESSAGE("Remove0DElement");
   RemoveElement(elem0d,true);
 }
 
@@ -1179,6 +1564,7 @@ void SMDS_Mesh::Remove0DElement(const SMDS_Mesh0DElement * elem0d)
 
 void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
 {
+    MESSAGE("RemoveEdge");
         RemoveElement(edge,true);
 }
 
@@ -1188,6 +1574,7 @@ void SMDS_Mesh::RemoveEdge(const SMDS_MeshEdge * edge)
 
 void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
 {
+    MESSAGE("RemoveFace");
         RemoveElement(face, true);
 }
 
@@ -1197,6 +1584,7 @@ void SMDS_Mesh::RemoveFace(const SMDS_MeshFace * face)
 
 void SMDS_Mesh::RemoveVolume(const SMDS_MeshVolume * volume)
 {
+    MESSAGE("RemoveVolume");
         RemoveElement(volume, true);
 }
 
@@ -1243,58 +1631,21 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
                                    const SMDS_MeshNode    * nodes[],
                                    const int                nbnodes)
 {
+  MESSAGE("SMDS_Mesh::ChangeElementNodes");
   // keep current nodes of elem
   set<const SMDS_MeshElement*> oldNodes;
   SMDS_ElemIteratorPtr itn = element->nodesIterator();
   while(itn->more())
-    oldNodes.insert(  itn->next() );
-
-  if ( !element->IsPoly() )
-    myInfo.remove( element ); // element may change type
+    oldNodes.insert(itn->next());
 
   // change nodes
   bool Ok = false;
-  SMDS_MeshElement* elem = const_cast<SMDS_MeshElement*>(element);
-  switch ( elem->GetType() )
-  {
-  case SMDSAbs_0DElement: {
-    if ( SMDS_Mesh0DElement* elem0d = dynamic_cast<SMDS_Mesh0DElement*>( elem ))
-      Ok = elem0d->ChangeNode( nodes[0] );
-    break;
-  }
-  case SMDSAbs_Edge: {
-    if ( nbnodes == 2 ) {
-      if ( SMDS_MeshEdge* edge = dynamic_cast<SMDS_MeshEdge*>( elem ))
-        Ok = edge->ChangeNodes( nodes[0], nodes[1] );
-    }
-    else if ( nbnodes == 3 ) {
-      if ( SMDS_QuadraticEdge* edge = dynamic_cast<SMDS_QuadraticEdge*>( elem ))
-        Ok = edge->ChangeNodes( nodes[0], nodes[1], nodes[2] );
+  SMDS_MeshCell* cell = dynamic_cast<SMDS_MeshCell*>((SMDS_MeshElement*) element);
+  if (cell)
+    {
+      Ok = cell->vtkOrder(nodes, nbnodes);
+      Ok = cell->ChangeNodes(nodes, nbnodes);
     }
-    break;
-  }
-  case SMDSAbs_Face: {
-    if ( SMDS_FaceOfNodes* face = dynamic_cast<SMDS_FaceOfNodes*>( elem ))
-      Ok = face->ChangeNodes( nodes, nbnodes );
-    else
-      if ( SMDS_QuadraticFaceOfNodes* QF = dynamic_cast<SMDS_QuadraticFaceOfNodes*>( elem ))
-        Ok = QF->ChangeNodes( nodes, nbnodes );
-      else
-        if (SMDS_PolygonalFaceOfNodes* face = dynamic_cast<SMDS_PolygonalFaceOfNodes*>(elem))
-          Ok = face->ChangeNodes(nodes, nbnodes);
-    break;
-  }
-  case SMDSAbs_Volume: {
-    if ( SMDS_VolumeOfNodes* vol = dynamic_cast<SMDS_VolumeOfNodes*>( elem ))
-      Ok = vol->ChangeNodes( nodes, nbnodes );
-    else
-      if ( SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<SMDS_QuadraticVolumeOfNodes*>( elem ))
-        Ok = QV->ChangeNodes( nodes, nbnodes );
-    break;
-  }
-  default:
-    MESSAGE ( "WRONG ELEM TYPE");
-  }
 
   if ( Ok ) { // update InverseElements
 
@@ -1305,7 +1656,7 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
       it = oldNodes.find( nodes[i] );
       if ( it == oldNodes.end() )
         // new node
-        const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( elem );
+        const_cast<SMDS_MeshNode*>( nodes[i] )->AddInverseElement( cell );
       else
         // remove from oldNodes a node that remains in elem
         oldNodes.erase( it );
@@ -1315,13 +1666,10 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
     {
       SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
         (const_cast<SMDS_MeshElement *>( *it ));
-      n->RemoveInverseElement( elem );
+      n->RemoveInverseElement( cell );
     }
   }
 
-  if ( !element->IsPoly() )
-    myInfo.add( element ); // element may change type
-
   return Ok;
 }
 
@@ -1338,7 +1686,7 @@ bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement *            elem,
     return false;
   }
 
-  const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>(elem);
+  const SMDS_VtkVolume* vol = dynamic_cast<const SMDS_VtkVolume*>(elem);
   if (!vol) {
     return false;
   }
@@ -1351,7 +1699,9 @@ bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement *            elem,
   }
 
   // change nodes
-  bool Ok = const_cast<SMDS_PolyhedralVolumeOfNodes*>(vol)->ChangeNodes(nodes, quantities);
+  // TODO remove this function
+  //bool Ok = const_cast<SMDS_VtkVolume*>(vol)->ChangeNodes(nodes, quantities);
+  bool Ok = false;
   if (!Ok) {
     return false;
   }
@@ -1412,19 +1762,19 @@ const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)
 //function : Find0DElementOrCreate
 //purpose  :
 //=======================================================================
-SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
-{
-  if (!node) return 0;
-  SMDS_Mesh0DElement * toReturn = NULL;
-  toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
-  if (toReturn == NULL) {
-    if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
-    toReturn = new SMDS_Mesh0DElement(node);
-    my0DElements.Add(toReturn);
-    myInfo.myNb0DElements++;
-  }
-  return toReturn;
-}
+//SMDS_Mesh0DElement* SMDS_Mesh::Find0DElementOrCreate(const SMDS_MeshNode * node)
+//{
+//  if (!node) return 0;
+//  SMDS_Mesh0DElement * toReturn = NULL;
+//  toReturn = const_cast<SMDS_Mesh0DElement*>(Find0DElement(node));
+//  if (toReturn == NULL) {
+//    //if (my0DElements.Extent() % CHECKMEMORY_INTERVAL == 0) CheckMemory();
+//    toReturn = new SMDS_Mesh0DElement(node);
+//    my0DElements.Add(toReturn);
+//    myInfo.myNb0DElements++;
+//  }
+//  return toReturn;
+//}
 
 
 //=======================================================================
@@ -1475,9 +1825,24 @@ SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
   SMDS_MeshEdge * toReturn=NULL;
   toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
   if(toReturn==NULL) {
-    if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
-    toReturn=new SMDS_MeshEdge(node1,node2);
-    myEdges.Add(toReturn);
+    //if ( myEdges.Extent() % CHECKMEMORY_INTERVAL == 0 ) CheckMemory();
+    int ID = myElementIDFactory->GetFreeID(); // -PR- voir si on range cet element
+    adjustmyCellsCapacity(ID);
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(node1->getVtkId());
+    nodeIds.push_back(node2->getVtkId());
+
+    SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
+    edgevtk->init(nodeIds, this);
+    if (!this->registerElement(ID,edgevtk))
+      {
+        this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
+        myEdgePool->destroy(edgevtk);
+        return 0;
+      }
+    toReturn = edgevtk;
+    myCells[ID] = toReturn;
     myInfo.myNbEdges++;
   }
   return toReturn;
@@ -1574,7 +1939,8 @@ SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
   SMDS_MeshFace * toReturn=NULL;
   toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
   if(toReturn==NULL) {
-    toReturn = createTriangle(node1,node2,node3);
+    int ID = myElementIDFactory->GetFreeID();
+    toReturn = createTriangle(node1,node2,node3, ID);
   }
   return toReturn;
 }
@@ -1632,7 +1998,8 @@ SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
   SMDS_MeshFace * toReturn=NULL;
   toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
   if(toReturn==NULL) {
-    toReturn=createQuadrangle(node1,node2,node3,node4);
+    int ID = myElementIDFactory->GetFreeID();
+    toReturn=createQuadrangle(node1,node2,node3,node4,ID);
   }
   return toReturn;
 }
@@ -1756,7 +2123,16 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
 
 const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
 {
-  return myElementIDFactory->MeshElement(IDelem);
+  if ((IDelem <= 0) || IDelem >= myCells.size())
+  {
+    MESSAGE("--------------------------------------------------------------------------------- ");
+    MESSAGE("----------------------------------- bad IDelem " << IDelem << " " << myCells.size());
+    MESSAGE("--------------------------------------------------------------------------------- ");
+    // TODO raise an exception
+    //assert(0);
+    return 0;
+  }
+  return myCells[IDelem];
 }
 
 //=======================================================================
@@ -1828,7 +2204,7 @@ void SMDS_Mesh::DumpNodes() const
 {
         MESSAGE("dump nodes of mesh : ");
         SMDS_NodeIteratorPtr itnode=nodesIterator();
-        while(itnode->more()) MESSAGE(itnode->next());
+        while(itnode->more()) ; //MESSAGE(itnode->next());
 }
 
 //=======================================================================
@@ -1839,7 +2215,7 @@ void SMDS_Mesh::Dump0DElements() const
 {
   MESSAGE("dump 0D elements of mesh : ");
   SMDS_0DElementIteratorPtr it0d = elements0dIterator();
-  while(it0d->more()) MESSAGE(it0d->next());
+  while(it0d->more()) ; //MESSAGE(it0d->next());
 }
 
 //=======================================================================
@@ -1851,7 +2227,7 @@ void SMDS_Mesh::DumpEdges() const
 {
         MESSAGE("dump edges of mesh : ");
         SMDS_EdgeIteratorPtr itedge=edgesIterator();
-        while(itedge->more()) MESSAGE(itedge->next());
+        while(itedge->more()) ; //MESSAGE(itedge->next());
 }
 
 //=======================================================================
@@ -1863,7 +2239,7 @@ void SMDS_Mesh::DumpFaces() const
 {
         MESSAGE("dump faces of mesh : ");
         SMDS_FaceIteratorPtr itface=facesIterator();
-        while(itface->more()) MESSAGE(itface->next());
+        while(itface->more()) ; //MESSAGE(itface->next());
 }
 
 //=======================================================================
@@ -1875,7 +2251,7 @@ void SMDS_Mesh::DumpVolumes() const
 {
         MESSAGE("dump volumes of mesh : ");
         SMDS_VolumeIteratorPtr itvol=volumesIterator();
-        while(itvol->more()) MESSAGE(itvol->next());
+        while(itvol->more()) ; //MESSAGE(itvol->next());
 }
 
 //=======================================================================
@@ -1933,7 +2309,10 @@ void SMDS_Mesh::DebugStats() const
 ///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::NbNodes() const
 {
-        return myNodes.Size();
+       //MESSAGE(myGrid->GetNumberOfPoints());
+       //MESSAGE(myInfo.NbNodes());
+       //MESSAGE(myNodeMax);
+    return myInfo.NbNodes();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1941,7 +2320,7 @@ int SMDS_Mesh::NbNodes() const
 ///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::Nb0DElements() const
 {
-  return my0DElements.Size();
+  return myInfo.Nb0DElements(); // -PR- a verfier
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1949,7 +2328,7 @@ int SMDS_Mesh::Nb0DElements() const
 ///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::NbEdges() const
 {
-        return myEdges.Size();
+        return myInfo.NbEdges(); // -PR- a verfier
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1957,7 +2336,7 @@ int SMDS_Mesh::NbEdges() const
 ///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::NbFaces() const
 {
-        return myFaces.Size();
+        return myInfo.NbFaces();  // -PR- a verfier
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -1965,7 +2344,7 @@ int SMDS_Mesh::NbFaces() const
 ///////////////////////////////////////////////////////////////////////////////
 int SMDS_Mesh::NbVolumes() const
 {
-        return myVolumes.Size();
+        return myInfo.NbVolumes(); // -PR- a verfier
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -2000,43 +2379,49 @@ SMDS_Mesh::~SMDS_Mesh()
   {
     SMDS_ElemIteratorPtr eIt = elementsIterator();
     while ( eIt->more() )
-      myElementIDFactory->ReleaseID(eIt->next()->GetID());
+      {
+        const SMDS_MeshElement *elem = eIt->next();
+        myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
+      }
     SMDS_NodeIteratorPtr itn = nodesIterator();
     while (itn->more())
-      myNodeIDFactory->ReleaseID(itn->next()->GetID());
+      {
+        const SMDS_MeshNode *node = itn->next();
+        myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
+      }
   }
 
-  SetOfNodes::Iterator itn(myNodes);
-  for (; itn.More(); itn.Next())
-    delete itn.Value();
+//   SetOfNodes::Iterator itn(myNodes);
+//   for (; itn.More(); itn.Next())
+//     delete itn.Value();
 
-  SetOf0DElements::Iterator it0d (my0DElements);
-  for (; it0d.More(); it0d.Next())
-  {
-    SMDS_MeshElement* elem = it0d.Value();
-    delete elem;
-  }
+//   SetOf0DElements::Iterator it0d (my0DElements);
+//   for (; it0d.More(); it0d.Next())
+//   {
+//     SMDS_MeshElement* elem = it0d.Value();
+//     delete elem;
+//   }
 
-  SetOfEdges::Iterator ite(myEdges);
-  for (; ite.More(); ite.Next())
-  {
-    SMDS_MeshElement* elem = ite.Value();
-    delete elem;
-  }
+//   SetOfEdges::Iterator ite(myEdges);
+//   for (; ite.More(); ite.Next())
+//   {
+//     SMDS_MeshElement* elem = ite.Value();
+//     delete elem;
+//   }
 
-  SetOfFaces::Iterator itf(myFaces);
-  for (; itf.More(); itf.Next())
-  {
-    SMDS_MeshElement* elem = itf.Value();
-    delete elem;
-  }
+//   SetOfFaces::Iterator itf(myFaces);
+//   for (; itf.More(); itf.Next())
+//   {
+//     SMDS_MeshElement* elem = itf.Value();
+//     delete elem;
+//   }
 
-  SetOfVolumes::Iterator itv(myVolumes);
-  for (; itv.More(); itv.Next())
-  {
-    SMDS_MeshElement* elem = itv.Value();
-    delete elem;
-  }
+//   SetOfVolumes::Iterator itv(myVolumes);
+//   for (; itv.More(); itv.Next())
+//   {
+//     SMDS_MeshElement* elem = itv.Value();
+//     delete elem;
+//   }
 }
 
 //================================================================================
@@ -2047,49 +2432,81 @@ SMDS_Mesh::~SMDS_Mesh()
 
 void SMDS_Mesh::Clear()
 {
-  if (myParent!=NULL) {
+  MESSAGE("SMDS_Mesh::Clear");
+  if (myParent!=NULL)
+    {
     SMDS_ElemIteratorPtr eIt = elementsIterator();
     while ( eIt->more() )
-      myElementIDFactory->ReleaseID(eIt->next()->GetID());
+      {
+        const SMDS_MeshElement *elem = eIt->next();
+        myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId());
+      }
     SMDS_NodeIteratorPtr itn = nodesIterator();
     while (itn->more())
-      myNodeIDFactory->ReleaseID(itn->next()->GetID());
-  }
-  else {
+      {
+        const SMDS_MeshNode *node = itn->next();
+        myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId());
+      }
+    }
+  else
+    {
     myNodeIDFactory->Clear();
     myElementIDFactory->Clear();
-  }
+    }
 
-  SMDS_VolumeIteratorPtr itv = volumesIterator();
+  SMDS_ElemIteratorPtr itv = elementsIterator();
   while (itv->more())
-    delete itv->next();
-  myVolumes.Clear();
-
-  SMDS_FaceIteratorPtr itf = facesIterator();
-  while (itf->more())
-    delete itf->next();
-  myFaces.Clear();
-
-  SMDS_EdgeIteratorPtr ite = edgesIterator();
-  while (ite->more())
-    delete ite->next();
-  myEdges.Clear();
-
-  SMDS_0DElementIteratorPtr it0d = elements0dIterator();
-  while (it0d->more())
-    delete it0d->next();
-  my0DElements.Clear();
+    {
+      SMDS_MeshElement* elem = (SMDS_MeshElement*)(itv->next());
+      SMDSAbs_ElementType aType = elem->GetType();
+      switch (aType)
+      {
+        case SMDSAbs_0DElement:
+          delete elem;
+          break;
+        case SMDSAbs_Edge:
+           myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(elem));
+          break;
+        case SMDSAbs_Face:
+          myFacePool->destroy(static_cast<SMDS_VtkFace*>(elem));
+          break;
+        case SMDSAbs_Volume:
+          myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(elem));
+          break;
+        default:
+          break;
+      }
+    }
+  myCells.clear();
+  myCellIdVtkToSmds.clear();
+  //myCellIdSmdsToVtk.clear();
 
   SMDS_NodeIteratorPtr itn = nodesIterator();
   while (itn->more())
-    delete itn->next();
-  myNodes.Clear();
+    {
+      SMDS_MeshNode *node = (SMDS_MeshNode*)(itn->next());
+      myNodePool->destroy(node);
+    }
+  myNodes.clear();
 
   list<SMDS_Mesh*>::iterator itc=myChildren.begin();
   while(itc!=myChildren.end())
     (*itc)->Clear();
 
+  myModified = false;
+  xmin = 0; xmax = 0;
+  ymin = 0; ymax = 0;
+  zmin = 0; zmax = 0;
+
   myInfo.Clear();
+
+  myGrid->Initialize();
+  myGrid->Allocate();
+  vtkPoints* points = vtkPoints::New();
+  points->SetNumberOfPoints(SMDS_Mesh::chunkSize);
+  myGrid->SetPoints( points );
+  points->Delete();
+  myGrid->BuildLinks();
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -2153,35 +2570,78 @@ void SMDS_Mesh::setInverseElements(bool b)
 
 namespace {
 
-  ///////////////////////////////////////////////////////////////////////////////
-  ///Iterator on NCollection_Map
-  ///////////////////////////////////////////////////////////////////////////////
-  template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
-  struct MYNCollection_Map_Iterator: public FATHER
+///////////////////////////////////////////////////////////////////////////////
+///Iterator on NCollection_Map
+///////////////////////////////////////////////////////////////////////////////
+template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
+struct MYNode_Map_Iterator: public FATHER
+{
+  int _ctr;
+  const MAP& _map;
+  MYNode_Map_Iterator(const MAP& map): _map(map) // map is a std::vector<ELEM>
   {
-    typename MAP::Iterator myIterator;
+      _ctr = 0;
+  }
 
-    MYNCollection_Map_Iterator(const MAP& map):myIterator(map){}
+  bool more()
+  {
+      while (_ctr < _map.size())
+      {
+          if (_map[_ctr])
+              return true;
+          _ctr++;
+      }
+          return false;
+  }
 
-    bool more()
-    {
-      while(myIterator.More())
+  ELEM next()
+  {
+    ELEM current = _map[_ctr];
+    _ctr++;
+    return current;
+  }
+};
+
+template <class MAP, typename ELEM=const SMDS_MeshElement*, class FATHER=SMDS_ElemIterator>
+struct MYElem_Map_Iterator: public FATHER
+{
+  int _ctr;
+  int _type;
+  const MAP& _map;
+  MYElem_Map_Iterator(const MAP& map, int typ): _map(map) // map is a std::vector<ELEM>
+  {
+      _ctr = 0;
+      _type = typ;
+      while (_ctr < _map.size()) // go to the first valid element
       {
-        if(myIterator.Value()->GetID()!=-1)
-          return true;
-        myIterator.Next();
+          if (_map[_ctr])
+            if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type))
+              break;
+          _ctr++;
       }
-      return false;
-    }
+  }
 
-    ELEM next()
-    {
-      ELEM current = (ELEM) myIterator.Value();
-      myIterator.Next();
-      return current;
-    }
-  };
-  //================================================================================
+bool more()
+  {
+      while (_ctr < _map.size())
+      {
+          if (_map[_ctr])
+            if ( (_type == SMDSAbs_All) || (_map[_ctr]->GetType() == _type))
+              return true;
+          _ctr++;
+      }
+          return false;
+  }
+
+  ELEM next()
+  {
+    ELEM current = dynamic_cast<ELEM> (_map[_ctr]);
+    _ctr++;
+    return current;
+  }
+};
+
+//================================================================================
   /*!
    * \brief Iterator on elements in id increasing order
    */
@@ -2232,12 +2692,14 @@ namespace {
 
 SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const
 {
-  typedef MYNCollection_Map_Iterator
+  typedef MYNode_Map_Iterator
     < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator;
-  typedef IdSortedIterator< const SMDS_MeshNode* >          TSortedIterator;
-  return ( idInceasingOrder ?
-           SMDS_NodeIteratorPtr( new TSortedIterator( *myNodeIDFactory, SMDSAbs_Node, NbNodes())) :
-           SMDS_NodeIteratorPtr( new TIterator(myNodes)));
+  return SMDS_NodeIteratorPtr( new TIterator(myNodes)); // naturally always sorted by ID
+
+//  typedef IdSortedIterator< const SMDS_MeshNode* >          TSortedIterator;
+//  return ( idInceasingOrder ?
+//           SMDS_NodeIteratorPtr( new TSortedIterator( *myNodeIDFactory, SMDSAbs_Node, NbNodes())) :
+//           SMDS_NodeIteratorPtr( new TIterator(myNodes)));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -2246,14 +2708,18 @@ SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const
 
 SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator(bool idInceasingOrder) const
 {
-  typedef MYNCollection_Map_Iterator
-    < SetOf0DElements, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
-  typedef IdSortedIterator< const SMDS_Mesh0DElement* >                    TSortedIterator;
-  return ( idInceasingOrder ?
-           SMDS_0DElementIteratorPtr( new TSortedIterator( *myElementIDFactory,
-                                                           SMDSAbs_0DElement,
-                                                           Nb0DElements() )) :
-           SMDS_0DElementIteratorPtr( new TIterator(my0DElements)));
+  typedef MYElem_Map_Iterator
+    < SetOfCells, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
+  return SMDS_0DElementIteratorPtr(new TIterator(myCells, SMDSAbs_0DElement)); // naturally always sorted by ID
+
+//  typedef MYNCollection_Map_Iterator
+//    < SetOf0DElements, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator;
+//  typedef IdSortedIterator< const SMDS_Mesh0DElement* >                    TSortedIterator;
+//  return ( idInceasingOrder ?
+//           SMDS_0DElementIteratorPtr( new TSortedIterator( *myElementIDFactory,
+//                                                           SMDSAbs_0DElement,
+//                                                           Nb0DElements() )) :
+//           SMDS_0DElementIteratorPtr( new TIterator(my0DElements)));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -2262,14 +2728,18 @@ SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator(bool idInceasingOrder) c
 
 SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const
 {
-  typedef MYNCollection_Map_Iterator
-    < SetOfEdges, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
-  typedef IdSortedIterator< const SMDS_MeshEdge* >          TSortedIterator;
-  return ( idInceasingOrder ?
-           SMDS_EdgeIteratorPtr( new TSortedIterator( *myElementIDFactory,
-                                                      SMDSAbs_Edge,
-                                                      NbEdges() )) :
-           SMDS_EdgeIteratorPtr(new TIterator(myEdges)));
+  typedef MYElem_Map_Iterator
+    < SetOfCells, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
+  return SMDS_EdgeIteratorPtr(new TIterator(myCells, SMDSAbs_Edge)); // naturally always sorted by ID
+
+//  typedef MYNCollection_Map_Iterator
+//    < SetOfEdges, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator;
+//  typedef IdSortedIterator< const SMDS_MeshEdge* >          TSortedIterator;
+//  return ( idInceasingOrder ?
+//           SMDS_EdgeIteratorPtr( new TSortedIterator( *myElementIDFactory,
+//                                                      SMDSAbs_Edge,
+//                                                      NbEdges() )) :
+//           SMDS_EdgeIteratorPtr(new TIterator(myEdges)));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -2278,14 +2748,18 @@ SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const
 
 SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const
 {
-  typedef MYNCollection_Map_Iterator
-    < SetOfFaces, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
-  typedef IdSortedIterator< const SMDS_MeshFace* >          TSortedIterator;
-  return ( idInceasingOrder ?
-           SMDS_FaceIteratorPtr( new TSortedIterator( *myElementIDFactory,
-                                                      SMDSAbs_Face,
-                                                      NbFaces() )) :
-           SMDS_FaceIteratorPtr(new TIterator(myFaces)));
+  typedef MYElem_Map_Iterator
+    < SetOfCells, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
+  return SMDS_FaceIteratorPtr(new TIterator(myCells, SMDSAbs_Face)); // naturally always sorted by ID
+
+//  typedef MYNCollection_Map_Iterator
+//    < SetOfFaces, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator;
+//  typedef IdSortedIterator< const SMDS_MeshFace* >          TSortedIterator;
+//  return ( idInceasingOrder ?
+//           SMDS_FaceIteratorPtr( new TSortedIterator( *myElementIDFactory,
+//                                                      SMDSAbs_Face,
+//                                                      NbFaces() )) :
+//           SMDS_FaceIteratorPtr(new TIterator(myFaces)));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -2294,14 +2768,18 @@ SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const
 
 SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator(bool idInceasingOrder) const
 {
-  typedef MYNCollection_Map_Iterator
-    < SetOfVolumes, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
-  typedef IdSortedIterator< const SMDS_MeshVolume* >              TSortedIterator;
-  return ( idInceasingOrder ?
-           SMDS_VolumeIteratorPtr( new TSortedIterator( *myElementIDFactory,
-                                                        SMDSAbs_Volume,
-                                                        NbVolumes() )) :
-           SMDS_VolumeIteratorPtr(new TIterator(myVolumes)));
+  typedef MYElem_Map_Iterator
+    < SetOfCells, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
+  return SMDS_VolumeIteratorPtr(new TIterator(myCells, SMDSAbs_Volume)); // naturally always sorted by ID
+
+  //  typedef MYNCollection_Map_Iterator
+//    < SetOfVolumes, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator;
+//  typedef IdSortedIterator< const SMDS_MeshVolume* >              TSortedIterator;
+//  return ( idInceasingOrder ?
+//           SMDS_VolumeIteratorPtr( new TSortedIterator( *myElementIDFactory,
+//                                                        SMDSAbs_Volume,
+//                                                        NbVolumes() )) :
+//           SMDS_VolumeIteratorPtr(new TIterator(myVolumes)));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -2311,17 +2789,19 @@ SMDS_ElemIteratorPtr SMDS_Mesh::elementsIterator(SMDSAbs_ElementType type) const
 {
   switch (type) {
   case SMDSAbs_All:
+    return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_All));
     break;
   case SMDSAbs_Volume:
-    return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOfVolumes >(myVolumes));
+    return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Volume));
   case SMDSAbs_Face:
-    return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOfFaces >(myFaces));
+    return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Face));
   case SMDSAbs_Edge:
-    return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOfEdges >(myEdges));
+    return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_Edge));
   case SMDSAbs_0DElement:
-    return SMDS_ElemIteratorPtr (new MYNCollection_Map_Iterator< SetOf0DElements >(my0DElements));
+    return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfCells >(myCells, SMDSAbs_0DElement));
   case SMDSAbs_Node:
-    return myNodeIDFactory->elementsIterator();
+    return SMDS_ElemIteratorPtr (new MYElem_Map_Iterator< SetOfNodes >(myNodes, SMDSAbs_All));
+    //return myNodeIDFactory->elementsIterator();
   default:;
   }
   return myElementIDFactory->elementsIterator();
@@ -2350,7 +2830,9 @@ static set<const SMDS_MeshElement*> * intersectionOfSets(
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-/// Return the list of finit elements owning the given element
+/// Return the list of finite elements owning the given element: elements
+/// containing all the nodes of the given element, for instance faces and
+/// volumes containing a given edge.
 ///////////////////////////////////////////////////////////////////////////////
 static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement * element)
 {
@@ -2362,16 +2844,24 @@ static set<const SMDS_MeshElement*> * getFinitElements(const SMDS_MeshElement *
         int i=0;
         while(itNodes->more())
         {
-                const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(itNodes->next());
+          const SMDS_MeshElement* node = itNodes->next();
+          MYASSERT(node);
+                const SMDS_MeshNode * n=static_cast<const SMDS_MeshNode*>(node);
                 SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
 
                 //initSet[i]=set<const SMDS_MeshElement*>();
                 while(itFe->more())
-                  initSet[i].insert(itFe->next());
+                {
+                  const SMDS_MeshElement* elem = itFe->next();
+                  MYASSERT(elem);
+                  initSet[i].insert(elem);
+
+                }
 
                 i++;
         }
         set<const SMDS_MeshElement*> *retSet=intersectionOfSets(initSet, numberOfSets);
+        MESSAGE("nb elems " << i << " intersection " << retSet->size());
         delete [] initSet;
         return retSet;
 }
@@ -2416,7 +2906,7 @@ void SMDS_Mesh::addChildrenWithNodes(set<const SMDS_MeshElement*>& setOfChildren
   switch(element->GetType())
     {
     case SMDSAbs_Node:
-      MESSAGE("Internal Error: This should not happend");
+      MESSAGE("Internal Error: This should not happen");
       break;
     case SMDSAbs_0DElement:
       {
@@ -2486,8 +2976,8 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
 
 ///////////////////////////////////////////////////////////////////////////////
 ///@param elem The element to delete
-///@param removedElems contains all removed elements
-///@param removedNodes contains all removed nodes
+///@param removedElems to be filled with all removed elements
+///@param removedNodes to be filled with all removed nodes
 ///@param removenodes if true remaining nodes will be removed
 ///////////////////////////////////////////////////////////////////////////////
 void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
@@ -2495,105 +2985,143 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
                               list<const SMDS_MeshElement *>& removedNodes,
                               bool                            removenodes)
 {
+  //MESSAGE("SMDS_Mesh::RemoveElement " << elem->getVtkId() << " " << removenodes);
   // get finite elements built on elem
   set<const SMDS_MeshElement*> * s1;
-  if (elem->GetType() == SMDSAbs_0DElement ||
-      elem->GetType() == SMDSAbs_Edge && !hasConstructionEdges() ||
-      elem->GetType() == SMDSAbs_Face && !hasConstructionFaces() ||
-      elem->GetType() == SMDSAbs_Volume)
-  {
-    s1 = new set<const SMDS_MeshElement*>();
-    s1->insert(elem);
-  }
+  if (elem->GetType() == SMDSAbs_0DElement || elem->GetType() == SMDSAbs_Edge && !hasConstructionEdges()
+      || elem->GetType() == SMDSAbs_Face && !hasConstructionFaces() || elem->GetType() == SMDSAbs_Volume)
+    {
+      s1 = new set<const SMDS_MeshElement*> ();
+      s1->insert(elem);
+    }
   else
     s1 = getFinitElements(elem);
 
   // get exclusive nodes (which would become free afterwards)
   set<const SMDS_MeshElement*> * s2;
   if (elem->GetType() == SMDSAbs_Node) // a node is removed
-  {
-    // do not remove nodes except elem
-    s2 = new set<const SMDS_MeshElement*>();
-    s2->insert(elem);
-    removenodes = true;
-  }
+    {
+      // do not remove nodes except elem
+      s2 = new set<const SMDS_MeshElement*> ();
+      s2->insert(elem);
+      removenodes = true;
+    }
   else
     s2 = getExclusiveNodes(*s1);
 
   // form the set of finite and construction elements to remove
   set<const SMDS_MeshElement*> s3;
-  set<const SMDS_MeshElement*>::iterator it=s1->begin();
-  while(it!=s1->end())
-  {
-    addChildrenWithNodes(s3, *it ,*s2);
-    s3.insert(*it);
-    it++;
-  }
-  if(elem->GetType()!=SMDSAbs_Node) s3.insert(elem);
-
-  // remove finite and construction elements
-  it=s3.begin();
-  while(it!=s3.end())
-  {
-    // Remove element from <InverseElements> of its nodes
-    SMDS_ElemIteratorPtr itn=(*it)->nodesIterator();
-    while(itn->more())
+  set<const SMDS_MeshElement*>::iterator it = s1->begin();
+  while (it != s1->end())
     {
-      SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
-        (const_cast<SMDS_MeshElement *>(itn->next()));
-      n->RemoveInverseElement( (*it) );
+      addChildrenWithNodes(s3, *it, *s2);
+      s3.insert(*it);
+      it++;
     }
+  if (elem->GetType() != SMDSAbs_Node)
+    s3.insert(elem);
 
-    switch((*it)->GetType())
+  // remove finite and construction elements
+  it = s3.begin();
+  while (it != s3.end())
     {
-    case SMDSAbs_Node:
-      MESSAGE("Internal Error: This should not happen");
-      break;
-    case SMDSAbs_0DElement:
-      my0DElements.Remove(static_cast<SMDS_Mesh0DElement*>
-                          (const_cast<SMDS_MeshElement*>(*it)));
-      //myInfo.Remove0DElement(*it);
-      myInfo.remove(*it);
-      break;
-    case SMDSAbs_Edge:
-      myEdges.Remove(static_cast<SMDS_MeshEdge*>
-                    (const_cast<SMDS_MeshElement*>(*it)));
-      myInfo.RemoveEdge(*it);
-      break;
-    case SMDSAbs_Face:
-      myFaces.Remove(static_cast<SMDS_MeshFace*>
-                    (const_cast<SMDS_MeshElement*>(*it)));
-      myInfo.RemoveFace(*it);
-      break;
-    case SMDSAbs_Volume:
-      myVolumes.Remove(static_cast<SMDS_MeshVolume*>
-                      (const_cast<SMDS_MeshElement*>(*it)));
-      myInfo.RemoveVolume(*it);
-      break;
+      // Remove element from <InverseElements> of its nodes
+      SMDS_ElemIteratorPtr itn = (*it)->nodesIterator();
+      while (itn->more())
+        {
+          SMDS_MeshNode * n = static_cast<SMDS_MeshNode *> (const_cast<SMDS_MeshElement *> (itn->next()));
+          n->RemoveInverseElement((*it));
+        }
+      int IdToRemove = (*it)->GetID();
+      int vtkid = (*it)->getVtkId();
+      //MESSAGE("elem Id to remove " << IdToRemove << " vtkid " << vtkid <<
+      //        " vtktype " << (*it)->GetVtkType() << " type " << (*it)->GetType());
+      switch ((*it)->GetType())
+      {
+        case SMDSAbs_Node:
+          MYASSERT("Internal Error: This should not happen")
+          ;
+          break;
+        case SMDSAbs_0DElement:
+          if (IdToRemove >= 0)
+            {
+              myCells[IdToRemove] = 0; // -PR- ici ou dans myElementIDFactory->ReleaseID ?
+              myInfo.remove(*it);
+            }
+          removedElems.push_back((*it));
+          myElementIDFactory->ReleaseID(IdToRemove, vtkid);
+          delete (*it);
+          break;
+        case SMDSAbs_Edge:
+          if (IdToRemove >= 0)
+            {
+              myCells[IdToRemove] = 0;
+              myInfo.RemoveEdge(*it);
+            }
+          removedElems.push_back((*it));
+          myElementIDFactory->ReleaseID(IdToRemove, vtkid);
+          if (const SMDS_VtkEdge* vtkElem = dynamic_cast<const SMDS_VtkEdge*>(*it))
+            myEdgePool->destroy((SMDS_VtkEdge*) vtkElem);
+          else
+            delete (*it);
+          break;
+        case SMDSAbs_Face:
+          if (IdToRemove >= 0)
+            {
+              myCells[IdToRemove] = 0;
+              myInfo.RemoveFace(*it);
+            }
+          removedElems.push_back((*it));
+          myElementIDFactory->ReleaseID(IdToRemove, vtkid);
+          if (const SMDS_VtkFace* vtkElem = dynamic_cast<const SMDS_VtkFace*>(*it))
+            myFacePool->destroy((SMDS_VtkFace*) vtkElem);
+          else
+            delete (*it);
+          break;
+        case SMDSAbs_Volume:
+          if (IdToRemove >= 0)
+            {
+              myCells[IdToRemove] = 0;
+              myInfo.RemoveVolume(*it);
+            }
+          removedElems.push_back((*it));
+          myElementIDFactory->ReleaseID(IdToRemove, vtkid);
+          if (const SMDS_VtkVolume* vtkElem = dynamic_cast<const SMDS_VtkVolume*>(*it))
+            myVolumePool->destroy((SMDS_VtkVolume*) vtkElem);
+          else
+            delete (*it);
+          break;
+      }
+      if (vtkid >= 0)
+        {
+          //MESSAGE("VTK_EMPTY_CELL in " << vtkid);
+          this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
+        }
+      it++;
     }
-    //MESSAGE( "SMDS: RM elem " << (*it)->GetID() );
-    removedElems.push_back( (*it) );
-    myElementIDFactory->ReleaseID((*it)->GetID());
-    delete (*it);
-    it++;
-  }
 
   // remove exclusive (free) nodes
-  if(removenodes)
-  {
-    it=s2->begin();
-    while(it!=s2->end())
+  if (removenodes)
     {
-      //MESSAGE( "SMDS: RM node " << (*it)->GetID() );
-      myNodes.Remove(static_cast<SMDS_MeshNode*>
-                    (const_cast<SMDS_MeshElement*>(*it)));
-      myInfo.myNbNodes--;
-      myNodeIDFactory->ReleaseID((*it)->GetID());
-      removedNodes.push_back( (*it) );
-      delete *it;
-      it++;
+      it = s2->begin();
+      while (it != s2->end())
+        {
+          int IdToRemove = (*it)->GetID();
+          //MESSAGE( "SMDS: RM node " << IdToRemove);
+          if (IdToRemove >= 0)
+            {
+              myNodes[IdToRemove] = 0;
+              myInfo.myNbNodes--;
+            }
+          myNodeIDFactory->ReleaseID((*it)->GetID(), (*it)->getVtkId());
+          removedNodes.push_back((*it));
+          if (const SMDS_MeshNode* vtkElem = dynamic_cast<const SMDS_MeshNode*>(*it))
+            myNodePool->destroy((SMDS_MeshNode*) vtkElem);
+          else
+            delete (*it);
+          it++;
+        }
     }
-  }
 
   delete s2;
   delete s1;
@@ -2605,22 +3133,28 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
 ///////////////////////////////////////////////////////////////////////////////
 void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
 {
+  int elemId = elem->GetID();
+  int vtkId = elem->getVtkId();
+  //MESSAGE("RemoveFreeElement " << elemId);
   SMDSAbs_ElementType aType = elem->GetType();
+  SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem);
   if (aType == SMDSAbs_Node) {
+    //MESSAGE("Remove free node " << elemId);
     // only free node can be removed by this method
-    const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>(elem);
+    const SMDS_MeshNode* n = static_cast<SMDS_MeshNode*>(todest);
     SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator();
     if (!itFe->more()) { // free node
-      myNodes.Remove(const_cast<SMDS_MeshNode*>(n));
+      myNodes[elemId] = 0;
       myInfo.myNbNodes--;
-      myNodeIDFactory->ReleaseID(elem->GetID());
-      delete elem;
+      myNodePool->destroy(static_cast<SMDS_MeshNode*>(todest));
+      myNodeIDFactory->ReleaseID(elemId, vtkId);
     }
   } else {
     if (hasConstructionEdges() || hasConstructionFaces())
       // this methods is only for meshes without descendants
       return;
 
+    //MESSAGE("Remove free element " << elemId);
     // Remove element from <InverseElements> of its nodes
     SMDS_ElemIteratorPtr itn = elem->nodesIterator();
     while (itn->more()) {
@@ -2630,33 +3164,34 @@ void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
     }
 
     // in meshes without descendants elements are always free
-    switch (aType) {
+     switch (aType) {
     case SMDSAbs_0DElement:
-      my0DElements.Remove(static_cast<SMDS_Mesh0DElement*>
-                          (const_cast<SMDS_MeshElement*>(elem)));
-      //myInfo.Remove0DElement(elem);
+      myCells[elemId] = 0;
       myInfo.remove(elem);
+      delete elem;
       break;
     case SMDSAbs_Edge:
-      myEdges.Remove(static_cast<SMDS_MeshEdge*>
-                     (const_cast<SMDS_MeshElement*>(elem)));
+      myCells[elemId] = 0;
       myInfo.RemoveEdge(elem);
+      myEdgePool->destroy(static_cast<SMDS_VtkEdge*>(todest));
       break;
     case SMDSAbs_Face:
-      myFaces.Remove(static_cast<SMDS_MeshFace*>
-                     (const_cast<SMDS_MeshElement*>(elem)));
+      myCells[elemId] = 0;
       myInfo.RemoveFace(elem);
+      myFacePool->destroy(static_cast<SMDS_VtkFace*>(todest));
       break;
     case SMDSAbs_Volume:
-      myVolumes.Remove(static_cast<SMDS_MeshVolume*>
-                       (const_cast<SMDS_MeshElement*>(elem)));
+      myCells[elemId] = 0;
       myInfo.RemoveVolume(elem);
+      myVolumePool->destroy(static_cast<SMDS_VtkVolume*>(todest));
       break;
     default:
       break;
     }
-    myElementIDFactory->ReleaseID(elem->GetID());
-    delete elem;
+    myElementIDFactory->ReleaseID(elemId, vtkId);
+
+    this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL);
+    // --- to do: keep vtkid in a list of reusable cells
   }
 }
 
@@ -2698,7 +3233,7 @@ bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const
 
 int SMDS_Mesh::MaxNodeID() const
 {
-  return myNodeIDFactory->GetMaxID();
+  return myNodeMax;
 }
 
 //=======================================================================
@@ -2708,7 +3243,7 @@ int SMDS_Mesh::MaxNodeID() const
 
 int SMDS_Mesh::MinNodeID() const
 {
-  return myNodeIDFactory->GetMinID();
+  return myNodeMin;
 }
 
 //=======================================================================
@@ -2738,10 +3273,11 @@ int SMDS_Mesh::MinElementID() const
 
 void SMDS_Mesh::Renumber (const bool isNodes, const int  startID, const int  deltaID)
 {
+    MESSAGE("Renumber");
   if ( deltaID == 0 )
     return;
 
-  SMDS_MeshElementIDFactory * idFactory =
+  SMDS_MeshNodeIDFactory * idFactory =
     isNodes ? myNodeIDFactory : myElementIDFactory;
 
   // get existing elements in the order of ID increasing
@@ -2836,23 +3372,34 @@ SMDS_MeshEdge* SMDS_Mesh::AddEdgeWithID(const SMDS_MeshNode * n1,
                                         int ID)
 {
   if ( !n1 || !n2 || !n12 ) return 0;
-  SMDS_QuadraticEdge* edge = new SMDS_QuadraticEdge(n1,n2,n12);
-  if(myElementIDFactory->BindID(ID, edge)) {
-    SMDS_MeshNode *node1,*node2, *node12;
-    node1 = const_cast<SMDS_MeshNode*>(n1);
-    node2 = const_cast<SMDS_MeshNode*>(n2);
-    node12 = const_cast<SMDS_MeshNode*>(n12);
-    node1->AddInverseElement(edge);
-    node2->AddInverseElement(edge);
-    node12->AddInverseElement(edge);
-    myEdges.Add(edge);
-    myInfo.myNbQuadEdges++;
-    return edge;
-  }
-  else {
-    delete edge;
-    return NULL;
-  }
+
+  // --- retrieve nodes ID
+  vector<vtkIdType> nodeIds;
+  nodeIds.clear();
+  nodeIds.push_back(n1->getVtkId());
+  nodeIds.push_back(n2->getVtkId());
+  nodeIds.push_back(n12->getVtkId());
+
+  SMDS_MeshEdge * edge = 0;
+  SMDS_VtkEdge *edgevtk = myEdgePool->getNew();
+  edgevtk->init(nodeIds, this);
+  if (!this->registerElement(ID,edgevtk))
+    {
+      this->myGrid->GetCellTypesArray()->SetValue(edgevtk->getVtkId(), VTK_EMPTY_CELL);
+      myEdgePool->destroy(edgevtk);
+      return 0;
+    }
+  edge = edgevtk;
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = edge;
+  myInfo.myNbQuadEdges++;
+
+//  if (!registerElement(ID, edge)) {
+//       RemoveElement(edge, false);
+//       edge = NULL;
+//  }
+  return edge;
+
 }
 
 
@@ -2905,16 +3452,38 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
     // creation quadratic edges - not implemented
     return 0;
   }
-  SMDS_QuadraticFaceOfNodes* face =
-    new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n12,n23,n31);
-  myFaces.Add(face);
-  myInfo.myNbQuadTriangles++;
-
-  if (!registerElement(ID, face)) {
-    RemoveElement(face, false);
-    face = NULL;
+  else
+  {
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(n1->getVtkId());
+    nodeIds.push_back(n2->getVtkId());
+    nodeIds.push_back(n3->getVtkId());
+    nodeIds.push_back(n12->getVtkId());
+    nodeIds.push_back(n23->getVtkId());
+    nodeIds.push_back(n31->getVtkId());
+
+    SMDS_MeshFace * face = 0;
+    SMDS_VtkFace *facevtk = myFacePool->getNew();
+    facevtk->init(nodeIds, this);
+    if (!this->registerElement(ID,facevtk))
+      {
+        this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
+        myFacePool->destroy(facevtk);
+        return 0;
+      }
+    face = facevtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = face;
+    myInfo.myNbQuadTriangles++;
+
+//    if (!registerElement(ID, face)) {
+//      RemoveElement(face, false);
+//      face = NULL;
+//    }
+    return face;
   }
-  return face;
 }
 
 
@@ -2971,17 +3540,42 @@ SMDS_MeshFace* SMDS_Mesh::AddFaceWithID(const SMDS_MeshNode * n1,
   if ( !n1 || !n2 || !n3 || !n4 || !n12 || !n23 || !n34 || !n41) return 0;
   if(hasConstructionEdges()) {
     // creation quadratic edges - not implemented
+       return 0;
   }
-  SMDS_QuadraticFaceOfNodes* face =
-    new SMDS_QuadraticFaceOfNodes(n1,n2,n3,n4,n12,n23,n34,n41);
-  myFaces.Add(face);
-  myInfo.myNbQuadQuadrangles++;
-
-  if (!registerElement(ID, face)) {
-    RemoveElement(face, false);
-    face = NULL;
+  else
+  {
+    // --- retrieve nodes ID
+    vector<vtkIdType> nodeIds;
+    nodeIds.clear();
+    nodeIds.push_back(n1->getVtkId());
+    nodeIds.push_back(n2->getVtkId());
+    nodeIds.push_back(n3->getVtkId());
+    nodeIds.push_back(n4->getVtkId());
+    nodeIds.push_back(n12->getVtkId());
+    nodeIds.push_back(n23->getVtkId());
+    nodeIds.push_back(n34->getVtkId());
+    nodeIds.push_back(n41->getVtkId());
+
+    SMDS_MeshFace * face = 0;
+    SMDS_VtkFace *facevtk = myFacePool->getNew();
+    facevtk->init(nodeIds, this);
+    if (!this->registerElement(ID,facevtk))
+      {
+        this->myGrid->GetCellTypesArray()->SetValue(facevtk->getVtkId(), VTK_EMPTY_CELL);
+        myFacePool->destroy(facevtk);
+        return 0;
+      }
+    face = facevtk;
+    adjustmyCellsCapacity(ID);
+    myCells[ID] = face;
+    myInfo.myNbQuadQuadrangles++;
+
+//    if (!registerElement(ID, face)) {
+//      RemoveElement(face, false);
+//      face = NULL;
+//    }
+    return face;
   }
-  return face;
 }
 
 
@@ -3051,16 +3645,39 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     // creation quadratic faces - not implemented
     return 0;
   }
-  SMDS_QuadraticVolumeOfNodes * volume =
-    new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n12,n23,n31,n14,n24,n34);
-  myVolumes.Add(volume);
+  // --- retrieve nodes ID
+  vector<vtkIdType> nodeIds;
+  nodeIds.clear();
+  nodeIds.push_back(n1->getVtkId());
+  nodeIds.push_back(n3->getVtkId());
+  nodeIds.push_back(n2->getVtkId());
+  nodeIds.push_back(n4->getVtkId());
+
+  nodeIds.push_back(n31->getVtkId());
+  nodeIds.push_back(n23->getVtkId());
+  nodeIds.push_back(n12->getVtkId());
+
+  nodeIds.push_back(n14->getVtkId());
+  nodeIds.push_back(n34->getVtkId());
+  nodeIds.push_back(n24->getVtkId());
+
+  SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+  volvtk->init(nodeIds, this);
+  if (!this->registerElement(ID,volvtk))
+    {
+      this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+      myVolumePool->destroy(volvtk);
+      return 0;
+    }
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = volvtk;
   myInfo.myNbQuadTetras++;
 
-  if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
-  }
-  return volume;
+//  if (!registerElement(ID, volvtk)) {
+//    RemoveElement(volvtk, false);
+//    volvtk = NULL;
+//  }
+  return volvtk;
 }
 
 
@@ -3141,17 +3758,42 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     // creation quadratic faces - not implemented
     return 0;
   }
-  SMDS_QuadraticVolumeOfNodes * volume =
-    new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n12,n23,
-                                    n34,n41,n15,n25,n35,n45);
-  myVolumes.Add(volume);
+  // --- retrieve nodes ID
+  vector<vtkIdType> nodeIds;
+  nodeIds.clear();
+  nodeIds.push_back(n1->getVtkId());
+  nodeIds.push_back(n4->getVtkId());
+  nodeIds.push_back(n3->getVtkId());
+  nodeIds.push_back(n2->getVtkId());
+  nodeIds.push_back(n5->getVtkId());
+
+  nodeIds.push_back(n41->getVtkId());
+  nodeIds.push_back(n34->getVtkId());
+  nodeIds.push_back(n23->getVtkId());
+  nodeIds.push_back(n12->getVtkId());
+
+  nodeIds.push_back(n15->getVtkId());
+  nodeIds.push_back(n45->getVtkId());
+  nodeIds.push_back(n35->getVtkId());
+  nodeIds.push_back(n25->getVtkId());
+
+  SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+  volvtk->init(nodeIds, this);
+  if (!this->registerElement(ID,volvtk))
+    {
+      this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+      myVolumePool->destroy(volvtk);
+      return 0;
+    }
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = volvtk;
   myInfo.myNbQuadPyramids++;
 
-  if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
-  }
-  return volume;
+//  if (!registerElement(ID, volvtk)) {
+//    RemoveElement(volvtk, false);
+//    volvtk = NULL;
+//  }
+  return volvtk;
 }
 
 
@@ -3240,17 +3882,46 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     // creation quadratic faces - not implemented
     return 0;
   }
-  SMDS_QuadraticVolumeOfNodes * volume =
-    new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n12,n23,n31,
-                                    n45,n56,n64,n14,n25,n36);
-  myVolumes.Add(volume);
+  // --- retrieve nodes ID
+  vector<vtkIdType> nodeIds;
+  nodeIds.clear();
+  nodeIds.push_back(n1->getVtkId());
+  nodeIds.push_back(n2->getVtkId());
+  nodeIds.push_back(n3->getVtkId());
+
+  nodeIds.push_back(n4->getVtkId());
+  nodeIds.push_back(n5->getVtkId());
+  nodeIds.push_back(n6->getVtkId());
+
+  nodeIds.push_back(n12->getVtkId());
+  nodeIds.push_back(n23->getVtkId());
+  nodeIds.push_back(n31->getVtkId());
+
+  nodeIds.push_back(n45->getVtkId());
+  nodeIds.push_back(n56->getVtkId());
+  nodeIds.push_back(n64->getVtkId());
+
+  nodeIds.push_back(n14->getVtkId());
+  nodeIds.push_back(n25->getVtkId());
+  nodeIds.push_back(n36->getVtkId());
+
+  SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+  volvtk->init(nodeIds, this);
+  if (!this->registerElement(ID,volvtk))
+    {
+      this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+      myVolumePool->destroy(volvtk);
+      return 0;
+    }
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = volvtk;
   myInfo.myNbQuadPrisms++;
 
-  if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
-  }
-  return volume;
+//  if (!registerElement(ID, volvtk)) {
+//    RemoveElement(volvtk, false);
+//    volvtk = NULL;
+//  }
+  return volvtk;
 }
 
 
@@ -3354,15 +4025,213 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
     return 0;
     // creation quadratic faces - not implemented
   }
-  SMDS_QuadraticVolumeOfNodes * volume =
-    new SMDS_QuadraticVolumeOfNodes(n1,n2,n3,n4,n5,n6,n7,n8,n12,n23,n34,n41,
-                                    n56,n67,n78,n85,n15,n26,n37,n48);
-  myVolumes.Add(volume);
+  // --- retrieve nodes ID
+  vector<vtkIdType> nodeIds;
+  nodeIds.clear();
+  nodeIds.push_back(n1->getVtkId());
+  nodeIds.push_back(n4->getVtkId());
+  nodeIds.push_back(n3->getVtkId());
+  nodeIds.push_back(n2->getVtkId());
+
+  nodeIds.push_back(n5->getVtkId());
+  nodeIds.push_back(n8->getVtkId());
+  nodeIds.push_back(n7->getVtkId());
+  nodeIds.push_back(n6->getVtkId());
+
+  nodeIds.push_back(n41->getVtkId());
+  nodeIds.push_back(n34->getVtkId());
+  nodeIds.push_back(n23->getVtkId());
+  nodeIds.push_back(n12->getVtkId());
+
+  nodeIds.push_back(n85->getVtkId());
+  nodeIds.push_back(n78->getVtkId());
+  nodeIds.push_back(n67->getVtkId());
+  nodeIds.push_back(n56->getVtkId());
+
+  nodeIds.push_back(n15->getVtkId());
+  nodeIds.push_back(n48->getVtkId());
+  nodeIds.push_back(n37->getVtkId());
+  nodeIds.push_back(n26->getVtkId());
+
+  SMDS_VtkVolume *volvtk = myVolumePool->getNew();
+  volvtk->init(nodeIds, this);
+  if (!this->registerElement(ID,volvtk))
+    {
+      this->myGrid->GetCellTypesArray()->SetValue(volvtk->getVtkId(), VTK_EMPTY_CELL);
+      myVolumePool->destroy(volvtk);
+      return 0;
+    }
+  adjustmyCellsCapacity(ID);
+  myCells[ID] = volvtk;
   myInfo.myNbQuadHexas++;
 
-  if (!registerElement(ID, volume)) {
-    RemoveElement(volume, false);
-    volume = NULL;
+//  if (!registerElement(ID, volvtk)) {
+//    RemoveElement(volvtk, false);
+//    volvtk = NULL;
+//  }
+  return volvtk;
+}
+
+void SMDS_Mesh::updateNodeMinMax()
+{
+  myNodeMin = 0;
+  if (myNodes.size() == 0)
+  {
+       myNodeMax=0;
+       return;
   }
-  return volume;
+  while (!myNodes[myNodeMin] && (myNodeMin<myNodes.size()))
+    myNodeMin++;
+  myNodeMax=myNodes.size()-1;
+  while (!myNodes[myNodeMax] && (myNodeMin>=0))
+    myNodeMin--;
+}
+
+void SMDS_Mesh::incrementNodesCapacity(int nbNodes)
+{
+//  int val = myCellIdSmdsToVtk.size();
+//  MESSAGE(" ------------------- resize myCellIdSmdsToVtk " << val << " --> " << val + nbNodes);
+//  myCellIdSmdsToVtk.resize(val + nbNodes, -1); // fill new elements with -1
+  int val = myNodes.size();
+  MESSAGE(" ------------------- resize myNodes " << val << " --> " << val + nbNodes);
+  myNodes.resize(val +nbNodes, 0);
+}
+
+void SMDS_Mesh::incrementCellsCapacity(int nbCells)
+{
+  int val = myCellIdVtkToSmds.size();
+  MESSAGE(" ------------------- resize myCellIdVtkToSmds " << val << " --> " << val + nbCells);
+  myCellIdVtkToSmds.resize(val + nbCells, -1); // fill new elements with -1
+  val = myCells.size();
+  MESSAGE(" ------------------- resize myCells " << val << " --> " << val + nbCells);
+  myNodes.resize(val +nbCells, 0);
+}
+
+void SMDS_Mesh::adjustStructure()
+{
+  myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID());
+}
+
+void SMDS_Mesh::dumpGrid(string ficdump)
+{
+       MESSAGE("SMDS_Mesh::dumpGrid " << ficdump);
+//  vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
+//  aWriter->SetFileName(ficdump.c_str());
+//  aWriter->SetInput(myGrid);
+//  if(myGrid->GetNumberOfCells())
+//  {
+//    aWriter->Write();
+//  }
+//  aWriter->Delete();
+  ficdump = ficdump + "_connectivity";
+  ofstream ficcon(ficdump.c_str(), ios::out);
+  int nbPoints = myGrid->GetNumberOfPoints();
+  ficcon << "-------------------------------- points " <<  nbPoints << endl;
+  for (int i=0; i<nbPoints; i++)
+  {
+       ficcon << i << " " << *(myGrid->GetPoint(i)) << " " << *(myGrid->GetPoint(i)+1) << " " << " " << *(myGrid->GetPoint(i)+2) << endl;
+  }
+  int nbCells = myGrid->GetNumberOfCells();
+  ficcon << "-------------------------------- cells " <<  nbCells << endl;
+  for (int i=0; i<nbCells; i++)
+  {
+//     MESSAGE(i << " " << myGrid->GetCell(i));
+//     MESSAGE("  " << myGrid->GetCell(i)->GetCellType());
+       ficcon << i << " - " << myGrid->GetCell(i)->GetCellType() << " -";
+       int nbptcell = myGrid->GetCell(i)->GetNumberOfPoints();
+       vtkIdList *listid = myGrid->GetCell(i)->GetPointIds();
+       for (int j=0; j<nbptcell; j++)
+       {
+               ficcon << " " <<  listid->GetId(j);
+       }
+       ficcon << endl;
+  }
+  ficcon << "-------------------------------- connectivity " <<  nbPoints << endl;
+       vtkCellLinks *links = myGrid->GetCellLinks();
+  for (int i=0; i<nbPoints; i++)
+  {
+       int ncells = links->GetNcells(i);
+       vtkIdType *cells = links->GetCells(i);
+       ficcon << i << " - " << ncells << " -";
+       for (int j=0; j<ncells; j++)
+       {
+               ficcon << " " << cells[j];
+       }
+       ficcon << endl;
+  }
+  ficcon.close();
+
+}
+
+void SMDS_Mesh::compactMesh()
+{
+  MESSAGE("SMDS_Mesh::compactMesh do nothing!");
+}
+
+int SMDS_Mesh::fromVtkToSmds(int vtkid)
+{
+  if (vtkid >= 0 && vtkid < myCellIdVtkToSmds.size())
+    return myCellIdVtkToSmds[vtkid];
+  throw SALOME_Exception(LOCALIZED ("vtk id out of bounds"));
+}
+
+void SMDS_Mesh::updateBoundingBox()
+{
+  xmin = 0; xmax = 0;
+  ymin = 0; ymax = 0;
+  zmin = 0; zmax = 0;
+  vtkPoints *points = myGrid->GetPoints();
+  int myNodesSize = this->myNodes.size();
+  for (int i = 0; i < myNodesSize; i++)
+    {
+      if (SMDS_MeshNode *n = myNodes[i])
+        {
+          double coords[3];
+          points->GetPoint(n->myVtkID, coords);
+          if (coords[0] < xmin) xmin = coords[0];
+          else if (coords[0] > xmax) xmax = coords[0];
+          if (coords[1] < ymin) ymin = coords[1];
+          else if (coords[1] > ymax) ymax = coords[1];
+          if (coords[2] < zmin) zmin = coords[2];
+          else if (coords[2] > zmax) zmax = coords[2];
+        }
+    }
+}
+
+double SMDS_Mesh::getMaxDim()
+{
+  double dmax = 1.e-3;
+  if ((xmax - xmin) > dmax) dmax = xmax -xmin;
+  if ((ymax - ymin) > dmax) dmax = ymax -ymin;
+  if ((zmax - zmin) > dmax) dmax = zmax -zmin;
+  MESSAGE("getMaxDim " << dmax);
+  return dmax;
+}
+
+//! modification that needs compact structure and redraw
+void SMDS_Mesh::Modified()
+{
+  if (this->myModified)
+    {
+      this->myModifTime++;
+      MESSAGE("modified");
+      myModified = false;
+    }
+}
+
+//! get last modification timeStamp
+unsigned long SMDS_Mesh::GetMTime()
+{
+  return this->myModifTime;
+}
+
+bool SMDS_Mesh::isCompacted()
+{
+  if (this->myModifTime > this->myCompactTime)
+    {
+      MESSAGE(" *** isCompacted " << myCompactTime << " < " << myModifTime);
+      this->myCompactTime = this->myModifTime;
+      return false;
+    }
+  return true;
 }
index e9397b6a202318e2a59cf599af92acf87090614e..6daf98478b4a9f255c2e844a2c9a3e3751a7a616 100644 (file)
 #include "SMESH_SMDS.hxx"
 
 #include "SMDS_MeshNode.hxx"
+#include "SMDS_MeshCell.hxx"
 #include "SMDS_Mesh0DElement.hxx"
 #include "SMDS_MeshEdge.hxx"
 #include "SMDS_MeshFace.hxx"
 #include "SMDS_MeshVolume.hxx"
+#include "SMDS_MeshNodeIDFactory.hxx"
 #include "SMDS_MeshElementIDFactory.hxx"
 #include "SMDS_MeshInfo.hxx"
 #include "SMDS_ElemIterator.hxx"
-#include <NCollection_Map.hxx>
+#include "SMDS_VolumeOfNodes.hxx"
+#include "SMDS_VtkEdge.hxx"
+#include "SMDS_VtkFace.hxx"
+#include "SMDS_VtkVolume.hxx"
+#include "ObjectPool.hxx"
+#include "SMDS_UnstructuredGrid.hxx"
 
 #include <boost/shared_ptr.hpp>
 #include <set>
 #include <list>
+#include <vector>
+#include <vtkSystemIncludes.h>
+
+#include "Utils_SALOME_Exception.hxx"
+#define MYASSERT(val) if (!(val)) throw SALOME_Exception(LOCALIZED("assertion not verified"));
 
 class SMDS_EXPORT SMDS_Mesh:public SMDS_MeshObject{
 public:
+  friend class SMDS_MeshIDFactory;
+  friend class SMDS_MeshNodeIDFactory;
+  friend class SMDS_MeshElementIDFactory;
+  friend class SMDS_MeshVolumeVtkNodes;
+  friend class SMDS_MeshNode;
 
   SMDS_Mesh();
+  
+  //! to retreive this SMDS_Mesh instance from its elements (index stored in SMDS_Elements)
+  static std::vector<SMDS_Mesh*> _meshList;
+
+  //! actual nodes coordinates, cells definition and reverse connectivity are stored in a vtkUnstructuredGrid
+  inline SMDS_UnstructuredGrid* getGrid() {return myGrid; };
+  inline int getMeshId() {return myMeshId; };
 
   SMDS_NodeIteratorPtr nodesIterator          (bool idInceasingOrder=false) const;
   SMDS_0DElementIteratorPtr elements0dIterator(bool idInceasingOrder=false) const;
@@ -420,6 +444,11 @@ public:
                            (std::vector<const SMDS_MeshNode*> nodes,
                             std::vector<int>                  quantities);
 
+  virtual SMDS_MeshVolume* AddVolumeFromVtkIds(const std::vector<int>& vtkNodeIds);
+
+  virtual SMDS_MeshVolume* AddVolumeFromVtkIdsWithID(const std::vector<int>& vtkNodeIds,
+                                                     const int ID);
+
   virtual void RemoveElement(const SMDS_MeshElement *        elem,
                              std::list<const SMDS_MeshElement *>& removedElems,
                              std::list<const SMDS_MeshElement *>& removedNodes,
@@ -451,8 +480,10 @@ public:
 
   virtual void Renumber (const bool isNodes, const int startID = 1, const int deltaID = 1);
   // Renumber all nodes or elements.
+  virtual void compactMesh();
 
   const SMDS_MeshNode *FindNode(int idnode) const;
+  const SMDS_MeshNode *FindNodeVtk(int idnode) const;
   const SMDS_Mesh0DElement* Find0DElement(int idnode) const;
   const SMDS_MeshEdge *FindEdge(int idnode1, int idnode2) const;
   const SMDS_MeshEdge *FindEdge(int idnode1, int idnode2, int idnode3) const;
@@ -541,23 +572,40 @@ public:
    */
   bool Contains (const SMDS_MeshElement* elem) const;
 
-  typedef NCollection_Map<SMDS_MeshNode *> SetOfNodes;
-  typedef NCollection_Map<SMDS_Mesh0DElement *> SetOf0DElements;
-  typedef NCollection_Map<SMDS_MeshEdge *> SetOfEdges;
-  typedef NCollection_Map<SMDS_MeshFace *> SetOfFaces;
-  typedef NCollection_Map<SMDS_MeshVolume *> SetOfVolumes;
+  typedef std::vector<SMDS_MeshNode *> SetOfNodes;
+  typedef std::vector<SMDS_MeshCell *> SetOfCells;
+
+  void updateNodeMinMax();
+  void updateBoundingBox();
+  double getMaxDim();
+  int fromVtkToSmds(int vtkid);
+
+  void incrementNodesCapacity(int nbNodes);
+  void incrementCellsCapacity(int nbCells);
+  void adjustStructure();
+  void dumpGrid(string ficdump="dumpGrid");
+  static int chunkSize;
 
-private:
+  //! low level modification: add, change or remove node or element
+  inline void setMyModified() { this->myModified = true; };
+
+  void Modified();
+  unsigned long GetMTime();
+  bool isCompacted();
+
+protected:
   SMDS_Mesh(SMDS_Mesh * parent);
 
   SMDS_MeshFace * createTriangle(const SMDS_MeshNode * node1,
                                  const SMDS_MeshNode * node2,
-                                 const SMDS_MeshNode * node3);
+                                 const SMDS_MeshNode * node3,
+                                 int ID);
   SMDS_MeshFace * createQuadrangle(const SMDS_MeshNode * node1,
                                    const SMDS_MeshNode * node2,
                                    const SMDS_MeshNode * node3,
-                                   const SMDS_MeshNode * node4);
-  SMDS_Mesh0DElement* Find0DElementOrCreate(const SMDS_MeshNode * n);
+                                   const SMDS_MeshNode * node4,
+                                   int ID);
+//  SMDS_Mesh0DElement* Find0DElementOrCreate(const SMDS_MeshNode * n);
   SMDS_MeshEdge* FindEdgeOrCreate(const SMDS_MeshNode * n1,
                                   const SMDS_MeshNode * n2);
   SMDS_MeshFace* FindFaceOrCreate(const SMDS_MeshNode *n1,
@@ -574,22 +622,77 @@ private:
                             const SMDS_MeshElement * element,
                             std::set<const SMDS_MeshElement*>& nodes);
 
+  inline void adjustmyCellsCapacity(int ID)
+  {
+    assert(ID >= 0);
+    myElementIDFactory->adjustMaxId(ID);
+    if (ID >= myCells.size())
+      myCells.resize(ID+SMDS_Mesh::chunkSize,0);
+  };
+
+  inline void adjustBoundingBox(double x, double y, double z)
+  {
+    if (x > xmax) xmax = x;
+    else if (x < xmin) xmin = x;
+    if (y > ymax) ymax = y;
+    else if (y < ymin) ymin = y;
+    if (z > zmax) zmax = z;
+    else if (z < zmin) zmin = z;
+  };
+
   // Fields PRIVATE
 
+  //! index of this SMDS_mesh in the static vector<SMDS_Mesh*> _meshList
+  int myMeshId;
+
+  //! actual nodes coordinates, cells definition and reverse connectivity are stored in a vtkUnstructuredGrid
+  SMDS_UnstructuredGrid*      myGrid;
+
+  //! Small objects like SMDS_MeshNode are allocated by chunks to limit memory costs of new
+  ObjectPool<SMDS_MeshNode>* myNodePool;
+
+  //! Small objects like SMDS_VtkVolume are allocated by chunks to limit memory costs of new
+  ObjectPool<SMDS_VtkVolume>* myVolumePool;
+  ObjectPool<SMDS_VtkFace>* myFacePool;
+  ObjectPool<SMDS_VtkEdge>* myEdgePool;
+
+  //! SMDS_MeshNodes refer to vtk nodes (vtk id = index in myNodes),store reference to this mesh, and subshape
   SetOfNodes             myNodes;
-  SetOf0DElements        my0DElements;
-  SetOfEdges             myEdges;
-  SetOfFaces             myFaces;
-  SetOfVolumes           myVolumes;
+
+  //! SMDS_MeshCells refer to vtk cells (vtk id != index in myCells),store reference to this mesh, and subshape
+  SetOfCells             myCells;
+
+  //! for cells only: index = ID for SMDS users, value = ID in vtkUnstructuredGrid
+  //std::vector<int>       myCellIdSmdsToVtk;
+
+  //! for cells only: index = ID in vtkUnstructuredGrid, value = ID for SMDS users
+  std::vector<int>       myCellIdVtkToSmds;
+
   SMDS_Mesh *            myParent;
   std::list<SMDS_Mesh *> myChildren;
-  SMDS_MeshElementIDFactory *myNodeIDFactory;
+  SMDS_MeshNodeIDFactory *myNodeIDFactory;
   SMDS_MeshElementIDFactory *myElementIDFactory;
   SMDS_MeshInfo          myInfo;
 
+  //! use a counter to keep track of modifications
+  unsigned long myModifTime, myCompactTime;
+
+  int myNodeMin;
+  int myNodeMax;
+
   bool myHasConstructionEdges;
   bool myHasConstructionFaces;
   bool myHasInverseElements;
+
+  //! any add, remove or change of node or cell
+  bool myModified;
+
+  double xmin;
+  double xmax;
+  double ymin;
+  double ymax;
+  double zmin;
+  double zmax;
 };
 
 
index fec86593777a2ccb474e92a5b43f5958a6cda181..49b4d4abcd9825c327ba6a11d2502beb0446672f 100644 (file)
@@ -29,6 +29,7 @@
 #include "SMDS_Mesh0DElement.hxx"
 #include "SMDS_IteratorOfElements.hxx"
 #include "SMDS_MeshNode.hxx"
+#include "utilities.h"
 
 using namespace std;
 
@@ -37,7 +38,8 @@ using namespace std;
 //purpose  :
 //=======================================================================
 SMDS_Mesh0DElement::SMDS_Mesh0DElement (const SMDS_MeshNode * node)
-{       
+{
+  MESSAGE("SMDS_Mesh0DElement " << GetID());
   myNode = node;
 }
 
@@ -77,6 +79,11 @@ SMDSAbs_ElementType SMDS_Mesh0DElement::GetType() const
   return SMDSAbs_0DElement;
 }
 
+vtkIdType SMDS_Mesh0DElement::GetVtkType() const
+{
+  return VTK_VERTEX;
+}
+
 //=======================================================================
 //function : elementsIterator
 //purpose  :
@@ -124,8 +131,8 @@ SMDS_ElemIteratorPtr SMDS_Mesh0DElement::elementsIterator (SMDSAbs_ElementType t
 //=======================================================================
 bool operator< (const SMDS_Mesh0DElement & e1, const SMDS_Mesh0DElement & e2)
 {
-  int id1 = e1.myNode->GetID();
-  int id2 = e2.myNode->GetID();
+  int id1 = e1.myNode->getVtkId();
+  int id2 = e2.myNode->getVtkId();
 
   return (id1 < id2);
 }
index 7e5abd52b2baf9f593a78b42ed407760b1495c74..b137222914dde4c813ee0d811208c01c2df4534d 100644 (file)
 
 #include "SMESH_SMDS.hxx"
 
-#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshCell.hxx"
 
 #include <iostream>
 
-class SMDS_EXPORT SMDS_Mesh0DElement: public SMDS_MeshElement
+class SMDS_EXPORT SMDS_Mesh0DElement: public SMDS_MeshCell
 {
  public:
   SMDS_Mesh0DElement (const SMDS_MeshNode * node);
   bool ChangeNode (const SMDS_MeshNode * node);
+  virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) {return false;};
   void Print (std::ostream & OS) const;
 
   SMDSAbs_ElementType GetType() const;
+  virtual vtkIdType GetVtkType() const;
   SMDSAbs_EntityType  GetEntityType() const {return SMDSEntity_0D;}
   int NbNodes() const;
   int NbEdges() const;
diff --git a/src/SMDS/SMDS_MeshCell.cxx b/src/SMDS/SMDS_MeshCell.cxx
new file mode 100644 (file)
index 0000000..4cfd2a0
--- /dev/null
@@ -0,0 +1,18 @@
+#include "SMDS_MeshCell.hxx"
+#include "utilities.h"
+
+using namespace std;
+
+int SMDS_MeshCell::nbCells = 0;
+
+SMDS_MeshCell::SMDS_MeshCell() :
+  SMDS_MeshElement(-1)
+{
+  nbCells++;
+  myVtkID = -1;
+}
+
+SMDS_MeshCell::~SMDS_MeshCell()
+{
+  nbCells--;
+}
diff --git a/src/SMDS/SMDS_MeshCell.hxx b/src/SMDS/SMDS_MeshCell.hxx
new file mode 100644 (file)
index 0000000..792696f
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef _SMDS_MESHCELL_HXX_
+#define _SMDS_MESHCELL_HXX_
+
+#include "SMDS_MeshElement.hxx"
+
+/*!
+ * \brief Base class for all cells
+ */
+
+class SMDS_EXPORT SMDS_MeshCell: public SMDS_MeshElement
+{
+public:
+  SMDS_MeshCell();
+  virtual ~SMDS_MeshCell();
+
+  virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)= 0;
+  virtual bool vtkOrder(const SMDS_MeshNode* nodes[], const int nbNodes) {return true; };
+
+  static int nbCells;
+
+protected:
+  inline void exchange(const SMDS_MeshNode* nodes[],int a, int b)
+  {
+    const SMDS_MeshNode* noda = nodes[a];
+    nodes[a] = nodes[b];
+    nodes[b] = noda;
+  }
+};
+
+#endif
index 1910a3a4b3559fd75e2a6f8818835b627bb3661e..fc1e3c55a1e850fbb91276791436c6c159474077 100644 (file)
-//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-//  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
-//
-
-//  SMESH SMDS : implementaion of Salome mesh data structure
-//  File   : SMDS_MeshEdge.cxx
-//  Author : Jean-Michel BOULCOURT
-//  Module : SMESH
-//
-#ifdef _MSC_VER
-#pragma warning(disable:4786)
-#endif
-
 #include "SMDS_MeshEdge.hxx"
-#include "SMDS_IteratorOfElements.hxx"
-#include "SMDS_MeshNode.hxx"
-
-using namespace std;
-
-//=======================================================================
-//function : SMDS_MeshEdge
-//purpose  : 
-//=======================================================================
-
-SMDS_MeshEdge::SMDS_MeshEdge(const SMDS_MeshNode * node1,
-                             const SMDS_MeshNode * node2)
-{       
-        myNodes[0]=node1;
-        myNodes[1]=node2;
-}
-
-//=======================================================================
-//function : Print
-//purpose  : 
-//=======================================================================
-
-void SMDS_MeshEdge::Print(ostream & OS) const
-{
-        OS << "edge <" << GetID() << "> : (" << myNodes[0] << " , " << myNodes[1] <<
-                ") " << endl;
-}
-
-int SMDS_MeshEdge::NbNodes() const
-{
-        return 2;
-}
-
-int SMDS_MeshEdge::NbEdges() const
-{
-        return 1;
-}
 
 SMDSAbs_ElementType SMDS_MeshEdge::GetType() const
 {
-        return SMDSAbs_Edge;
+       return SMDSAbs_Edge;
 }
 
-class SMDS_MeshEdge_MyNodeIterator:public SMDS_ElemIterator
-{
-  const SMDS_MeshNode *const* myNodes;
-  int myIndex;
- public:
-  SMDS_MeshEdge_MyNodeIterator(const SMDS_MeshNode * const* nodes):
-    myNodes(nodes),myIndex(0) {}
-
-  bool more()
-  {
-    return myIndex<2;
-  }
-
-  const SMDS_MeshElement* next()
-  {
-    myIndex++;
-    return myNodes[myIndex-1];
-  }
-};
-
-SMDS_ElemIteratorPtr SMDS_MeshEdge::
-        elementsIterator(SMDSAbs_ElementType type) const
-{
-  switch(type)
-  {
-  case SMDSAbs_Edge:
-    return SMDS_MeshElement::elementsIterator(SMDSAbs_Edge); 
-  case SMDSAbs_Node:
-    return SMDS_ElemIteratorPtr(new SMDS_MeshEdge_MyNodeIterator(myNodes));
-  default:
-    return SMDS_ElemIteratorPtr
-      (new SMDS_IteratorOfElements
-       (this,type, SMDS_ElemIteratorPtr(new SMDS_MeshEdge_MyNodeIterator(myNodes))));
-  }
-}
-
-bool operator<(const SMDS_MeshEdge & e1, const SMDS_MeshEdge & e2)
-{
-        int id11=e1.myNodes[0]->GetID();
-        int id21=e2.myNodes[0]->GetID();
-        int id12=e1.myNodes[1]->GetID();
-        int id22=e2.myNodes[1]->GetID();
-        int tmp;
-
-        if(id11>=id12) 
-        {
-                tmp=id11;
-                id11=id12;
-                id12=tmp;       
-        }
-        if(id21>=id22) 
-        {
-                tmp=id21;
-                id21=id22;
-                id22=tmp;       
-        }
-
-        if(id11<id21) return true;
-        else if(id11==id21) return (id21<id22);
-        else return false;
-}
-
-/*!
- * \brief Return node by its index
- * \param ind - node index
- * \retval const SMDS_MeshNode* - the node
- */
-const SMDS_MeshNode* SMDS_MeshEdge::GetNode(const int ind) const
-{
-  return myNodes[ ind ];
-}
-
-//=======================================================================
-//function : ChangeNodes
-//purpose  : 
-//=======================================================================
-
-bool SMDS_MeshEdge::ChangeNodes(const SMDS_MeshNode * node1,
-                                const SMDS_MeshNode * node2)
+vtkIdType SMDS_MeshEdge::GetVtkType() const
 {
-  myNodes[0]=node1;
-  myNodes[1]=node2;
-  return true;
+  return VTK_POLY_VERTEX; // --- must be reimplemented in derived classes
 }
index 65a85798ec22406c2692b3fe55a982422b4d9b30..3f5b089d6f433ff7fbbd942da2f2a4e6bc603e1c 100644 (file)
 
 #include "SMESH_SMDS.hxx"
 
-#include "SMDS_MeshElement.hxx"
-#include <iostream>
+#include "SMDS_MeshCell.hxx"
 
-class SMDS_EXPORT SMDS_MeshEdge:public SMDS_MeshElement
+class SMDS_EXPORT SMDS_MeshEdge:public SMDS_MeshCell
 {
-
+       
   public:
-        SMDS_MeshEdge(const SMDS_MeshNode * node1,
-                      const SMDS_MeshNode * node2);
-        bool ChangeNodes(const SMDS_MeshNode * node1,
-                         const SMDS_MeshNode * node2);
-        void Print(std::ostream & OS) const;
-
-        virtual SMDSAbs_ElementType GetType() const;
-        virtual SMDSAbs_EntityType GetEntityType() const { return SMDSEntity_Edge; }
-        int NbNodes() const;
-        int NbEdges() const;
-        friend bool operator<(const SMDS_MeshEdge& e1, const SMDS_MeshEdge& e2);
-
-  /*!
-   * \brief Return node by its index
-    * \param ind - node index
-    * \retval const SMDS_MeshNode* - the node
-   */
-  virtual const SMDS_MeshNode* GetNode(const int ind) const;
-
-  protected:
-        SMDS_ElemIteratorPtr
-                elementsIterator(SMDSAbs_ElementType type) const;
-
-  protected:
-        const SMDS_MeshNode* myNodes[3];
-
+        SMDSAbs_ElementType GetType() const;
+        virtual vtkIdType GetVtkType() const;
 };
 #endif
index 185b3c5498408dcbcd048631ee9fc2c059ed4919..3b4cd2520115c4f741c4ab737b7f8911a76e9700 100644 (file)
 
 using namespace std;
 
-SMDS_MeshElement::SMDS_MeshElement(int ID):myID(ID)
+SMDS_MeshElement::SMDS_MeshElement(int ID):myID(ID), myMeshId(-1), myShapeId(0), myIdInShape(-1)
+{
+}
+
+SMDS_MeshElement::SMDS_MeshElement(int id, ShortType meshId, ShortType shapeId):
+  myID(id), myMeshId(meshId), myShapeId(shapeId), myIdInShape(-1)
 {
 }
 
@@ -146,6 +151,7 @@ class SMDS_MeshElement_MyIterator:public SMDS_ElemIterator
     return myElement;   
   }     
 };
+
 SMDS_ElemIteratorPtr SMDS_MeshElement::
         elementsIterator(SMDSAbs_ElementType type) const
 {
@@ -162,12 +168,18 @@ SMDS_ElemIteratorPtr SMDS_MeshElement::
         }
 }
 
-///////////////////////////////////////////////////////////////////////////////
-///Return the ID of the element
-///////////////////////////////////////////////////////////////////////////////
-int SMDS_MeshElement::GetID() const
+//! virtual, redefined in vtkEdge, vtkFace and vtkVolume classes
+SMDS_ElemIteratorPtr SMDS_MeshElement::nodesIteratorToUNV() const
+{
+  MESSAGE("Iterator not implemented");
+  return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL);
+}
+
+//! virtual, redefined in vtkEdge, vtkFace and vtkVolume classes
+SMDS_ElemIteratorPtr SMDS_MeshElement::interlacedNodesElemIterator() const
 {
-        return myID;
+  MESSAGE("Iterator not implemented");
+  return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL);
 }
 
 bool operator<(const SMDS_MeshElement& e1, const SMDS_MeshElement& e2)
index 593b7fe00c39deb1a7acd38bd5689fd4788e2e70..d4f32a51b40e68426a55d5fc545abed0a570f51a 100644 (file)
 #include <vector>
 #include <iostream>
 
+#include <vtkType.h>
+#include <vtkCellType.h>
+
+//typedef unsigned short UShortType;
+typedef short ShortType;
+
 class SMDS_MeshNode;
 class SMDS_MeshEdge;
-class SMDS_MeshFace;    
+class SMDS_MeshFace;
+class SMDS_Mesh;
 
 // ============================================================
 /*!
@@ -48,6 +55,7 @@ class SMDS_MeshFace;
  */
 // ============================================================
 
+
 class SMDS_EXPORT SMDS_MeshElement:public SMDS_MeshObject
 {
 public:
@@ -56,6 +64,8 @@ public:
   SMDS_ElemIteratorPtr edgesIterator() const;
   SMDS_ElemIteratorPtr facesIterator() const;
   virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const;
+  virtual SMDS_ElemIteratorPtr nodesIteratorToUNV() const;
+  virtual SMDS_ElemIteratorPtr interlacedNodesElemIterator() const;
 
   // std-like iteration on nodes
   typedef SMDS_StdIterator< const SMDS_MeshNode*, SMDS_ElemIteratorPtr > iterator;
@@ -65,11 +75,12 @@ public:
   virtual int NbNodes() const;
   virtual int NbEdges() const;
   virtual int NbFaces() const;
-  int GetID() const;
+  inline int GetID() const { return myID; };
 
   ///Return the type of the current element
   virtual SMDSAbs_ElementType GetType() const = 0;
-  virtual bool IsPoly() const { return false; }
+  virtual vtkIdType GetVtkType() const = 0;
+  virtual bool IsPoly() const { return false; };
   virtual bool IsQuadratic() const;
   //! Return type of entity
   virtual SMDSAbs_EntityType  GetEntityType() const = 0;
@@ -78,7 +89,11 @@ public:
   virtual int  NbCornerNodes() const;
 
   friend SMDS_EXPORT std::ostream & operator <<(std::ostream & OS, const SMDS_MeshElement *);
-  friend SMDS_EXPORT bool SMDS_MeshElementIDFactory::BindID(int ID,SMDS_MeshElement*elem);
+  friend SMDS_EXPORT bool SMDS_MeshElementIDFactory::BindID(int ID,SMDS_MeshElement* elem);
+  friend class SMDS_Mesh;
+  friend class SMESHDS_Mesh;
+  friend class SMESHDS_SubMesh;
+  friend class SMDS_MeshElementIDFactory;
 
   // ===========================
   //  Access to nodes by index
@@ -124,14 +139,33 @@ public:
    */
   int GetNodeIndex( const SMDS_MeshNode* node ) const;
 
+  inline ShortType getMeshId() const {return myMeshId; };
+  inline ShortType getshapeId() const {return myShapeId; };
+  inline int getIdInShape() const { return myIdInShape; };
+  inline int getVtkId() const { return myVtkID; };
+
 protected:
+  inline void setId(int id) {myID = id; };
+  inline void setShapeId(ShortType shapeId) {myShapeId = shapeId; };
+  inline void setIdInShape(int id) { myIdInShape = id; };
+  inline void setVtkId(int vtkId) { myVtkID = vtkId; };
   SMDS_MeshElement(int ID=-1);
+  SMDS_MeshElement(int id, ShortType meshId, ShortType shapeId = 0);
   virtual void Print(std::ostream & OS) const;
 
-private:
+  //! Element index in vector SMDS_Mesh::myNodes or SMDS_Mesh::myCells
   int myID;
+  //! index in vtkUnstructuredGrid
+  int myVtkID;
+  //! SMDS_Mesh identification in SMESH
+  ShortType myMeshId;
+  //! SubShape and SubMesh identification in SMESHDS
+  ShortType myShapeId;
+  //! Element index in SMESHDS_SubMesh vector
+  int myIdInShape;
 };
 
+
 // ============================================================
 /*!
  * \brief Comparator of elements by ID for usage in std containers
index b86ddad9eb15d03cd124f38c048435ddf4a638b8..1278192dc4ec398dea560373f9477fbf9c817a49 100644 (file)
 
 #include "SMDS_MeshElementIDFactory.hxx"
 #include "SMDS_MeshElement.hxx"
+#include "SMDS_Mesh.hxx"
+
+#include "utilities.h"
+
+#include <SMDS_UnstructuredGrid.hxx>
+#include <vtkCellType.h>
 
 using namespace std;
 
@@ -39,86 +45,110 @@ using namespace std;
 //purpose  : 
 //=======================================================================
 SMDS_MeshElementIDFactory::SMDS_MeshElementIDFactory():
-  SMDS_MeshIDFactory(),
-  myMin(0), myMax(0)
+  SMDS_MeshNodeIDFactory()
+{
+//    myIDElements.clear();
+//    myVtkIndex.clear();
+    myVtkCellTypes.clear();
+    myVtkCellTypes.reserve(SMDSEntity_Last);
+    myVtkCellTypes[SMDSEntity_Node]            = VTK_VERTEX;
+    myVtkCellTypes[SMDSEntity_0D]              = VTK_VERTEX;
+    myVtkCellTypes[SMDSEntity_Edge]            = VTK_LINE;
+    myVtkCellTypes[SMDSEntity_Quad_Edge]       = VTK_QUADRATIC_EDGE;
+    myVtkCellTypes[SMDSEntity_Triangle]        = VTK_TRIANGLE;
+    myVtkCellTypes[SMDSEntity_Quad_Triangle]   = VTK_QUADRATIC_TRIANGLE;
+    myVtkCellTypes[SMDSEntity_Quadrangle]      = VTK_QUAD;
+    myVtkCellTypes[SMDSEntity_Quad_Quadrangle] = VTK_QUADRATIC_TRIANGLE;
+    myVtkCellTypes[SMDSEntity_Polygon]         = VTK_POLYGON;
+    myVtkCellTypes[SMDSEntity_Quad_Polygon]    = VTK_POLYGON; // -PR- verifer
+    myVtkCellTypes[SMDSEntity_Tetra]           = VTK_TETRA;
+    myVtkCellTypes[SMDSEntity_Quad_Tetra]      = VTK_QUADRATIC_TETRA;
+    myVtkCellTypes[SMDSEntity_Pyramid]         = VTK_PYRAMID;
+    myVtkCellTypes[SMDSEntity_Quad_Pyramid]    = VTK_CONVEX_POINT_SET;
+    myVtkCellTypes[SMDSEntity_Hexa]            = VTK_HEXAHEDRON;
+    myVtkCellTypes[SMDSEntity_Quad_Hexa]       = VTK_QUADRATIC_HEXAHEDRON;
+    myVtkCellTypes[SMDSEntity_Penta]           = VTK_WEDGE;
+    myVtkCellTypes[SMDSEntity_Quad_Penta]      = VTK_QUADRATIC_WEDGE;
+//#ifdef VTK_HAVE_POLYHEDRON
+    myVtkCellTypes[SMDSEntity_Polyhedra]       = VTK_POLYHEDRON;
+//#else
+//    myVtkCellTypes[SMDSEntity_Polyhedra]       = VTK_CONVEX_POINT_SET;
+//#endif
+    myVtkCellTypes[SMDSEntity_Quad_Polyhedra]  = VTK_CONVEX_POINT_SET;
+}
+
+int SMDS_MeshElementIDFactory::SetInVtkGrid(SMDS_MeshElement * elem)
 {
+   // --- retrieve nodes ID
+
+  SMDS_MeshCell *cell = dynamic_cast<SMDS_MeshCell*>(elem);
+  assert(cell);
+  vector<vtkIdType> nodeIds;
+  SMDS_ElemIteratorPtr it = elem->nodesIterator();
+  while(it->more())
+  {
+      int nodeId = (static_cast<const SMDS_MeshNode*>(it->next()))->getVtkId();
+      MESSAGE("   node in cell " << cell->getVtkId() << " : " << nodeId)
+      nodeIds.push_back(nodeId);
+  }
+
+  // --- insert cell in vtkUnstructuredGrid
+
+  vtkUnstructuredGrid * grid = myMesh->getGrid();
+  int typ = GetVtkCellType(elem->GetType());
+  int cellId = grid->InsertNextLinkedCell(typ, nodeIds.size(), &nodeIds[0]);
+  cell->setVtkId(cellId); 
+  //MESSAGE("SMDS_MeshElementIDFactory::SetInVtkGrid " << cellId);
+  return cellId;
 }
 
 //=======================================================================
 //function : BindID
 //purpose  : 
 //=======================================================================
+
 bool SMDS_MeshElementIDFactory::BindID(int ID, SMDS_MeshElement * elem)
 {
-  if (myIDElements.IsBound(ID))
-    return false;
-  myIDElements.Bind(ID,elem);
-  elem->myID=ID;
-  updateMinMax (ID);
-  return true;
+  MESSAGE("SMDS_MeshElementIDFactory::BindID " << ID);
+  SetInVtkGrid(elem);
+  return myMesh->registerElement(ID, elem);
 }
 
 //=======================================================================
 //function : MeshElement
 //purpose  : 
 //=======================================================================
-SMDS_MeshElement* SMDS_MeshElementIDFactory::MeshElement(int ID) const
+SMDS_MeshElement* SMDS_MeshElementIDFactory::MeshElement(int ID)
 {
-  if (!myIDElements.IsBound(ID))
+  if ((ID<1) || (ID>=myMesh->myCells.size()))
     return NULL;
-  return myIDElements.Find(ID);
-}
-
-
-//=======================================================================
-//function : GetFreeID
-//purpose  : 
-//=======================================================================
-int SMDS_MeshElementIDFactory::GetFreeID()
-{
-  int ID;
-  do {
-    ID = SMDS_MeshIDFactory::GetFreeID();
-  } while (myIDElements.IsBound(ID));
-  return ID;
+  const SMDS_MeshElement* elem = GetMesh()->FindElement(ID);
+  return (SMDS_MeshElement*)(elem);
 }
 
 //=======================================================================
 //function : ReleaseID
 //purpose  : 
 //=======================================================================
-void SMDS_MeshElementIDFactory::ReleaseID(const int ID)
+void SMDS_MeshElementIDFactory::ReleaseID(int ID, int vtkId)
 {
-  myIDElements.UnBind(ID);
+  if (ID < 1) // TODO check case ID == O
+    {
+      MESSAGE("~~~~~~~~~~~~~~ SMDS_MeshElementIDFactory::ReleaseID ID = " << ID);
+      return;
+    }
+  //MESSAGE("~~~~~~~~~~~~~~ SMDS_MeshElementIDFactory::ReleaseID smdsId vtkId " << ID << " " << vtkId);
+  if (vtkId >= 0)
+    {
+      assert(vtkId < myMesh->myCellIdVtkToSmds.size());
+      myMesh->myCellIdVtkToSmds[vtkId] = -1;
+      myMesh->setMyModified();
+    }
   SMDS_MeshIDFactory::ReleaseID(ID);
   if (ID == myMax)
     myMax = 0;
   if (ID == myMin)
-    myMin = 0;
-}
-
-//=======================================================================
-//function : GetMaxID
-//purpose  : 
-//=======================================================================
-
-int SMDS_MeshElementIDFactory::GetMaxID() const
-{
-  if (myMax == 0)
-    updateMinMax();
-  return myMax;
-}
-
-//=======================================================================
-//function : GetMinID
-//purpose  : 
-//=======================================================================
-
-int SMDS_MeshElementIDFactory::GetMinID() const
-{
-  if (myMin == 0)
-    updateMinMax();
-  return myMin;
+    myMax = 0;
 }
 
 //=======================================================================
@@ -130,9 +160,17 @@ void SMDS_MeshElementIDFactory::updateMinMax() const
 {
   myMin = IntegerLast();
   myMax = 0;
-  SMDS_IdElementMap::Iterator it(myIDElements);
-  for (; it.More(); it.Next())
-    updateMinMax (it.Key());
+  for (int i = 0; i < myMesh->myCells.size(); i++)
+    {
+      if (myMesh->myCells[i])
+        {
+          int id = myMesh->myCells[i]->GetID();
+          if (id > myMax)
+            myMax = id;
+          if (id < myMin)
+            myMin = id;
+        }
+    }
   if (myMin == IntegerLast())
     myMin = 0;
 }
@@ -142,35 +180,21 @@ void SMDS_MeshElementIDFactory::updateMinMax() const
 //purpose  : Return an iterator on elements of the factory
 //=======================================================================
 
-class SMDS_Fact_MyElemIterator:public SMDS_ElemIterator
-{
-  SMDS_IdElementMap::Iterator myIterator;
- public:
-  SMDS_Fact_MyElemIterator(const SMDS_IdElementMap& s):myIterator(s)
-  {}
-
-  bool more()
-  {
-    return myIterator.More() != Standard_False;
-  }
-
-  const SMDS_MeshElement* next()
-  {
-    const SMDS_MeshElement* current = myIterator.Value();
-    myIterator.Next();
-    return current;
-  }
-};
-
 SMDS_ElemIteratorPtr SMDS_MeshElementIDFactory::elementsIterator() const
 {
-  return SMDS_ElemIteratorPtr
-    (new SMDS_Fact_MyElemIterator(myIDElements));
+    return myMesh->elementsIterator(SMDSAbs_All);
 }
 
 void SMDS_MeshElementIDFactory::Clear()
 {
-  myIDElements.Clear();
+  //myMesh->myCellIdSmdsToVtk.clear();
+  myMesh->myCellIdVtkToSmds.clear();
   myMin = myMax = 0;
   SMDS_MeshIDFactory::Clear();
 }
+
+int SMDS_MeshElementIDFactory::GetVtkCellType(int SMDSType)
+{
+    assert((SMDSType >=0) && (SMDSType< SMDSEntity_Last));
+    return myVtkCellTypes[SMDSType];
+}
index 548cd452a82dd68a057ed6b957558108d69785ec..3ce1674b4b05857da742e93c8fd108649df64b74 100644 (file)
 
 #include "SMESH_SMDS.hxx"
 
-#include "SMDS_MeshIDFactory.hxx"
-#include "SMDS_ElemIterator.hxx"
+#include "SMDS_MeshNodeIDFactory.hxx"
 
-#include <NCollection_DataMap.hxx>
+#include <vector>
 
 class SMDS_MeshElement;
+class SMDS_Mesh;
 
-typedef NCollection_DataMap<int, SMDS_MeshElement *> SMDS_IdElementMap;
-
-class SMDS_EXPORT SMDS_MeshElementIDFactory:public SMDS_MeshIDFactory
+class SMDS_EXPORT SMDS_MeshElementIDFactory:public SMDS_MeshNodeIDFactory
 {
 public:
+  friend class SMDS_Mesh;
+  
   SMDS_MeshElementIDFactory();
   bool BindID(int ID, SMDS_MeshElement * elem);
-  SMDS_MeshElement * MeshElement(int ID) const;
-  virtual int GetFreeID();
-  virtual void ReleaseID(int ID);
-  int GetMaxID() const;
-  int GetMinID() const;
+  int SetInVtkGrid(SMDS_MeshElement * elem);
+  SMDS_MeshElement * MeshElement(int ID);
+  virtual void ReleaseID(int ID, int vtkId = -1);
   SMDS_ElemIteratorPtr elementsIterator() const;
   virtual void Clear();
-private:
+  int GetVtkCellType(int SMDSType);
+
+protected:
   void updateMinMax() const;
   void updateMinMax(int id) const
   {
@@ -58,8 +58,7 @@ private:
     if (id < myMin) myMin = id;
   }
 
-  SMDS_IdElementMap myIDElements;
-  mutable int myMin, myMax;
+  std::vector<int> myVtkCellTypes;
 
 };
 
index 45598898ae108eba82730f8c2a5633202e2b9d38..691bdc1165b9145b885295c192ff9fec0669fc76 100644 (file)
@@ -28,3 +28,8 @@ SMDSAbs_ElementType SMDS_MeshFace::GetType() const
 {
         return SMDSAbs_Face;
 }
+
+vtkIdType SMDS_MeshFace::GetVtkType() const
+{
+  return VTK_POLY_LINE;  // --- must be reimplemented in derived classes
+}
index 2e59ce53e2bc4f42397892d7b6c67aed8cae049f..6587b2960ffa524fa70449e4fa0cd41b55922d51 100644 (file)
 
 #include "SMESH_SMDS.hxx"
 
-#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshCell.hxx"
 
-class SMDS_EXPORT SMDS_MeshFace:public SMDS_MeshElement
+class SMDS_EXPORT SMDS_MeshFace:public SMDS_MeshCell
 {
   public:
         SMDSAbs_ElementType GetType() const;
+        virtual vtkIdType GetVtkType() const;
 };
 
 #endif
index 5d79cf34a029659ddfada2b4e514e3cd837a8091..f254c700337e9261320cd0b09842c169d7be4493 100644 (file)
@@ -26,6 +26,8 @@
 //  Module : SMESH
 //
 #include "SMDS_MeshIDFactory.hxx"
+#include "SMDS_Mesh.hxx"
+#include "utilities.h"
 
 using namespace std;
 
@@ -34,27 +36,33 @@ using namespace std;
 //purpose  : 
 //=======================================================================
 
-SMDS_MeshIDFactory::SMDS_MeshIDFactory():myMaxID(0)
+SMDS_MeshIDFactory::SMDS_MeshIDFactory():myMaxID(0), myMesh(0)
 {
 }
 
 int SMDS_MeshIDFactory::GetFreeID()
 {
-        if (myPoolOfID.empty()) return ++myMaxID;
+        int newid;
+        if (myPoolOfID.empty())
+        {
+            newid = ++myMaxID;
+            //MESSAGE("GetFreeID new " << newid);
+        }
         else
         {
                 set<int>::iterator i = myPoolOfID.begin();
-                int ID = *i;//myPoolOfID.top();
+                newid = *i;//myPoolOfID.top();
                 myPoolOfID.erase( i );//myPoolOfID.pop();
-                return ID;
+                //MESSAGE("GetFreeID pool " << newid);
         }
+    return newid;
 }
 
 //=======================================================================
 //function : ReleaseID
 //purpose  : 
 //=======================================================================
-void SMDS_MeshIDFactory::ReleaseID(const int ID)
+void SMDS_MeshIDFactory::ReleaseID(int ID, int vtkId)
 {
   if ( ID > 0 )
   {
@@ -83,6 +91,24 @@ void SMDS_MeshIDFactory::ReleaseID(const int ID)
 
 void SMDS_MeshIDFactory::Clear()
 {
-  myMaxID = 0;
-  myPoolOfID.clear();
+       myMaxID = 0;
+       myPoolOfID.clear();
+}
+
+void SMDS_MeshIDFactory::SetMesh(SMDS_Mesh *mesh)
+{
+       myMesh = mesh;
+}
+
+SMDS_Mesh* SMDS_MeshIDFactory::GetMesh()
+{
+       return myMesh;
+}
+
+void SMDS_MeshIDFactory::emptyPool(int maxId)
+{
+       MESSAGE("SMDS_MeshIDFactory::emptyPool " << myMaxID << " --> " << maxId);
+       myMaxID = maxId;
+       myPoolOfID.clear();
 }
+
index b86abf550381efcb99fec037dcc58cb85c326610..fed18dc69f7b77d8853509a6f30902d843406cbc 100644 (file)
 #include "SMDS_MeshObject.hxx"
 #include <set>
 
+class SMDS_Mesh;
 
 class SMDS_EXPORT SMDS_MeshIDFactory:public SMDS_MeshObject
 {
 public:
-  virtual int  GetFreeID();
-  virtual void ReleaseID(int ID);
+  int  GetFreeID();
+  virtual void ReleaseID(int ID, int vtkId = -1);
   virtual void Clear();
 
-  protected:
-        SMDS_MeshIDFactory();
-        int myMaxID;
-        std::set<int> myPoolOfID;
+  void SetMesh(SMDS_Mesh *mesh);
+  SMDS_Mesh* GetMesh();
+  inline bool isPoolIdEmpty() { return myPoolOfID.empty(); };
+  virtual void emptyPool(int maxId);
+  inline void adjustMaxId(int ID) { if (ID > myMaxID) myMaxID = ID;};
+protected:
+  SMDS_MeshIDFactory();
+  int myMaxID;
+  std::set<int> myPoolOfID;
+  SMDS_Mesh *myMesh;
 };
 
 #endif
index 9df6348a5bee159e05d10bf6a870cdc1627a47ef..c574b867121dcd51d2a894d22dac859e6a12869b 100644 (file)
 #include "SMDS_MeshNode.hxx"
 #include "SMDS_SpacePosition.hxx"
 #include "SMDS_IteratorOfElements.hxx"
+#include "SMDS_Mesh.hxx"
+#include <vtkUnstructuredGrid.h>
+
+#define protected public
+#include <vtkCellLinks.h>
+#define protected protected
+
+#include "utilities.h"
+#include "Utils_SALOME_Exception.hxx"
+#include <cassert>
 
 using namespace std;
 
+int SMDS_MeshNode::nbNodes =0;
+
 //=======================================================================
 //function : SMDS_MeshNode
 //purpose  : 
 //=======================================================================
+SMDS_MeshNode::SMDS_MeshNode() :
+  SMDS_MeshElement(-1, -1, 0),
+  myPosition(SMDS_SpacePosition::originSpacePosition())
+{
+  nbNodes++;
+}
+
+SMDS_MeshNode::SMDS_MeshNode(int id, int meshId, int shapeId, double x, double y, double z):
+  SMDS_MeshElement(id, meshId, shapeId),
+  myPosition(SMDS_SpacePosition::originSpacePosition())
+{
+  nbNodes++;
+  init(id, meshId, shapeId, x, y ,z);
+}
+
+void SMDS_MeshNode::init(int id, int meshId, int shapeId, double x, double y, double z)
+{
+  myVtkID = id -1;
+  assert(myVtkID >= 0);
+  myID = id;
+  myMeshId = meshId;
+  myShapeId = shapeId;
+  myIdInShape = -1;
+  //MESSAGE("Node " << myID << " " << myVtkID << " (" << x << ", " << y << ", " << z << ")");
+  SMDS_Mesh* mesh = SMDS_Mesh::_meshList[myMeshId];
+  vtkUnstructuredGrid * grid = mesh->getGrid();
+  vtkPoints *points = grid->GetPoints();
+  points->InsertPoint(myVtkID, x, y, z);
+  vtkCellLinks *cellLinks = grid->GetCellLinks();
+  if (myVtkID >=cellLinks->Size)
+         cellLinks->Resize(myVtkID+SMDS_Mesh::chunkSize);
+}
 
-SMDS_MeshNode::SMDS_MeshNode(double x, double y, double z):
-        myX(x), myY(y), myZ(z),
-        myPosition(SMDS_SpacePosition::originSpacePosition())
+SMDS_MeshNode::~SMDS_MeshNode()
 {
+  nbNodes--;
 }
 
 //=======================================================================
@@ -50,14 +93,10 @@ SMDS_MeshNode::SMDS_MeshNode(double x, double y, double z):
 
 void SMDS_MeshNode::RemoveInverseElement(const SMDS_MeshElement * parent)
 {
-  NCollection_List<const SMDS_MeshElement*>::Iterator it(myInverseElements);
-  while (it.More()) {
-    const SMDS_MeshElement* elem = it.Value();
-    if (elem == parent)
-      myInverseElements.Remove(it);
-    else
-      it.Next();
-  }
+    //MESSAGE("RemoveInverseElement " << myID << " " << parent->GetID());
+    const SMDS_MeshCell* cell = dynamic_cast<const SMDS_MeshCell*>(parent);
+    MYASSERT(cell);
+    SMDS_Mesh::_meshList[myMeshId]->getGrid()->RemoveReferenceToCell(myVtkID, cell->getVtkId());
 }
 
 //=======================================================================
@@ -67,8 +106,8 @@ void SMDS_MeshNode::RemoveInverseElement(const SMDS_MeshElement * parent)
 
 void SMDS_MeshNode::Print(ostream & OS) const
 {
-        OS << "Node <" << GetID() << "> : X = " << myX << " Y = "
-                << myY << " Z = " << myZ << endl;
+        OS << "Node <" << myID << "> : X = " << X() << " Y = "
+                << Y() << " Z = " << Z() << endl;
 }
 
 //=======================================================================
@@ -97,77 +136,116 @@ const SMDS_PositionPtr& SMDS_MeshNode::GetPosition() const
  */
 //=======================================================================
 
-class SMDS_MeshNode_MyInvIterator:public SMDS_ElemIterator
+class SMDS_MeshNode_MyInvIterator: public SMDS_ElemIterator
 {
-  NCollection_List<const SMDS_MeshElement*>::Iterator myIterator;
-  SMDSAbs_ElementType                                 myType;
- public:
-  SMDS_MeshNode_MyInvIterator(const NCollection_List<const SMDS_MeshElement*>& s,
-                              SMDSAbs_ElementType type):
-    myIterator(s), myType(type)
-  {}
+private:
+  SMDS_Mesh* myMesh;
+  vtkIdType* myCells;
+  int myNcells;
+  SMDSAbs_ElementType myType;
+  int iter;
+  vector<vtkIdType> cellList;
+
+public:
+  SMDS_MeshNode_MyInvIterator(SMDS_Mesh *mesh, vtkIdType* cells, int ncells, SMDSAbs_ElementType type) :
+    myMesh(mesh), myCells(cells), myNcells(ncells), myType(type), iter(0)
+  {
+    //MESSAGE("SMDS_MeshNode_MyInvIterator : ncells " << myNcells);
+    cellList.clear();
+    if (type == SMDSAbs_All)
+      for (int i = 0; i < ncells; i++)
+        cellList.push_back(cells[i]);
+    else for (int i = 0; i < ncells; i++)
+      {
+        int vtkId = cells[i];
+        int smdsId = myMesh->fromVtkToSmds(vtkId);
+        const SMDS_MeshElement* elem = myMesh->FindElement(smdsId);
+        if (elem->GetType() == type)
+          {
+            //MESSAGE("Add element vtkId " << vtkId << " " << elem->GetType())
+            cellList.push_back(vtkId);
+          }
+      }
+    myCells = &cellList[0];
+    myNcells = cellList.size();
+    //MESSAGE("myNcells="<<myNcells);
+  }
 
   bool more()
   {
-    if ( myType != SMDSAbs_All ) {
-      while ( myIterator.More() && myIterator.Value()->GetType() != myType)
-        myIterator.Next();
-    }
-    return myIterator.More() != Standard_False;
+    //MESSAGE("iter " << iter << " ncells " << myNcells);
+    return (iter < myNcells);
   }
 
   const SMDS_MeshElement* next()
   {
-    if ( !more() ) return 0;
-    const SMDS_MeshElement* current=myIterator.Value();
-    myIterator.Next();
-    return current;
-  }     
+    int vtkId = myCells[iter];
+    int smdsId = myMesh->fromVtkToSmds(vtkId);
+    const SMDS_MeshElement* elem = myMesh->FindElement(smdsId);
+    if (!elem)
+      {
+        MESSAGE("SMDS_MeshNode_MyInvIterator problem Null element");
+        throw SALOME_Exception("SMDS_MeshNode_MyInvIterator problem Null element");
+      }
+    //MESSAGE("vtkId " << vtkId << " smdsId " << smdsId << " " << elem->GetType());
+    iter++;
+    return elem;
+  }
 };
 
 SMDS_ElemIteratorPtr SMDS_MeshNode::
         GetInverseElementIterator(SMDSAbs_ElementType type) const
 {
-  return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(myInverseElements,type));
+    vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID);
+    //MESSAGE("myID " << myID << " ncells " << l.ncells);
+    return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(SMDS_Mesh::_meshList[myMeshId], l.cells, l.ncells, type));
 }
 
 // Same as GetInverseElementIterator but the create iterator only return
 // wanted type elements.
 class SMDS_MeshNode_MyIterator:public SMDS_ElemIterator
 {
-  NCollection_List<const SMDS_MeshElement*> mySet;
-  NCollection_List<const SMDS_MeshElement*>::Iterator myIterator;
+private:
+  SMDS_Mesh* myMesh;
+  vtkIdType* myCells;
+  int  myNcells;
+  SMDSAbs_ElementType                                 myType;
+  int  iter;
+  vector<SMDS_MeshElement*> myFiltCells;
+
  public:
-  SMDS_MeshNode_MyIterator(SMDSAbs_ElementType type,
-                           const NCollection_List<const SMDS_MeshElement*>& s)
+  SMDS_MeshNode_MyIterator(SMDS_Mesh *mesh,
+                           vtkIdType* cells,
+                           int ncells,
+                           SMDSAbs_ElementType type):
+    myMesh(mesh), myCells(cells), myNcells(ncells), myType(type), iter(0)
   {
-    const SMDS_MeshElement * e;
-    bool toInsert;
-    NCollection_List<const SMDS_MeshElement*>::Iterator it(s);
-    for(; it.More(); it.Next())
-    {
-      e=it.Value();
-      switch(type)
-      {
-      case SMDSAbs_Edge: toInsert=true; break;
-      case SMDSAbs_Face: toInsert=(e->GetType()!=SMDSAbs_Edge); break;
-      case SMDSAbs_Volume: toInsert=(e->GetType()==SMDSAbs_Volume); break;
-      }
-      if(toInsert) mySet.Append(e);
-    }
-    myIterator.Init(mySet);
+       //MESSAGE("myNcells " << myNcells);
+       for (; iter<ncells; iter++)
+        {
+           int vtkId = myCells[iter];
+           int smdsId = myMesh->fromVtkToSmds(vtkId);
+           //MESSAGE("vtkId " << vtkId << " smdsId " << smdsId);
+           const SMDS_MeshElement* elem = myMesh->FindElement(smdsId);
+           if (elem->GetType() == type)
+               myFiltCells.push_back((SMDS_MeshElement*)elem);
+        }
+        myNcells = myFiltCells.size();
+               //MESSAGE("myNcells " << myNcells);
+       iter = 0;
+        //MESSAGE("SMDS_MeshNode_MyIterator (filter) " << ncells << " " << myNcells);
   }
 
   bool more()
   {
-    return myIterator.More() != Standard_False;
+      return (iter< myNcells);
   }
 
   const SMDS_MeshElement* next()
   {
-    const SMDS_MeshElement* current=myIterator.Value();
-    myIterator.Next();
-    return current;
+      const SMDS_MeshElement* elem = myFiltCells[iter];
+      iter++;
+      return elem;
   }
 };
 
@@ -177,10 +255,10 @@ SMDS_ElemIteratorPtr SMDS_MeshNode::
   if(type==SMDSAbs_Node)
     return SMDS_MeshElement::elementsIterator(SMDSAbs_Node); 
   else
-    return SMDS_ElemIteratorPtr
-      (new SMDS_IteratorOfElements
-       (this,type,
-        SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyIterator(type, myInverseElements))));
+  {
+    vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID);
+    return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyIterator(SMDS_Mesh::_meshList[myMeshId], l.cells, l.ncells, type));
+  }
 }
 
 int SMDS_MeshNode::NbNodes() const
@@ -188,26 +266,37 @@ int SMDS_MeshNode::NbNodes() const
         return 1;
 }
 
+double* SMDS_MeshNode::getCoord() const
+{
+  return SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetPoint(myVtkID);
+}
+
 double SMDS_MeshNode::X() const
 {
-        return myX;
+  double *coord = getCoord();
+  return coord[0];
 }
 
 double SMDS_MeshNode::Y() const
 {
-        return myY;
+  double *coord = getCoord();
+  return coord[1];
 }
 
 double SMDS_MeshNode::Z() const
 {
-        return myZ;
+  double *coord = getCoord();
+  return coord[2];
 }
 
+//* resize the vtkPoints structure every SMDS_Mesh::chunkSize points
 void SMDS_MeshNode::setXYZ(double x, double y, double z)
 {
-        myX=x;
-        myY=y;
-        myZ=z;  
+  SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId];
+  vtkPoints *points = mesh->getGrid()->GetPoints();
+  points->InsertPoint(myVtkID, x, y, z);
+  mesh->adjustBoundingBox(x, y, z);
+  mesh->setMyModified();
 }
 
 SMDSAbs_ElementType SMDS_MeshNode::GetType() const
@@ -215,19 +304,20 @@ SMDSAbs_ElementType SMDS_MeshNode::GetType() const
         return SMDSAbs_Node;
 }
 
+vtkIdType SMDS_MeshNode::GetVtkType() const
+{
+  return VTK_VERTEX;
+}
+
 //=======================================================================
 //function : AddInverseElement
 //purpose  :
 //=======================================================================
 void SMDS_MeshNode::AddInverseElement(const SMDS_MeshElement* ME)
 {
-  NCollection_List<const SMDS_MeshElement*>::Iterator it(myInverseElements);
-  for (; it.More(); it.Next()) {
-    const SMDS_MeshElement* elem = it.Value();
-    if (elem == ME)
-      return;
-  }
-  myInverseElements.Append(ME);
+    const SMDS_MeshCell *cell = dynamic_cast<const SMDS_MeshCell*>(ME);
+    assert(cell);
+    SMDS_Mesh::_meshList[myMeshId]->getGrid()->AddReferenceToCell(myVtkID, cell->getVtkId());
 }
 
 //=======================================================================
@@ -236,7 +326,13 @@ void SMDS_MeshNode::AddInverseElement(const SMDS_MeshElement* ME)
 //=======================================================================
 void SMDS_MeshNode::ClearInverseElements()
 {
-  myInverseElements.Clear();
+  SMDS_Mesh::_meshList[myMeshId]->getGrid()->ResizeCellList(myVtkID, 0);
+}
+
+bool SMDS_MeshNode::emptyInverseElements()
+{
+  vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID);
+  return (l.ncells == 0);
 }
 
 //================================================================================
@@ -247,13 +343,19 @@ void SMDS_MeshNode::ClearInverseElements()
 
 int SMDS_MeshNode::NbInverseElements(SMDSAbs_ElementType type) const
 {
+  vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID);
+
   if ( type == SMDSAbs_All )
-    return myInverseElements.Extent();
+    return l.ncells;
+
   int nb = 0;
-  NCollection_List<const SMDS_MeshElement*>::Iterator it( myInverseElements );
-  for ( ; it.More(); it.Next() )
-    if ( it.Value()->GetType() == type )
-      nb++;
+  SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId];
+  for (int i=0; i<l.ncells; i++)
+        {
+           const SMDS_MeshElement* elem = mesh->FindElement(mesh->fromVtkToSmds(l.cells[i]));
+           if (elem->GetType() == type)
+                nb++;
+        }
   return nb;
 }
 
@@ -262,7 +364,7 @@ int SMDS_MeshNode::NbInverseElements(SMDSAbs_ElementType type) const
 ///////////////////////////////////////////////////////////////////////////////
 bool operator<(const SMDS_MeshNode& e1, const SMDS_MeshNode& e2)
 {
-        return e1.GetID()<e2.GetID();
+        return e1.getVtkId()<e2.getVtkId();
         /*if(e1.myX<e2.myX) return true;
         else if(e1.myX==e2.myX)
         {
index 9ab02f20ffd002add16147c91e9d543c109ff380..02fc1ef61bb0bdbe21bc94e429ffbd329196bd77 100644 (file)
 
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_Position.hxx"
+#include "ObjectPool.hxx"
 #include <NCollection_List.hxx>
 
 class SMDS_EXPORT SMDS_MeshNode:public SMDS_MeshElement
 {
-
 public:
-  SMDS_MeshNode(double x, double y, double z);
+  friend class SMESHDS_Mesh;
+  friend class SMDS_Mesh;
+  friend class ObjectPool<SMDS_MeshNode>;
 
+  void Print(std::ostream & OS) const;
   double X() const;
   double Y() const;
   double Z() const;
-  void setXYZ(double x, double y, double z);
-
-  void AddInverseElement(const SMDS_MeshElement * ME);
-  void RemoveInverseElement(const SMDS_MeshElement * parent);
-  void ClearInverseElements();
   SMDS_ElemIteratorPtr GetInverseElementIterator(SMDSAbs_ElementType type=SMDSAbs_All) const;
   int NbInverseElements(SMDSAbs_ElementType type=SMDSAbs_All) const;
-
-  void SetPosition(const SMDS_PositionPtr& aPos);
   const SMDS_PositionPtr& GetPosition() const;
-
   SMDSAbs_ElementType GetType() const;
+  virtual vtkIdType GetVtkType() const;
   SMDSAbs_EntityType  GetEntityType() const {return SMDSEntity_Node;}
+  int NbNodes() const;
 
   friend bool operator<(const SMDS_MeshNode& e1, const SMDS_MeshNode& e2);
-  void Print(std::ostream & OS) const;
 
-  /*!
-   * \brief Return node by its index
-   * \param ind - node index
-   * \retval const SMDS_MeshNode* - the node
-   */
-  virtual const SMDS_MeshNode* GetNode(const int) const { return this; }
-  virtual int NbNodes() const;
+  void SetPosition(const SMDS_PositionPtr& aPos);
+  void setXYZ(double x, double y, double z);
+
+  static int nbNodes;
 
 protected:
+  SMDS_MeshNode();
+  SMDS_MeshNode(int id, int meshId, int shapeId = -1, double x=0, double y=0, double z=0);
+  virtual ~SMDS_MeshNode();
+  void init(int id, int meshId, int shapeId = -1, double x=0, double y=0, double z=0);
+  inline void setVtkId(int vtkId) { myVtkID = vtkId; };
+  double* getCoord() const;
+  void AddInverseElement(const SMDS_MeshElement * ME);
+  void RemoveInverseElement(const SMDS_MeshElement * parent);
+  void ClearInverseElements();
+  bool emptyInverseElements();
+
   SMDS_ElemIteratorPtr
   elementsIterator(SMDSAbs_ElementType type) const;
 
 private:
-  double myX, myY, myZ;
   SMDS_PositionPtr myPosition;
-  NCollection_List<const SMDS_MeshElement*> myInverseElements;
 };
 
 #endif
diff --git a/src/SMDS/SMDS_MeshNodeIDFactory.cxx b/src/SMDS/SMDS_MeshNodeIDFactory.cxx
new file mode 100644 (file)
index 0000000..4a31041
--- /dev/null
@@ -0,0 +1,136 @@
+//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  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
+//
+//  SMESH SMDS : implementaion of Salome mesh data structure
+//  File   : SMDS_MeshNodeIDFactory.cxx
+//  Author : Jean-Michel BOULCOURT
+//  Module : SMESH
+//
+#ifdef _MSC_VER
+#pragma warning(disable:4786)
+#endif
+
+#include "SMDS_MeshNodeIDFactory.hxx"
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_Mesh.hxx"
+
+#include <vtkUnstructuredGrid.h>
+#include <vtkCellType.h>
+
+using namespace std;
+
+//=======================================================================
+//function : SMDS_MeshNodeIDFactory
+//purpose  : 
+//=======================================================================
+SMDS_MeshNodeIDFactory::SMDS_MeshNodeIDFactory() :
+  SMDS_MeshIDFactory(), myMin(0), myMax(0)
+{
+}
+
+//=======================================================================
+//function : BindID
+//purpose  : 
+//=======================================================================
+bool SMDS_MeshNodeIDFactory::BindID(int ID, SMDS_MeshElement * elem)
+{
+  updateMinMax(ID);
+  return true;
+}
+
+//=======================================================================
+//function : MeshElement
+//purpose  : 
+//=======================================================================
+SMDS_MeshElement* SMDS_MeshNodeIDFactory::MeshElement(int ID)
+{
+  if ((ID < 1) || (ID > myMax))
+    return NULL;
+  const SMDS_MeshElement* elem = GetMesh()->FindNode(ID);
+  return (SMDS_MeshElement*) (elem);
+}
+
+//=======================================================================
+//function : ReleaseID
+//purpose  : 
+//=======================================================================
+void SMDS_MeshNodeIDFactory::ReleaseID(const int ID, int vtkId)
+{
+  SMDS_MeshIDFactory::ReleaseID(ID);
+  myMesh->setMyModified();
+  if (ID == myMax)
+    myMax = 0; // --- force updateMinMax
+  if (ID == myMin)
+    myMax = 0; // --- force updateMinMax
+}
+
+//=======================================================================
+//function : GetMaxID
+//purpose  : 
+//=======================================================================
+
+int SMDS_MeshNodeIDFactory::GetMaxID() const
+{
+  if (myMax == 0)
+    updateMinMax();
+  return myMax;
+}
+
+//=======================================================================
+//function : GetMinID
+//purpose  : 
+//=======================================================================
+
+int SMDS_MeshNodeIDFactory::GetMinID() const
+{
+  if (myMax == 0)
+    updateMinMax();
+  return myMin;
+}
+
+//=======================================================================
+//function : updateMinMax
+//purpose  : 
+//=======================================================================
+
+void SMDS_MeshNodeIDFactory::updateMinMax() const
+{
+  myMesh->updateNodeMinMax();
+  myMin = myMesh->MinNodeID();
+  myMax = myMesh->MaxNodeID();
+}
+
+SMDS_ElemIteratorPtr SMDS_MeshNodeIDFactory::elementsIterator() const
+{
+  return myMesh->elementsIterator(SMDSAbs_Node);
+}
+
+void SMDS_MeshNodeIDFactory::Clear()
+{
+  myMin = myMax = 0;
+  SMDS_MeshIDFactory::Clear();
+}
+
+void SMDS_MeshNodeIDFactory::emptyPool(int maxId)
+{
+  SMDS_MeshIDFactory::emptyPool(maxId);
+  myMax = maxId;
+}
diff --git a/src/SMDS/SMDS_MeshNodeIDFactory.hxx b/src/SMDS/SMDS_MeshNodeIDFactory.hxx
new file mode 100644 (file)
index 0000000..a79d68e
--- /dev/null
@@ -0,0 +1,65 @@
+//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  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
+//
+//  SMESH SMDS : implementaion of Salome mesh data structure
+//  File   : SMDS_MeshElementIDFactory.hxx
+//  Module : SMESH
+//
+#ifndef _SMDS_MeshNodeIDFactory_HeaderFile
+#define _SMDS_MeshNodeIDFactory_HeaderFile
+
+#include "SMESH_SMDS.hxx"
+
+#include "SMDS_MeshIDFactory.hxx"
+#include "SMDS_ElemIterator.hxx"
+
+#include <vector>
+
+class SMDS_MeshElement;
+
+class SMDS_EXPORT SMDS_MeshNodeIDFactory: public SMDS_MeshIDFactory
+{
+public:
+  SMDS_MeshNodeIDFactory();
+  bool BindID(int ID, SMDS_MeshElement * elem);
+  SMDS_MeshElement * MeshElement(int ID);
+  virtual void ReleaseID(int ID, int vtkId = -1);
+  int GetMaxID() const;
+  int GetMinID() const;
+  SMDS_ElemIteratorPtr elementsIterator() const;
+  virtual void Clear();
+  virtual void emptyPool(int maxId);
+
+protected:
+  void updateMinMax() const;
+  void updateMinMax(int id) const
+  {
+    if (id > myMax)
+      myMax = id;
+    if (id < myMin)
+      myMin = id;
+  }
+
+  mutable int myMin, myMax;
+
+};
+
+#endif
index d4bef7da5dc42673cc7d127744c8fe68b3e93e6c..dae6ee1db0a89f51d5c57db89494972dc9465062 100644 (file)
@@ -36,3 +36,7 @@ SMDSAbs_ElementType SMDS_MeshVolume::GetType() const
         return SMDSAbs_Volume;
 }
 
+vtkIdType SMDS_MeshVolume::GetVtkType() const
+{
+  return VTK_CONVEX_POINT_SET; // --- must be reimplemented in derived classes
+}
index ca703b3799d4948068c5307d9af67a89526884b2..0aac68b711ee97fe7d6f340287d9ab00e94f3bec 100644 (file)
 
 #include "SMESH_SMDS.hxx"
 
-#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshCell.hxx"
 
-class SMDS_EXPORT SMDS_MeshVolume:public SMDS_MeshElement
+class SMDS_EXPORT SMDS_MeshVolume:public SMDS_MeshCell
 {
         
   public:
         SMDSAbs_ElementType GetType() const;
+  virtual vtkIdType GetVtkType() const;
 };
 #endif
index b441db266e8db2c8a689d1f6d0dad9ca79cd7967..9d7be9028d0f522d912f87520b5152fed18ad39b 100644 (file)
@@ -43,6 +43,7 @@ using namespace std;
 SMDS_PolygonalFaceOfNodes::SMDS_PolygonalFaceOfNodes
                           (std::vector<const SMDS_MeshNode *> nodes)
 {
+  //MESSAGE("******************************************** SMDS_PolygonalFaceOfNodes");
   myNodes = nodes;
 }
 
index 54143251a4ed3009207fa1cc54b6f674c3bd6675..1de208b1ba837a6627e44b48eca8bd9266336a9c 100644 (file)
@@ -45,6 +45,7 @@ SMDS_PolyhedralVolumeOfNodes::SMDS_PolyhedralVolumeOfNodes
                                  vector<int>                   quantities)
 : SMDS_VolumeOfNodes(NULL, NULL, NULL, NULL)
 {
+  //MESSAGE("****************************************** SMDS_PolyhedralVolumeOfNodes");
   ChangeNodes(nodes, quantities);
 }
 
index a2dfc7847ffedba9683af5f42d6c01cd879c8baa..e0c6d853d6ae14f5467219f60095cb588e4712aa 100644 (file)
 //  Module : SMESH
 //
 #include "SMDS_Position.hxx"
+#include "utilities.h"
 
 //=======================================================================
 //function : SMDS_Position
 //purpose  : 
 //=======================================================================
 
-SMDS_Position::SMDS_Position(int aShapeId) :myShapeId(aShapeId)
+SMDS_Position::SMDS_Position()
 {
-}
-
-//=======================================================================
-//function : SetShapeId
-//purpose  : 
-//=======================================================================
-
-void SMDS_Position::SetShapeId(int aShapeId)
-{
-        myShapeId = aShapeId;
-}
-
-//=======================================================================
-//function : GetShapeId
-//purpose  : 
-//=======================================================================
-
-int SMDS_Position::GetShapeId() const
-{
-        return myShapeId;
+  //MESSAGE("########################## SMDS_Position ");
 }
 
 //=======================================================================
index 11168fc85c036b49b958bd68fc7e84a8d3efd08f..31449526acfbcf627e59acf32ddc3e2fb4173d32 100644 (file)
 #include <boost/shared_ptr.hpp>
 
 class SMDS_Position;
-typedef boost::shared_ptr<SMDS_Position> SMDS_PositionPtr;
+//typedef boost::shared_ptr<SMDS_Position> SMDS_PositionPtr;
+typedef SMDS_Position* SMDS_PositionPtr;
 
 class SMDS_EXPORT SMDS_Position
 {
 
   public:
-        const virtual double * Coords() const = 0;
         virtual SMDS_TypeOfPosition GetTypeOfPosition() const = 0;
         virtual int GetDim() const;
-        void SetShapeId(int aShapeId);
-        int GetShapeId() const;
         virtual ~SMDS_Position() {}
 
   protected:
-          SMDS_Position(int aShapeId);
-
-  private:
-        int myShapeId;
+          SMDS_Position();
 };
 
 
index 2e41ad2964fa3f61ecf07d6d028dfd001731cf57..46d0e0f1cbfb605707d0c79290012eecaefef9c8 100644 (file)
@@ -30,6 +30,7 @@
 #include "SMDS_SetIterator.hxx"
 #include "SMDS_IteratorOfElements.hxx"
 #include "SMDS_MeshNode.hxx"
+#include "utilities.h"
 
 using namespace std;
 
@@ -41,8 +42,9 @@ using namespace std;
 SMDS_QuadraticEdge::SMDS_QuadraticEdge(const SMDS_MeshNode * node1,
                                        const SMDS_MeshNode * node2,
                                        const SMDS_MeshNode * node12)
-     :SMDS_MeshEdge(node1,node2)
-{       
+     :SMDS_LinearEdge(node1,node2)
+{
+  //MESSAGE("******************************************************* SMDS_QuadraticEdge");
   myNodes[2]=node12;
 }
 
index c0d15ad4dc5240c0fa25b49000eba31784dc8237..367f3b0419faaa76f1b489355937a8ea03a82201 100644 (file)
 
 #include "SMESH_SMDS.hxx"
 
-#include "SMDS_MeshEdge.hxx"
+#include "SMDS_LinearEdge.hxx"
 #include <iostream>
 
-class SMDS_EXPORT SMDS_QuadraticEdge: public SMDS_MeshEdge
+class SMDS_EXPORT SMDS_QuadraticEdge: public SMDS_LinearEdge
 {
 
 public:
index 6b69227ced5ca29d46399a2f91ce7fff8be371f8..5170f492bf46eb20bb76985f42ba6ca98b31d841 100644 (file)
@@ -49,6 +49,7 @@ SMDS_QuadraticFaceOfNodes::SMDS_QuadraticFaceOfNodes(const SMDS_MeshNode * n1,
                                                      const SMDS_MeshNode * n23,
                                                      const SMDS_MeshNode * n31)
 {
+  //MESSAGE("********************************************** SMDS_QuadraticFaceOfNodes 1");
   myNodes.resize( 6 );
   myNodes[ 0 ] = n1;
   myNodes[ 1 ] = n2;
@@ -73,6 +74,7 @@ SMDS_QuadraticFaceOfNodes::SMDS_QuadraticFaceOfNodes(const SMDS_MeshNode * n1,
                                                      const SMDS_MeshNode * n34,
                                                      const SMDS_MeshNode * n41)
 {
+  //MESSAGE("********************************************* SMDS_QuadraticFaceOfNodes 2");
   myNodes.resize( 8 );
   myNodes[ 0 ] = n1;
   myNodes[ 1 ] = n2;
index ea1147a4c8114306a80b559a7b6c7b12f0d30e18..ff5e4eacd34dd5a501f94064543455172c91b9ea 100644 (file)
@@ -54,6 +54,7 @@ SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes
                                                 const SMDS_MeshNode * n24,
                                                 const SMDS_MeshNode * n34)
 {
+  //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes");
   myNodes.resize( 10 );
   myNodes[ 0 ] = n1;
   myNodes[ 1 ] = n2;
@@ -88,6 +89,7 @@ SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes
                                                 const SMDS_MeshNode * n35,
                                                 const SMDS_MeshNode * n45)
 {
+  //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes");
   myNodes.resize( 13 );
   myNodes[ 0 ] = n1;
   myNodes[ 1 ] = n2;
@@ -127,6 +129,7 @@ SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes
                                                 const SMDS_MeshNode * n25,
                                                 const SMDS_MeshNode * n36)
 {
+  //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes");
   myNodes.resize( 15 );
   myNodes[ 0 ] = n1;
   myNodes[ 1 ] = n2;
@@ -173,6 +176,7 @@ SMDS_QuadraticVolumeOfNodes::SMDS_QuadraticVolumeOfNodes
                                                 const SMDS_MeshNode * n37,
                                                 const SMDS_MeshNode * n48)
 {
+  //MESSAGE("*********************************************** SMDS_QuadraticVolumeOfNodes");
   myNodes.resize( 20 );
   myNodes[ 0 ] = n1;
   myNodes[ 1 ] = n2;
index d42acecaa437fb90482c0550ed02e6a69457df55..5835b64340939ecc7d968fbb5e1b9c94b1ca4380 100644 (file)
 //  Author : Jean-Michel BOULCOURT
 //  Module : SMESH
 //
+
 #include "SMDS_SpacePosition.hxx"
 
-//=======================================================================
-//function : SMDS_SpacePosition
-//purpose  : 
-//=======================================================================
+SMDS_SpacePosition* SMDS_SpacePosition::_originPosition = new SMDS_SpacePosition();
 
-SMDS_SpacePosition::SMDS_SpacePosition(double x, double y, double z):
-        SMDS_Position(0)
+SMDS_SpacePosition::SMDS_SpacePosition(double x, double y, double z)
 {
-        myCoords[0]=x;
-        myCoords[1]=y;
-        myCoords[2]=z;
 }
 
-/**
-*/
 SMDS_TypeOfPosition SMDS_SpacePosition::GetTypeOfPosition() const
 {
-        return SMDS_TOP_3DSPACE;
-}
-
-const double * SMDS_SpacePosition::Coords() const
-{
-        return myCoords;
+  return SMDS_TOP_3DSPACE;
 }
 
 SMDS_PositionPtr SMDS_SpacePosition::originSpacePosition()
 {
-  static SMDS_PositionPtr staticpos (new SMDS_SpacePosition());
-  return staticpos;
+  return _originPosition;
 }
index 4f46dd699f1dbda001bc7ae998d9404440543963..49b7c89e414246cb54f4958238f380971b9dc557 100644 (file)
 class SMDS_EXPORT SMDS_SpacePosition:public SMDS_Position
 {
 
-  public:
-        SMDS_SpacePosition(double x=0, double y=0, double z=0);
-        const virtual double * Coords() const;
-        virtual inline SMDS_TypeOfPosition GetTypeOfPosition() const;
-        inline void SetCoords(const double x, const double y, const double z);
-        static SMDS_PositionPtr originSpacePosition();
-  private:
-        double myCoords[3];     
+public:
+  SMDS_SpacePosition(double x=0, double y=0, double z=0);
+  virtual inline SMDS_TypeOfPosition GetTypeOfPosition() const;
+  static SMDS_PositionPtr originSpacePosition();
+private:
+  static SMDS_SpacePosition* _originPosition;
 };
 
 #endif
diff --git a/src/SMDS/SMDS_UnstructuredGrid.cxx b/src/SMDS/SMDS_UnstructuredGrid.cxx
new file mode 100644 (file)
index 0000000..7b65dfd
--- /dev/null
@@ -0,0 +1,841 @@
+#define CHRONODEF
+#include "SMDS_UnstructuredGrid.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDS_MeshInfo.hxx"
+#include "SMDS_Downward.hxx"
+
+#include "utilities.h"
+
+#include <vtkCellArray.h>
+#include <vtkCellLinks.h>
+#include <vtkIdTypeArray.h>
+#include <vtkUnsignedCharArray.h>
+
+#include <list>
+
+using namespace std;
+
+SMDS_UnstructuredGrid* SMDS_UnstructuredGrid::New()
+{
+  MESSAGE("SMDS_UnstructuredGrid::New");
+  return new SMDS_UnstructuredGrid();
+}
+
+SMDS_UnstructuredGrid::SMDS_UnstructuredGrid() :
+  vtkUnstructuredGrid()
+{
+  _cellIdToDownId.clear();
+  _downTypes.clear();
+  _downArray.clear();
+  _mesh = 0;
+}
+
+SMDS_UnstructuredGrid::~SMDS_UnstructuredGrid()
+{
+}
+
+unsigned long SMDS_UnstructuredGrid::GetMTime()
+{
+  unsigned long mtime = vtkUnstructuredGrid::GetMTime();
+  MESSAGE("vtkUnstructuredGrid::GetMTime: " << mtime);
+  return mtime;
+}
+
+void SMDS_UnstructuredGrid::Update()
+{
+  MESSAGE("SMDS_UnstructuredGrid::Update");
+  return vtkUnstructuredGrid::Update();
+}
+
+void SMDS_UnstructuredGrid::UpdateInformation()
+{
+  MESSAGE("SMDS_UnstructuredGrid::UpdateInformation");
+  return vtkUnstructuredGrid::UpdateInformation();
+}
+
+vtkPoints* SMDS_UnstructuredGrid::GetPoints()
+{
+  // TODO erreur incomprehensible de la macro vtk GetPoints apparue avec la version paraview de fin aout 2010
+  //MESSAGE("*********************** SMDS_UnstructuredGrid::GetPoints " << this->Points << " " << vtkUnstructuredGrid::GetPoints());
+  return this->Points;
+}
+
+//#ifdef VTK_HAVE_POLYHEDRON
+int SMDS_UnstructuredGrid::InsertNextLinkedCell(int type, int npts, vtkIdType *pts)
+{
+  if (type != VTK_POLYHEDRON)
+    return vtkUnstructuredGrid::InsertNextLinkedCell(type, npts, pts);
+
+  // --- type = VTK_POLYHEDRON
+  MESSAGE("InsertNextLinkedCell VTK_POLYHEDRON");
+  int cellid = this->InsertNextCell(type, npts, pts);
+
+  set<vtkIdType> setOfNodes;
+  setOfNodes.clear();
+  int nbfaces = npts;
+  int i = 0;
+  for (int nf = 0; nf < nbfaces; nf++)
+    {
+      int nbnodes = pts[i];
+      i++;
+      for (int k = 0; k < nbnodes; k++)
+        {
+          MESSAGE(" cell " << cellid << " face " << nf << " node " << pts[i]);
+          setOfNodes.insert(pts[i]);
+          i++;
+        }
+    }
+
+  set<vtkIdType>::iterator it = setOfNodes.begin();
+  for (; it != setOfNodes.end(); ++it)
+    {
+      MESSAGE("reverse link for node " << *it << " cell " << cellid);
+      this->Links->ResizeCellList(*it, 1);
+      this->Links->AddCellReference(cellid, *it);
+    }
+
+  return cellid;
+}
+//#endif
+
+void SMDS_UnstructuredGrid::setSMDS_mesh(SMDS_Mesh *mesh)
+{
+  _mesh = mesh;
+}
+
+void SMDS_UnstructuredGrid::compactGrid(std::vector<int>& idNodesOldToNew, int newNodeSize,
+                                        std::vector<int>& idCellsOldToNew, int newCellSize)
+{
+  // TODO utiliser mieux vtk pour faire plus simple (plus couteux ?)
+
+  MESSAGE("------------------------- SMDS_UnstructuredGrid::compactGrid " << newNodeSize << " " << newCellSize);CHRONO(1);
+  int startHole = 0;
+  int endHole = 0;
+  int startBloc = 0;
+  int endBloc = 0;
+  int alreadyCopied = 0;
+  int holes = 0;
+
+  typedef enum
+  {
+    lookHoleStart, lookHoleEnd, lookBlocEnd
+  } enumState;
+  enumState compactState = lookHoleStart;
+
+  //   if (this->Links)
+  //   {
+  //           this->Links->UnRegister(this);
+  //           this->Links = 0;
+  //   }
+
+  // --- if newNodeSize, create a new compacted vtkPoints
+
+  vtkPoints *newPoints = 0;
+  if (newNodeSize)
+    {
+      MESSAGE("-------------- compactGrid, newNodeSize " << newNodeSize);
+      newPoints = vtkPoints::New();
+      newPoints->Initialize();
+      newPoints->Allocate(newNodeSize);
+      newPoints->SetNumberOfPoints(newNodeSize);
+      int oldNodeSize = idNodesOldToNew.size();
+
+      for (int i = 0; i < oldNodeSize; i++)
+        {
+          //MESSAGE("                                    " << i << " " << idNodesOldToNew[i]);
+          switch (compactState)
+          {
+            case lookHoleStart:
+              if (idNodesOldToNew[i] < 0)
+                {
+                  MESSAGE("-------------- newNodeSize, startHole " << i << " " << oldNodeSize);
+                  startHole = i;
+                  if (!alreadyCopied) // copy the first bloc
+                    {
+                      MESSAGE("--------- copy first nodes before hole " << i << " " << oldNodeSize);
+                      copyNodes(newPoints, idNodesOldToNew, alreadyCopied, 0, startHole);
+                    }
+                  compactState = lookHoleEnd;
+                }
+              break;
+            case lookHoleEnd:
+              if (idNodesOldToNew[i] >= 0)
+                {
+                  MESSAGE("-------------- newNodeSize, endHole " << i << " " << oldNodeSize);
+                  endHole = i;
+                  startBloc = i;
+                  compactState = lookBlocEnd;
+                }
+              break;
+            case lookBlocEnd:
+              if (idNodesOldToNew[i] < 0)
+                endBloc = i; // see nbPoints below
+              else if (i == (oldNodeSize - 1))
+                endBloc = i + 1;
+              if (endBloc)
+                {
+                  MESSAGE("-------------- newNodeSize, endbloc " << endBloc << " " << oldNodeSize);
+                  copyNodes(newPoints, idNodesOldToNew, alreadyCopied, startBloc, endBloc);
+                  compactState = lookHoleEnd;
+                  startHole = i;
+                  endHole = 0;
+                  startBloc = 0;
+                  endBloc = 0;
+                }
+              break;
+          }
+        }
+      if (!alreadyCopied) // no hole, but shorter, no need to modify idNodesOldToNew
+        {
+          MESSAGE("------------- newNodeSize, shorter " << oldNodeSize);
+          copyNodes(newPoints, idNodesOldToNew, alreadyCopied, 0, newNodeSize);
+        }
+      newPoints->Squeeze();
+    }
+
+  // --- create new compacted Connectivity, Locations and Types
+
+  int oldCellSize = this->Types->GetNumberOfTuples();
+
+  vtkCellArray *newConnectivity = vtkCellArray::New();
+  newConnectivity->Initialize();
+  int oldCellDataSize = this->Connectivity->GetData()->GetSize();
+  newConnectivity->Allocate(oldCellDataSize);
+  MESSAGE("oldCellSize="<< oldCellSize << " oldCellDataSize=" << oldCellDataSize);
+
+  vtkUnsignedCharArray *newTypes = vtkUnsignedCharArray::New();
+  newTypes->Initialize();
+  newTypes->SetNumberOfValues(newCellSize);
+
+  vtkIdTypeArray *newLocations = vtkIdTypeArray::New();
+  newLocations->Initialize();
+  newLocations->SetNumberOfValues(newCellSize);
+
+  startHole = 0;
+  endHole = 0;
+  startBloc = 0;
+  endBloc = 0;
+  alreadyCopied = 0;
+  holes = 0;
+  compactState = lookHoleStart;
+
+  // TODO some polyhedron may be huge (only in some tests)
+  vtkIdType tmpid[NBMAXNODESINCELL];
+  vtkIdType *pointsCell = &tmpid[0]; // --- points id to fill a new cell
+
+  for (int i = 0; i < oldCellSize; i++)
+    {
+      switch (compactState)
+      {
+        case lookHoleStart:
+          if (this->Types->GetValue(i) == VTK_EMPTY_CELL)
+            {
+              MESSAGE(" -------- newCellSize, startHole " << i << " " << oldCellSize);
+              startHole = i;
+              compactState = lookHoleEnd;
+              if (!alreadyCopied) // copy the first bloc
+                {
+                  MESSAGE("--------- copy first bloc before hole " << i << " " << oldCellSize);
+                  copyBloc(newTypes, idCellsOldToNew, idNodesOldToNew, newConnectivity, newLocations, pointsCell,
+                           alreadyCopied, 0, startHole);
+                }
+            }
+          break;
+        case lookHoleEnd:
+          if (this->Types->GetValue(i) != VTK_EMPTY_CELL)
+            {
+              MESSAGE(" -------- newCellSize, EndHole " << i << " " << oldCellSize);
+              endHole = i;
+              startBloc = i;
+              compactState = lookBlocEnd;
+              holes += endHole - startHole;
+            }
+          break;
+        case lookBlocEnd:
+          endBloc = 0;
+          if (this->Types->GetValue(i) == VTK_EMPTY_CELL)
+            endBloc = i;
+          else if (i == (oldCellSize - 1))
+            endBloc = i + 1;
+          if (endBloc)
+            {
+              MESSAGE(" -------- newCellSize, endBloc " << endBloc << " " << oldCellSize);
+              copyBloc(newTypes, idCellsOldToNew, idNodesOldToNew, newConnectivity, newLocations, pointsCell,
+                       alreadyCopied, startBloc, endBloc);
+              compactState = lookHoleEnd;
+            }
+          break;
+      }
+    }
+  if (!alreadyCopied) // no hole, but shorter
+    {
+      MESSAGE(" -------- newCellSize, shorter " << oldCellSize);
+      copyBloc(newTypes, idCellsOldToNew, idNodesOldToNew, newConnectivity, newLocations, pointsCell, alreadyCopied, 0,
+               oldCellSize);
+    }
+
+  newConnectivity->Squeeze();
+  //newTypes->Squeeze();
+  //newLocations->Squeeze();
+
+  if (newNodeSize)
+    {
+      MESSAGE("------- newNodeSize, setPoints");
+      this->SetPoints(newPoints);
+      MESSAGE("NumberOfPoints: " << this->GetNumberOfPoints());
+    }
+//#ifdef VTK_HAVE_POLYHEDRON
+  // TODO compact faces for Polyhedrons
+  // refaire completement faces et faceLocation
+  // pour chaque cell, recup oldCellId, oldFacesId, recopie dans newFaces de la faceStream
+  // en changeant les numeros de noeuds
+//  vtkIdTypeArray *newFaceLocations = vtkIdTypeArray::New();
+//  newFaceLocations->Initialize();
+//  vtkIdTypeArray *newFaces = vtkIdTypeArray::New();
+//  newFaces->Initialize();
+//  newFaceLocations->DeepCopy(this->FaceLocations);
+//  newFaces->DeepCopy(this->Faces);
+//  this->SetCells(newTypes, newLocations, newConnectivity, newFaceLocations, newFaces);
+//  newFaceLocations->Delete();
+//  newFaces->Delete();
+  if (this->FaceLocations) this->FaceLocations->Register(this);
+  if (this->Faces) this->Faces->Register(this);
+  this->SetCells(newTypes, newLocations, newConnectivity, FaceLocations, Faces);
+//#else
+//  this->SetCells(newTypes, newLocations, newConnectivity);
+//#endif
+  newTypes->Delete();
+  newLocations->Delete();
+  newConnectivity->Delete();
+  this->BuildLinks();
+}
+
+void SMDS_UnstructuredGrid::copyNodes(vtkPoints *newPoints, std::vector<int>& idNodesOldToNew, int& alreadyCopied,
+                                      int start, int end)
+{
+  MESSAGE("copyNodes " << alreadyCopied << " " << start << " " << end << " size: " << end - start << " total: " << alreadyCopied + end - start);
+  void *target = newPoints->GetVoidPointer(3 * alreadyCopied);
+  void *source = this->Points->GetVoidPointer(3 * start);
+  int nbPoints = end - start;
+  if (nbPoints > 0)
+    {
+      memcpy(target, source, 3 * sizeof(float) * nbPoints);
+      for (int j = start; j < end; j++)
+        idNodesOldToNew[j] = alreadyCopied++; // old vtkId --> new vtkId
+        //idNodesOldToNew[alreadyCopied++] = idNodesOldToNew[j]; // new vtkId --> old SMDS id
+    }
+}
+
+void SMDS_UnstructuredGrid::copyBloc(vtkUnsignedCharArray *newTypes, std::vector<int>& idCellsOldToNew,
+                                     std::vector<int>& idNodesOldToNew, vtkCellArray* newConnectivity,
+                                     vtkIdTypeArray* newLocations, vtkIdType* pointsCell, int& alreadyCopied,
+                                     int start, int end)
+{
+  MESSAGE("copyBloc " << alreadyCopied << " " << start << " " << end << " size: " << end - start << " total: " << alreadyCopied + end - start);
+  for (int j = start; j < end; j++)
+    {
+      newTypes->SetValue(alreadyCopied, this->Types->GetValue(j));
+      idCellsOldToNew[j] = alreadyCopied; // old vtkId --> new vtkId
+      vtkIdType oldLoc = this->Locations->GetValue(j);
+      vtkIdType nbpts;
+      vtkIdType *oldPtsCell = 0;
+      this->Connectivity->GetCell(oldLoc, nbpts, oldPtsCell);
+      assert(nbpts < NBMAXNODESINCELL);
+      //MESSAGE(j << " " << alreadyCopied << " " << (int)this->Types->GetValue(j) << " " << oldLoc << " " << nbpts );
+      for (int l = 0; l < nbpts; l++)
+        {
+          int oldval = oldPtsCell[l];
+          pointsCell[l] = idNodesOldToNew[oldval];
+          //MESSAGE("   " << oldval << " " << pointsCell[l]);
+        }
+      int newcnt = newConnectivity->InsertNextCell(nbpts, pointsCell);
+      int newLoc = newConnectivity->GetInsertLocation(nbpts);
+      //MESSAGE(newcnt << " " << newLoc);
+      newLocations->SetValue(alreadyCopied, newLoc);
+      alreadyCopied++;
+    }
+}
+
+int SMDS_UnstructuredGrid::CellIdToDownId(int vtkCellId)
+{
+  // ASSERT((vtkCellId >= 0) && (vtkCellId < _cellIdToDownId.size()));
+  return _cellIdToDownId[vtkCellId];
+}
+
+void SMDS_UnstructuredGrid::setCellIdToDownId(int vtkCellId, int downId)
+{
+  // ASSERT((vtkCellId >= 0) && (vtkCellId < _cellIdToDownId.size()));
+  _cellIdToDownId[vtkCellId] = downId;
+}
+
+/*! Build downward connectivity: to do only when needed because heavy memory load.
+ *  Downward connectivity is no more valid if vtkUnstructuredGrid is modified.
+ *
+ */
+void SMDS_UnstructuredGrid::BuildDownwardConnectivity(bool withEdges)
+{
+  MESSAGE("SMDS_UnstructuredGrid::BuildDownwardConnectivity");CHRONO(2);
+  // TODO calcul partiel sans edges
+
+  // --- erase previous data if any
+
+  for (int i = 0; i < _downArray.size(); i++)
+    {
+      if (_downArray[i])
+        delete _downArray[i];
+      _downArray[i] = 0;
+    }
+  _cellIdToDownId.clear();
+
+  // --- create SMDS_Downward structures (in _downArray vector[vtkCellType])
+
+  _downArray.resize(VTK_MAXTYPE + 1, 0); // --- max. type value = VTK_QUADRATIC_PYRAMID
+
+  _downArray[VTK_LINE] = new SMDS_DownEdge(this);
+  _downArray[VTK_QUADRATIC_EDGE] = new SMDS_DownQuadEdge(this);
+  _downArray[VTK_TRIANGLE] = new SMDS_DownTriangle(this);
+  _downArray[VTK_QUADRATIC_TRIANGLE] = new SMDS_DownQuadTriangle(this);
+  _downArray[VTK_QUAD] = new SMDS_DownQuadrangle(this);
+  _downArray[VTK_QUADRATIC_QUAD] = new SMDS_DownQuadQuadrangle(this);
+  _downArray[VTK_TETRA] = new SMDS_DownTetra(this);
+  _downArray[VTK_QUADRATIC_TETRA] = new SMDS_DownQuadTetra(this);
+  _downArray[VTK_PYRAMID] = new SMDS_DownPyramid(this);
+  _downArray[VTK_QUADRATIC_PYRAMID] = new SMDS_DownQuadPyramid(this);
+  _downArray[VTK_WEDGE] = new SMDS_DownPenta(this);
+  _downArray[VTK_QUADRATIC_WEDGE] = new SMDS_DownQuadPenta(this);
+  _downArray[VTK_HEXAHEDRON] = new SMDS_DownHexa(this);
+  _downArray[VTK_QUADRATIC_HEXAHEDRON] = new SMDS_DownQuadHexa(this);
+
+  // --- get detailed info of number of cells of each type, allocate SMDS_downward structures
+
+  const SMDS_MeshInfo &meshInfo = _mesh->GetMeshInfo();
+
+  int nbLinTetra = meshInfo.NbTetras(ORDER_LINEAR);
+  int nbQuadTetra = meshInfo.NbTetras(ORDER_QUADRATIC);
+  int nbLinPyra = meshInfo.NbPyramids(ORDER_LINEAR);
+  int nbQuadPyra = meshInfo.NbPyramids(ORDER_QUADRATIC);
+  int nbLinPrism = meshInfo.NbPrisms(ORDER_LINEAR);
+  int nbQuadPrism = meshInfo.NbPrisms(ORDER_QUADRATIC);
+  int nbLinHexa = meshInfo.NbHexas(ORDER_LINEAR);
+  int nbQuadHexa = meshInfo.NbHexas(ORDER_QUADRATIC);
+
+  int nbLineGuess = int((4.0 / 3.0) * nbLinTetra + 2 * nbLinPrism + 2.5 * nbLinPyra + 3 * nbLinHexa);
+  int nbQuadEdgeGuess = int((4.0 / 3.0) * nbQuadTetra + 2 * nbQuadPrism + 2.5 * nbQuadPyra + 3 * nbQuadHexa);
+  int nbLinTriaGuess = 2 * nbLinTetra + nbLinPrism + 2 * nbLinPyra;
+  int nbQuadTriaGuess = 2 * nbQuadTetra + nbQuadPrism + 2 * nbQuadPyra;
+  int nbLinQuadGuess = int((2.0 / 3.0) * nbLinPrism + (1.0 / 2.0) * nbLinPyra + 3 * nbLinHexa);
+  int nbQuadQuadGuess = int((2.0 / 3.0) * nbQuadPrism + (1.0 / 2.0) * nbQuadPyra + 3 * nbQuadHexa);
+
+  int GuessSize[VTK_QUADRATIC_TETRA];
+  GuessSize[VTK_LINE] = nbLineGuess;
+  GuessSize[VTK_QUADRATIC_EDGE] = nbQuadEdgeGuess;
+  GuessSize[VTK_TRIANGLE] = nbLinTriaGuess;
+  GuessSize[VTK_QUADRATIC_TRIANGLE] = nbQuadTriaGuess;
+  GuessSize[VTK_QUAD] = nbLinQuadGuess;
+  GuessSize[VTK_QUADRATIC_QUAD] = nbQuadQuadGuess;
+  GuessSize[VTK_TETRA] = nbLinTetra;
+  GuessSize[VTK_QUADRATIC_TETRA] = nbQuadTetra;
+  GuessSize[VTK_PYRAMID] = nbLinPyra;
+  GuessSize[VTK_QUADRATIC_PYRAMID] = nbQuadPyra;
+  GuessSize[VTK_WEDGE] = nbLinPrism;
+  GuessSize[VTK_QUADRATIC_WEDGE] = nbQuadPrism;
+  GuessSize[VTK_HEXAHEDRON] = nbLinHexa;
+  GuessSize[VTK_QUADRATIC_HEXAHEDRON] = nbQuadHexa;
+
+  _downArray[VTK_LINE]->allocate(nbLineGuess);
+  _downArray[VTK_QUADRATIC_EDGE]->allocate(nbQuadEdgeGuess);
+  _downArray[VTK_TRIANGLE]->allocate(nbLinTriaGuess);
+  _downArray[VTK_QUADRATIC_TRIANGLE]->allocate(nbQuadTriaGuess);
+  _downArray[VTK_QUAD]->allocate(nbLinQuadGuess);
+  _downArray[VTK_QUADRATIC_QUAD]->allocate(nbQuadQuadGuess);
+  _downArray[VTK_TETRA]->allocate(nbLinTetra);
+  _downArray[VTK_QUADRATIC_TETRA]->allocate(nbQuadTetra);
+  _downArray[VTK_PYRAMID]->allocate(nbLinPyra);
+  _downArray[VTK_QUADRATIC_PYRAMID]->allocate(nbQuadPyra);
+  _downArray[VTK_WEDGE]->allocate(nbLinPrism);
+  _downArray[VTK_QUADRATIC_WEDGE]->allocate(nbQuadPrism);
+  _downArray[VTK_HEXAHEDRON]->allocate(nbLinHexa);
+  _downArray[VTK_QUADRATIC_HEXAHEDRON]->allocate(nbQuadHexa);
+
+  // --- iteration on vtkUnstructuredGrid cells, only faces
+  //     for each vtk face:
+  //       create a downward face entry with its downward id.
+  //       compute vtk volumes, create downward volumes entry.
+  //       mark face in downward volumes
+  //       mark volumes in downward face
+
+  MESSAGE("--- iteration on vtkUnstructuredGrid cells, only faces");CHRONO(20);
+  int cellSize = this->Types->GetNumberOfTuples();
+  _cellIdToDownId.resize(cellSize, -1);
+
+  for (int i = 0; i < cellSize; i++)
+    {
+      int vtkFaceType = this->GetCellType(i);
+      if (SMDS_Downward::getCellDimension(vtkFaceType) == 2)
+        {
+          int vtkFaceId = i;
+          //ASSERT(_downArray[vtkFaceType]);
+          int connFaceId = _downArray[vtkFaceType]->addCell(vtkFaceId);
+          SMDS_Down2D* downFace = static_cast<SMDS_Down2D*> (_downArray[vtkFaceType]);
+          downFace->setTempNodes(connFaceId, vtkFaceId);
+          int vols[2] = { -1, -1 };
+          int nbVolumes = downFace->computeVolumeIds(vtkFaceId, vols);
+          //MESSAGE("nbVolumes="<< nbVolumes);
+          for (int ivol = 0; ivol < nbVolumes; ivol++)
+            {
+              int vtkVolId = vols[ivol];
+              int vtkVolType = this->GetCellType(vtkVolId);
+              //ASSERT(_downArray[vtkVolType]);
+              int connVolId = _downArray[vtkVolType]->addCell(vtkVolId);
+              _downArray[vtkVolType]->addDownCell(connVolId, connFaceId, vtkFaceType);
+              _downArray[vtkFaceType]->addUpCell(connFaceId, connVolId, vtkVolType);
+              // MESSAGE("Face " << vtkFaceId << " belongs to volume " << vtkVolId);
+            }
+        }
+    }
+
+  // --- iteration on vtkUnstructuredGrid cells, only volumes
+  //     for each vtk volume:
+  //       create downward volumes entry if not already done
+  //       build a temporary list of faces described with their nodes
+  //       for each face
+  //         compute the vtk volumes containing this face
+  //         check if the face is already listed in the volumes (comparison of ordered list of nodes)
+  //         if not, create a downward face entry (resizing of structure required)
+  //         (the downward faces store a temporary list of nodes to ease the comparison)
+  //         create downward volumes entry if not already done
+  //         mark volumes in downward face
+  //         mark face in downward volumes
+
+  CHRONOSTOP(20);
+  MESSAGE("--- iteration on vtkUnstructuredGrid cells, only volumes");CHRONO(21);
+
+  for (int i = 0; i < cellSize; i++)
+    {
+      int vtkType = this->GetCellType(i);
+      if (SMDS_Downward::getCellDimension(vtkType) == 3)
+        {
+          //CHRONO(31);
+          int vtkVolId = i;
+          // MESSAGE("vtk volume " << vtkVolId);
+          //ASSERT(_downArray[vtkType]);
+          int connVolId = _downArray[vtkType]->addCell(vtkVolId);
+
+          // --- find all the faces of the volume, describe the faces by their nodes
+
+          SMDS_Down3D* downVol = static_cast<SMDS_Down3D*> (_downArray[vtkType]);
+          ListElemByNodesType facesWithNodes;
+          downVol->computeFacesWithNodes(vtkVolId, facesWithNodes);
+          // MESSAGE("vtk volume " << vtkVolId << " contains " << facesWithNodes.nbElems << " faces");
+          //CHRONOSTOP(31);
+          for (int iface = 0; iface < facesWithNodes.nbElems; iface++)
+            {
+              // --- find the volumes containing the face
+
+              //CHRONO(32);
+              int vtkFaceType = facesWithNodes.elems[iface].vtkType;
+              SMDS_Down2D* downFace = static_cast<SMDS_Down2D*> (_downArray[vtkFaceType]);
+              int vols[2] = { -1, -1 };
+              int *nodes = &facesWithNodes.elems[iface].nodeIds[0];
+              int lg = facesWithNodes.elems[iface].nbNodes;
+              int nbVolumes = downFace->computeVolumeIdsFromNodesFace(nodes, lg, vols);
+              // MESSAGE("vtk volume " << vtkVolId << " face " << iface << " belongs to " << nbVolumes << " volumes");
+
+              // --- check if face is registered in the volumes
+              //CHRONOSTOP(32);
+
+              //CHRONO(33);
+              int connFaceId = -1;
+              for (int ivol = 0; ivol < nbVolumes; ivol++)
+                {
+                  int vtkVolId2 = vols[ivol];
+                  int vtkVolType = this->GetCellType(vtkVolId2);
+                  //ASSERT(_downArray[vtkVolType]);
+                  int connVolId2 = _downArray[vtkVolType]->addCell(vtkVolId2);
+                  SMDS_Down3D* downVol2 = static_cast<SMDS_Down3D*> (_downArray[vtkVolType]);
+                  connFaceId = downVol2->FindFaceByNodes(connVolId2, facesWithNodes.elems[iface]);
+                  if (connFaceId >= 0)
+                    break; // --- face already created
+                }//CHRONOSTOP(33);
+
+              // --- if face is not registered in the volumes, create face
+
+              //CHRONO(34);
+              if (connFaceId < 0)
+                {
+                  connFaceId = _downArray[vtkFaceType]->addCell();
+                  downFace->setTempNodes(connFaceId, facesWithNodes.elems[iface]);
+                }//CHRONOSTOP(34);
+
+              // --- mark volumes in downward face and mark face in downward volumes
+
+              //CHRONO(35);
+              for (int ivol = 0; ivol < nbVolumes; ivol++)
+                {
+                  int vtkVolId2 = vols[ivol];
+                  int vtkVolType = this->GetCellType(vtkVolId2);
+                  //ASSERT(_downArray[vtkVolType]);
+                  int connVolId2 = _downArray[vtkVolType]->addCell(vtkVolId2);
+                  _downArray[vtkVolType]->addDownCell(connVolId2, connFaceId, vtkFaceType);
+                  _downArray[vtkFaceType]->addUpCell(connFaceId, connVolId2, vtkVolType);
+                  // MESSAGE(" From volume " << vtkVolId << " face " << connFaceId << " belongs to volume " << vtkVolId2);
+                }//CHRONOSTOP(35);
+            }
+        }
+    }
+
+  // --- iteration on vtkUnstructuredGrid cells, only edges
+  //     for each vtk edge:
+  //       create downward edge entry
+  //       store the nodes id's in downward edge (redundant with vtkUnstructuredGrid)
+  //       find downward faces
+  //       (from vtk faces or volumes, get downward faces, they have a temporary list of nodes)
+  //       mark edge in downward faces
+  //       mark faces in downward edge
+
+  CHRONOSTOP(21);
+  MESSAGE("--- iteration on vtkUnstructuredGrid cells, only edges");CHRONO(22);
+
+  for (int i = 0; i < cellSize; i++)
+    {
+      int vtkEdgeType = this->GetCellType(i);
+      if (SMDS_Downward::getCellDimension(vtkEdgeType) == 1)
+        {
+          int vtkEdgeId = i;
+          //ASSERT(_downArray[vtkEdgeType]);
+          int connEdgeId = _downArray[vtkEdgeType]->addCell(vtkEdgeId);
+          SMDS_Down1D* downEdge = static_cast<SMDS_Down1D*> (_downArray[vtkEdgeType]);
+          downEdge->setNodes(connEdgeId, vtkEdgeId);
+          vector<int> vtkIds;
+          int nbVtkCells = downEdge->computeVtkCells(connEdgeId, vtkIds);
+          int downFaces[1000];
+          unsigned char downTypes[1000];
+          int nbDownFaces = downEdge->computeFaces(connEdgeId, &vtkIds[0], nbVtkCells, downFaces, downTypes);
+          for (int n = 0; n < nbDownFaces; n++)
+            {
+              _downArray[downTypes[n]]->addDownCell(downFaces[n], connEdgeId, vtkEdgeType);
+              _downArray[vtkEdgeType]->addUpCell(connEdgeId, downFaces[n], downTypes[n]);
+            }
+        }
+    }
+
+  // --- iteration on downward faces (they are all listed now)
+  //     for each downward face:
+  //       build a temporary list of edges with their ordered list of nodes
+  //       for each edge:
+  //         find all the vtk cells containing this edge
+  //         then identify all the downward faces containing the edge, from the vtk cells
+  //         check if the edge is already listed in the faces (comparison of ordered list of nodes)
+  //         if not, create a downward edge entry with the node id's
+  //         mark edge in downward faces
+  //         mark downward faces in edge (size of list unknown, to be allocated)
+
+  CHRONOSTOP(22);CHRONO(23);
+
+  for (int vtkFaceType = 0; vtkFaceType < VTK_QUADRATIC_PYRAMID; vtkFaceType++)
+    {
+      if (SMDS_Downward::getCellDimension(vtkFaceType) != 2)
+        continue;
+
+      // --- find all the edges of the face, describe the edges by their nodes
+
+      SMDS_Down2D* downFace = static_cast<SMDS_Down2D*> (_downArray[vtkFaceType]);
+      int maxId = downFace->getMaxId();
+      for (int faceId = 0; faceId < maxId; faceId++)
+        {
+          //CHRONO(40);
+          ListElemByNodesType edgesWithNodes;
+          downFace->computeEdgesWithNodes(faceId, edgesWithNodes);
+          // MESSAGE("downward face type " << vtkFaceType << " num " << faceId << " contains " << edgesWithNodes.nbElems << " edges");
+
+          //CHRONOSTOP(40);
+          for (int iedge = 0; iedge < edgesWithNodes.nbElems; iedge++)
+            {
+
+              // --- check if the edge is already registered by exploration of the faces
+
+              //CHRONO(41);
+              vector<int> vtkIds;
+              unsigned char vtkEdgeType = edgesWithNodes.elems[iedge].vtkType;
+              int *pts = &edgesWithNodes.elems[iedge].nodeIds[0];
+              SMDS_Down1D* downEdge = static_cast<SMDS_Down1D*> (_downArray[vtkEdgeType]);
+              int nbVtkCells = downEdge->computeVtkCells(pts, vtkIds);
+              //CHRONOSTOP(41);CHRONO(42);
+              int downFaces[1000];
+              unsigned char downTypes[1000];
+              int nbDownFaces = downEdge->computeFaces(pts, &vtkIds[0], nbVtkCells, downFaces, downTypes);
+              //CHRONOSTOP(42);
+
+              //CHRONO(43);
+              int connEdgeId = -1;
+              for (int idf = 0; idf < nbDownFaces; idf++)
+                {
+                  int faceId2 = downFaces[idf];
+                  int faceType = downTypes[idf];
+                  //ASSERT(_downArray[faceType]);
+                  SMDS_Down2D* downFace2 = static_cast<SMDS_Down2D*> (_downArray[faceType]);
+                  connEdgeId = downFace2->FindEdgeByNodes(faceId2, edgesWithNodes.elems[iedge]);
+                  if (connEdgeId >= 0)
+                    break; // --- edge already created
+                }//CHRONOSTOP(43);
+
+              // --- if edge is not registered in the faces, create edge
+
+              if (connEdgeId < 0)
+                {
+                  //CHRONO(44);
+                  connEdgeId = _downArray[vtkEdgeType]->addCell();
+                  downEdge->setNodes(connEdgeId, edgesWithNodes.elems[iedge].nodeIds);
+                  //CHRONOSTOP(44);
+                }
+
+              // --- mark faces in downward edge and mark edge in downward faces
+
+              //CHRONO(45);
+              for (int idf = 0; idf < nbDownFaces; idf++)
+                {
+                  int faceId2 = downFaces[idf];
+                  int faceType = downTypes[idf];
+                  //ASSERT(_downArray[faceType]);
+                  SMDS_Down2D* downFace2 = static_cast<SMDS_Down2D*> (_downArray[faceType]);
+                  _downArray[vtkEdgeType]->addUpCell(connEdgeId, faceId2, faceType);
+                  _downArray[faceType]->addDownCell(faceId2, connEdgeId, vtkEdgeType);
+                  // MESSAGE(" From face t:" << vtkFaceType << " " << faceId <<
+                  //  " edge " << connEdgeId << " belongs to face t:" << faceType << " " << faceId2);
+                }//CHRONOSTOP(45);
+            }
+        }
+    }
+
+  CHRONOSTOP(23);CHRONO(24);
+
+  // compact downward connectivity structure: adjust downward arrays size, replace vector<vector int>> by a single vector<int>
+  // 3D first then 2D and last 1D to release memory before edge upCells reorganization, (temporary memory use)
+
+  for (int vtkType = VTK_QUADRATIC_PYRAMID; vtkType >= 0; vtkType--)
+    {
+      if (SMDS_Downward *down = _downArray[vtkType])
+        {
+          down->compactStorage();
+        }
+    }
+
+  // --- Statistics
+
+  for (int vtkType = 0; vtkType <= VTK_QUADRATIC_PYRAMID; vtkType++)
+    {
+      if (SMDS_Downward *down = _downArray[vtkType])
+        {
+          if (down->getMaxId())
+            {
+              MESSAGE("Cells of Type " << vtkType << " : number of entities, est: "
+                  << GuessSize[vtkType] << " real: " << down->getMaxId());
+            }
+        }
+    }CHRONOSTOP(24);CHRONOSTOP(2);
+  counters::stats();
+}
+
+/*! Get the neighbors of a cell.
+ * Only the neighbors having the dimension of the cell are taken into account
+ * (neighbors of a volume are the volumes sharing a face with this volume,
+ *  neighbors of a face are the faces sharing an edge with this face...).
+ * @param neighborsVtkIds vector of neighbors vtk id's to fill (reserve enough space).
+ * @param downIds downward id's of cells of dimension n-1, to fill (reserve enough space).
+ * @param downTypes vtk types of cells of dimension n-1, to fill (reserve enough space).
+ * @param vtkId the vtk id of the cell
+ * @return number of neighbors
+ */
+int SMDS_UnstructuredGrid::GetNeighbors(int* neighborsVtkIds, int* downIds, unsigned char* downTypes, int vtkId)
+{
+  int vtkType = this->GetCellType(vtkId);
+  int cellDim = SMDS_Downward::getCellDimension(vtkType);
+  if (cellDim != 3)
+    return 0; // TODO voisins des faces ou edges
+  int cellId = this->_cellIdToDownId[vtkId];
+
+  int nbCells = _downArray[vtkType]->getNumberOfDownCells(cellId);
+  const int *downCells = _downArray[vtkType]->getDownCells(cellId);
+  const unsigned char* downTyp = _downArray[vtkType]->getDownTypes(cellId);
+
+  // --- iteration on faces of the 3D cell.
+
+  int nb = 0;
+  for (int i = 0; i < nbCells; i++)
+    {
+      int downId = downCells[i];
+      int cellType = downTyp[i];
+      int nbUp = _downArray[cellType]->getNumberOfUpCells(downId);
+      const int *upCells = _downArray[cellType]->getUpCells(downId);
+      const unsigned char* upTypes = _downArray[cellType]->getUpTypes(downId);
+
+      // --- max 2 upCells, one is this cell, the other is a neighbor
+
+      for (int j = 0; j < nbUp; j++)
+        {
+          if ((upCells[j] == cellId) && (upTypes[j] == vtkType))
+            continue;
+          int vtkNeighbor = _downArray[upTypes[j]]->getVtkCellId(upCells[j]);
+          neighborsVtkIds[nb] = vtkNeighbor;
+          downIds[nb] = downId;
+          downTypes[nb] = cellType;
+          nb++;
+        }
+      if (nb >= NBMAXNEIGHBORS)
+        assert(0);
+    }
+  return nb;
+}
+
+/*! get the node id's of a cell.
+ * The cell is defined by it's downward connectivity id and type.
+ * @param nodeSet set of of vtk node id's to fill.
+ * @param downId downward connectivity id of the cell.
+ * @param downType type of cell.
+ */
+void SMDS_UnstructuredGrid::GetNodeIds(std::set<int>& nodeSet, int downId, unsigned char downType)
+{
+  _downArray[downType]->getNodeIds(downId, nodeSet);
+}
+
+/*! change some nodes in cell without modifying type or internal connectivity.
+ * Nodes inverse connectivity is maintained up to date.
+ * @param vtkVolId vtk id of the cell
+ * @param localClonedNodeIds map old node id to new node id.
+ */
+void SMDS_UnstructuredGrid::ModifyCellNodes(int vtkVolId, std::map<int, int> localClonedNodeIds)
+{
+  vtkIdType npts = 0;
+  vtkIdType *pts; // will refer to the point id's of the face
+  this->GetCellPoints(vtkVolId, npts, pts);
+  for (int i = 0; i < npts; i++)
+    {
+      if (localClonedNodeIds.count(pts[i]))
+        {
+          vtkIdType oldpt = pts[i];
+          pts[i] = localClonedNodeIds[oldpt];
+          //MESSAGE(oldpt << " --> " << pts[i]);
+          //this->RemoveReferenceToCell(oldpt, vtkVolId);
+          //this->AddReferenceToCell(pts[i], vtkVolId);
+        }
+    }
+}
+
+/*! Create a volume (prism or hexahedron) by duplication of a face.
+ * the nodes of the new face are already created.
+ * @param vtkVolId vtk id of a volume containing the face, to get an orientation for the face.
+ * @param localClonedNodeIds map old node id to new node id.
+ * @return vtk id of the new volume.
+ */
+int SMDS_UnstructuredGrid::getOrderedNodesOfFace(int vtkVolId, std::vector<int>& orderedNodes)
+{
+  int vtkType = this->GetCellType(vtkVolId);
+  int cellDim = SMDS_Downward::getCellDimension(vtkType);
+  if (cellDim != 3)
+    return 0;
+  SMDS_Down3D *downvol = static_cast<SMDS_Down3D*> (_downArray[vtkType]);
+  int downVolId = this->_cellIdToDownId[vtkVolId];
+  downvol->getOrderedNodesOfFace(downVolId, orderedNodes);
+  return orderedNodes.size();
+}
+
diff --git a/src/SMDS/SMDS_UnstructuredGrid.hxx b/src/SMDS/SMDS_UnstructuredGrid.hxx
new file mode 100644 (file)
index 0000000..808a4ed
--- /dev/null
@@ -0,0 +1,80 @@
+/* 
+ * File:   SMDS_UnstructuredGrid.hxx
+ * Author: prascle
+ *
+ * Created on September 16, 2009, 10:28 PM
+ */
+
+#ifndef _SMDS_UNSTRUCTUREDGRID_HXX
+#define        _SMDS_UNSTRUCTUREDGRID_HXX
+
+#include <vtkUnstructuredGrid.h>
+#include "chrono.hxx"
+
+#include <vector>
+#include <set>
+#include <map>
+
+//#define VTK_HAVE_POLYHEDRON
+//#ifdef VTK_HAVE_POLYHEDRON
+  #define VTK_MAXTYPE VTK_POLYHEDRON
+//#else
+//  #define VTK_MAXTYPE VTK_QUADRATIC_PYRAMID
+//#endif
+
+#define NBMAXNEIGHBORS 100
+
+// allow very huge polyhedrons in tests
+#define NBMAXNODESINCELL 5000
+
+class SMDS_Downward;
+class SMDS_Mesh;
+
+class SMDS_UnstructuredGrid: public vtkUnstructuredGrid
+{
+public:
+  void setSMDS_mesh(SMDS_Mesh *mesh);
+  void compactGrid(std::vector<int>& idNodesOldToNew, int newNodeSize, std::vector<int>& idCellsOldToNew,
+                   int newCellSize);
+
+  virtual unsigned long GetMTime();
+  virtual void Update();
+  virtual void UpdateInformation();
+  virtual vtkPoints *GetPoints();
+
+//#ifdef VTK_HAVE_POLYHEDRON
+  int InsertNextLinkedCell(int type, int npts, vtkIdType *pts);
+//#endif
+
+  int CellIdToDownId(int vtkCellId);
+  void setCellIdToDownId(int vtkCellId, int downId);
+  void BuildDownwardConnectivity(bool withEdges);
+  int GetNeighbors(int* neighborsVtkIds, int* downIds, unsigned char* downTypes, int vtkId);
+  void GetNodeIds(std::set<int>& nodeSet, int downId, unsigned char downType);
+  void ModifyCellNodes(int vtkVolId, std::map<int, int> localClonedNodeIds);
+  int getOrderedNodesOfFace(int vtkVolId, std::vector<int>& orderedNodes);
+  vtkCellLinks* GetLinks()
+  {
+    return Links;
+  }
+  SMDS_Downward* getDownArray(unsigned char vtkType)
+  {
+    return _downArray[vtkType];
+  }
+  static SMDS_UnstructuredGrid* New();
+  SMDS_Mesh *_mesh;
+protected:
+  SMDS_UnstructuredGrid();
+  ~SMDS_UnstructuredGrid();
+  void copyNodes(vtkPoints *newPoints, std::vector<int>& idNodesOldToNew, int& alreadyCopied, int start, int end);
+  void copyBloc(vtkUnsignedCharArray *newTypes, std::vector<int>& idCellsOldToNew, std::vector<int>& idNodesOldToNew,
+                vtkCellArray* newConnectivity, vtkIdTypeArray* newLocations, vtkIdType* pointsCell, int& alreadyCopied,
+                int start, int end);
+
+  std::vector<int> _cellIdToDownId; //!< convert vtk Id to downward[vtkType] id, initialized with -1
+  std::vector<unsigned char> _downTypes;
+  std::vector<SMDS_Downward*> _downArray;
+};
+
+#endif /* _SMDS_UNSTRUCTUREDGRID_HXX */
+
index 6a2b7dc0d2e404642bb224d16a4bc14aead29daf..efc13b7921ecaa685f67b2db9c474f93ea7f3bbe 100644 (file)
@@ -36,25 +36,13 @@ using namespace std;
 //purpose  : 
 //=======================================================================
 
-SMDS_VertexPosition:: SMDS_VertexPosition(const int aVertexId)
-        :SMDS_Position(aVertexId)
+SMDS_VertexPosition:: SMDS_VertexPosition()
 {
+  //MESSAGE("*********************************************** SMDS_VertexPosition " << aVertexId);
 }
 
-//=======================================================================
-//function : Coords
-//purpose  : 
-//=======================================================================
-
-const double *SMDS_VertexPosition::Coords() const
-{
-        const static double origin[]={0,0,0};
-        MESSAGE("SMDS_VertexPosition::Coords not implemented");
-        return origin;
-}
-
-
 SMDS_TypeOfPosition SMDS_VertexPosition::GetTypeOfPosition() const
 {
+  //MESSAGE("################################################# GetTypeOfPosition");
         return SMDS_TOP_VERTEX;
 }
index 845f20aaf2e0c9ca05a46e94a8afd28b5954e7d3..0fbfd1b86d40fc5d6f96db35ee70b4d404836321 100644 (file)
@@ -36,8 +36,7 @@ class SMDS_EXPORT SMDS_VertexPosition:public SMDS_Position
 
   public:       
         SMDS_TypeOfPosition GetTypeOfPosition() const;
-        SMDS_VertexPosition(int aVertexId=0);
-        const double *Coords() const;
+        SMDS_VertexPosition();
 };
 
 #endif
index 6b006b938f50989ec8bf2e64df362e6fce2d1ca4..4b3cabc1ffbae99aedd3b3bc8f8b2b28f98f45ef 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "SMDS_VolumeOfFaces.hxx"
 #include "SMDS_IteratorOfElements.hxx"
+#include "utilities.h"
 
 using namespace std;
 
@@ -96,6 +97,7 @@ SMDS_VolumeOfFaces::SMDS_VolumeOfFaces(const SMDS_MeshFace * face1,
                                        const SMDS_MeshFace * face3,
                                        const SMDS_MeshFace * face4)
 {
+  //MESSAGE("****************************************************** SMDS_VolumeOfFaces");
         myNbFaces = 4;
         myFaces[0]=face1;
         myFaces[1]=face2;
@@ -111,6 +113,7 @@ SMDS_VolumeOfFaces::SMDS_VolumeOfFaces(const SMDS_MeshFace * face1,
                                        const SMDS_MeshFace * face4,
                                        const SMDS_MeshFace * face5)
 {
+  //MESSAGE("****************************************************** SMDS_VolumeOfFaces");
         myNbFaces = 5;
         myFaces[0]=face1;
         myFaces[1]=face2;
@@ -127,6 +130,7 @@ SMDS_VolumeOfFaces::SMDS_VolumeOfFaces(const SMDS_MeshFace * face1,
                                        const SMDS_MeshFace * face5,
                                        const SMDS_MeshFace * face6)
 {
+  //MESSAGE("****************************************************** SMDS_VolumeOfFaces");
         myNbFaces = 6;
         myFaces[0]=face1;
         myFaces[1]=face2;
index 05d96422cdb6dc7edeef40ad09ce549ae94782c2..1b93c68a079ec9622d324faad5b89e150f7c6a60 100644 (file)
@@ -56,8 +56,9 @@ class SMDS_EXPORT SMDS_VolumeOfFaces:public SMDS_MeshVolume
                            const SMDS_MeshFace * face6);
 
         virtual SMDSAbs_EntityType GetEntityType() const;
+        virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) {return false;};
         void Print(std::ostream & OS) const;
-        
+
         int NbFaces() const;
 
   protected:
index 7c7795563fd7240b4e225783cd9ab50e4e5d73c5..c17e21d2642e10a5ceef1d4005821ee9f58d7067 100644 (file)
 #include "SMDS_MeshNode.hxx"
 #include "SMDS_SetIterator.hxx"
 #include "SMDS_VolumeTool.hxx"
+#include "SMDS_Mesh.hxx"
 #include "utilities.h"
 
-#include <vector>
-
 using namespace std;
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -50,6 +49,7 @@ SMDS_VolumeOfNodes::SMDS_VolumeOfNodes(
                 const SMDS_MeshNode * node7,
                 const SMDS_MeshNode * node8)
 {
+  //MESSAGE("***************************************************** SMDS_VolumeOfNodes");
         myNbNodes = 8;
         myNodes = new const SMDS_MeshNode* [myNbNodes];
         myNodes[0]=node1;
@@ -68,6 +68,7 @@ SMDS_VolumeOfNodes::SMDS_VolumeOfNodes(
                 const SMDS_MeshNode * node3,
                 const SMDS_MeshNode * node4)
 {
+  //MESSAGE("***************************************************** SMDS_VolumeOfNodes");
         myNbNodes = 4;
         myNodes = new const SMDS_MeshNode* [myNbNodes];
         myNodes[0]=node1;
@@ -83,6 +84,7 @@ SMDS_VolumeOfNodes::SMDS_VolumeOfNodes(
                 const SMDS_MeshNode * node4,
                 const SMDS_MeshNode * node5)
 {
+  //MESSAGE("***************************************************** SMDS_VolumeOfNodes");
         myNbNodes = 5;
         myNodes = new const SMDS_MeshNode* [myNbNodes];
         myNodes[0]=node1;
@@ -100,6 +102,7 @@ SMDS_VolumeOfNodes::SMDS_VolumeOfNodes(
                 const SMDS_MeshNode * node5,
                 const SMDS_MeshNode * node6)
 {
+  //MESSAGE("***************************************************** SMDS_VolumeOfNodes");
         myNbNodes = 6;
         myNodes = new const SMDS_MeshNode* [myNbNodes];
         myNodes[0]=node1;
@@ -133,11 +136,6 @@ SMDS_VolumeOfNodes::~SMDS_VolumeOfNodes()
   }
 }
 
-//=======================================================================
-//function : Print
-//purpose  : 
-//=======================================================================
-
 void SMDS_VolumeOfNodes::Print(ostream & OS) const
 {
         OS << "volume <" << GetID() << "> : ";
@@ -177,12 +175,9 @@ int SMDS_VolumeOfNodes::NbEdges() const
         return 0;
 }
 
-/// ===================================================================
 /*!
  * \brief Iterator on node of volume
  */
-/// ===================================================================
-
 class SMDS_VolumeOfNodes_MyIterator:public SMDS_NodeArrayElemIterator
 {
  public:
@@ -190,12 +185,9 @@ class SMDS_VolumeOfNodes_MyIterator:public SMDS_NodeArrayElemIterator
     SMDS_NodeArrayElemIterator( s, & s[ l ]) {}
 };
 
-/// ===================================================================
 /*!
  * \brief Iterator on faces or edges of volume
  */
-/// ===================================================================
-
 class _MySubIterator : public SMDS_ElemIterator
 {
   vector< const SMDS_MeshElement* > myElems;
@@ -261,3 +253,5 @@ SMDSAbs_EntityType SMDS_VolumeOfNodes::GetEntityType() const
   }
   return aType;
 }
+
+
index 6f6600d396b0dcc6f18985473fa0246160a2be69..c194ea3ba9b32392fa87f4fb7cb4f6d06b9b048e 100644 (file)
@@ -85,5 +85,7 @@ class SMDS_EXPORT SMDS_VolumeOfNodes:public SMDS_MeshVolume
                 elementsIterator(SMDSAbs_ElementType type) const;
         const SMDS_MeshNode** myNodes;
         int                   myNbNodes;
+
 };
+
 #endif
index 42640287c13dfa0847ea572f5db4512897a79aa0..913281eae5d30c40ab6e9a7e969737d4e16adf12 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
-#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+#include "SMDS_VtkVolume.hxx"
 #include "SMDS_Mesh.hxx"
 
 #include "utilities.h"
@@ -418,6 +418,7 @@ SMDS_VolumeTool::SMDS_VolumeTool ()
        myFaceNodeIndices( NULL ),
        myFaceNodes( NULL )
 {
+  //MESSAGE("******************************************************** SMDS_VolumeToo");
 }
 
 //=======================================================================
@@ -438,6 +439,7 @@ SMDS_VolumeTool::SMDS_VolumeTool (const SMDS_MeshElement* theVolume)
        myFaceNodeIndices( NULL ),
        myFaceNodes( NULL )
 {
+  //MESSAGE("******************************************************** SMDS_VolumeToo");
   Set( theVolume );
 }
 
@@ -499,7 +501,7 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume)
     }
 
     if (myVolume->IsPoly()) {
-      myPolyedre = static_cast<const SMDS_PolyhedralVolumeOfNodes*>( myVolume );
+      myPolyedre = dynamic_cast<const SMDS_VtkVolume*>( myVolume );
       if (!myPolyedre) {
         MESSAGE("Warning: bad volumic element");
         return false;
@@ -694,12 +696,13 @@ double SMDS_VolumeTool::GetSize() const
     if ( !myPolyedre )
       return 0.;
 
+    SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myPolyedre->getMeshId()];
     // split a polyhedron into tetrahedrons
 
     SMDS_VolumeTool* me = const_cast< SMDS_VolumeTool* > ( this );
     XYZ baryCenter;
     me->GetBaryCenter(baryCenter.x, baryCenter.y, baryCenter.z);
-    SMDS_MeshNode bcNode ( baryCenter.x, baryCenter.y, baryCenter.z );
+    SMDS_MeshNode *bcNode = mesh->AddNode( baryCenter.x, baryCenter.y, baryCenter.z );
 
     for ( int f = 0; f < NbFaces(); ++f )
     {
@@ -709,11 +712,12 @@ double SMDS_VolumeTool::GetSize() const
         double Vn = getTetraVolume( myFaceNodes[ 0 ],
                                     myFaceNodes[ n-1 ],
                                     myFaceNodes[ n ],
-                                    bcNode );
+                                    bcNode );
 ///         cout <<"++++   " << Vn << "   nodes " <<myFaceNodes[ 0 ]->GetID() << " " <<myFaceNodes[ n-1 ]->GetID() << " " <<myFaceNodes[ n ]->GetID() << "        < " << V << endl;
         V += externalFace ? -Vn : Vn;
       }
     }
+    mesh->RemoveNode(bcNode);
   }
   else 
   {
index 8d82a609169fba6fba94d62a954a276688170679..2e17f145b4120607129581b88762c61f7ed1115b 100644 (file)
@@ -33,7 +33,7 @@
 
 class SMDS_MeshElement;
 class SMDS_MeshNode;
-class SMDS_PolyhedralVolumeOfNodes;
+class SMDS_VtkVolume;
 class SMDS_MeshVolume;
 
 #include <vector>
@@ -212,7 +212,7 @@ private:
   bool setFace( int faceIndex );
 
   const SMDS_MeshElement* myVolume;
-  const SMDS_PolyhedralVolumeOfNodes* myPolyedre;
+  const SMDS_VtkVolume*   myPolyedre;
 
   bool                    myVolForward;
   int                     myNbFaces;
diff --git a/src/SMDS/SMDS_VtkCellIterator.cxx b/src/SMDS/SMDS_VtkCellIterator.cxx
new file mode 100644 (file)
index 0000000..0a4163b
--- /dev/null
@@ -0,0 +1,234 @@
+#include "SMDS_VtkCellIterator.hxx"
+#include "utilities.h"
+
+SMDS_VtkCellIterator::SMDS_VtkCellIterator(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType) :
+  _mesh(mesh), _cellId(vtkCellId), _index(0), _type(aType)
+{
+  //MESSAGE("SMDS_VtkCellIterator " << _type);
+  _vtkIdList = vtkIdList::New();
+  vtkUnstructuredGrid* grid = _mesh->getGrid();
+  grid->GetCellPoints(_cellId, _vtkIdList);
+  _nbNodes = _vtkIdList->GetNumberOfIds();
+  switch (_type)
+  {
+    case SMDSEntity_Tetra:
+      {
+        this->exchange(1, 2);
+        break;
+      }
+    case SMDSEntity_Pyramid:
+      {
+        this->exchange(1, 3);
+        break;
+      }
+    case SMDSEntity_Penta:
+      {
+        //this->exchange(1, 2);
+        //this->exchange(4, 5);
+        break;
+      }
+    case SMDSEntity_Hexa:
+      {
+        this->exchange(1, 3);
+        this->exchange(5, 7);
+        break;
+      }
+    case SMDSEntity_Quad_Tetra:
+      {
+        this->exchange(1, 2);
+        this->exchange(4, 6);
+        this->exchange(8, 9);
+        break;
+      }
+    case SMDSEntity_Quad_Pyramid:
+      {
+        this->exchange(1, 3);
+        this->exchange(5, 8);
+        this->exchange(6, 7);
+        this->exchange(10, 12);
+        break;
+      }
+    case SMDSEntity_Quad_Penta:
+      {
+        //this->exchange(1, 2);
+        //this->exchange(4, 5);
+        //this->exchange(6, 8);
+        //this->exchange(9, 11);
+        //this->exchange(13, 14);
+        break;
+      }
+    case SMDSEntity_Quad_Hexa:
+      {
+        MESSAGE("SMDS_VtkCellIterator Quad_Hexa");
+        this->exchange(1, 3);
+        this->exchange(5, 7);
+        this->exchange(8, 11);
+        this->exchange(9, 10);
+        this->exchange(12, 15);
+        this->exchange(13, 14);
+        this->exchange(17, 19);
+        break;
+      }
+    case SMDSEntity_Polyhedra:
+      MESSAGE("SMDS_VtkCellIterator Polyhedra (iterate on actual nodes)");
+      break;
+    default:
+      break;
+  }
+}
+
+SMDS_VtkCellIterator::~SMDS_VtkCellIterator()
+{
+  _vtkIdList->Delete();
+}
+
+bool SMDS_VtkCellIterator::more()
+{
+  return (_index < _nbNodes);
+}
+
+const SMDS_MeshElement* SMDS_VtkCellIterator::next()
+{
+  vtkIdType id = _vtkIdList->GetId(_index++);
+  return _mesh->FindNodeVtk(id);
+}
+
+SMDS_VtkCellIteratorToUNV::SMDS_VtkCellIteratorToUNV(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType) :
+  SMDS_VtkCellIterator()
+{
+  _mesh = mesh;
+  _cellId = vtkCellId;
+  _index = 0;
+  _type = aType;
+  //MESSAGE("SMDS_VtkCellInterlacedIterator (UNV)" << _type);
+
+  _vtkIdList = vtkIdList::New();
+  vtkIdType* pts;
+  vtkUnstructuredGrid* grid = _mesh->getGrid();
+  grid->GetCellPoints(_cellId, _nbNodes, pts);
+  _vtkIdList->SetNumberOfIds(_nbNodes);
+  int *ids = 0;
+  switch (_type)
+  {
+    case SMDSEntity_Quad_Edge:
+      {
+        static int id[] = { 0, 2, 1 };
+        ids = id;
+        break;
+      }
+    case SMDSEntity_Quad_Triangle:
+      {
+        static int id[] = { 0, 3, 1, 4, 2, 5 };
+        ids = id;
+        break;
+      }
+    case SMDSEntity_Quad_Quadrangle:
+      {
+        static int id[] = { 0, 4, 1, 5, 2, 6, 3, 7 };
+        ids = id;
+        break;
+      }
+    case SMDSEntity_Quad_Tetra:
+      {
+        static int id[] = { 0, 4, 1, 5, 2, 6, 7, 8, 9, 3 };
+        ids = id;
+        break;
+      }
+    case SMDSEntity_Quad_Pyramid:
+      {
+        static int id[] = { 0, 5, 1, 6, 2, 7, 3, 8, 9, 10, 11, 12, 4 };
+        ids = id;
+        break;
+      }
+    case SMDSEntity_Penta:
+      {
+        static int id[] = { 0, 2, 1, 3, 5, 4 };
+        ids = id;
+        break;
+      }
+    case SMDSEntity_Quad_Penta:
+      {
+        static int id[] = { 0, 8, 2, 7, 1, 6, 12, 14, 13, 3, 11, 5, 10, 4, 9 };
+        ids = id;
+        break;
+      }
+    case SMDSEntity_Quad_Hexa:
+      {
+        static int id[] = { 0, 8, 1, 9, 2, 10, 3, 11, 16, 17, 18, 19, 4, 12, 5, 13, 6, 14, 7, 15 };
+        ids = id;
+        break;
+      }
+    case SMDSEntity_Polygon:
+    case SMDSEntity_Quad_Polygon:
+    case SMDSEntity_Polyhedra:
+    case SMDSEntity_Quad_Polyhedra:
+    default:
+      {
+        static int id[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+                            25, 26, 27, 28, 29 };
+        ids = id;
+        break;
+      }
+  }
+  //MESSAGE("_nbNodes " << _nbNodes);
+  for (int i = 0; i < _nbNodes; i++)
+    _vtkIdList->SetId(i, pts[ids[i]]);
+}
+
+SMDS_VtkCellIteratorToUNV::~SMDS_VtkCellIteratorToUNV()
+{
+}
+
+SMDS_VtkCellIteratorPolyH::SMDS_VtkCellIteratorPolyH(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType) :
+  SMDS_VtkCellIterator()
+{
+  _mesh = mesh;
+  _cellId = vtkCellId;
+  _index = 0;
+  _type = aType;
+  //MESSAGE("SMDS_VtkCellIteratorPolyH " << _type);
+  _vtkIdList = vtkIdList::New();
+  vtkUnstructuredGrid* grid = _mesh->getGrid();
+  grid->GetCellPoints(_cellId, _vtkIdList);
+  _nbNodes = _vtkIdList->GetNumberOfIds();
+  switch (_type)
+  {
+    case SMDSEntity_Polyhedra:
+      {
+        //MESSAGE("SMDS_VtkCellIterator Polyhedra");
+        vtkIdType nFaces = 0;
+        vtkIdType* ptIds = 0;
+        grid->GetFaceStream(_cellId, nFaces, ptIds);
+        int id = 0;
+        _nbNodesInFaces = 0;
+        for (int i = 0; i < nFaces; i++)
+          {
+            int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace]
+            _nbNodesInFaces += nodesInFace;
+            id += (nodesInFace + 1);
+          }
+        _vtkIdList->SetNumberOfIds(_nbNodesInFaces);
+        id = 0;
+        int n = 0;
+        for (int i = 0; i < nFaces; i++)
+          {
+            int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace]
+            for (int k = 1; k <= nodesInFace; k++)
+              _vtkIdList->SetId(n++, ptIds[id + k]);
+            id += (nodesInFace + 1);
+          }
+        break;
+      }
+    default:
+      assert(0);
+  }
+}
+
+SMDS_VtkCellIteratorPolyH::~SMDS_VtkCellIteratorPolyH()
+{
+}
+
+bool SMDS_VtkCellIteratorPolyH::more()
+{
+  return (_index < _nbNodesInFaces);
+}
diff --git a/src/SMDS/SMDS_VtkCellIterator.hxx b/src/SMDS/SMDS_VtkCellIterator.hxx
new file mode 100644 (file)
index 0000000..91ab3dc
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef _SMDS_VTKCELLITERATOR_HXX_
+#define _SMDS_VTKCELLITERATOR_HXX_
+
+#include "SMDS_ElemIterator.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDSAbs_ElementType.hxx"
+
+#include <vtkCell.h>
+#include <vtkIdList.h>
+
+class SMDS_VtkCellIterator: public SMDS_ElemIterator
+{
+public:
+  SMDS_VtkCellIterator(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType);
+  virtual ~SMDS_VtkCellIterator();
+  virtual bool more();
+  virtual const SMDS_MeshElement* next();
+  inline void exchange(vtkIdType a, vtkIdType b)
+  {
+    vtkIdType t = _vtkIdList->GetId(a);
+    _vtkIdList->SetId(a, _vtkIdList->GetId(b));
+    _vtkIdList->SetId(b, t);
+  }
+
+protected:
+  SMDS_VtkCellIterator() {};
+
+  SMDS_Mesh* _mesh;
+  int _cellId;
+  int _index;
+  int _nbNodes;
+  SMDSAbs_EntityType _type;
+  vtkIdList* _vtkIdList;
+};
+
+class SMDS_VtkCellIteratorToUNV: public SMDS_VtkCellIterator
+{
+public:
+  SMDS_VtkCellIteratorToUNV(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType);
+  virtual ~SMDS_VtkCellIteratorToUNV();
+};
+
+class SMDS_VtkCellIteratorPolyH: public SMDS_VtkCellIterator
+{
+public:
+  SMDS_VtkCellIteratorPolyH(SMDS_Mesh* mesh, int vtkCellId, SMDSAbs_EntityType aType);
+  virtual ~SMDS_VtkCellIteratorPolyH();
+  virtual bool more();
+protected:
+  int _nbNodesInFaces;
+};
+
+#endif
diff --git a/src/SMDS/SMDS_VtkEdge.cxx b/src/SMDS/SMDS_VtkEdge.cxx
new file mode 100644 (file)
index 0000000..6cd006d
--- /dev/null
@@ -0,0 +1,151 @@
+#include "SMDS_VtkEdge.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDS_VtkCellIterator.hxx"
+
+#include "utilities.h"
+
+#include <vector>
+#include <cassert>
+
+using namespace std;
+
+SMDS_VtkEdge::SMDS_VtkEdge()
+{
+}
+
+SMDS_VtkEdge::SMDS_VtkEdge(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
+{
+  init(nodeIds, mesh);
+}
+
+SMDS_VtkEdge::~SMDS_VtkEdge()
+{
+}
+
+void SMDS_VtkEdge::init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
+{
+  vtkUnstructuredGrid* grid = mesh->getGrid();
+  myIdInShape = -1;
+  myMeshId = mesh->getMeshId();
+  vtkIdType aType = VTK_LINE;
+  if (nodeIds.size() == 3)
+    aType = VTK_QUADRATIC_EDGE;
+  myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), &nodeIds[0]);
+  mesh->setMyModified();
+  //MESSAGE("SMDS_VtkEdge::init myVtkID " << myVtkID);
+}
+
+bool SMDS_VtkEdge::ChangeNodes(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2)
+{
+  const SMDS_MeshNode* nodes[] = { node1, node2 };
+  SMDS_Mesh::_meshList[myMeshId]->setMyModified();
+  return ChangeNodes(nodes, 2);
+}
+
+bool SMDS_VtkEdge::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType npts = 0;
+  vtkIdType* pts = 0;
+  grid->GetCellPoints(myVtkID, npts, pts);
+  if (nbNodes != npts)
+    {
+      MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes);
+      return false;
+    }
+  for (int i = 0; i < nbNodes; i++)
+    {
+      pts[i] = nodes[i]->getVtkId();
+    }
+  SMDS_Mesh::_meshList[myMeshId]->setMyModified();
+  return true;
+}
+
+bool SMDS_VtkEdge::IsMediumNode(const SMDS_MeshNode* node) const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType npts = 0;
+  vtkIdType* pts = 0;
+  grid->GetCellPoints(myVtkID, npts, pts);
+  //MESSAGE("IsMediumNode " << npts  << " " << (node->getVtkId() == pts[npts-1]));
+  return ((npts == 3) && (node->getVtkId() == pts[2]));
+}
+
+void SMDS_VtkEdge::Print(std::ostream & OS) const
+{
+  OS << "edge <" << GetID() << "> : ";
+}
+
+int SMDS_VtkEdge::NbNodes() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  int nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints();
+  assert(nbPoints >= 2);
+  return nbPoints;
+}
+
+int SMDS_VtkEdge::NbEdges() const
+{
+  return 1;
+}
+
+SMDSAbs_EntityType SMDS_VtkEdge::GetEntityType() const
+{
+  if (NbNodes() == 2)
+    return SMDSEntity_Edge;
+  else
+    return SMDSEntity_Quad_Edge;
+}
+
+vtkIdType SMDS_VtkEdge::GetVtkType() const
+{
+  if (NbNodes() == 2)
+    return VTK_LINE;
+  else
+    return VTK_QUADRATIC_EDGE;
+
+}
+
+/*!
+ * \brief Return node by its index
+ * \param ind - node index
+ * \retval const SMDS_MeshNode* - the node
+ */
+const SMDS_MeshNode*
+SMDS_VtkEdge::GetNode(const int ind) const
+{
+  // TODO optimize !!
+  return SMDS_MeshElement::GetNode(ind);
+}
+
+bool SMDS_VtkEdge::IsQuadratic() const
+{
+  if (this->NbNodes() > 2)
+    return true;
+  else
+    return false;
+}
+
+SMDS_ElemIteratorPtr SMDS_VtkEdge::elementsIterator(SMDSAbs_ElementType type) const
+{
+  switch (type)
+  {
+    case SMDSAbs_Node:
+      return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
+    default:
+      MESSAGE("ERROR : Iterator not implemented")
+      ;
+      return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL);
+  }
+}
+
+SMDS_ElemIteratorPtr SMDS_VtkEdge::nodesIteratorToUNV() const
+{
+  return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
+}
+
+SMDS_ElemIteratorPtr SMDS_VtkEdge::interlacedNodesElemIterator() const
+{
+  return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
+}
diff --git a/src/SMDS/SMDS_VtkEdge.hxx b/src/SMDS/SMDS_VtkEdge.hxx
new file mode 100644 (file)
index 0000000..e7aa32b
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef _SMDS_VTKEDGE_HXX_
+#define _SMDS_VTKEDGE_HXX_
+
+#include "SMESH_SMDS.hxx"
+
+#include "SMDS_MeshEdge.hxx"
+#include <vtkUnstructuredGrid.h>
+#include <vector>
+
+class SMDS_EXPORT SMDS_VtkEdge: public SMDS_MeshEdge
+{
+
+public:
+  SMDS_VtkEdge();
+  SMDS_VtkEdge(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh);
+  ~SMDS_VtkEdge();
+  void init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh);
+  bool ChangeNodes(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2);
+  virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes);
+  virtual bool IsMediumNode(const SMDS_MeshNode* node) const;
+
+  void Print(std::ostream & OS) const;
+  int NbNodes() const;
+  int NbEdges() const;
+
+  virtual vtkIdType GetVtkType() const;
+  virtual SMDSAbs_EntityType GetEntityType() const;
+  virtual const SMDS_MeshNode* GetNode(const int ind) const;
+  virtual bool IsQuadratic() const;
+
+  virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const;
+  virtual SMDS_ElemIteratorPtr nodesIteratorToUNV() const;
+  virtual SMDS_ElemIteratorPtr interlacedNodesElemIterator() const;
+protected:
+};
+#endif
diff --git a/src/SMDS/SMDS_VtkFace.cxx b/src/SMDS/SMDS_VtkFace.cxx
new file mode 100644 (file)
index 0000000..79a0877
--- /dev/null
@@ -0,0 +1,262 @@
+#include "SMDS_VtkFace.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDS_VtkCellIterator.hxx"
+
+#include "utilities.h"
+
+#include <vector>
+
+using namespace std;
+
+SMDS_VtkFace::SMDS_VtkFace()
+{
+}
+
+SMDS_VtkFace::SMDS_VtkFace(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
+{
+  init(nodeIds, mesh);
+}
+
+SMDS_VtkFace::~SMDS_VtkFace()
+{
+}
+
+void SMDS_VtkFace::init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
+{
+  vtkUnstructuredGrid* grid = mesh->getGrid();
+  myIdInShape = -1;
+  myMeshId = mesh->getMeshId();
+  vtkIdType aType = VTK_TRIANGLE;
+  switch (nodeIds.size())
+  {
+    case 3:
+      aType = VTK_TRIANGLE;
+      break;
+    case 4:
+      aType = VTK_QUAD;
+      break;
+    case 6:
+      aType = VTK_QUADRATIC_TRIANGLE;
+      break;
+    case 8:
+      aType = VTK_QUADRATIC_QUAD;
+      break;
+    default:
+      aType = VTK_POLYGON;
+      break;
+  }
+  myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), &nodeIds[0]);
+  mesh->setMyModified();
+  //MESSAGE("SMDS_VtkFace::init myVtkID " << myVtkID);
+}
+
+void SMDS_VtkFace::initPoly(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
+{
+  vtkUnstructuredGrid* grid = mesh->getGrid();
+  myIdInShape = -1;
+  myMeshId = mesh->getMeshId();
+  myVtkID = grid->InsertNextLinkedCell(VTK_POLYGON, nodeIds.size(), &nodeIds[0]);
+  mesh->setMyModified();
+}
+
+bool SMDS_VtkFace::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType npts = 0;
+  vtkIdType* pts = 0;
+  grid->GetCellPoints(myVtkID, npts, pts);
+  if (nbNodes != npts)
+    {
+      MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes);
+      return false;
+    }
+  for (int i = 0; i < nbNodes; i++)
+    {
+      pts[i] = nodes[i]->getVtkId();
+    }
+  SMDS_Mesh::_meshList[myMeshId]->setMyModified();
+  return true;
+}
+
+void SMDS_VtkFace::Print(std::ostream & OS) const
+{
+  OS << "face <" << GetID() << "> : ";
+}
+
+int SMDS_VtkFace::NbEdges() const
+{
+  // TODO quadratic polygons ?
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  int nbEdges = 3;
+  switch (aVtkType)
+  {
+    case VTK_TRIANGLE:
+    case VTK_QUADRATIC_TRIANGLE:
+      nbEdges = 3;
+      break;
+    case VTK_QUAD:
+    case VTK_QUADRATIC_QUAD:
+      nbEdges = 4;
+      break;
+    case VTK_POLYGON:
+    default:
+      nbEdges = grid->GetCell(myVtkID)->GetNumberOfPoints();
+      break;
+  }
+  return nbEdges;
+}
+
+int SMDS_VtkFace::NbFaces() const
+{
+  return 1;
+}
+
+int SMDS_VtkFace::NbNodes() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  int nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints();
+  return nbPoints;
+}
+
+/*!
+ * \brief Return node by its index
+ * \param ind - node index
+ * \retval const SMDS_MeshNode* - the node
+ */
+const SMDS_MeshNode*
+SMDS_VtkFace::GetNode(const int ind) const
+{
+  return SMDS_MeshElement::GetNode(ind); // --- a optimiser !
+}
+
+bool SMDS_VtkFace::IsQuadratic() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  // TODO quadratic polygons ?
+  switch (aVtkType)
+  {
+    case VTK_QUADRATIC_TRIANGLE:
+    case VTK_QUADRATIC_QUAD:
+      return true;
+      break;
+    default:
+      return false;
+  }
+}
+
+bool SMDS_VtkFace::IsPoly() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  return (aVtkType == VTK_POLYGON);
+}
+
+bool SMDS_VtkFace::IsMediumNode(const SMDS_MeshNode* node) const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  int rankFirstMedium = 0;
+  switch (aVtkType)
+  {
+    case VTK_QUADRATIC_TRIANGLE:
+      rankFirstMedium = 3; // medium nodes are of rank 3,4,5
+      break;
+    case VTK_QUADRATIC_QUAD:
+      rankFirstMedium = 4; // medium nodes are of rank 4,5,6,7
+      break;
+    default:
+      //MESSAGE("wrong element type " << aVtkType);
+      return false;
+  }
+  vtkIdType npts = 0;
+  vtkIdType* pts = 0;
+  grid->GetCellPoints(myVtkID, npts, pts);
+  vtkIdType nodeId = node->getVtkId();
+  for (int rank = 0; rank < npts; rank++)
+    {
+      if (pts[rank] == nodeId)
+        {
+          //MESSAGE("rank " << rank << " is medium node " << (rank < rankFirstMedium));
+          if (rank < rankFirstMedium)
+            return false;
+          else
+            return true;
+        }
+    }
+  //throw SALOME_Exception(LOCALIZED("node does not belong to this element"));
+  MESSAGE("======================================================");
+  MESSAGE("= IsMediumNode: node does not belong to this element =");
+  MESSAGE("======================================================");
+  return false;
+}
+
+SMDSAbs_EntityType SMDS_VtkFace::GetEntityType() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  SMDSAbs_EntityType aType = SMDSEntity_Polygon;
+  switch (aVtkType)
+  {
+    case VTK_TRIANGLE:
+      aType = SMDSEntity_Triangle;
+      break;
+    case VTK_QUAD:
+      aType = SMDSEntity_Quadrangle;
+      break;
+    case VTK_QUADRATIC_TRIANGLE:
+      aType = SMDSEntity_Quad_Triangle;
+      break;
+    case VTK_QUADRATIC_QUAD:
+      aType = SMDSEntity_Quad_Quadrangle;
+      break;
+    default:
+      aType = SMDSEntity_Polygon;
+  }
+  return aType;
+}
+
+vtkIdType SMDS_VtkFace::GetVtkType() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  return aVtkType;
+}
+
+SMDS_ElemIteratorPtr SMDS_VtkFace::elementsIterator(SMDSAbs_ElementType type) const
+{
+  switch (type)
+  {
+    case SMDSAbs_Node:
+      return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
+    default:
+      MESSAGE("ERROR : Iterator not implemented")
+      ;
+      return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL);
+  }
+}
+
+SMDS_ElemIteratorPtr SMDS_VtkFace::nodesIteratorToUNV() const
+{
+  return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
+}
+
+SMDS_ElemIteratorPtr SMDS_VtkFace::interlacedNodesElemIterator() const
+{
+  return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
+}
+
+//! change only the first node, used for temporary triangles in quadrangle to triangle adaptor
+void SMDS_VtkFace::ChangeApex(const SMDS_MeshNode* node)
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType npts = 0;
+  vtkIdType* pts = 0;
+  grid->GetCellPoints(myVtkID, npts, pts);
+  grid->RemoveReferenceToCell(pts[0], myVtkID);
+  pts[0] = node->getVtkId();
+  grid->AddReferenceToCell(pts[0], myVtkID);
+  SMDS_Mesh::_meshList[myMeshId]->setMyModified();
+}
diff --git a/src/SMDS/SMDS_VtkFace.hxx b/src/SMDS/SMDS_VtkFace.hxx
new file mode 100644 (file)
index 0000000..7a346fd
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef _SMDS_VTKFACE_HXX_
+#define _SMDS_VTKFACE_HXX_
+
+#include "SMESH_SMDS.hxx"
+
+#include "SMDS_MeshFace.hxx"
+#include <vtkUnstructuredGrid.h>
+#include <vector>
+
+class SMDS_EXPORT SMDS_VtkFace: public SMDS_MeshFace
+{
+public:
+  SMDS_VtkFace();
+  SMDS_VtkFace(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh);
+  ~SMDS_VtkFace();
+  void init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh);
+  void initPoly(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh);
+  bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes);
+  void ChangeApex(const SMDS_MeshNode* node); // to use only for tmp triangles
+  void Print(std::ostream & OS) const;
+  int NbEdges() const;
+  int NbFaces() const;
+  int NbNodes() const;
+
+  virtual vtkIdType GetVtkType() const;
+  virtual SMDSAbs_EntityType GetEntityType() const;
+  virtual const SMDS_MeshNode* GetNode(const int ind) const;
+  virtual bool IsQuadratic() const;
+  virtual bool IsPoly() const;
+  virtual bool IsMediumNode(const SMDS_MeshNode* node) const;
+
+  virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const;
+  virtual SMDS_ElemIteratorPtr nodesIteratorToUNV() const;
+  virtual SMDS_ElemIteratorPtr interlacedNodesElemIterator() const;
+protected:
+};
+
+#endif
diff --git a/src/SMDS/SMDS_VtkVolume.cxx b/src/SMDS/SMDS_VtkVolume.cxx
new file mode 100644 (file)
index 0000000..45c61be
--- /dev/null
@@ -0,0 +1,594 @@
+#include "SMDS_VtkVolume.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDS_VtkCellIterator.hxx"
+
+#include "utilities.h"
+
+#include <vector>
+
+SMDS_VtkVolume::SMDS_VtkVolume()
+{
+}
+
+SMDS_VtkVolume::SMDS_VtkVolume(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
+{
+  init(nodeIds, mesh);
+}
+/*!
+ * typed used are vtk types (@see vtkCellType.h)
+ * see GetEntityType() for conversion in SMDS type (@see SMDSAbs_ElementType.hxx)
+ */
+void SMDS_VtkVolume::init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
+{
+  vtkUnstructuredGrid* grid = mesh->getGrid();
+  myIdInShape = -1;
+  myMeshId = mesh->getMeshId();
+  vtkIdType aType = VTK_TETRA;
+  switch (nodeIds.size())
+  {
+    case 4:
+      aType = VTK_TETRA;
+      break;
+    case 5:
+      aType = VTK_PYRAMID;
+      break;
+    case 6:
+      aType = VTK_WEDGE;
+      break;
+    case 8:
+      aType = VTK_HEXAHEDRON;
+      break;
+    case 10:
+      aType = VTK_QUADRATIC_TETRA;
+      break;
+    case 13:
+      aType = VTK_QUADRATIC_PYRAMID;
+      break;
+    case 15:
+      aType = VTK_QUADRATIC_WEDGE;
+      break;
+    case 20:
+      aType = VTK_QUADRATIC_HEXAHEDRON;
+      break;
+    default:
+      aType = VTK_HEXAHEDRON;
+      break;
+  }
+  myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), &nodeIds[0]);
+  mesh->setMyModified();
+  //MESSAGE("SMDS_VtkVolume::init myVtkID " << myVtkID);
+}
+
+//#ifdef VTK_HAVE_POLYHEDRON
+void SMDS_VtkVolume::initPoly(std::vector<vtkIdType> nodeIds, std::vector<int> nbNodesPerFace, SMDS_Mesh* mesh)
+{
+  MESSAGE("SMDS_VtkVolume::initPoly");
+  SMDS_UnstructuredGrid* grid = mesh->getGrid();
+  // TODO is it useful to orient faces ?
+  double center[3];
+  this->gravityCenter(grid, &nodeIds[0], nodeIds.size(), &center[0]);
+  vector<vtkIdType> ptIds;
+  ptIds.clear();
+  vtkIdType nbFaces = nbNodesPerFace.size();
+  int k = 0;
+  for (int i = 0; i < nbFaces; i++)
+    {
+      int nf = nbNodesPerFace[i];
+      ptIds.push_back(nf);
+//      double a[3];
+//      double b[3];
+//      double c[3];
+//      grid->GetPoints()->GetPoint(nodeIds[k], a);
+//      grid->GetPoints()->GetPoint(nodeIds[k + 1], b);
+//      grid->GetPoints()->GetPoint(nodeIds[k + 2], c);
+//      bool isFaceForward = this->isForward(a, b, c, center);
+      bool isFaceForward = true;
+      //MESSAGE("isFaceForward " << i << " " << isFaceForward);
+      vtkIdType *facePts = &nodeIds[k];
+      if (isFaceForward)
+        for (int n = 0; n < nf; n++)
+          ptIds.push_back(facePts[n]);
+      else
+        for (int n = nf - 1; n >= 0; n--)
+          ptIds.push_back(facePts[n]);
+      k += nf;
+    }
+  myVtkID = grid->InsertNextLinkedCell(VTK_POLYHEDRON, nbFaces, &ptIds[0]);
+  mesh->setMyModified();
+}
+//#endif
+
+bool SMDS_VtkVolume::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType npts = 0;
+  vtkIdType* pts = 0;
+  grid->GetCellPoints(myVtkID, npts, pts);
+  if (nbNodes != npts)
+    {
+      MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes);
+      return false;
+    }
+  for (int i = 0; i < nbNodes; i++)
+    {
+      pts[i] = nodes[i]->getVtkId();
+    }
+  SMDS_Mesh::_meshList[myMeshId]->setMyModified();
+  return true;
+}
+
+/*!
+ * Reorder in VTK order a list of nodes given in SMDS order.
+ * To be used before ChangeNodes: lists are given or computed in SMDS order.
+ */
+bool SMDS_VtkVolume::vtkOrder(const SMDS_MeshNode* nodes[], const int nbNodes)
+{
+  if (nbNodes != this->NbNodes())
+    {
+      MESSAGE("vtkOrder, wrong number of nodes " << nbNodes << " instead of "<< this->NbNodes());
+      return false;
+    }
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  switch (aVtkType)
+  {
+    case VTK_TETRA:
+      this->exchange(nodes, 1, 2);
+      break;
+    case VTK_QUADRATIC_TETRA:
+      this->exchange(nodes, 1, 2);
+      this->exchange(nodes, 4, 6);
+      this->exchange(nodes, 8, 9);
+      break;
+    case VTK_PYRAMID:
+      this->exchange(nodes, 1, 3);
+      break;
+    case VTK_WEDGE:
+      break;
+    case VTK_QUADRATIC_PYRAMID:
+      this->exchange(nodes, 1, 3);
+      this->exchange(nodes, 5, 8);
+      this->exchange(nodes, 6, 7);
+      this->exchange(nodes, 10, 12);
+      break;
+    case VTK_QUADRATIC_WEDGE:
+      break;
+    case VTK_HEXAHEDRON:
+      this->exchange(nodes, 1, 3);
+      this->exchange(nodes, 5, 7);
+      break;
+    case VTK_QUADRATIC_HEXAHEDRON:
+      this->exchange(nodes, 1, 3);
+      this->exchange(nodes, 5, 7);
+      this->exchange(nodes, 8, 11);
+      this->exchange(nodes, 9, 10);
+      this->exchange(nodes, 12, 15);
+      this->exchange(nodes, 13, 14);
+      this->exchange(nodes, 17, 19);
+      break;
+    case VTK_POLYHEDRON:
+    default:
+      break;
+  }
+}
+
+SMDS_VtkVolume::~SMDS_VtkVolume()
+{
+}
+
+void SMDS_VtkVolume::Print(ostream & OS) const
+{
+  OS << "volume <" << GetID() << "> : ";
+}
+
+int SMDS_VtkVolume::NbFaces() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  int nbFaces = 4;
+  switch (aVtkType)
+  {
+    case VTK_TETRA:
+    case VTK_QUADRATIC_TETRA:
+      nbFaces = 4;
+      break;
+    case VTK_PYRAMID:
+    case VTK_WEDGE:
+    case VTK_QUADRATIC_PYRAMID:
+    case VTK_QUADRATIC_WEDGE:
+      nbFaces = 5;
+      break;
+    case VTK_HEXAHEDRON:
+    case VTK_QUADRATIC_HEXAHEDRON:
+      nbFaces = 6;
+      break;
+    case VTK_POLYHEDRON:
+      {
+        vtkIdType nFaces = 0;
+        vtkIdType* ptIds = 0;
+        grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
+        nbFaces = nFaces;
+        break;
+      }
+    default:
+      MESSAGE("invalid volume type")
+      ;
+      nbFaces = 0;
+      break;
+  }
+  return nbFaces;
+}
+
+int SMDS_VtkVolume::NbNodes() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  int nbPoints = 0;
+  if (aVtkType != VTK_POLYHEDRON)
+    {
+      nbPoints = grid->GetCell(myVtkID)->GetNumberOfPoints();
+    }
+  else
+    {
+      vtkIdType nFaces = 0;
+      vtkIdType* ptIds = 0;
+      grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
+      int id = 0;
+      for (int i = 0; i < nFaces; i++)
+        {
+          int nodesInFace = ptIds[id];
+          nbPoints += nodesInFace;
+          id += (nodesInFace + 1);
+        }
+    }
+  return nbPoints;
+}
+
+int SMDS_VtkVolume::NbEdges() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  int nbEdges = 6;
+  switch (aVtkType)
+  {
+    case VTK_TETRA:
+    case VTK_QUADRATIC_TETRA:
+      nbEdges = 6;
+      break;
+    case VTK_PYRAMID:
+    case VTK_QUADRATIC_PYRAMID:
+      nbEdges = 8;
+      break;
+    case VTK_WEDGE:
+    case VTK_QUADRATIC_WEDGE:
+      nbEdges = 9;
+      break;
+    case VTK_HEXAHEDRON:
+    case VTK_QUADRATIC_HEXAHEDRON:
+      nbEdges = 12;
+      break;
+    case VTK_POLYHEDRON:
+      {
+        vtkIdType nFaces = 0;
+        vtkIdType* ptIds = 0;
+        grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
+        nbEdges = 0;
+        int id = 0;
+        for (int i = 0; i < nFaces; i++)
+          {
+            int edgesInFace = ptIds[id];
+            id += (edgesInFace + 1);
+            nbEdges += edgesInFace;
+          }
+        nbEdges = nbEdges / 2;
+        break;
+      }
+    default:
+      MESSAGE("invalid volume type")
+      ;
+      nbEdges = 0;
+      break;
+  }
+  return nbEdges;
+}
+
+/*! polyhedron only,
+ *  1 <= face_ind <= NbFaces()
+ */
+int SMDS_VtkVolume::NbFaceNodes(const int face_ind) const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  int nbNodes = 0;
+  if (aVtkType == VTK_POLYHEDRON)
+    {
+      vtkIdType nFaces = 0;
+      vtkIdType* ptIds = 0;
+      grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
+      int id = 0;
+      for (int i = 0; i < nFaces; i++)
+        {
+          int nodesInFace = ptIds[id];
+          id += (nodesInFace + 1);
+          if (i == face_ind - 1)
+            {
+              nbNodes = nodesInFace;
+              break;
+            }
+        }
+    }
+  return nbNodes;
+}
+
+/*! polyhedron only,
+ *  1 <= face_ind <= NbFaces()
+ *  1 <= node_ind <= NbFaceNodes()
+ */
+const SMDS_MeshNode* SMDS_VtkVolume::GetFaceNode(const int face_ind, const int node_ind) const
+{
+  SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId];
+  vtkUnstructuredGrid* grid = mesh->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  const SMDS_MeshNode* node = 0;
+  if (aVtkType == VTK_POLYHEDRON)
+    {
+      vtkIdType nFaces = 0;
+      vtkIdType* ptIds = 0;
+      grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
+      int id = 0;
+      for (int i = 0; i < nFaces; i++)
+        {
+          int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace]
+          if (i == face_ind - 1) // first face is number 1
+            {
+              if ((node_ind > 0) && (node_ind <= nodesInFace))
+                node = mesh->FindNodeVtk(ptIds[id + node_ind]); // ptIds[id+1] : first node
+              break;
+            }
+          id += (nodesInFace + 1);
+        }
+    }
+  return node;
+}
+
+/*! polyhedron only,
+ *  return number of nodes for each face
+ */
+const std::vector<int> & SMDS_VtkVolume::GetQuantities() const
+{
+  vector<int> quantities;
+  quantities.clear();
+  SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId];
+  vtkUnstructuredGrid* grid = mesh->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  if (aVtkType == VTK_POLYHEDRON)
+    {
+      vtkIdType nFaces = 0;
+      vtkIdType* ptIds = 0;
+      grid->GetFaceStream(this->myVtkID, nFaces, ptIds);
+      int id = 0;
+      for (int i = 0; i < nFaces; i++)
+        {
+          int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace]
+          quantities.push_back(nodesInFace);
+          id += (nodesInFace + 1);
+        }
+    }
+  return quantities;
+}
+
+SMDS_ElemIteratorPtr SMDS_VtkVolume::elementsIterator(SMDSAbs_ElementType type) const
+{
+  switch (type)
+  {
+    case SMDSAbs_Node:
+      {
+        SMDSAbs_EntityType aType = this->GetEntityType();
+        if (aType == SMDSEntity_Polyhedra)
+          return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorPolyH(SMDS_Mesh::_meshList[myMeshId], myVtkID, aType));
+        else
+          return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, aType));
+      }
+    default:
+      MESSAGE("ERROR : Iterator not implemented");
+      return SMDS_ElemIteratorPtr((SMDS_ElemIterator*) NULL);
+  }
+}
+
+SMDS_ElemIteratorPtr SMDS_VtkVolume::nodesIteratorToUNV() const
+{
+  return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
+}
+
+SMDS_ElemIteratorPtr SMDS_VtkVolume::interlacedNodesElemIterator() const
+{
+  return SMDS_ElemIteratorPtr(new SMDS_VtkCellIteratorToUNV(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
+}
+
+SMDSAbs_ElementType SMDS_VtkVolume::GetType() const
+{
+  return SMDSAbs_Volume;
+}
+
+/*!
+ * \brief Return node by its index
+ * \param ind - node index
+ * \retval const SMDS_MeshNode* - the node
+ */
+const SMDS_MeshNode* SMDS_VtkVolume::GetNode(const int ind) const
+{
+  // TODO optimize if possible (vtkCellIterator)
+  return SMDS_MeshElement::GetNode(ind);
+}
+
+bool SMDS_VtkVolume::IsQuadratic() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  // TODO quadratic polyhedrons ?
+  switch (aVtkType)
+  {
+    case VTK_QUADRATIC_TETRA:
+    case VTK_QUADRATIC_PYRAMID:
+    case VTK_QUADRATIC_WEDGE:
+    case VTK_QUADRATIC_HEXAHEDRON:
+      return true;
+      break;
+    default:
+      return false;
+  }
+}
+
+bool SMDS_VtkVolume::IsPoly() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  return (aVtkType == VTK_POLYHEDRON);
+}
+
+bool SMDS_VtkVolume::IsMediumNode(const SMDS_MeshNode* node) const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+  int rankFirstMedium = 0;
+  switch (aVtkType)
+  {
+    case VTK_QUADRATIC_TETRA:
+      rankFirstMedium = 4; // medium nodes are of rank 4 to 9
+      break;
+    case VTK_QUADRATIC_PYRAMID:
+      rankFirstMedium = 5; // medium nodes are of rank 5 to 12
+      break;
+    case VTK_QUADRATIC_WEDGE:
+      rankFirstMedium = 6; // medium nodes are of rank 6 to 14
+      break;
+    case VTK_QUADRATIC_HEXAHEDRON:
+      rankFirstMedium = 8; // medium nodes are of rank 8 to 19
+      break;
+    default:
+      return false;
+  }
+  vtkIdType npts = 0;
+  vtkIdType* pts = 0;
+  grid->GetCellPoints(myVtkID, npts, pts);
+  vtkIdType nodeId = node->getVtkId();
+  for (int rank = 0; rank < npts; rank++)
+    {
+      if (pts[rank] == nodeId)
+        {
+          if (rank < rankFirstMedium)
+            return false;
+          else
+            return true;
+        }
+    }
+  //throw SALOME_Exception(LOCALIZED("node does not belong to this element"));
+  MESSAGE("======================================================");
+  MESSAGE("= IsMediumNode: node does not belong to this element =");
+  MESSAGE("======================================================");
+  return false;
+}
+
+SMDSAbs_EntityType SMDS_VtkVolume::GetEntityType() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aVtkType = grid->GetCellType(this->myVtkID);
+
+  SMDSAbs_EntityType aType = SMDSEntity_Tetra;
+  switch (aVtkType)
+  {
+    case VTK_TETRA:
+      aType = SMDSEntity_Tetra;
+      break;
+    case VTK_PYRAMID:
+      aType = SMDSEntity_Pyramid;
+      break;
+    case VTK_WEDGE:
+      aType = SMDSEntity_Penta;
+      break;
+    case VTK_HEXAHEDRON:
+      aType = SMDSEntity_Hexa;
+      break;
+    case VTK_QUADRATIC_TETRA:
+      aType = SMDSEntity_Quad_Tetra;
+      break;
+    case VTK_QUADRATIC_PYRAMID:
+      aType = SMDSEntity_Quad_Pyramid;
+      break;
+    case VTK_QUADRATIC_WEDGE:
+      aType = SMDSEntity_Quad_Penta;
+      break;
+    case VTK_QUADRATIC_HEXAHEDRON:
+      aType = SMDSEntity_Quad_Hexa;
+      break;
+//#ifdef VTK_HAVE_POLYHEDRON
+    case VTK_POLYHEDRON:
+      aType = SMDSEntity_Polyhedra;
+      break;
+//#endif
+    default:
+      aType = SMDSEntity_Polyhedra;
+      break;
+  }
+  return aType;
+}
+
+vtkIdType SMDS_VtkVolume::GetVtkType() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkIdType aType = grid->GetCellType(myVtkID);
+  return aType;
+}
+
+void SMDS_VtkVolume::gravityCenter(SMDS_UnstructuredGrid* grid, vtkIdType *nodeIds, int nbNodes, double* result)
+{
+  for (int j = 0; j < 3; j++)
+    result[j] = 0;
+  if (nbNodes <= 0)
+    return;
+  for (int i = 0; i < nbNodes; i++)
+    {
+      double *coords = grid->GetPoint(nodeIds[i]);
+      for (int j = 0; j < 3; j++)
+        result[j] += coords[j];
+    }
+  for (int j = 0; j < 3; j++)
+    result[j] = result[j] / nbNodes;
+  //MESSAGE("center " << result[0] << " " << result[1] << " "  << result[2]);
+  return;
+}
+
+bool SMDS_VtkVolume::isForward(double* a, double* b, double* c, double* d)
+{
+  double u[3], v[3], w[3];
+  for (int j = 0; j < 3; j++)
+    {
+      //MESSAGE("a,b,c,d " << a[j] << " " << b[j] << " " << c[j] << " " << d[j]);
+      u[j] = b[j] - a[j];
+      v[j] = c[j] - a[j];
+      w[j] = d[j] - a[j];
+      //MESSAGE("u,v,w " << u[j] << " " << v[j] << " " << w[j]);
+    }
+  double prodmixte = (u[2] * v[3] - u[3] * v[2]) * w[1] + (u[3] * v[1] - u[1] * v[3]) * w[2] + (u[1] * v[2] - u[2]
+      * v[1]) * w[3];
+  return (prodmixte >= 0);
+}
+
+/*! For polyhedron only
+ *  @return actual number of nodes (not the sum of nodes of all faces)
+ */
+int SMDS_VtkVolume::NbUniqueNodes() const
+{
+  vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  return grid->GetCell(myVtkID)->GetNumberOfPoints();
+}
+
+/*! For polyhedron use only
+ *  @return iterator on actual nodes (not through the faces)
+ */
+SMDS_ElemIteratorPtr SMDS_VtkVolume::uniqueNodesIterator() const
+{
+  MESSAGE("uniqueNodesIterator");
+  return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType()));
+}
diff --git a/src/SMDS/SMDS_VtkVolume.hxx b/src/SMDS/SMDS_VtkVolume.hxx
new file mode 100644 (file)
index 0000000..b43c73e
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef _SMDS_VTKVOLUME_HXX_
+#define _SMDS_VTKVOLUME_HXX_
+
+#include "SMESH_SMDS.hxx"
+
+#include "SMDS_MeshVolume.hxx"
+#include "SMDS_UnstructuredGrid.hxx"
+#include <vector>
+
+class SMDS_EXPORT SMDS_VtkVolume: public SMDS_MeshVolume
+{
+public:
+  SMDS_VtkVolume();
+  SMDS_VtkVolume(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh);
+  ~SMDS_VtkVolume();
+  void init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh);
+//#ifdef VTK_HAVE_POLYHEDRON
+  void initPoly(std::vector<vtkIdType> nodeIds, std::vector<int> nbNodesPerFace, SMDS_Mesh* mesh);
+//#endif
+  virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes);
+  virtual bool vtkOrder(const SMDS_MeshNode* nodes[], const int nbNodes);
+
+  void Print(std::ostream & OS) const;
+  int NbFaces() const;
+  int NbNodes() const;
+  int NbEdges() const;
+
+  // 1 <= face_ind <= NbFaces()
+  int NbFaceNodes (const int face_ind) const;
+  // 1 <= face_ind <= NbFaces()
+  // 1 <= node_ind <= NbFaceNodes()
+  const SMDS_MeshNode* GetFaceNode (const int face_ind, const int node_ind) const;
+
+  virtual SMDSAbs_ElementType GetType() const;
+  virtual vtkIdType GetVtkType() const;
+  virtual SMDSAbs_EntityType GetEntityType() const;
+  virtual const SMDS_MeshNode* GetNode(const int ind) const;
+  virtual bool IsQuadratic() const;
+  virtual bool IsPoly() const;
+  virtual bool IsMediumNode(const SMDS_MeshNode* node) const;
+  static void gravityCenter(SMDS_UnstructuredGrid* grid,
+                            vtkIdType *nodeIds,
+                            int nbNodes,
+                            double* result);
+  static bool isForward(double* a,double* b,double* c,double* d);
+  int NbUniqueNodes() const;
+  SMDS_ElemIteratorPtr uniqueNodesIterator() const;
+  const std::vector<int> & GetQuantities() const;
+
+  virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const;
+  virtual SMDS_ElemIteratorPtr nodesIteratorToUNV() const;
+  virtual SMDS_ElemIteratorPtr interlacedNodesElemIterator() const;
+
+protected:
+};
+
+#endif
diff --git a/src/SMDS/chrono.cxx b/src/SMDS/chrono.cxx
new file mode 100644 (file)
index 0000000..73fbddb
--- /dev/null
@@ -0,0 +1,86 @@
+//  Copyright (C) 2006-2010  CEA/DEN, EDF R&D
+//
+//  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
+//
+
+#include "chrono.hxx"
+#include "utilities.h"
+
+using namespace std;
+
+cntStruct* counters::_ctrs = 0;
+int counters::_nbChrono = 0;
+
+counters::counters(int nb)
+{
+  MESSAGE("counters::counters(int nb)");
+  _nbChrono = nb;
+  _ctrs = new cntStruct[_nbChrono];
+
+  for (int i = 0; i < _nbChrono; i++)
+    {
+      _ctrs[i]._ctrNames = 0;
+      _ctrs[i]._ctrLines = 0;
+      _ctrs[i]._ctrOccur = 0;
+      _ctrs[i]._ctrCumul = 0;
+    }
+
+  MESSAGE("counters::counters()");
+}
+
+counters::~counters()
+{
+  stats();
+}
+
+void counters::stats()
+{
+  MESSAGE("counters::stats()");
+  for (int i = 0; i < _nbChrono; i++)
+    if (_ctrs[i]._ctrOccur)
+      {
+        MESSAGE("Compteur[" << i << "]: "<< _ctrs[i]._ctrNames << "[" << _ctrs[i]._ctrLines << "]");
+        MESSAGE("  " << _ctrs[i]._ctrOccur);
+        MESSAGE("  " << _ctrs[i]._ctrCumul);
+      }
+}
+
+chrono::chrono(int i) :
+  _ctr(i), _run(true)
+{
+  //MESSAGE("chrono::chrono " << _ctr << " " << _run);
+  _start = clock();
+}
+
+chrono::~chrono()
+{
+  if (_run)
+    stop();
+}
+
+void chrono::stop()
+{
+  //MESSAGE("chrono::stop " << _ctr << " " << _run);
+  if (_run)
+    {
+      _run = false;
+      _end = clock();
+      double elapse = double(_end - _start) / double(CLOCKS_PER_SEC);
+      counters::_ctrs[_ctr]._ctrOccur++;
+      counters::_ctrs[_ctr]._ctrCumul += elapse;
+    }
+}
diff --git a/src/SMDS/chrono.hxx b/src/SMDS/chrono.hxx
new file mode 100644 (file)
index 0000000..6c7b3c9
--- /dev/null
@@ -0,0 +1,73 @@
+//  Copyright (C) 2006-2010  CEA/DEN, EDF R&D
+//
+//  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
+//
+
+#ifndef _CHRONO_HXX_
+#define _CHRONO_HXX_
+
+#include <vector>
+#include <string>
+#include <iostream>
+#include <ctime>
+
+typedef struct acnt
+{
+  char*  _ctrNames;
+  int    _ctrLines;
+  int    _ctrOccur;
+  double _ctrCumul;
+} cntStruct;
+
+class counters
+{
+public:
+  static cntStruct *_ctrs;
+  counters(int nb);
+  ~counters();
+  static void stats();
+protected:
+  static int _nbChrono;
+};
+
+class chrono
+{
+public:
+  chrono(int i);
+  ~chrono();
+  void stop();
+protected:
+  bool _run;
+  int _ctr;
+  clock_t _start, _end;
+};
+
+#ifdef CHRONODEF
+#define CHRONO(i) counters::_ctrs[i]._ctrNames = (char *)__FILE__; \
+  counters::_ctrs[i]._ctrLines = __LINE__; \
+  chrono aChrono##i(i);
+
+#define CHRONOSTOP(i) aChrono##i.stop();
+
+#else  // CHRONODEF
+
+#define CHRONO(i)
+#define CHRONOSTOP(i)
+
+#endif // CHRONODEF
+
+#endif // _CHRONO_HXX_
index ef7e491bb2c5532a4dfb93fdb6ee3f893c33b3af..9db3b14506b0ddd0594da91f39364a1183ee26dc 100644 (file)
@@ -85,6 +85,7 @@ libSMESHimpl_la_CPPFLAGS = \
        $(CAS_CPPFLAGS) \
        $(MED_CXXFLAGS) \
        $(GEOM_CXX_FLAGS) \
+        $(VTK_INCLUDES) \
        $(BOOST_CPPFLAGS) \
        @HDF5_INCLUDES@ \
        -I$(srcdir)/../Controls \
index 3a6a4efd97dad1f5624cdbb07a530c909c59b2b1..953bf9e2ba7f82b9a7b0fef1d91551e64976c2f9 100644 (file)
@@ -255,10 +255,10 @@ bool SMESH_Algo::IsReversedSubMesh (const TopoDS_Face&  theFace,
         const SMDS_PositionPtr& pos = node->GetPosition();
         if ( !pos ) continue;
         if ( pos->GetTypeOfPosition() == SMDS_TOP_FACE ) {
-          fPos = dynamic_cast< const SMDS_FacePosition* >( pos.get() );
+          fPos = dynamic_cast< const SMDS_FacePosition* >( pos );
         }
         else if ( pos->GetTypeOfPosition() == SMDS_TOP_VERTEX ) {
-          vID = pos->GetShapeId();
+          vID = node->getshapeId();
         }
       }
       if ( fPos || ( !normalOK && vID )) {
@@ -366,7 +366,7 @@ bool SMESH_Algo::GetNodeParamOnEdge(const SMESHDS_Mesh* theMesh,
       if ( pos->GetTypeOfPosition() != SMDS_TOP_EDGE )
         return false;
       const SMDS_EdgePosition* epos =
-        static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+        static_cast<const SMDS_EdgePosition*>(node->GetPosition());
       if ( !paramSet.insert( epos->GetUParameter() ).second )
         return false; // equal parameters
     }
@@ -433,8 +433,9 @@ bool SMESH_Algo::GetSortedNodesOnEdge(const SMESHDS_Mesh*                   theM
       if ( pos->GetTypeOfPosition() != SMDS_TOP_EDGE )
         return false;
       const SMDS_EdgePosition* epos =
-        static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+        static_cast<const SMDS_EdgePosition*>(node->GetPosition());
       theNodes.insert( make_pair( epos->GetUParameter(), node ));
+      //MESSAGE("U " << epos->GetUParameter() << " ID " << node->GetID());
       ++nbNodes;
     }
   }
@@ -443,6 +444,7 @@ bool SMESH_Algo::GetSortedNodesOnEdge(const SMESHDS_Mesh*                   theM
   TopExp::Vertices(theEdge, v1, v2);
   const SMDS_MeshNode* n1 = VertexNode( v1, (SMESHDS_Mesh*) theMesh );
   const SMDS_MeshNode* n2 = VertexNode( v2, (SMESHDS_Mesh*) theMesh );
+  //MESSAGE("Vertices ID " << n1->GetID() << " " << n2->GetID());
   Standard_Real f, l;
   BRep_Tool::Range(theEdge, f, l);
   if ( v1.Orientation() != TopAbs_FORWARD )
index 47947add9a6aeb8547b8f5e8c1d3a105ea046682..2b19f938e537716042c6e2a8547090e04e170434 100644 (file)
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
 //
+#define CHRONODEF
 #include "SMESH_Gen.hxx"
 #include "SMESH_subMesh.hxx"
 #include "SMESH_HypoFilter.hxx"
 #include "SMESHDS_Document.hxx"
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
+#include "SMDS_Mesh.hxx"
 
 #include "utilities.h"
 #include "OpUtil.hxx"
@@ -41,6 +43,8 @@
 #include <TopTools_ListOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 
+#include "memoire.h"
+
 using namespace std;
 
 //=============================================================================
@@ -51,10 +55,13 @@ using namespace std;
 
 SMESH_Gen::SMESH_Gen()
 {
-  MESSAGE("SMESH_Gen::SMESH_Gen");
-  _localId = 0;
-  _hypId = 0;
-  _segmentation = _nbSegments = 10;
+        MESSAGE("SMESH_Gen::SMESH_Gen");
+        _localId = 0;
+        _hypId = 0;
+        _segmentation = 10;
+        SMDS_Mesh::_meshList.clear();
+        MESSAGE(SMDS_Mesh::_meshList.size());
+        _counters = new counters(100);
 }
 
 //=============================================================================
@@ -108,6 +115,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh &          aMesh,
                         TSetOfInt*            aShapesId)
 {
   MESSAGE("SMESH_Gen::Compute");
+  MEMOSTAT;
 
   bool ret = true;
 
@@ -151,6 +159,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh &          aMesh,
       else if ( aShapesId )
         aShapesId->insert( smToCompute->GetId() );
     }
+    //aMesh.GetMeshDS()->Modified();
     return ret;
   }
   else
@@ -265,6 +274,26 @@ bool SMESH_Gen::Compute(SMESH_Mesh &          aMesh,
   }
 
   MESSAGE( "VSR - SMESH_Gen::Compute() finished, OK = " << ret);
+  MEMOSTAT;
+
+  SMESHDS_Mesh *myMesh = aMesh.GetMeshDS();
+  myMesh->adjustStructure();
+  MESSAGE("*** compactMesh after compute");
+  myMesh->compactMesh();
+  //myMesh->adjustStructure();
+  list<int> listind = myMesh->SubMeshIndices();
+  list<int>::iterator it = listind.begin();
+  int total = 0;
+  for(; it != listind.end(); ++it)
+    {
+      ::SMESHDS_SubMesh *subMesh = myMesh->MeshElements(*it);
+      total +=  subMesh->getSize();
+    }
+  MESSAGE("total elements and nodes in submesh sets:" << total);
+  MESSAGE("Number of node objects " << SMDS_MeshNode::nbNodes);
+  MESSAGE("Number of cell objects " << SMDS_MeshCell::nbCells);
+  //myMesh->dumpGrid();
+  //aMesh.GetMeshDS()->Modified();
   return ret;
 }
 
index 606c96d1866f30223a123f86b095390ebb68d8b4..a9af382ef5061cc22a8f69985af2874ea61b08f4 100644 (file)
@@ -41,6 +41,8 @@
 #include "SMESH_3D_Algo.hxx"
 #include "SMESH_Mesh.hxx"
 
+#include "chrono.hxx"
+
 #include <TopoDS_Shape.hxx>
 
 #include <map>
@@ -159,6 +161,7 @@ private:
   int _segmentation;
   // default of segments
   int _nbSegments;
+  counters *_counters;
 };
 
 #endif
index 9ababf9e424017ac86b4ac398eacf5bb30f552cb..dca74e5d1dd4697e0e24eb46fb761797a8ef553d 100644 (file)
@@ -24,6 +24,7 @@
 //  File   : SMESH_Hypothesis.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
+//  $Header$
 //
 #include "SMESH_Hypothesis.hxx"
 #include "SMESH_Gen.hxx"
index f26db9a0cbe68c21c6d7f6ac02667a37449a2fc2..a5740a0d27f92e971bef2f980e6e21a69e5b77e2 100644 (file)
@@ -25,6 +25,7 @@
 // Created   : Mon Apr 12 16:10:22 2004
 // Author    : Edward AGAPOV (eap)
 //
+#define CHRONODEF
 #include "SMESH_MeshEditor.hxx"
 
 #include "SMDS_FaceOfNodes.hxx"
 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
 #include "SMDS_FacePosition.hxx"
 #include "SMDS_SpacePosition.hxx"
-#include "SMDS_QuadraticFaceOfNodes.hxx"
+//#include "SMDS_QuadraticFaceOfNodes.hxx"
 #include "SMDS_MeshGroup.hxx"
+#include "SMDS_LinearEdge.hxx"
+#include "SMDS_Downward.hxx"
 #include "SMDS_SetIterator.hxx"
 
 #include "SMESHDS_Group.hxx"
@@ -124,75 +127,76 @@ SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
                              const bool                           isPoly,
                              const int                            ID)
 {
+  //MESSAGE("AddElement " <<node.size() << " " << type << " " << isPoly << " " << ID);
   SMDS_MeshElement* e = 0;
   int nbnode = node.size();
   SMESHDS_Mesh* mesh = GetMeshDS();
   switch ( type ) {
   case SMDSAbs_0DElement:
     if ( nbnode == 1 )
-      if ( ID ) e = mesh->Add0DElementWithID(node[0], ID);
+      if ( ID >= 0 ) e = mesh->Add0DElementWithID(node[0], ID);
       else      e = mesh->Add0DElement      (node[0] );
     break;
   case SMDSAbs_Edge:
     if ( nbnode == 2 )
-      if ( ID ) e = mesh->AddEdgeWithID(node[0], node[1], ID);
+      if ( ID >= 0 ) e = mesh->AddEdgeWithID(node[0], node[1], ID);
       else      e = mesh->AddEdge      (node[0], node[1] );
     else if ( nbnode == 3 )
-      if ( ID ) e = mesh->AddEdgeWithID(node[0], node[1], node[2], ID);
+      if ( ID >= 0 ) e = mesh->AddEdgeWithID(node[0], node[1], node[2], ID);
       else      e = mesh->AddEdge      (node[0], node[1], node[2] );
     break;
   case SMDSAbs_Face:
     if ( !isPoly ) {
       if      (nbnode == 3)
-        if ( ID ) e = mesh->AddFaceWithID(node[0], node[1], node[2], ID);
+        if ( ID >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], ID);
         else      e = mesh->AddFace      (node[0], node[1], node[2] );
       else if (nbnode == 4) 
-        if ( ID ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3], ID);
+        if ( ID >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3], ID);
         else      e = mesh->AddFace      (node[0], node[1], node[2], node[3] );
       else if (nbnode == 6)
-        if ( ID ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3],
+        if ( ID >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3],
                                           node[4], node[5], ID);
         else      e = mesh->AddFace      (node[0], node[1], node[2], node[3],
                                           node[4], node[5] );
       else if (nbnode == 8)
-        if ( ID ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3],
+        if ( ID >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3],
                                           node[4], node[5], node[6], node[7], ID);
         else      e = mesh->AddFace      (node[0], node[1], node[2], node[3],
                                           node[4], node[5], node[6], node[7] );
     } else {
-      if ( ID ) e = mesh->AddPolygonalFaceWithID(node, ID);
+      if ( ID >= 0 ) e = mesh->AddPolygonalFaceWithID(node, ID);
       else      e = mesh->AddPolygonalFace      (node    );
     }
     break;
   case SMDSAbs_Volume:
     if ( !isPoly ) {
       if      (nbnode == 4)
-        if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], ID);
+        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], ID);
         else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3] );
       else if (nbnode == 5)
-        if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
                                             node[4], ID);
         else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
                                             node[4] );
       else if (nbnode == 6)
-        if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
                                             node[4], node[5], ID);
         else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
                                             node[4], node[5] );
       else if (nbnode == 8)
-        if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
                                             node[4], node[5], node[6], node[7], ID);
         else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
                                             node[4], node[5], node[6], node[7] );
       else if (nbnode == 10)
-        if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
                                             node[4], node[5], node[6], node[7],
                                             node[8], node[9], ID);
         else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
                                             node[4], node[5], node[6], node[7],
                                             node[8], node[9] );
       else if (nbnode == 13)
-        if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
                                             node[4], node[5], node[6], node[7],
                                             node[8], node[9], node[10],node[11],
                                             node[12],ID);
@@ -201,7 +205,7 @@ SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
                                             node[8], node[9], node[10],node[11],
                                             node[12] );
       else if (nbnode == 15)
-        if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
                                             node[4], node[5], node[6], node[7],
                                             node[8], node[9], node[10],node[11],
                                             node[12],node[13],node[14],ID);
@@ -210,7 +214,7 @@ SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
                                             node[8], node[9], node[10],node[11],
                                             node[12],node[13],node[14] );
       else if (nbnode == 20)
-        if ( ID ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
+        if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
                                             node[4], node[5], node[6], node[7],
                                             node[8], node[9], node[10],node[11],
                                             node[12],node[13],node[14],node[15],
@@ -279,7 +283,7 @@ int SMESH_MeshEditor::Remove (const list< int >& theIDs,
     if ( isNodes ) {
       const SMDS_MeshNode* node = cast2Node( elem );
       if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX )
-        if ( int aShapeID = node->GetPosition()->GetShapeId() )
+        if ( int aShapeID = node->getshapeId() )
           if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( aShapeID ) )
             smmap.insert( sm );
     }
@@ -333,22 +337,21 @@ int SMESH_MeshEditor::FindShape (const SMDS_MeshElement * theElem)
   if ( aMesh->ShapeToMesh().IsNull() )
     return 0;
 
-  if ( theElem->GetType() == SMDSAbs_Node ) {
-    const SMDS_PositionPtr& aPosition =
-      static_cast<const SMDS_MeshNode*>( theElem )->GetPosition();
-    if ( aPosition.get() )
-      return aPosition->GetShapeId();
-    else
-      return 0;
-  }
+  if ( theElem->GetType() == SMDSAbs_Node )
+    {
+      int aShapeID = theElem->getshapeId();
+      if (aShapeID <= 0)
+        return 0;
+      else
+        return aShapeID;
+    }
 
   TopoDS_Shape aShape; // the shape a node is on
   SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator();
   while ( nodeIt->more() ) {
     const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-    const SMDS_PositionPtr& aPosition = node->GetPosition();
-    if ( aPosition.get() ) {
-      int aShapeID = aPosition->GetShapeId();
+    int aShapeID = node->getshapeId();
+    if (aShapeID > 0) {
       SMESHDS_SubMesh * sm = aMesh->MeshElements( aShapeID );
       if ( sm ) {
         if ( sm->Contains( theElem ))
@@ -479,15 +482,19 @@ static bool GetNodesFromTwoTria(const SMDS_MeshElement * theTria1,
 bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1,
                                     const SMDS_MeshElement * theTria2 )
 {
+  MESSAGE("InverseDiag");
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
 
   if (!theTria1 || !theTria2)
     return false;
 
-  const SMDS_FaceOfNodes* F1 = dynamic_cast<const SMDS_FaceOfNodes*>( theTria1 );
-  const SMDS_FaceOfNodes* F2 = dynamic_cast<const SMDS_FaceOfNodes*>( theTria2 );
-  if (F1 && F2) {
+  const SMDS_VtkFace* F1 = dynamic_cast<const SMDS_VtkFace*>( theTria1 );
+  if (!F1) return false;
+  const SMDS_VtkFace* F2 = dynamic_cast<const SMDS_VtkFace*>( theTria2 );
+  if (!F2) return false;
+  if ((theTria1->GetEntityType() == SMDSEntity_Triangle) &&
+      (theTria2->GetEntityType() == SMDSEntity_Triangle)) {
 
     //  1 +--+ A  theTria1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A
     //    | /|    theTria2: ( B A 2 ) B->1 ( 1 A 2 )   |\ |
@@ -540,24 +547,18 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1,
     // theTria2: B->1
     aNodes[ sameInd[ iB ]] = aNodes[ i1 ];
 
-    //MESSAGE( theTria1 << theTria2 );
-
     GetMeshDS()->ChangeElementNodes( theTria1, aNodes, 3 );
     GetMeshDS()->ChangeElementNodes( theTria2, &aNodes[ 3 ], 3 );
 
-    //MESSAGE( theTria1 << theTria2 );
-
     return true;
 
   } // end if(F1 && F2)
 
   // check case of quadratic faces
-  const SMDS_QuadraticFaceOfNodes* QF1 =
-    dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (theTria1);
-  if(!QF1) return false;
-  const SMDS_QuadraticFaceOfNodes* QF2 =
-    dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (theTria2);
-  if(!QF2) return false;
+  if (theTria1->GetEntityType() != SMDSEntity_Quad_Triangle)
+    return false;
+  if (theTria2->GetEntityType() != SMDSEntity_Quad_Triangle)
+    return false;
 
   //       5
   //  1 +--+--+ 2  theTria1: (1 2 4 5 9 7) or (2 4 1 9 7 5) or (4 1 2 7 5 9)
@@ -660,11 +661,12 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshNode * theNode1,
   if ( !findTriangles( theNode1, theNode2, tr1, tr2 ))
     return false;
 
-  const SMDS_FaceOfNodes* F1 = dynamic_cast<const SMDS_FaceOfNodes*>( tr1 );
-  //if (!F1) return false;
-  const SMDS_FaceOfNodes* F2 = dynamic_cast<const SMDS_FaceOfNodes*>( tr2 );
-  //if (!F2) return false;
-  if (F1 && F2) {
+  const SMDS_VtkFace* F1 = dynamic_cast<const SMDS_VtkFace*>( tr1 );
+  if (!F1) return false;
+  const SMDS_VtkFace* F2 = dynamic_cast<const SMDS_VtkFace*>( tr2 );
+  if (!F2) return false;
+  if ((tr1->GetEntityType() == SMDSEntity_Triangle) &&
+      (tr2->GetEntityType() == SMDSEntity_Triangle)) {
 
     //  1 +--+ A  tr1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A
     //    | /|    tr2: ( B A 2 ) B->1 ( 1 A 2 )   |\ |
@@ -702,23 +704,13 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshNode * theNode1,
     // tr2: B->1
     aNodes2[ iB2 ] = aNodes1[ i1 ];
 
-    //MESSAGE( tr1 << tr2 );
-
     GetMeshDS()->ChangeElementNodes( tr1, aNodes1, 3 );
     GetMeshDS()->ChangeElementNodes( tr2, aNodes2, 3 );
 
-    //MESSAGE( tr1 << tr2 );
-
     return true;
   }
 
   // check case of quadratic faces
-  const SMDS_QuadraticFaceOfNodes* QF1 =
-    dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (tr1);
-  if(!QF1) return false;
-  const SMDS_QuadraticFaceOfNodes* QF2 =
-    dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (tr2);
-  if(!QF2) return false;
   return InverseDiag(tr1,tr2);
 }
 
@@ -792,34 +784,39 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1,
   if ( !findTriangles( theNode1, theNode2, tr1, tr2 ))
     return false;
 
-  const SMDS_FaceOfNodes* F1 = dynamic_cast<const SMDS_FaceOfNodes*>( tr1 );
-  //if (!F1) return false;
-  const SMDS_FaceOfNodes* F2 = dynamic_cast<const SMDS_FaceOfNodes*>( tr2 );
-  //if (!F2) return false;
-  if (F1 && F2) {
+  const SMDS_VtkFace* F1 = dynamic_cast<const SMDS_VtkFace*>( tr1 );
+  if (!F1) return false;
+  const SMDS_VtkFace* F2 = dynamic_cast<const SMDS_VtkFace*>( tr2 );
+  if (!F2) return false;
+  SMESHDS_Mesh * aMesh = GetMeshDS();
+
+  if ((tr1->GetEntityType() == SMDSEntity_Triangle) &&
+      (tr2->GetEntityType() == SMDSEntity_Triangle)) {
 
     const SMDS_MeshNode* aNodes [ 4 ];
     if ( ! getQuadrangleNodes( aNodes, theNode1, theNode2, tr1, tr2 ))
       return false;
 
-    //MESSAGE( endl << tr1 << tr2 );
-
-    GetMeshDS()->ChangeElementNodes( tr1, aNodes, 4 );
-    myLastCreatedElems.Append(tr1);
-    GetMeshDS()->RemoveElement( tr2 );
-
-    //MESSAGE( endl << tr1 );
+    const SMDS_MeshElement* newElem = 0;
+    newElem = aMesh->AddFace( aNodes[0], aNodes[1], aNodes[2], aNodes[3] );
+    myLastCreatedElems.Append(newElem);
+    AddToSameGroups( newElem, tr1, aMesh );
+    int aShapeId = tr1->getshapeId();
+    if ( aShapeId )
+      {
+        aMesh->SetMeshElementOnShape( newElem, aShapeId );
+      }
+    aMesh->RemoveElement( tr1 );
+    aMesh->RemoveElement( tr2 );
 
     return true;
   }
 
   // check case of quadratic faces
-  const SMDS_QuadraticFaceOfNodes* QF1 =
-    dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (tr1);
-  if(!QF1) return false;
-  const SMDS_QuadraticFaceOfNodes* QF2 =
-    dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (tr2);
-  if(!QF2) return false;
+  if (tr1->GetEntityType() != SMDSEntity_Quad_Triangle)
+    return false;
+  if (tr2->GetEntityType() != SMDSEntity_Quad_Triangle)
+    return false;
 
   //       5
   //  1 +--+--+ 2  tr1: (1 2 4 5 9 7) or (2 4 1 9 7 5) or (4 1 2 7 5 9)
@@ -849,9 +846,18 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1,
   aNodes[6] = N2[3];
   aNodes[7] = N1[5];
 
-  GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
-  myLastCreatedElems.Append(tr1);
-  GetMeshDS()->RemoveElement( tr2 );
+  const SMDS_MeshElement* newElem = 0;
+  newElem = aMesh->AddFace( aNodes[0], aNodes[1], aNodes[2], aNodes[3],
+                            aNodes[4], aNodes[5], aNodes[6], aNodes[7]);
+  myLastCreatedElems.Append(newElem);
+  AddToSameGroups( newElem, tr1, aMesh );
+  int aShapeId = tr1->getshapeId();
+  if ( aShapeId )
+    {
+      aMesh->SetMeshElementOnShape( newElem, aShapeId );
+    }
+  aMesh->RemoveElement( tr1 );
+  aMesh->RemoveElement( tr2 );
 
   // remove middle node (9)
   GetMeshDS()->RemoveNode( N1[4] );
@@ -866,6 +872,7 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1,
 
 bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem)
 {
+  MESSAGE("Reorient");
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
 
@@ -912,8 +919,10 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem)
   }
   case SMDSAbs_Volume: {
     if (theElem->IsPoly()) {
-      const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
-        static_cast<const SMDS_PolyhedralVolumeOfNodes*>( theElem );
+      // TODO reorient vtk polyhedron
+      MESSAGE("reorient vtk polyhedron ?");
+      const SMDS_VtkVolume* aPolyedre =
+        dynamic_cast<const SMDS_VtkVolume*>( theElem );
       if (!aPolyedre) {
         MESSAGE("Warning: bad volumic element");
         return false;
@@ -942,6 +951,7 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem)
       if ( !vTool.Set( theElem ))
         return false;
       vTool.Inverse();
+      MESSAGE("ChangeElementNodes reorient: check vTool.Inverse");
       return GetMeshDS()->ChangeElementNodes( theElem, vTool.GetNodes(), vTool.NbNodes() );
     }
   }
@@ -1014,21 +1024,21 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet &                   theElems,
     aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit );
 
     int aShapeId = FindShape( elem );
-    const SMDS_MeshElement* newElem = 0;
+    const SMDS_MeshElement* newElem1 = 0;
+    const SMDS_MeshElement* newElem2 = 0;
 
     if( !elem->IsQuadratic() ) {
 
       // split liner quadrangle
-
       if ( aBadRate1 <= aBadRate2 ) {
         // tr1 + tr2 is better
-        aMesh->ChangeElementNodes( elem, aNodes, 3 );
-        newElem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] );
+        newElem1 = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] );
+        newElem2 = aMesh->AddFace( aNodes[2], aNodes[0], aNodes[1] );
       }
       else {
         // tr3 + tr4 is better
-        aMesh->ChangeElementNodes( elem, &aNodes[1], 3 );
-        newElem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
+        newElem1 = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
+        newElem2 = aMesh->AddFace( aNodes[3], aNodes[1], aNodes[2] );
       }
     }
     else {
@@ -1089,8 +1099,10 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet &                   theElems,
         N[3] = aNodes[4];
         N[4] = aNodes[5];
         N[5] = newN;
-        newElem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0],
-                                 aNodes[6], aNodes[7], newN );
+        newElem1 = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0],
+                                  aNodes[6], aNodes[7], newN );
+        newElem2 = aMesh->AddFace(aNodes[2], aNodes[0], aNodes[1],
+                                  newN,      aNodes[4], aNodes[5] );
       }
       else {
         N[0] = aNodes[1];
@@ -1099,21 +1111,27 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet &                   theElems,
         N[3] = aNodes[5];
         N[4] = aNodes[6];
         N[5] = newN;
-        newElem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1],
-                                 aNodes[7], aNodes[4], newN );
+        newElem1 = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1],
+                                  aNodes[7], aNodes[4], newN );
+        newElem2 = aMesh->AddFace(aNodes[3], aNodes[1], aNodes[2],
+                                  newN,      aNodes[5], aNodes[6] );
       }
-      aMesh->ChangeElementNodes( elem, N, 6 );
-
     } // quadratic case
 
     // care of a new element
 
-    myLastCreatedElems.Append(newElem);
-    AddToSameGroups( newElem, elem, aMesh );
+    myLastCreatedElems.Append(newElem1);
+    myLastCreatedElems.Append(newElem2);
+    AddToSameGroups( newElem1, elem, aMesh );
+    AddToSameGroups( newElem2, elem, aMesh );
 
     // put a new triangle on the same shape
     if ( aShapeId )
-      aMesh->SetMeshElementOnShape( newElem, aShapeId );
+      {
+        aMesh->SetMeshElementOnShape( newElem1, aShapeId );
+        aMesh->SetMeshElementOnShape( newElem2, aShapeId );
+      }
+    aMesh->RemoveElement( elem );
   }
   return true;
 }
@@ -1821,20 +1839,28 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
         aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
 
       int aShapeId = FindShape( elem );
-      const SMDS_MeshElement* newElem = 0;
+      const SMDS_MeshElement* newElem1 = 0;
+      const SMDS_MeshElement* newElem2 = 0;
       if ( the13Diag ) {
-        aMesh->ChangeElementNodes( elem, aNodes, 3 );
-        newElem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] );
+        newElem1 = aMesh->AddFace( aNodes[2], aNodes[0], aNodes[1] );
+        newElem2 = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] );
       }
       else {
-        aMesh->ChangeElementNodes( elem, &aNodes[1], 3 );
-        newElem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
+        newElem1 = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
+        newElem2 = aMesh->AddFace( aNodes[3], aNodes[1], aNodes[2] );
       }
-      myLastCreatedElems.Append(newElem);
+      myLastCreatedElems.Append(newElem1);
+      myLastCreatedElems.Append(newElem2);
       // put a new triangle on the same shape and add to the same groups
       if ( aShapeId )
-        aMesh->SetMeshElementOnShape( newElem, aShapeId );
-      AddToSameGroups( newElem, elem, aMesh );
+        {
+          aMesh->SetMeshElementOnShape( newElem1, aShapeId );
+          aMesh->SetMeshElementOnShape( newElem2, aShapeId );
+        }
+      AddToSameGroups( newElem1, elem, aMesh );
+      AddToSameGroups( newElem2, elem, aMesh );
+      //aMesh->RemoveFreeElement(elem, aMesh->MeshElements(aShapeId), true);
+      aMesh->RemoveElement( elem );
     }
 
     // Quadratic quadrangle
@@ -1889,7 +1915,8 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
       myLastCreatedNodes.Append(newN);
 
       // create a new element
-      const SMDS_MeshElement* newElem = 0;
+      const SMDS_MeshElement* newElem1 = 0;
+      const SMDS_MeshElement* newElem2 = 0;
       const SMDS_MeshNode* N[6];
       if ( the13Diag ) {
         N[0] = aNodes[0];
@@ -1898,8 +1925,10 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
         N[3] = aNodes[4];
         N[4] = aNodes[5];
         N[5] = newN;
-        newElem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0],
-                                 aNodes[6], aNodes[7], newN );
+        newElem1 = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0],
+                                  aNodes[6], aNodes[7], newN );
+        newElem2 = aMesh->AddFace(aNodes[2], aNodes[0], aNodes[1],
+                                  newN,      aNodes[4], aNodes[5] );
       }
       else {
         N[0] = aNodes[1];
@@ -1908,15 +1937,22 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
         N[3] = aNodes[5];
         N[4] = aNodes[6];
         N[5] = newN;
-        newElem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1],
-                                 aNodes[7], aNodes[4], newN );
+        newElem1 = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1],
+                                  aNodes[7], aNodes[4], newN );
+        newElem2 = aMesh->AddFace(aNodes[3], aNodes[1], aNodes[2],
+                                  newN,      aNodes[5], aNodes[6] );
       }
-      myLastCreatedElems.Append(newElem);
-      aMesh->ChangeElementNodes( elem, N, 6 );
+      myLastCreatedElems.Append(newElem1);
+      myLastCreatedElems.Append(newElem2);
       // put a new triangle on the same shape and add to the same groups
       if ( aShapeId )
-        aMesh->SetMeshElementOnShape( newElem, aShapeId );
-      AddToSameGroups( newElem, elem, aMesh );
+        {
+          aMesh->SetMeshElementOnShape( newElem1, aShapeId );
+          aMesh->SetMeshElementOnShape( newElem2, aShapeId );
+        }
+      AddToSameGroups( newElem1, elem, aMesh );
+      AddToSameGroups( newElem2, elem, aMesh );
+      aMesh->RemoveElement( elem );
     }
   }
 
@@ -2212,16 +2248,17 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet &                   theElems,
           mapEl_setLi.erase( tr2 );
           mapLi_listEl.erase( *link12 );
           if(tr1->NbNodes()==3) {
-            if( tr1->GetID() < tr2->GetID() ) {
-              aMesh->ChangeElementNodes( tr1, n12, 4 );
-              myLastCreatedElems.Append(tr1);
-              aMesh->RemoveElement( tr2 );
-            }
-            else {
-              aMesh->ChangeElementNodes( tr2, n12, 4 );
-              myLastCreatedElems.Append(tr2);
-              aMesh->RemoveElement( tr1);
-            }
+            const SMDS_MeshElement* newElem = 0;
+            newElem = aMesh->AddFace(n12[0], n12[1], n12[2], n12[3] );
+            myLastCreatedElems.Append(newElem);
+            AddToSameGroups( newElem, tr1, aMesh );
+            int aShapeId = tr1->getshapeId();
+            if ( aShapeId )
+              {
+                aMesh->SetMeshElementOnShape( newElem, aShapeId );
+              }
+            aMesh->RemoveElement( tr1 );
+            aMesh->RemoveElement( tr2 );
           }
           else {
             const SMDS_MeshNode* N1 [6];
@@ -2239,16 +2276,18 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet &                   theElems,
             aNodes[5] = N2[5];
             aNodes[6] = N2[3];
             aNodes[7] = N1[5];
-            if( tr1->GetID() < tr2->GetID() ) {
-              GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
-              myLastCreatedElems.Append(tr1);
-              GetMeshDS()->RemoveElement( tr2 );
-            }
-            else {
-              GetMeshDS()->ChangeElementNodes( tr2, aNodes, 8 );
-              myLastCreatedElems.Append(tr2);
-              GetMeshDS()->RemoveElement( tr1 );
-            }
+            const SMDS_MeshElement* newElem = 0;
+            newElem = aMesh->AddFace(aNodes[0], aNodes[1], aNodes[2], aNodes[3],
+                                     aNodes[4], aNodes[5], aNodes[6], aNodes[7]);
+            myLastCreatedElems.Append(newElem);
+            AddToSameGroups( newElem, tr1, aMesh );
+            int aShapeId = tr1->getshapeId();
+            if ( aShapeId )
+              {
+                aMesh->SetMeshElementOnShape( newElem, aShapeId );
+              }
+            aMesh->RemoveElement( tr1 );
+            aMesh->RemoveElement( tr2 );
             // remove middle node (9)
             GetMeshDS()->RemoveNode( N1[4] );
           }
@@ -2257,16 +2296,17 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet &                   theElems,
           mapEl_setLi.erase( tr3 );
           mapLi_listEl.erase( *link13 );
           if(tr1->NbNodes()==3) {
-            if( tr1->GetID() < tr2->GetID() ) {
-              aMesh->ChangeElementNodes( tr1, n13, 4 );
-              myLastCreatedElems.Append(tr1);
-              aMesh->RemoveElement( tr3 );
-            }
-            else {
-              aMesh->ChangeElementNodes( tr3, n13, 4 );
-              myLastCreatedElems.Append(tr3);
-              aMesh->RemoveElement( tr1 );
-            }
+            const SMDS_MeshElement* newElem = 0;
+            newElem = aMesh->AddFace(n13[0], n13[1], n13[2], n13[3] );
+            myLastCreatedElems.Append(newElem);
+            AddToSameGroups( newElem, tr1, aMesh );
+            int aShapeId = tr1->getshapeId();
+            if ( aShapeId )
+              {
+                aMesh->SetMeshElementOnShape( newElem, aShapeId );
+              }
+            aMesh->RemoveElement( tr1 );
+            aMesh->RemoveElement( tr3 );
           }
           else {
             const SMDS_MeshNode* N1 [6];
@@ -2284,16 +2324,18 @@ bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet &                   theElems,
             aNodes[5] = N2[5];
             aNodes[6] = N2[3];
             aNodes[7] = N1[5];
-            if( tr1->GetID() < tr2->GetID() ) {
-              GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
-              myLastCreatedElems.Append(tr1);
-              GetMeshDS()->RemoveElement( tr3 );
-            }
-            else {
-              GetMeshDS()->ChangeElementNodes( tr3, aNodes, 8 );
-              myLastCreatedElems.Append(tr3);
-              GetMeshDS()->RemoveElement( tr1 );
-            }
+            const SMDS_MeshElement* newElem = 0;
+            newElem = aMesh->AddFace(aNodes[0], aNodes[1], aNodes[2], aNodes[3],
+                                     aNodes[4], aNodes[5], aNodes[6], aNodes[7]);
+            myLastCreatedElems.Append(newElem);
+            AddToSameGroups( newElem, tr1, aMesh );
+            int aShapeId = tr1->getshapeId();
+            if ( aShapeId )
+              {
+                aMesh->SetMeshElementOnShape( newElem, aShapeId );
+              }
+            aMesh->RemoveElement( tr1 );
+            aMesh->RemoveElement( tr3 );
             // remove middle node (9)
             GetMeshDS()->RemoveNode( N1[4] );
           }
@@ -2905,7 +2947,7 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
       while ( nn++ < nbn ) {
         node = static_cast<const SMDS_MeshNode*>( itN->next() );
         const SMDS_PositionPtr& pos = node->GetPosition();
-        posType = pos.get() ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE;
+        posType = pos ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE;
         if (posType != SMDS_TOP_EDGE &&
             posType != SMDS_TOP_VERTEX &&
             theFixedNodes.find( node ) == theFixedNodes.end())
@@ -2963,27 +3005,27 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
         node = *n;
         gp_XY uv( 0, 0 );
         const SMDS_PositionPtr& pos = node->GetPosition();
-        posType = pos.get() ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE;
+        posType = pos ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE;
         // get existing UV
         switch ( posType ) {
         case SMDS_TOP_FACE: {
-          SMDS_FacePosition* fPos = ( SMDS_FacePosition* ) pos.get();
+          SMDS_FacePosition* fPos = ( SMDS_FacePosition* ) pos;
           uv.SetCoord( fPos->GetUParameter(), fPos->GetVParameter() );
           break;
         }
         case SMDS_TOP_EDGE: {
-          TopoDS_Shape S = aMesh->IndexToShape( pos->GetShapeId() );
+          TopoDS_Shape S = aMesh->IndexToShape( node->getshapeId() );
           Handle(Geom2d_Curve) pcurve;
           if ( !S.IsNull() && S.ShapeType() == TopAbs_EDGE )
             pcurve = BRep_Tool::CurveOnSurface( TopoDS::Edge( S ), face, f,l );
           if ( !pcurve.IsNull() ) {
-            double u = (( SMDS_EdgePosition* ) pos.get() )->GetUParameter();
+            double u = (( SMDS_EdgePosition* ) pos )->GetUParameter();
             uv = pcurve->Value( u ).XY();
           }
           break;
         }
         case SMDS_TOP_VERTEX: {
-          TopoDS_Shape S = aMesh->IndexToShape( pos->GetShapeId() );
+          TopoDS_Shape S = aMesh->IndexToShape( node->getshapeId() );
           if ( !S.IsNull() && S.ShapeType() == TopAbs_VERTEX )
             uv = BRep_Tool::Parameters( TopoDS::Vertex( S ), face ).XY();
           break;
@@ -3246,7 +3288,7 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
       if ( node_uv != uvMap.end() ) {
         gp_XY* uv = node_uv->second;
         node->SetPosition
-          ( SMDS_PositionPtr( new SMDS_FacePosition( *fId, uv->X(), uv->Y() )));
+          ( SMDS_PositionPtr( new SMDS_FacePosition( uv->X(), uv->Y() )));
       }
     }
 
@@ -3258,14 +3300,14 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
         helper.SetSubShape( face );
       list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin();
       for ( ; elemIt != elemsOnFace.end(); ++elemIt ) {
-        const SMDS_QuadraticFaceOfNodes* QF =
-          dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (*elemIt);
-        if(QF) {
+        const SMDS_VtkFace* QF =
+          dynamic_cast<const SMDS_VtkFace*> (*elemIt);
+        if(QF && QF->IsQuadratic()) {
           vector<const SMDS_MeshNode*> Ns;
           Ns.reserve(QF->NbNodes()+1);
-          SMDS_NodeIteratorPtr anIter = QF->interlacedNodesIterator();
+          SMDS_ElemIteratorPtr anIter = QF->interlacedNodesElemIterator();
           while ( anIter->more() )
-            Ns.push_back( anIter->next() );
+            Ns.push_back( cast2Node(anIter->next()) );
           Ns.push_back( Ns[0] );
           double x, y, z;
           for(int i=0; i<QF->NbNodes(); i=i+2) {
@@ -3343,6 +3385,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
                                     const int                             nbSteps,
                                     SMESH_SequenceOfElemPtr&              srcElements)
 {
+  //MESSAGE("sweepElement " << nbSteps);
   SMESHDS_Mesh* aMesh = GetMeshDS();
 
   // Loop on elem nodes:
@@ -3381,7 +3424,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
     }
   }
 
-  //cout<<"  nbSame = "<<nbSame<<endl;
+  //cerr<<"  nbSame = "<<nbSame<<endl;
   if ( nbSame == nbNodes || nbSame > 2) {
     MESSAGE( " Too many same nodes of element " << elem->GetID() );
     //INFOS( " Too many same nodes of element " << elem->GetID() );
@@ -3418,6 +3461,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
   }
 
   // make new elements
+  const SMDS_MeshElement* lastElem = elem;
   for (int iStep = 0; iStep < nbSteps; iStep++ ) {
     // get next nodes
     for ( iNode = 0; iNode < nbNodes; iNode++ ) {
@@ -3433,7 +3477,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
           nextNod[ iNode ] = *itNN[ iNode ];
           itNN[ iNode ]++;
         }
-        else if(!elem->IsQuadratic() || elem->IsMediumNode(prevNod[iNode]) ) {
+        else if(!elem->IsQuadratic() || lastElem->IsMediumNode(prevNod[iNode]) ) {
           // we have to use each second node
           //itNN[ iNode ]++;
           nextNod[ iNode ] = *itNN[ iNode ];
@@ -3738,6 +3782,7 @@ void SMESH_MeshEditor::sweepElement(const SMDS_MeshElement*               elem,
       newElems.push_back( aNewElem );
       myLastCreatedElems.Append(aNewElem);
       srcElements.Append( elem );
+      lastElem = aNewElem;
     }
 
     // set new prev nodes
@@ -3766,6 +3811,7 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
                                   const int                nbSteps,
                                   SMESH_SequenceOfElemPtr& srcElements)
 {
+  MESSAGE("makeWalls");
   ASSERT( newElemsMap.size() == elemNewNodesMap.size() );
   SMESHDS_Mesh* aMesh = GetMeshDS();
 
@@ -3966,7 +4012,10 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
               if ( !f )
                 myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ));
               else if ( nodes[ 1 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 1 ))
-                aMesh->ChangeElementNodes( f, nodes, nbn );
+                {
+                  myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ));
+                  aMesh->RemoveElement(f);
+                }
               break;
             }
             case 4: { ///// quadrangle
@@ -3974,7 +4023,10 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
               if ( !f )
                 myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] ));
               else if ( nodes[ 1 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 1 ))
-                aMesh->ChangeElementNodes( f, nodes, nbn );
+                {
+                  myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] ));
+                  aMesh->RemoveElement(f);
+                }
               break;
             }
             default:
@@ -3994,7 +4046,9 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
                     tmpnodes[3] = nodes[1];
                     tmpnodes[4] = nodes[3];
                     tmpnodes[5] = nodes[5];
-                    aMesh->ChangeElementNodes( f, tmpnodes, nbn );
+                    myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4],
+                                                             nodes[1], nodes[3], nodes[5]));
+                    aMesh->RemoveElement(f);
                   }
                 }
                 else {       /////// quadratic quadrangle
@@ -4014,7 +4068,9 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
                     tmpnodes[5] = nodes[3];
                     tmpnodes[6] = nodes[5];
                     tmpnodes[7] = nodes[7];
-                    aMesh->ChangeElementNodes( f, tmpnodes, nbn );
+                    myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6],
+                                                             nodes[1], nodes[3], nodes[5], nodes[7]));
+                    aMesh->RemoveElement(f);
                   }
                 }
               }
@@ -4024,7 +4080,11 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
                 if ( !f )
                   myLastCreatedElems.Append(aMesh->AddPolygonalFace(polygon_nodes));
                 else if ( nodes[ 1 ] != f->GetNodeWrap( f->GetNodeIndex( nodes[ 0 ] ) + 1 ))
+                  {
+                  // TODO problem ChangeElementNodes : not the same number of nodes, not the same type
+                  MESSAGE("ChangeElementNodes");
                   aMesh->ChangeElementNodes( f, nodes, nbn );
+                  }
               }
             }
             while ( srcElements.Length() < myLastCreatedElems.Length() )
@@ -4322,6 +4382,7 @@ SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet &  theElems,
                                   const int           theFlags,
                                   const double        theTolerance)
 {
+  MESSAGE("ExtrusionSweep " << theMakeGroups << " " << theFlags << " " << theTolerance);
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
 
@@ -4522,6 +4583,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
                                        const gp_Pnt&        theRefPoint,
                                        const bool           theMakeGroups)
 {
+  MESSAGE("ExtrusionAlongTrack");
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
 
@@ -4580,7 +4642,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
     while ( aItN->more() ) {
       const SMDS_MeshNode* pNode = aItN->next();
       const SMDS_EdgePosition* pEPos =
-        static_cast<const SMDS_EdgePosition*>( pNode->GetPosition().get() );
+        static_cast<const SMDS_EdgePosition*>( pNode->GetPosition() );
       double aT = pEPos->GetUParameter();
       aPrms.push_back( aT );
     }
@@ -4624,7 +4686,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
         while ( aItN->more() ) {
           const SMDS_MeshNode* pNode = aItN->next();
           const SMDS_EdgePosition* pEPos =
-            static_cast<const SMDS_EdgePosition*>( pNode->GetPosition().get() );
+            static_cast<const SMDS_EdgePosition*>( pNode->GetPosition() );
           double aT = pEPos->GetUParameter();
           aPrms.push_back( aT );
         }
@@ -4752,7 +4814,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
       const SMDS_MeshNode* pNode = aItN->next();
       if( pNode==aN1 || pNode==aN2 ) continue;
       const SMDS_EdgePosition* pEPos =
-        static_cast<const SMDS_EdgePosition*>( pNode->GetPosition().get() );
+        static_cast<const SMDS_EdgePosition*>( pNode->GetPosition() );
       double aT = pEPos->GetUParameter();
       aPrms.push_back( aT );
     }
@@ -4799,7 +4861,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
         while ( aItN->more() ) {
           const SMDS_MeshNode* pNode = aItN->next();
           const SMDS_EdgePosition* pEPos =
-            static_cast<const SMDS_EdgePosition*>( pNode->GetPosition().get() );
+            static_cast<const SMDS_EdgePosition*>( pNode->GetPosition() );
           double aT = pEPos->GetUParameter();
           aPrms.push_back( aT );
         }
@@ -4925,6 +4987,7 @@ SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet&  theElements,
                                    const gp_Pnt& theRefPoint,
                                    const bool theMakeGroups)
 {
+  MESSAGE("MakeExtrElements");
   //cout<<"MakeExtrElements  fullList.size() = "<<fullList.size()<<endl;
   int aNbTP = fullList.size();
   vector<SMESH_MeshEditor_PathPoint> aPPs(aNbTP);
@@ -5080,6 +5143,7 @@ SMESH_MeshEditor::MakeExtrElements(TIDSortedElemSet&  theElements,
           }
 
           // make new node
+          //MESSAGE("elem->IsQuadratic " << elem->IsQuadratic() << " " << elem->IsMediumNode(node));
           if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) {
             // create additional node
             double x = ( aPN1.X() + aPN0.X() )/2.;
@@ -5262,35 +5326,35 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
   // source elements for each generated one
   SMESH_SequenceOfElemPtr srcElems, srcNodes;
 
-  // issue 021015: EDF 1578 SMESH: Free nodes are removed when translating a mesh
-  list<SMDS_MeshNode>          orphanCopy; // copies of orphan nodes
-  vector<const SMDS_MeshNode*> orphanNode; // original orphan nodes
-
-  if ( theElems.empty() ) // transform the whole mesh
-  {
-    // add all elements
-    SMDS_ElemIteratorPtr eIt = aMesh->elementsIterator();
-    while ( eIt->more() ) theElems.insert( eIt->next() );
-    // add orphan nodes
-    SMDS_MeshElementIDFactory idFactory;
-    SMDS_NodeIteratorPtr nIt = aMesh->nodesIterator();
-    while ( nIt->more() )
-    {
-      const SMDS_MeshNode* node = nIt->next();
-      if ( node->NbInverseElements() == 0 && !theElems.insert( node ).second )
-      {
-        // node was not inserted into theElems because an element with the same ID
-        // is already there. As a work around we insert a copy of node with
-        // an ID = -<index in orphanNode>
-        orphanCopy.push_back( *node ); // copy node
-        SMDS_MeshNode* nodeCopy = &orphanCopy.back();
-        int uniqueID = -orphanNode.size();
-        orphanNode.push_back( node );
-        idFactory.BindID( uniqueID, nodeCopy );
-        theElems.insert( nodeCopy );
-      }
-    }
-  }
+//  // issue 021015: EDF 1578 SMESH: Free nodes are removed when translating a mesh
+//  list<SMDS_MeshNode>          orphanCopy; // copies of orphan nodes
+//  vector<const SMDS_MeshNode*> orphanNode; // original orphan nodes
+//
+//  if ( theElems.empty() ) // transform the whole mesh
+//  {
+//    // add all elements
+//    SMDS_ElemIteratorPtr eIt = aMesh->elementsIterator();
+//    while ( eIt->more() ) theElems.insert( eIt->next() );
+//    // add orphan nodes
+//    SMDS_MeshElementIDFactory idFactory;
+//    SMDS_NodeIteratorPtr nIt = aMesh->nodesIterator();
+//    while ( nIt->more() )
+//    {
+//      const SMDS_MeshNode* node = nIt->next();
+//      if ( node->NbInverseElements() == 0 && !theElems.insert( node ).second )
+//      {
+//        // node was not inserted into theElems because an element with the same ID
+//        // is already there. As a work around we insert a copy of node with
+//        // an ID = -<index in orphanNode>
+//        orphanCopy.push_back( *node ); // copy node
+//        SMDS_MeshNode* nodeCopy = &orphanCopy.back();
+//        int uniqueID = -orphanNode.size();
+//        orphanNode.push_back( node );
+//        idFactory.BindID( uniqueID, nodeCopy );
+//        theElems.insert( nodeCopy );
+//      }
+//    }
+//  }
   // loop on theElems to transorm nodes
   TIDSortedElemSet::iterator itElem;
   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
@@ -5303,8 +5367,8 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
     while ( itN->more() ) {
 
       const SMDS_MeshNode* node = cast2Node( itN->next() );
-      if ( node->GetID() < 0 )
-        node = orphanNode[ -node->GetID() ];
+//      if ( node->GetID() < 0 )
+//        node = orphanNode[ -node->GetID() ];
       // check if a node has been already transformed
       pair<TNodeNodeMap::iterator,bool> n2n_isnew =
         nodeMap.insert( make_pair ( node, node ));
@@ -5355,7 +5419,7 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
     theElems.insert( *invElemIt );
 
   // replicate or reverse elements
-
+  // TODO revoir ordre reverse vtk
   enum {
     REV_TETRA   = 0,  //  = nbNodes - 4
     REV_PYRAMID = 1,  //  = nbNodes - 4
@@ -5423,8 +5487,8 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
       case SMDSAbs_Volume:
         {
           // ATTENTION: Reversing is not yet done!!!
-          const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
-            dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>( elem );
+          const SMDS_VtkVolume* aPolyedre =
+            dynamic_cast<const SMDS_VtkVolume*>( elem );
           if (!aPolyedre) {
             MESSAGE("Warning: bad volumic element");
             continue;
@@ -5554,6 +5618,332 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
   return newGroupIDs;
 }
 
+
+////=======================================================================
+////function : Scale
+////purpose  :
+////=======================================================================
+//
+//SMESH_MeshEditor::PGroupIDs
+//SMESH_MeshEditor::Scale (TIDSortedElemSet & theElems,
+//                         const gp_Pnt&            thePoint,
+//                         const std::list<double>& theScaleFact,
+//                         const bool         theCopy,
+//                         const bool         theMakeGroups,
+//                         SMESH_Mesh*        theTargetMesh)
+//{
+//  MESSAGE("Scale");
+//  myLastCreatedElems.Clear();
+//  myLastCreatedNodes.Clear();
+//
+//  SMESH_MeshEditor targetMeshEditor( theTargetMesh );
+//  SMESHDS_Mesh* aTgtMesh = theTargetMesh ? theTargetMesh->GetMeshDS() : 0;
+//  SMESHDS_Mesh* aMesh    = GetMeshDS();
+//
+//  double scaleX=1.0, scaleY=1.0, scaleZ=1.0;
+//  std::list<double>::const_iterator itS = theScaleFact.begin();
+//  scaleX = (*itS);
+//  if(theScaleFact.size()==1) {
+//    scaleY = (*itS);
+//    scaleZ= (*itS);
+//  }
+//  if(theScaleFact.size()==2) {
+//    itS++;
+//    scaleY = (*itS);
+//    scaleZ= (*itS);
+//  }
+//  if(theScaleFact.size()>2) {
+//    itS++;
+//    scaleY = (*itS);
+//    itS++;
+//    scaleZ= (*itS);
+//  }
+//
+//  // map old node to new one
+//  TNodeNodeMap nodeMap;
+//
+//  // elements sharing moved nodes; those of them which have all
+//  // nodes mirrored but are not in theElems are to be reversed
+//  TIDSortedElemSet inverseElemSet;
+//
+//  // source elements for each generated one
+//  SMESH_SequenceOfElemPtr srcElems, srcNodes;
+//
+//  // loop on theElems
+//  TIDSortedElemSet::iterator itElem;
+//  for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
+//    const SMDS_MeshElement* elem = *itElem;
+//    if ( !elem )
+//      continue;
+//
+//    // loop on elem nodes
+//    SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+//    while ( itN->more() ) {
+//
+//      // check if a node has been already transformed
+//      const SMDS_MeshNode* node = cast2Node( itN->next() );
+//      pair<TNodeNodeMap::iterator,bool> n2n_isnew =
+//        nodeMap.insert( make_pair ( node, node ));
+//      if ( !n2n_isnew.second )
+//        continue;
+//
+//      //double coord[3];
+//      //coord[0] = node->X();
+//      //coord[1] = node->Y();
+//      //coord[2] = node->Z();
+//      //theTrsf.Transforms( coord[0], coord[1], coord[2] );
+//      double dx = (node->X() - thePoint.X()) * scaleX;
+//      double dy = (node->Y() - thePoint.Y()) * scaleY;
+//      double dz = (node->Z() - thePoint.Z()) * scaleZ;
+//      if ( theTargetMesh ) {
+//        //const SMDS_MeshNode * newNode = aTgtMesh->AddNode( coord[0], coord[1], coord[2] );
+//        const SMDS_MeshNode * newNode =
+//          aTgtMesh->AddNode( thePoint.X()+dx, thePoint.Y()+dy, thePoint.Z()+dz );
+//        n2n_isnew.first->second = newNode;
+//        myLastCreatedNodes.Append(newNode);
+//        srcNodes.Append( node );
+//      }
+//      else if ( theCopy ) {
+//        //const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+//        const SMDS_MeshNode * newNode =
+//          aMesh->AddNode( thePoint.X()+dx, thePoint.Y()+dy, thePoint.Z()+dz );
+//        n2n_isnew.first->second = newNode;
+//        myLastCreatedNodes.Append(newNode);
+//        srcNodes.Append( node );
+//      }
+//      else {
+//        //aMesh->MoveNode( node, coord[0], coord[1], coord[2] );
+//        aMesh->MoveNode( node, thePoint.X()+dx, thePoint.Y()+dy, thePoint.Z()+dz );
+//        // node position on shape becomes invalid
+//        const_cast< SMDS_MeshNode* > ( node )->SetPosition
+//          ( SMDS_SpacePosition::originSpacePosition() );
+//      }
+//
+//      // keep inverse elements
+//      //if ( !theCopy && !theTargetMesh && needReverse ) {
+//      //  SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator();
+//      //  while ( invElemIt->more() ) {
+//      //    const SMDS_MeshElement* iel = invElemIt->next();
+//      //    inverseElemSet.insert( iel );
+//      //  }
+//      //}
+//    }
+//  }
+//
+//  // either create new elements or reverse mirrored ones
+//  //if ( !theCopy && !needReverse && !theTargetMesh )
+//  if ( !theCopy && !theTargetMesh )
+//    return PGroupIDs();
+//
+//  TIDSortedElemSet::iterator invElemIt = inverseElemSet.begin();
+//  for ( ; invElemIt != inverseElemSet.end(); invElemIt++ )
+//    theElems.insert( *invElemIt );
+//
+//  // replicate or reverse elements
+//
+//  enum {
+//    REV_TETRA   = 0,  //  = nbNodes - 4
+//    REV_PYRAMID = 1,  //  = nbNodes - 4
+//    REV_PENTA   = 2,  //  = nbNodes - 4
+//    REV_FACE    = 3,
+//    REV_HEXA    = 4,  //  = nbNodes - 4
+//    FORWARD     = 5
+//  };
+//  int index[][8] = {
+//    { 2, 1, 0, 3, 4, 0, 0, 0 },  // REV_TETRA
+//    { 2, 1, 0, 3, 4, 0, 0, 0 },  // REV_PYRAMID
+//    { 2, 1, 0, 5, 4, 3, 0, 0 },  // REV_PENTA
+//    { 2, 1, 0, 3, 0, 0, 0, 0 },  // REV_FACE
+//    { 2, 1, 0, 3, 6, 5, 4, 7 },  // REV_HEXA
+//    { 0, 1, 2, 3, 4, 5, 6, 7 }   // FORWARD
+//  };
+//
+//  for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
+//  {
+//    const SMDS_MeshElement* elem = *itElem;
+//    if ( !elem || elem->GetType() == SMDSAbs_Node )
+//      continue;
+//
+//    int nbNodes = elem->NbNodes();
+//    int elemType = elem->GetType();
+//
+//    if (elem->IsPoly()) {
+//      // Polygon or Polyhedral Volume
+//      switch ( elemType ) {
+//      case SMDSAbs_Face:
+//        {
+//          vector<const SMDS_MeshNode*> poly_nodes (nbNodes);
+//          int iNode = 0;
+//          SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+//          while (itN->more()) {
+//            const SMDS_MeshNode* node =
+//              static_cast<const SMDS_MeshNode*>(itN->next());
+//            TNodeNodeMap::iterator nodeMapIt = nodeMap.find(node);
+//            if (nodeMapIt == nodeMap.end())
+//              break; // not all nodes transformed
+//            //if (needReverse) {
+//            //  // reverse mirrored faces and volumes
+//            //  poly_nodes[nbNodes - iNode - 1] = (*nodeMapIt).second;
+//            //} else {
+//            poly_nodes[iNode] = (*nodeMapIt).second;
+//            //}
+//            iNode++;
+//          }
+//          if ( iNode != nbNodes )
+//            continue; // not all nodes transformed
+//
+//          if ( theTargetMesh ) {
+//            myLastCreatedElems.Append(aTgtMesh->AddPolygonalFace(poly_nodes));
+//            srcElems.Append( elem );
+//          }
+//          else if ( theCopy ) {
+//            myLastCreatedElems.Append(aMesh->AddPolygonalFace(poly_nodes));
+//            srcElems.Append( elem );
+//          }
+//          else {
+//            aMesh->ChangePolygonNodes(elem, poly_nodes);
+//          }
+//        }
+//        break;
+//      case SMDSAbs_Volume:
+//        {
+//          // ATTENTION: Reversing is not yet done!!!
+//          const SMDS_VtkVolume* aPolyedre =
+//            dynamic_cast<const SMDS_VtkVolume*>( elem );
+//          if (!aPolyedre) {
+//            MESSAGE("Warning: bad volumic element");
+//            continue;
+//          }
+//
+//          vector<const SMDS_MeshNode*> poly_nodes;
+//          vector<int> quantities;
+//
+//          bool allTransformed = true;
+//          int nbFaces = aPolyedre->NbFaces();
+//          for (int iface = 1; iface <= nbFaces && allTransformed; iface++) {
+//            int nbFaceNodes = aPolyedre->NbFaceNodes(iface);
+//            for (int inode = 1; inode <= nbFaceNodes && allTransformed; inode++) {
+//              const SMDS_MeshNode* node = aPolyedre->GetFaceNode(iface, inode);
+//              TNodeNodeMap::iterator nodeMapIt = nodeMap.find(node);
+//              if (nodeMapIt == nodeMap.end()) {
+//                allTransformed = false; // not all nodes transformed
+//              } else {
+//                poly_nodes.push_back((*nodeMapIt).second);
+//              }
+//            }
+//            quantities.push_back(nbFaceNodes);
+//          }
+//          if ( !allTransformed )
+//            continue; // not all nodes transformed
+//
+//          if ( theTargetMesh ) {
+//            myLastCreatedElems.Append(aTgtMesh->AddPolyhedralVolume(poly_nodes, quantities));
+//            srcElems.Append( elem );
+//          }
+//          else if ( theCopy ) {
+//            myLastCreatedElems.Append(aMesh->AddPolyhedralVolume(poly_nodes, quantities));
+//            srcElems.Append( elem );
+//          }
+//          else {
+//            aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
+//          }
+//        }
+//        break;
+//      default:;
+//      }
+//      continue;
+//    }
+//
+//    // Regular elements
+//    int* i = index[ FORWARD ];
+//    //if ( needReverse && nbNodes > 2) // reverse mirrored faces and volumes
+//    //  if ( elemType == SMDSAbs_Face )
+//    //    i = index[ REV_FACE ];
+//    //  else
+//    //    i = index[ nbNodes - 4 ];
+//
+//    if(elem->IsQuadratic()) {
+//      static int anIds[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+//      i = anIds;
+//      //if(needReverse) {
+//      //  if(nbNodes==3) { // quadratic edge
+//      //    static int anIds[] = {1,0,2};
+//      //    i = anIds;
+//      //  }
+//      //  else if(nbNodes==6) { // quadratic triangle
+//      //    static int anIds[] = {0,2,1,5,4,3};
+//      //    i = anIds;
+//      //  }
+//      //  else if(nbNodes==8) { // quadratic quadrangle
+//      //    static int anIds[] = {0,3,2,1,7,6,5,4};
+//      //    i = anIds;
+//      //  }
+//      //  else if(nbNodes==10) { // quadratic tetrahedron of 10 nodes
+//      //    static int anIds[] = {0,2,1,3,6,5,4,7,9,8};
+//      //    i = anIds;
+//      //  }
+//      //  else if(nbNodes==13) { // quadratic pyramid of 13 nodes
+//      //    static int anIds[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
+//      //    i = anIds;
+//      //  }
+//      //  else if(nbNodes==15) { // quadratic pentahedron with 15 nodes
+//      //    static int anIds[] = {0,2,1,3,5,4,8,7,6,11,10,9,12,14,13};
+//      //    i = anIds;
+//      //  }
+//      //  else { // nbNodes==20 - quadratic hexahedron with 20 nodes
+//      //    static int anIds[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
+//      //    i = anIds;
+//      //  }
+//      //}
+//    }
+//
+//    // find transformed nodes
+//    vector<const SMDS_MeshNode*> nodes(nbNodes);
+//    int iNode = 0;
+//    SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+//    while ( itN->more() ) {
+//      const SMDS_MeshNode* node =
+//        static_cast<const SMDS_MeshNode*>( itN->next() );
+//      TNodeNodeMap::iterator nodeMapIt = nodeMap.find( node );
+//      if ( nodeMapIt == nodeMap.end() )
+//        break; // not all nodes transformed
+//      nodes[ i [ iNode++ ]] = (*nodeMapIt).second;
+//    }
+//    if ( iNode != nbNodes )
+//      continue; // not all nodes transformed
+//
+//    if ( theTargetMesh ) {
+//      if ( SMDS_MeshElement* copy =
+//           targetMeshEditor.AddElement( nodes, elem->GetType(), elem->IsPoly() )) {
+//        myLastCreatedElems.Append( copy );
+//        srcElems.Append( elem );
+//      }
+//    }
+//    else if ( theCopy ) {
+//      if ( SMDS_MeshElement* copy = AddElement( nodes, elem->GetType(), elem->IsPoly() )) {
+//        myLastCreatedElems.Append( copy );
+//        srcElems.Append( elem );
+//      }
+//    }
+//    else {
+//      // reverse element as it was reversed by transformation
+//      if ( nbNodes > 2 )
+//        aMesh->ChangeElementNodes( elem, &nodes[0], nbNodes );
+//    }
+//  }
+//
+//  PGroupIDs newGroupIDs;
+//
+//  if ( theMakeGroups && theCopy ||
+//       theMakeGroups && theTargetMesh ) {
+//    string groupPostfix = "scaled";
+//    newGroupIDs = generateGroups( srcNodes, srcElems, groupPostfix, theTargetMesh );
+//  }
+//
+//  return newGroupIDs;
+//}
+
+
 //=======================================================================
 /*!
  * \brief Create groups of elements made during transformation
@@ -5757,9 +6147,8 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher
    */
   const SMDS_MeshNode* FindClosestTo( const gp_Pnt& thePnt )
   {
-    SMDS_MeshNode tgtNode( thePnt.X(), thePnt.Y(), thePnt.Z() );
     map<double, const SMDS_MeshNode*> dist2Nodes;
-    myOctreeNode->NodesAround( &tgtNode, dist2Nodes, myHalfLeafSize );
+    myOctreeNode->NodesAround( thePnt.Coord(), dist2Nodes, myHalfLeafSize );
     if ( !dist2Nodes.empty() )
       return dist2Nodes.begin()->second;
     list<const SMDS_MeshNode*> nodes;
@@ -5775,14 +6164,14 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher
       list< SMESH_OctreeNode* >::iterator trIt;
       treeList.push_back( myOctreeNode );
 
-      SMDS_MeshNode pointNode( thePnt.X(), thePnt.Y(), thePnt.Z() );
-      bool pointInside = myOctreeNode->isInside( &pointNode, myHalfLeafSize );
+      gp_XYZ pointNode( thePnt.X(), thePnt.Y(), thePnt.Z() );
+      bool pointInside = myOctreeNode->isInside( pointNode, myHalfLeafSize );
       for ( trIt = treeList.begin(); trIt != treeList.end(); ++trIt)
       {
         SMESH_OctreeNode* tree = *trIt;
         if ( !tree->isLeaf() ) // put children to the queue
         {
-          if ( pointInside && !tree->isInside( &pointNode, myHalfLeafSize )) continue;
+          if ( pointInside && !tree->isInside( pointNode, myHalfLeafSize )) continue;
           SMESH_OctreeNodeIteratorPtr cIt = tree->GetChildrenIterator();
           while ( cIt->more() )
             treeList.push_back( cIt->next() );
@@ -6138,7 +6527,6 @@ double SMESH_ElementSearcherImpl::getTolerance()
               meshInfo.NbElements( SMDSAbs_ElementType( complexType )) < 1 )
         --complexType;
       if ( complexType == SMDSAbs_All ) return 0; // empty mesh
-
       double elemSize;
       if ( complexType == int( SMDSAbs_Node ))
       {
@@ -6149,8 +6537,9 @@ double SMESH_ElementSearcherImpl::getTolerance()
       }
       else
       {
-        const SMDS_MeshElement* elem =
-          _mesh->elementsIterator( SMDSAbs_ElementType( complexType ))->next();
+        SMDS_ElemIteratorPtr elemIt =
+            _mesh->elementsIterator( SMDSAbs_ElementType( complexType ));
+        const SMDS_MeshElement* elem = elemIt->next();
         SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
         SMESH_MeshEditor::TNodeXYZ n1( cast2Node( nodeIt->next() ));
         while ( nodeIt->more() )
@@ -6632,16 +7021,21 @@ bool SMESH_MeshEditor::isOut( const SMDS_MeshElement* element, const gp_Pnt& poi
   // get ordered nodes
 
   vector< gp_XYZ > xyz;
+  vector<const SMDS_MeshNode*> nodeList;
 
   SMDS_ElemIteratorPtr nodeIt = element->nodesIterator();
   if ( element->IsQuadratic() )
-    if (const SMDS_QuadraticFaceOfNodes* f=dynamic_cast<const SMDS_QuadraticFaceOfNodes*>(element))
+    if (const SMDS_VtkFace* f=dynamic_cast<const SMDS_VtkFace*>(element))
       nodeIt = f->interlacedNodesElemIterator();
-    else if (const SMDS_QuadraticEdge*  e =dynamic_cast<const SMDS_QuadraticEdge*>(element))
+    else if (const SMDS_VtkEdge*  e =dynamic_cast<const SMDS_VtkEdge*>(element))
       nodeIt = e->interlacedNodesElemIterator();
 
   while ( nodeIt->more() )
-    xyz.push_back( TNodeXYZ( cast2Node( nodeIt->next() )));
+    {
+      const SMDS_MeshNode* node = cast2Node( nodeIt->next() );
+      xyz.push_back( TNodeXYZ(node) );
+      nodeList.push_back(node);
+    }
 
   int i, nbNodes = element->NbNodes();
 
@@ -6650,6 +7044,7 @@ bool SMESH_MeshEditor::isOut( const SMDS_MeshElement* element, const gp_Pnt& poi
     // compute face normal
     gp_Vec faceNorm(0,0,0);
     xyz.push_back( xyz.front() );
+    nodeList.push_back( nodeList.front() );
     for ( i = 0; i < nbNodes; ++i )
     {
       gp_Vec edge1( xyz[i+1], xyz[i]);
@@ -6662,9 +7057,7 @@ bool SMESH_MeshEditor::isOut( const SMDS_MeshElement* element, const gp_Pnt& poi
       // degenerated face: point is out if it is out of all face edges
       for ( i = 0; i < nbNodes; ++i )
       {
-        SMDS_MeshNode n1( xyz[i].X(),   xyz[i].Y(),   xyz[i].Z() );
-        SMDS_MeshNode n2( xyz[i+1].X(), xyz[i+1].Y(), xyz[i+1].Z() );
-        SMDS_MeshEdge edge( &n1, &n2 );
+        SMDS_LinearEdge edge( nodeList[i], nodeList[i+1] );
         if ( !isOut( &edge, point, tol ))
           return false;
       }
@@ -6862,6 +7255,7 @@ int SMESH_MeshEditor::SimplifyFace (const vector<const SMDS_MeshNode *> faceNode
 
 void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
 {
+  MESSAGE("MergeNodes");
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
 
@@ -6878,10 +7272,12 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
     list<const SMDS_MeshNode*>& nodes = *grIt;
     list<const SMDS_MeshNode*>::iterator nIt = nodes.begin();
     const SMDS_MeshNode* nToKeep = *nIt;
+    //MESSAGE("node to keep " << nToKeep->GetID());
     for ( ++nIt; nIt != nodes.end(); nIt++ ) {
       const SMDS_MeshNode* nToRemove = *nIt;
       nodeNodeMap.insert( TNodeNodeMap::value_type( nToRemove, nToKeep ));
       if ( nToRemove != nToKeep ) {
+        //MESSAGE("  node to remove " << nToRemove->GetID());
         rmNodeIds.push_back( nToRemove->GetID() );
         AddToSameGroups( nToKeep, nToRemove, aMesh );
       }
@@ -6898,6 +7294,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
   set<const SMDS_MeshElement*>::iterator eIt = elems.begin();
   for ( ; eIt != elems.end(); eIt++ ) {
     const SMDS_MeshElement* elem = *eIt;
+    //MESSAGE(" ---- inverse elem on node to remove " << elem->GetID());
     int nbNodes = elem->NbNodes();
     int aShapeId = FindShape( elem );
 
@@ -6947,6 +7344,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
 
     bool isOk = true;
     int nbUniqueNodes = nodeSet.size();
+    //MESSAGE("nbNodes nbUniqueNodes " << nbNodes << " " << nbUniqueNodes);
     if ( nbNodes != nbUniqueNodes ) { // some nodes stick
       // Polygons and Polyhedral volumes
       if (elem->IsPoly()) {
@@ -6976,7 +7374,19 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
               if (aShapeId)
                 aMesh->SetMeshElementOnShape(newElem, aShapeId);
             }
-            aMesh->ChangeElementNodes(elem, &polygons_nodes[inode], quantities[nbNew - 1]);
+
+            MESSAGE("ChangeElementNodes MergeNodes Polygon");
+            //aMesh->ChangeElementNodes(elem, &polygons_nodes[inode], quantities[nbNew - 1]);
+            vector<const SMDS_MeshNode *> polynodes(polygons_nodes.begin()+inode,polygons_nodes.end());
+            int quid =0;
+            if (nbNew > 0) quid = nbNew - 1;
+            vector<int> newquant(quantities.begin()+quid, quantities.end());
+            const SMDS_MeshElement* newElem = 0;
+            newElem = aMesh->AddPolyhedralVolume(polynodes, newquant);
+            myLastCreatedElems.Append(newElem);
+            if ( aShapeId && newElem )
+              aMesh->SetMeshElementOnShape( newElem, aShapeId );
+            rmElemIds.push_back(elem->GetID());
           }
           else {
             rmElemIds.push_back(elem->GetID());
@@ -6989,9 +7399,9 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
             rmElemIds.push_back(elem->GetID());
           }
           else {
-            // each face has to be analized in order to check volume validity
-            const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
-              static_cast<const SMDS_PolyhedralVolumeOfNodes*>( elem );
+            // each face has to be analyzed in order to check volume validity
+            const SMDS_VtkVolume* aPolyedre =
+              dynamic_cast<const SMDS_VtkVolume*>( elem );
             if (aPolyedre) {
               int nbFaces = aPolyedre->NbFaces();
 
@@ -7019,10 +7429,16 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
               }
 
               if (quantities.size() > 3)
-                aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
-              else
-                rmElemIds.push_back(elem->GetID());
-
+                {
+                  MESSAGE("ChangeElementNodes MergeNodes Polyhedron");
+                  //aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
+                  const SMDS_MeshElement* newElem = 0;
+                  newElem = aMesh->AddPolyhedralVolume(poly_nodes, quantities);
+                  myLastCreatedElems.Append(newElem);
+                  if ( aShapeId && newElem )
+                    aMesh->SetMeshElementOnShape( newElem, aShapeId );
+                  rmElemIds.push_back(elem->GetID());
+                }
             }
             else {
               rmElemIds.push_back(elem->GetID());
@@ -7036,6 +7452,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
       }
 
       // Regular elements
+      // TODO not all the possible cases are solved. Find something more generic?
       switch ( nbNodes ) {
       case 2: ///////////////////////////////////// EDGE
         isOk = false; break;
@@ -7049,6 +7466,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
             isOk = false;
           else if ( nbRepl == 2 && iRepl[ 1 ] - iRepl[ 0 ] == 2 )
             isOk = false; // opposite nodes stick
+          //MESSAGE("isOk " << isOk);
         }
         break;
       case 6: ///////////////////////////////////// PENTAHEDRON
@@ -7113,7 +7531,11 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
           //    +---+---+
           //   0    7    3
           isOk = false;
+          if(nbRepl==2) {
+            MESSAGE("nbRepl=2: " << iRepl[0] << " " << iRepl[1]);
+          }
           if(nbRepl==3) {
+            MESSAGE("nbRepl=3: " << iRepl[0] << " " << iRepl[1]  << " " << iRepl[2]);
             nbUniqueNodes = 6;
             if( iRepl[0]==0 && iRepl[1]==1 && iRepl[2]==4 ) {
               uniqueNodes[0] = curNodes[0];
@@ -7188,6 +7610,12 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
               isOk = true;
             }
           }
+          if(nbRepl==4) {
+            MESSAGE("nbRepl=4: " << iRepl[0] << " " << iRepl[1]  << " " << iRepl[2] << " " << iRepl[3]);
+          }
+          if(nbRepl==5) {
+            MESSAGE("nbRepl=5: " << iRepl[0] << " " << iRepl[1]  << " " << iRepl[2] << " " << iRepl[3] << " " << iRepl[4]);
+          }
           break;
         }
         //////////////////////////////////// HEXAHEDRON
@@ -7372,8 +7800,8 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
     if ( isOk ) {
       if (elem->IsPoly() && elem->GetType() == SMDSAbs_Volume) {
         // Change nodes of polyedre
-        const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
-          static_cast<const SMDS_PolyhedralVolumeOfNodes*>( elem );
+        const SMDS_VtkVolume* aPolyedre =
+          dynamic_cast<const SMDS_VtkVolume*>( elem );
         if (aPolyedre) {
           int nbFaces = aPolyedre->NbFaces();
 
@@ -7398,21 +7826,32 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
         }
       }
       else {
-        // Change regular element or polygon
-        aMesh->ChangeElementNodes( elem, & uniqueNodes[0], nbUniqueNodes );
+        int elemId = elem->GetID();
+        //MESSAGE("Change regular element or polygon " << elemId);
+        SMDSAbs_ElementType etyp = elem->GetType();
+        uniqueNodes.resize(nbUniqueNodes);
+        SMDS_MeshElement* newElem = this->AddElement(uniqueNodes, etyp, false);
+        if (newElem)
+          {
+            myLastCreatedElems.Append(newElem);
+            if ( aShapeId )
+              aMesh->SetMeshElementOnShape( newElem, aShapeId );
+          }
+        aMesh->RemoveElement(elem);
       }
     }
     else {
       // Remove invalid regular element or invalid polygon
+      //MESSAGE("Remove invalid " << elem->GetID());
       rmElemIds.push_back( elem->GetID() );
     }
 
   } // loop on elements
 
-  // Remove equal nodes and bad elements
+  // Remove bad elements, then equal nodes (order important)
 
-  Remove( rmNodeIds, true );
   Remove( rmElemIds, false );
+  Remove( rmNodeIds, true );
 
 }
 
@@ -7575,8 +8014,10 @@ SMESH_MeshEditor::FindFaceInSet(const SMDS_MeshNode*    n1,
   const SMDS_MeshElement* face = 0;
 
   SMDS_ElemIteratorPtr invElemIt = n1->GetInverseElementIterator(SMDSAbs_Face);
+  //MESSAGE("n1->GetInverseElementIterator(SMDSAbs_Face) " << invElemIt);
   while ( invElemIt->more() && !face ) // loop on inverse faces of n1
   {
+    //MESSAGE("in while ( invElemIt->more() && !face )");
     const SMDS_MeshElement* elem = invElemIt->next();
     if (avoidSet.count( elem ))
       continue;
@@ -7595,10 +8036,11 @@ SMESH_MeshEditor::FindFaceInSet(const SMDS_MeshNode*    n1,
     if ( !face && elem->IsQuadratic())
     {
       // analysis for quadratic elements using all nodes
-      const SMDS_QuadraticFaceOfNodes* F =
-        static_cast<const SMDS_QuadraticFaceOfNodes*>(elem);
+      const SMDS_VtkFace* F =
+        dynamic_cast<const SMDS_VtkFace*>(elem);
+      if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace"));
       // use special nodes iterator
-      SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+      SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator();
       const SMDS_MeshNode* prevN = cast2Node( anIter->next() );
       for ( i1 = -1, i2 = 0; anIter->more() && !face; i1++, i2++ )
       {
@@ -7682,12 +8124,13 @@ bool SMESH_MeshEditor::FindFreeBorder (const SMDS_MeshNode*             theFirst
         vector<const SMDS_MeshNode*> nodes(nbNodes+1);
 
         if(e->IsQuadratic()) {
-          const SMDS_QuadraticFaceOfNodes* F =
-            static_cast<const SMDS_QuadraticFaceOfNodes*>(e);
+          const SMDS_VtkFace* F =
+            dynamic_cast<const SMDS_VtkFace*>(e);
+          if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace"));
           // use special nodes iterator
-          SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+          SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator();
           while( anIter->more() ) {
-            nodes[ iNode++ ] = anIter->next();
+            nodes[ iNode++ ] = cast2Node(anIter->next());
           }
         }
         else {
@@ -7857,7 +8300,7 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
     //    links of the free border
     // -------------------------------------------------------------------------
 
-    // 1. Since sewing may brake if there are volumes to split on the side 2,
+    // 1. Since sewing may break if there are volumes to split on the side 2,
     //    we wont move nodes but just compute new coordinates for them
     typedef map<const SMDS_MeshNode*, gp_XYZ> TNodeXYZMap;
     TNodeXYZMap nBordXYZ;
@@ -7955,12 +8398,13 @@ SMESH_MeshEditor::SewFreeBorder (const SMDS_MeshNode* theBordFirstNode,
         else if ( elem->GetType()==SMDSAbs_Face ) { // --face
           // retrieve all face nodes and find iPrevNode - an index of the prevSideNode
           if(elem->IsQuadratic()) {
-            const SMDS_QuadraticFaceOfNodes* F =
-              static_cast<const SMDS_QuadraticFaceOfNodes*>(elem);
+            const SMDS_VtkFace* F =
+              dynamic_cast<const SMDS_VtkFace*>(elem);
+            if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace"));
             // use special nodes iterator
-            SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+            SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator();
             while( anIter->more() ) {
-              nodes[ iNode ] = anIter->next();
+              nodes[ iNode ] = cast2Node(anIter->next());
               if ( nodes[ iNode++ ] == prevSideNode )
                 iPrevNode = iNode - 1;
             }
@@ -8274,12 +8718,13 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
   vector<const SMDS_MeshNode*> nodes( theFace->NbNodes() );
 
   if(theFace->IsQuadratic()) {
-    const SMDS_QuadraticFaceOfNodes* F =
-      static_cast<const SMDS_QuadraticFaceOfNodes*>(theFace);
+    const SMDS_VtkFace* F =
+      dynamic_cast<const SMDS_VtkFace*>(theFace);
+    if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace"));
     // use special nodes iterator
-    SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+    SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator();
     while( anIter->more() ) {
-      const SMDS_MeshNode* n = anIter->next();
+      const SMDS_MeshNode* n = cast2Node(anIter->next());
       if ( n == theBetweenNode1 )
         il1 = iNode;
       else if ( n == theBetweenNode2 )
@@ -8335,12 +8780,13 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     bool isFLN = false;
 
     if(theFace->IsQuadratic()) {
-      const SMDS_QuadraticFaceOfNodes* F =
-        static_cast<const SMDS_QuadraticFaceOfNodes*>(theFace);
+      const SMDS_VtkFace* F =
+        dynamic_cast<const SMDS_VtkFace*>(theFace);
+      if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace"));
       // use special nodes iterator
-      SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+      SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator();
       while( anIter->more()  && !isFLN ) {
-        const SMDS_MeshNode* n = anIter->next();
+        const SMDS_MeshNode* n = cast2Node(anIter->next());
         poly_nodes[iNode++] = n;
         if (n == nodes[il1]) {
           isFLN = true;
@@ -8353,7 +8799,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
       }
       // add nodes of face starting from last node of link
       while ( anIter->more() ) {
-        poly_nodes[iNode++] = anIter->next();
+        poly_nodes[iNode++] = cast2Node(anIter->next());
       }
     }
     else {
@@ -8396,6 +8842,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     return;
   }
 
+  SMESHDS_Mesh *aMesh = GetMeshDS();
   if( !theFace->IsQuadratic() ) {
 
     // put aNodesToInsert between theBetweenNode1 and theBetweenNode2
@@ -8446,7 +8893,6 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     }
 
     // create new elements
-    SMESHDS_Mesh *aMesh = GetMeshDS();
     int aShapeId = FindShape( theFace );
 
     i1 = 0; i2 = 1;
@@ -8472,8 +8918,16 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     newNodes[ 1 ] = linkNodes[ i2 ];
     newNodes[ 2 ] = nodes[ iSplit >= iBestQuad ? i3 : i4 ];
     newNodes[ 3 ] = nodes[ i4 ];
-    aMesh->ChangeElementNodes( theFace, newNodes, iSplit == iBestQuad ? 4 : 3 );
-  } // end if(!theFace->IsQuadratic())
+    //aMesh->ChangeElementNodes( theFace, newNodes, iSplit == iBestQuad ? 4 : 3 );
+    const SMDS_MeshElement* newElem = 0;
+    if (iSplit == iBestQuad)
+      newElem = aMesh->AddFace( newNodes[0], newNodes[1], newNodes[2], newNodes[3] );
+    else
+      newElem = aMesh->AddFace( newNodes[0], newNodes[1], newNodes[2] );
+    myLastCreatedElems.Append(newElem);
+    if ( aShapeId && newElem )
+      aMesh->SetMeshElementOnShape( newElem, aShapeId );
+} // end if(!theFace->IsQuadratic())
   else { // theFace is quadratic
     // we have to split theFace on simple triangles and one simple quadrangle
     int tmp = il1/2;
@@ -8500,7 +8954,6 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     //           n4           n6      n5     n4
 
     // create new elements
-    SMESHDS_Mesh *aMesh = GetMeshDS();
     int aShapeId = FindShape( theFace );
 
     int n1,n2,n3;
@@ -8583,9 +9036,9 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
       if ( aShapeId && newElem )
         aMesh->SetMeshElementOnShape( newElem, aShapeId );
     }
-    // remove old quadratic face
-    aMesh->RemoveElement(theFace);
   }
+  // remove old face
+  aMesh->RemoveElement(theFace);
 }
 
 //=======================================================================
@@ -8697,14 +9150,14 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh *   theSm,
     if( !elem || elem->IsQuadratic() ) continue;
 
     int id = elem->GetID();
+    //MESSAGE("elem " << id);
+    id = 0; // get a free number for new elements
     int nbNodes = elem->NbNodes();
     SMDSAbs_ElementType aType = elem->GetType();
 
     vector<const SMDS_MeshNode *> nodes (elem->begin_nodes(), elem->end_nodes());
     if ( elem->GetEntityType() == SMDSEntity_Polyhedra )
-      nbNodeInFaces = static_cast<const SMDS_PolyhedralVolumeOfNodes* >( elem )->GetQuanities();
-
-    GetMeshDS()->RemoveFreeElement(elem, theSm, /*fromGroups=*/false);
+      nbNodeInFaces = static_cast<const SMDS_VtkVolume* >( elem )->GetQuantities();
 
     const SMDS_MeshElement* NewElem = 0;
 
@@ -8759,7 +9212,11 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh *   theSm,
     ReplaceElemInGroups( elem, NewElem, GetMeshDS());
     if( NewElem )
       theSm->AddElement( NewElem );
+
+    GetMeshDS()->RemoveFreeElement(elem, theSm, /*fromGroups=*/false);
   }
+//  if (!GetMeshDS()->isCompacted())
+//    GetMeshDS()->compactMesh();
   return nbElem;
 }
 
@@ -8800,6 +9257,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
       if(edge && !edge->IsQuadratic())
       {
         int id = edge->GetID();
+        //MESSAGE("edge->GetID() " << id);
         const SMDS_MeshNode* n1 = edge->GetNode(0);
         const SMDS_MeshNode* n2 = edge->GetNode(1);
 
@@ -8846,7 +9304,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
       int nbNodes = volume->NbNodes();
       vector<const SMDS_MeshNode *> nodes (volume->begin_nodes(), volume->end_nodes());
       if ( volume->GetEntityType() == SMDSEntity_Polyhedra )
-        nbNodeInFaces = static_cast<const SMDS_PolyhedralVolumeOfNodes* >(volume)->GetQuanities();
+        nbNodeInFaces = static_cast<const SMDS_VtkVolume* >(volume)->GetQuantities();
 
       meshDS->RemoveFreeElement(volume, smDS, /*fromGroups=*/false);
 
@@ -8881,6 +9339,8 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
     aHelper.SetSubShape(0); // apply FixQuadraticElements() to the whole mesh
     aHelper.FixQuadraticElements();
   }
+  if (!GetMeshDS()->isCompacted())
+    GetMeshDS()->compactMesh();
 }
 
 //=======================================================================
@@ -8935,9 +9395,9 @@ int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh *    theSm,
       for ( ; nIt != mediumNodes.end(); ++nIt ) {
         const SMDS_MeshNode* n = *nIt;
         if ( n->NbInverseElements() == 0 ) {
-          if ( n->GetPosition()->GetShapeId() != theShapeID )
+          if ( n->getshapeId() != theShapeID )
             meshDS->RemoveFreeNode( n, meshDS->MeshElements
-                                    ( n->GetPosition()->GetShapeId() ));
+                                    ( n->getshapeId() ));
           else
             meshDS->RemoveFreeNode( n, theSm );
         }
@@ -9008,12 +9468,13 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet&    theSide1,
   // 1. Build set of faces representing each side:
   // =======================================================================
   // a. build set of nodes belonging to faces
-  // b. complete set of faces: find missing fices whose nodes are in set of nodes
+  // b. complete set of faces: find missing faces whose nodes are in set of nodes
   // c. create temporary faces representing side of volumes if correspondent
   //    face does not exist
 
   SMESHDS_Mesh* aMesh = GetMeshDS();
-  SMDS_Mesh aTmpFacesMesh;
+  // TODO algoritm not OK with vtkUnstructuredGrid: 2 meshes can't share nodes
+  //SMDS_Mesh aTmpFacesMesh; // try to use the same mesh
   set<const SMDS_MeshElement*> faceSet1, faceSet2;
   set<const SMDS_MeshElement*> volSet1,  volSet2;
   set<const SMDS_MeshNode*>    nodeSet1, nodeSet2;
@@ -9023,6 +9484,7 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet&    theSide1,
   TIDSortedElemSet * elemSetPtr[] = { &theSide1, &theSide2 };
   int iSide, iFace, iNode;
 
+  list<const SMDS_MeshElement* > tempFaceList;
   for ( iSide = 0; iSide < 2; iSide++ ) {
     set<const SMDS_MeshNode*>    * nodeSet = nodeSetPtr[ iSide ];
     TIDSortedElemSet * elemSet = elemSetPtr[ iSide ];
@@ -9050,7 +9512,7 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet&    theSide1,
     // -----------------------------------------------------------
     // 1a. Collect nodes of existing faces
     //     and build set of face nodes in order to detect missing
-    //     faces corresponing to sides of volumes
+    //     faces corresponding to sides of volumes
     // -----------------------------------------------------------
 
     set< set <const SMDS_MeshNode*> > setOfFaceNodeSet;
@@ -9074,7 +9536,7 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet&    theSide1,
         volSet->insert( elem );
     }
     // ------------------------------------------------------------------------------
-    // 1b. Complete set of faces: find missing fices whose nodes are in set of nodes
+    // 1b. Complete set of faces: find missing faces whose nodes are in set of nodes
     // ------------------------------------------------------------------------------
 
     for ( nIt = nodeSet->begin(); nIt != nodeSet->end(); nIt++ ) { // loop on nodes of iSide
@@ -9142,18 +9604,23 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet&    theSide1,
           if ( !aFreeFace ) {
             // create a temporary face
             if ( nbNodes == 3 ) {
-              aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2] );
+              //aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2] );
+              aFreeFace = aMesh->AddFace( fNodes[0],fNodes[1],fNodes[2] );
             }
             else if ( nbNodes == 4 ) {
-              aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] );
+              //aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] );
+              aFreeFace = aMesh->AddFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] );
             }
             else {
               vector<const SMDS_MeshNode *> poly_nodes ( fNodes, & fNodes[nbNodes]);
-              aFreeFace = aTmpFacesMesh.AddPolygonalFace(poly_nodes);
+              //aFreeFace = aTmpFacesMesh.AddPolygonalFace(poly_nodes);
+              aFreeFace = aMesh->AddPolygonalFace(poly_nodes);
             }
           }
-          if ( aFreeFace )
+          if ( aFreeFace ) {
             freeFaceList.push_back( aFreeFace );
+            tempFaceList.push_back( aFreeFace );
+          }
 
         } // loop on faces of a volume
 
@@ -9183,7 +9650,7 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet&    theSide1,
               fIt++;
             }
             else
-              freeFaceList.erase( fIt++ ); // here fIt++ occures before erase
+              freeFaceList.erase( fIt++ ); // here fIt++ occurs before erase
           }
           if ( freeFaceList.size() > 1 )
           {
@@ -9267,9 +9734,12 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet&    theSide1,
 
   if ( faceSet1.size() != faceSet2.size() ) {
     // delete temporary faces: they are in reverseElements of actual nodes
-    SMDS_FaceIteratorPtr tmpFaceIt = aTmpFacesMesh.facesIterator();
-    while ( tmpFaceIt->more() )
-      aTmpFacesMesh.RemoveElement( tmpFaceIt->next() );
+//    SMDS_FaceIteratorPtr tmpFaceIt = aTmpFacesMesh.facesIterator();
+//    while ( tmpFaceIt->more() )
+//      aTmpFacesMesh.RemoveElement( tmpFaceIt->next() );
+//    list<const SMDS_MeshElement* >::iterator tmpFaceIt = tempFaceList.begin();
+//    for (; tmpFaceIt !=tempFaceList.end(); ++tmpFaceIt)
+//      aMesh->RemoveElement(*tmpFaceIt);
     MESSAGE("Diff nb of faces");
     return SEW_TOPO_DIFF_SETS_OF_ELEMENTS;
   }
@@ -9382,10 +9852,11 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet&    theSide1,
               }
             }
             else { // f->IsQuadratic()
-              const SMDS_QuadraticFaceOfNodes* F =
-                static_cast<const SMDS_QuadraticFaceOfNodes*>(f);
+              const SMDS_VtkFace* F =
+                dynamic_cast<const SMDS_VtkFace*>(f);
+              if (!F) throw SALOME_Exception(LOCALIZED("not an SMDS_VtkFace"));
               // use special nodes iterator
-              SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+              SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator();
               while ( anIter->more() ) {
                 const SMDS_MeshNode* n =
                   static_cast<const SMDS_MeshNode*>( anIter->next() );
@@ -9524,9 +9995,12 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet&    theSide1,
   // ====================================================================
 
   // delete temporary faces: they are in reverseElements of actual nodes
-  SMDS_FaceIteratorPtr tmpFaceIt = aTmpFacesMesh.facesIterator();
-  while ( tmpFaceIt->more() )
-    aTmpFacesMesh.RemoveElement( tmpFaceIt->next() );
+//  SMDS_FaceIteratorPtr tmpFaceIt = aTmpFacesMesh.facesIterator();
+//  while ( tmpFaceIt->more() )
+//    aTmpFacesMesh.RemoveElement( tmpFaceIt->next() );
+//  list<const SMDS_MeshElement* >::iterator tmpFaceIt = tempFaceList.begin();
+//  for (; tmpFaceIt !=tempFaceList.end(); ++tmpFaceIt)
+//    aMesh->RemoveElement(*tmpFaceIt);
 
   if ( aResult != SEW_OK)
     return aResult;
@@ -9560,7 +10034,21 @@ SMESH_MeshEditor::SewSideElements (TIDSortedElemSet&    theSide1,
         //         elemIDsToRemove.push_back( e->GetID() );
         //       else
         if ( nbReplaced )
-          aMesh->ChangeElementNodes( e, & nodes[0], nbNodes );
+          {
+            SMDSAbs_ElementType etyp = e->GetType();
+            SMDS_MeshElement* newElem = this->AddElement(nodes, etyp, false);
+            if (newElem)
+              {
+                myLastCreatedElems.Append(newElem);
+                AddToSameGroups(newElem, e, aMesh);
+                int aShapeId = e->getshapeId();
+                if ( aShapeId )
+                  {
+                    aMesh->SetMeshElementOnShape( newElem, aShapeId );
+                  }
+              }
+            aMesh->RemoveElement(e);
+          }
       }
     }
 
@@ -9796,6 +10284,7 @@ bool SMESH_MeshEditor::doubleNodes( SMESHDS_Mesh*     theMeshDS,
                                     const SMDS_MeshNode* >& theNodeNodeMap,
                                     const bool theIsDoubleElem )
 {
+  MESSAGE("doubleNodes");
   // iterate on through element and duplicate them (by nodes duplication)
   bool res = false;
   TIDSortedElemSet::const_iterator elemItr = theElems.begin();
@@ -9833,8 +10322,10 @@ bool SMESH_MeshEditor::doubleNodes( SMESHDS_Mesh*     theMeshDS,
     if ( theIsDoubleElem )
       AddElement(newNodes, anElem->GetType(), anElem->IsPoly());
     else
+      {
+      MESSAGE("ChangeElementNodes");
       theMeshDS->ChangeElementNodes( anElem, &newNodes[ 0 ], anElem->NbNodes() );
-
+      }
     res = true;
   }
   return res;
@@ -9854,6 +10345,7 @@ bool SMESH_MeshEditor::doubleNodes( SMESHDS_Mesh*     theMeshDS,
 bool SMESH_MeshEditor::DoubleNodes( const std::list< int >& theListOfNodes, 
                                     const std::list< int >& theListOfModifiedElems )
 {
+  MESSAGE("DoubleNodes");
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
 
@@ -9926,7 +10418,10 @@ bool SMESH_MeshEditor::DoubleNodes( const std::list< int >& theListOfNodes,
     const SMDS_MeshElement* anElem = anElemToNodesIter->first;
     vector<const SMDS_MeshNode*> aNodeArr = anElemToNodesIter->second;
     if ( anElem )
+      {
+      MESSAGE("ChangeElementNodes");
       aMeshDS->ChangeElementNodes( anElem, &aNodeArr[ 0 ], anElem->NbNodes() );
+      }
   }
 
   return true;
@@ -10054,6 +10549,194 @@ bool SMESH_MeshEditor::DoubleNodesInRegion( const TIDSortedElemSet& theElems,
   return DoubleNodes( theElems, theNodesNot, anAffected );
 }
 
+/*!
+ * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
+ * The list of groups must describe a partition of the mesh volumes.
+ * The nodes of the internal faces at the boundaries of the groups are doubled.
+ * In option, the internal faces are replaced by flat elements.
+ * Triangles are transformed in prisms, and quadrangles in hexahedrons.
+ * @param theElems - list of groups of volumes, where a group of volume is a set of
+ * SMDS_MeshElements sorted by Id.
+ * @param createJointElems - if TRUE, create the elements
+ * @return TRUE if operation has been completed successfully, FALSE otherwise
+ */
+bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector<TIDSortedElemSet>& theElems,
+                                                     bool createJointElems)
+{
+  MESSAGE("------------------------------------------------------");
+  MESSAGE("SMESH_MeshEditor::CreateJointElementsOnGroupBoundaries");
+  MESSAGE("------------------------------------------------------");
+
+  SMESHDS_Mesh *meshDS = this->myMesh->GetMeshDS();
+  meshDS->BuildDownWardConnectivity(false);
+  CHRONO(50);
+  SMDS_UnstructuredGrid *grid = meshDS->getGrid();
+
+  // --- build the list of faces shared by 2 domains (group of elements), with their domain and volume indexes
+  //     build the list of nodes shared by 2 or more domains, with their domain indexes
+
+  std::map<DownIdType, std::map<int,int>, DownIdCompare> faceDomains; // 2x(id domain --> id volume)
+  std::map<int, std::map<int,int> > nodeDomains; //oldId ->  (domainId -> newId)
+  faceDomains.clear();
+  nodeDomains.clear();
+  std::map<int,int> emptyMap;
+  emptyMap.clear();
+
+  for (int idom = 0; idom < theElems.size(); idom++)
+    {
+
+      // --- build a map (face to duplicate --> volume to modify)
+      //     with all the faces shared by 2 domains (group of elements)
+      //     and corresponding volume of this domain, for each shared face.
+      //     a volume has a face shared by 2 domains if it has a neighbor which is not in is domain.
+
+      const TIDSortedElemSet& domain = theElems[idom];
+      TIDSortedElemSet::const_iterator elemItr = domain.begin();
+      for (; elemItr != domain.end(); ++elemItr)
+        {
+          SMDS_MeshElement* anElem = (SMDS_MeshElement*) *elemItr;
+          if (!anElem)
+            continue;
+          int vtkId = anElem->getVtkId();
+          int neighborsVtkIds[NBMAXNEIGHBORS];
+          int downIds[NBMAXNEIGHBORS];
+          unsigned char downTypes[NBMAXNEIGHBORS];
+          int nbNeighbors = grid->GetNeighbors(neighborsVtkIds, downIds, downTypes, vtkId);
+          for (int n = 0; n < nbNeighbors; n++)
+            {
+              int smdsId = meshDS->fromVtkToSmds(neighborsVtkIds[n]);
+              const SMDS_MeshElement* elem = meshDS->FindElement(smdsId);
+              if (! domain.count(elem)) // neighbor is in another domain : face is shared
+                {
+                  DownIdType face(downIds[n], downTypes[n]);
+                  if (!faceDomains.count(face))
+                    faceDomains[face] = emptyMap; // create an empty entry for face
+                  if (!faceDomains[face].count(idom))
+                    {
+                      faceDomains[face][idom] = vtkId; // volume associated to face in this domain
+                    }
+                }
+            }
+        }
+    }
+
+  MESSAGE("Number of shared faces " << faceDomains.size());
+
+  // --- for each shared face, get the nodes
+  //     for each node, for each domain of the face, create a clone of the node
+
+  std::map<DownIdType, std::map<int,int>, DownIdCompare>::iterator itface = faceDomains.begin();
+  for( ; itface != faceDomains.end();++itface )
+    {
+      DownIdType face = itface->first;
+      std::map<int,int> domvol = itface->second;
+      std::set<int> oldNodes;
+      oldNodes.clear();
+      grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
+      std::set<int>::iterator itn = oldNodes.begin();
+      for (;itn != oldNodes.end(); ++itn)
+        {
+          int oldId = *itn;
+          if (!nodeDomains.count(oldId))
+            nodeDomains[oldId] = emptyMap; // create an empty entry for node
+          std::map<int,int>::iterator itdom = domvol.begin();
+          for(; itdom != domvol.end(); ++itdom)
+            {
+              int idom = itdom->first;
+              if ( nodeDomains[oldId].empty() )
+                nodeDomains[oldId][idom] = oldId; // keep the old node in the first domain
+              else
+                {
+                  double *coords = grid->GetPoint(oldId);
+                  SMDS_MeshNode *newNode = meshDS->AddNode(coords[0], coords[1], coords[2]);
+                  int newId = newNode->getVtkId();
+                  nodeDomains[oldId][idom] = newId; // cloned node for other domains
+                }
+            }
+        }
+    }
+
+  // --- iterate on shared faces (volumes to modify, face to extrude)
+  //     get node id's of the face (id SMDS = id VTK)
+  //     create flat element with old and new nodes if requested
+
+  if (createJointElems)
+    {
+      itface = faceDomains.begin();
+      for( ; itface != faceDomains.end();++itface )
+        {
+          DownIdType face = itface->first;
+          std::set<int> oldNodes;
+          std::set<int>::iterator itn;
+          oldNodes.clear();
+          grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
+          std::map<int,int> localClonedNodeIds;
+
+          std::map<int,int> domvol = itface->second;
+          std::map<int,int>::iterator itdom = domvol.begin();
+          int dom1 = itdom->first;
+          int vtkVolId = itdom->second;
+          itdom++;
+          int dom2 = itdom->first;
+
+          localClonedNodeIds.clear();
+          for (itn = oldNodes.begin(); itn != oldNodes.end(); ++itn)
+            {
+              int oldId = *itn;
+              int refid = oldId;
+              if (nodeDomains[oldId].count(dom1))
+                refid = nodeDomains[oldId][dom1];
+              else
+                MESSAGE("--- problem domain node " << dom1 << " " << oldId);
+              int newid = oldId;
+              if (nodeDomains[oldId].count(dom2))
+                newid = nodeDomains[oldId][dom2];
+              else
+                MESSAGE("--- problem domain node " << dom2 << " " << oldId);
+              localClonedNodeIds[oldId] = newid;
+            }
+          meshDS->extrudeVolumeFromFace(vtkVolId, localClonedNodeIds);
+        }
+    }
+
+  // --- iterate on shared faces (volumes to modify, face to extrude)
+  //     get node id's of the face
+  //     replace old nodes by new nodes in volumes, and update inverse connectivity
+
+  itface = faceDomains.begin();
+  for( ; itface != faceDomains.end();++itface )
+    {
+      DownIdType face = itface->first;
+      std::set<int> oldNodes;
+      std::set<int>::iterator itn;
+      oldNodes.clear();
+      grid->GetNodeIds(oldNodes, face.cellId, face.cellType);
+      std::map<int,int> localClonedNodeIds;
+
+      std::map<int,int> domvol = itface->second;
+      std::map<int,int>::iterator itdom = domvol.begin();
+      for(; itdom != domvol.end(); ++itdom)
+        {
+          int idom = itdom->first;
+          int vtkVolId = itdom->second;
+          localClonedNodeIds.clear();
+          for (itn = oldNodes.begin(); itn != oldNodes.end(); ++itn)
+            {
+              int oldId = *itn;
+              if (nodeDomains[oldId].count(idom))
+                localClonedNodeIds[oldId] = nodeDomains[oldId][idom];
+            }
+          meshDS->ModifyCellNodes(vtkVolId, localClonedNodeIds);
+        }
+    }
+  grid->BuildLinks();
+
+  // TODO replace also old nodes by new nodes in faces and edges
+  CHRONOSTOP(50);
+  counters::stats();
+  return true;
+}
+
 //================================================================================
 /*!
  * \brief Generates skin mesh (containing 2D cells) from 3D mesh
@@ -10122,7 +10805,7 @@ namespace
  *  \param group - a group to store created boundary elements in
  *  \param targetMesh - a mesh to store created boundary elements in
  *  \param toCopyElements - if true, the checked elements will be copied into the targetMesh
- *  \param toCopyExistingBondary - if true, not only new but also pre-existing 
+ *  \param toCopyExistingBondary - if true, not only new but also pre-existing
  *                                boundary elements will be copied into the targetMesh
  */
 //================================================================================
@@ -10168,7 +10851,7 @@ void SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
     vector<TConnectivity>           missingBndElems;
     TConnectivity nodes;
     if ( vTool.Set(elem) ) // elem is a volume ------------------------------------------
-    { 
+    {
       vTool.SetExternalNormal();
       for ( int iface = 0, n = vTool.NbFaces(); iface < n; iface++ )
       {
index dabe3f8db851dacacfef236dd253a66484f117c3..6b61b3095b2ecda86152d9ff584638cc2822e4e4 100644 (file)
@@ -170,14 +170,14 @@ public:
   SMDS_MeshElement* AddElement(const std::vector<const SMDS_MeshNode*> & nodes,
                                const SMDSAbs_ElementType                 type,
                                const bool                                isPoly,
-                               const int                                 ID = 0);
+                               const int                                 ID = -1);
   /*!
    * \brief Add element
    */
   SMDS_MeshElement* AddElement(const std::vector<int>  & nodeIDs,
                                const SMDSAbs_ElementType type,
                                const bool                isPoly,
-                               const int                 ID = 0);
+                               const int                 ID = -1);
 
   int Remove (const std::list< int >& theElemIDs, const bool isNodes);
   // Remove a node or an element.
@@ -624,6 +624,14 @@ public:
                             const TIDSortedElemSet& theNodesNot,
                             const TopoDS_Shape&     theShape );
   
+  bool DoubleNodesOnGroupBoundaries( const std::vector<TIDSortedElemSet>& theElems,
+                                     bool createJointElems);
+
+  /*!
+   * \brief Generated skin mesh (containing 2D cells) from 3D mesh
+   * The created 2D mesh elements based on nodes of free faces of boundary volumes
+   * \return TRUE if operation has been completed successfully, FALSE otherwise
+   */
   bool Make2DMeshFrom3D();
 
   enum Bnd_Dimension { BND_2DFROM3D, BND_1DFROM3D, BND_1DFROM2D };
index c3e284a472edc879973b951ad8bbbd957122afe1..bcdd2096a0e5f22528ef9bec48357005c07124e7 100644 (file)
@@ -293,7 +293,7 @@ bool SMESH_MesherHelper::IsMedium(const SMDS_MeshNode*      node,
 TopoDS_Shape SMESH_MesherHelper::GetSubShapeByNode(const SMDS_MeshNode* node,
                                                    SMESHDS_Mesh*        meshDS)
 {
-  int shapeID = node->GetPosition()->GetShapeId();
+  int shapeID = node->getshapeId();
   if ( 0 < shapeID && shapeID <= meshDS->MaxShapeIndex() )
     return meshDS->IndexToShape( shapeID );
   else
@@ -385,7 +385,7 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face&   F,
   {
     // node has position on face
     const SMDS_FacePosition* fpos =
-      static_cast<const SMDS_FacePosition*>(n->GetPosition().get());
+      static_cast<const SMDS_FacePosition*>(n->GetPosition());
     uv.SetCoord(fpos->GetUParameter(),fpos->GetVParameter());
     if ( check )
       uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*MaxTolerance( F ));
@@ -396,8 +396,8 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face&   F,
     // corresponding edge from face, get pcurve for this
     // edge and retrieve value from this pcurve
     const SMDS_EdgePosition* epos =
-      static_cast<const SMDS_EdgePosition*>(n->GetPosition().get());
-    int edgeID = Pos->GetShapeId();
+      static_cast<const SMDS_EdgePosition*>(n->GetPosition());
+    int edgeID = n->getshapeId();
     TopoDS_Edge E = TopoDS::Edge(GetMeshDS()->IndexToShape(edgeID));
     double f, l, u = epos->GetUParameter();
     Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
@@ -432,7 +432,7 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face&   F,
   }
   else if(Pos->GetTypeOfPosition()==SMDS_TOP_VERTEX)
   {
-    if ( int vertexID = n->GetPosition()->GetShapeId() ) {
+    if ( int vertexID = n->getshapeId() ) {
       const TopoDS_Vertex& V = TopoDS::Vertex(GetMeshDS()->IndexToShape(vertexID));
       try {
         uv = BRep_Tool::Parameters( V, F );
@@ -502,9 +502,12 @@ bool SMESH_MesherHelper::CheckNodeUV(const TopoDS_Face&   F,
                                      const double         tol,
                                      const bool           force) const
 {
-  int shapeID = n->GetPosition()->GetShapeId();
+  int shapeID = n->getshapeId();
   if ( force || toCheckPosOnShape( shapeID ))
   {
+    double toldis = tol;
+    double tolmin = 1.e-7*myMesh->GetMeshDS()->getMaxDim(); // nodes coordinates are stored in float format
+    if (toldis < tolmin) toldis = tolmin;
     // check that uv is correct
     TopLoc_Location loc;
     Handle(Geom_Surface) surface = BRep_Tool::Surface( F,loc );
@@ -512,7 +515,7 @@ bool SMESH_MesherHelper::CheckNodeUV(const TopoDS_Face&   F,
     if ( !loc.IsIdentity() ) nodePnt.Transform( loc.Transformation().Inverted() );
     if ( Precision::IsInfinite( uv.X() ) ||
          Precision::IsInfinite( uv.Y() ) ||
-         nodePnt.Distance( surface->Value( uv.X(), uv.Y() )) > tol )
+         nodePnt.Distance( surface->Value( uv.X(), uv.Y() )) > toldis )
     {
       setPosOnShapeValidity( shapeID, false );
       // uv incorrect, project the node to surface
@@ -526,7 +529,7 @@ bool SMESH_MesherHelper::CheckNodeUV(const TopoDS_Face&   F,
       Quantity_Parameter U,V;
       projector.LowerDistanceParameters(U,V);
       uv.SetCoord( U,V );
-      if ( nodePnt.Distance( surface->Value( U, V )) > tol )
+      if ( nodePnt.Distance( surface->Value( U, V )) > toldis )
       {
         MESSAGE( "SMESH_MesherHelper::CheckNodeUV(), invalid projection" );
         return false;
@@ -534,7 +537,7 @@ bool SMESH_MesherHelper::CheckNodeUV(const TopoDS_Face&   F,
       // store the fixed UV on the face
       if ( myShape.IsSame(F) && shapeID == myShapeID )
         const_cast<SMDS_MeshNode*>(n)->SetPosition
-          ( SMDS_PositionPtr( new SMDS_FacePosition( shapeID, U, V )));
+          ( SMDS_PositionPtr( new SMDS_FacePosition( U, V )));
     }
     else if ( uv.Modulus() > numeric_limits<double>::min() )
     {
@@ -642,7 +645,7 @@ double SMESH_MesherHelper::GetNodeU(const TopoDS_Edge&   E,
   const SMDS_PositionPtr pos = n->GetPosition();
   if ( pos->GetTypeOfPosition()==SMDS_TOP_EDGE )
   {
-    const SMDS_EdgePosition* epos = static_cast<const SMDS_EdgePosition*>( pos.get() );
+    const SMDS_EdgePosition* epos = static_cast<const SMDS_EdgePosition*>( pos );
     param =  epos->GetUParameter();
   }
   else if( pos->GetTypeOfPosition() == SMDS_TOP_VERTEX )
@@ -657,7 +660,7 @@ double SMESH_MesherHelper::GetNodeU(const TopoDS_Edge&   E,
     else
     {
       SMESHDS_Mesh * meshDS = GetMeshDS();
-      int vertexID = pos->GetShapeId();
+      int vertexID = n->getshapeId();
       const TopoDS_Vertex& V = TopoDS::Vertex(meshDS->IndexToShape(vertexID));
       param =  BRep_Tool::Parameter( V, E );
     }
@@ -668,7 +671,7 @@ double SMESH_MesherHelper::GetNodeU(const TopoDS_Edge&   E,
     double f,l;  BRep_Tool::Range( E, f,l );
     bool force = ( param < f-tol || param > l+tol );
     if ( !force && pos->GetTypeOfPosition()==SMDS_TOP_EDGE )
-      force = ( GetMeshDS()->ShapeToIndex( E ) != pos->GetShapeId() );
+      force = ( GetMeshDS()->ShapeToIndex( E ) != n->getshapeId() );
 
     *check = CheckNodeU( E, n, param, 2*tol, force );
   }
@@ -688,9 +691,12 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge&   E,
                                     const bool           force,
                                     double*              distance) const
 {
-  int shapeID = n->GetPosition()->GetShapeId();
+  int shapeID = n->getshapeId();
   if ( force || toCheckPosOnShape( shapeID ))
   {
+    double toldis = tol;
+    double tolmin = 1.e-7*myMesh->GetMeshDS()->getMaxDim(); // nodes coordinates are stored in float format
+    if (toldis < tolmin) toldis = tolmin;
     // check that u is correct
     TopLoc_Location loc; double f,l;
     Handle(Geom_Curve) curve = BRep_Tool::Curve( E,loc,f,l );
@@ -708,7 +714,7 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge&   E,
       if ( !loc.IsIdentity() ) nodePnt.Transform( loc.Transformation().Inverted() );
       double dist = nodePnt.Distance( curve->Value( u ));
       if ( distance ) *distance = dist;
-      if ( dist > tol )
+      if ( dist > toldis )
       {
         setPosOnShapeValidity( shapeID, false );
         // u incorrect, project the node to the curve
@@ -732,15 +738,16 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge&   E,
         u = double( U );
         dist = nodePnt.Distance( curve->Value( U ));
         if ( distance ) *distance = dist;
-        if ( dist > tol )
+        if ( dist > toldis )
         {
           MESSAGE( "SMESH_MesherHelper::CheckNodeU(), invalid projection" );
+          MESSAGE("distance " << nodePnt.Distance(curve->Value( U )) << " " << toldis);
           return false;
         }
         // store the fixed U on the edge
         if ( myShape.IsSame(E) && shapeID == myShapeID )
           const_cast<SMDS_MeshNode*>(n)->SetPosition
-            ( SMDS_PositionPtr( new SMDS_EdgePosition( shapeID, U )));
+            ( SMDS_PositionPtr( new SMDS_EdgePosition( U )));
       }
       else if ( fabs( u ) > numeric_limits<double>::min() )
       {
@@ -787,7 +794,7 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1,
   SMDS_MeshNode* n12;
   SMESHDS_Mesh* meshDS = GetMeshDS();
 
-  if ( IsSeamShape( n1->GetPosition()->GetShapeId() ))
+  if ( IsSeamShape( n1->getshapeId() ))
     // to get a correct UV of a node on seam, the second node must have checked UV
     std::swap( n1, n2 );
 
@@ -796,26 +803,27 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1,
   const SMDS_PositionPtr Pos1 = n1->GetPosition();
   const SMDS_PositionPtr Pos2 = n2->GetPosition();
 
+  TopoDS_Edge E; double u [2];
+  TopoDS_Face F; gp_XY  uv[2];
+  bool uvOK[2] = { false, false };
+
   if( myShape.IsNull() )
   {
     if( Pos1->GetTypeOfPosition()==SMDS_TOP_FACE ) {
-      faceID = Pos1->GetShapeId();
+      faceID = n1->getshapeId();
     }
     else if( Pos2->GetTypeOfPosition()==SMDS_TOP_FACE ) {
-      faceID = Pos2->GetShapeId();
+      faceID = n2->getshapeId();
     }
 
     if( Pos1->GetTypeOfPosition()==SMDS_TOP_EDGE ) {
-      edgeID = Pos1->GetShapeId();
+      edgeID = n1->getshapeId();
     }
     if( Pos2->GetTypeOfPosition()==SMDS_TOP_EDGE ) {
-      edgeID = Pos2->GetShapeId();
+      edgeID = n2->getshapeId();
     }
   }
   // get positions of the given nodes on shapes
-  TopoDS_Edge E; double u [2];
-  TopoDS_Face F; gp_XY  uv[2];
-  bool uvOK[2] = { false, false };
   TopAbs_ShapeEnum shapeType = myShape.IsNull() ? TopAbs_SHAPE : myShape.ShapeType();
   if ( faceID>0 || shapeType == TopAbs_FACE)
   {
@@ -832,7 +840,7 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1,
   {
     if ( Pos1->GetTypeOfPosition()==SMDS_TOP_EDGE &&
          Pos2->GetTypeOfPosition()==SMDS_TOP_EDGE &&
-         Pos1->GetShapeId() != Pos2->GetShapeId() ) // issue 0021006
+         n1->getshapeId() != n2->getshapeId() ) // issue 0021006
     return getMediumNodeOnComposedWire(n1,n2,force3d);
 
     if( myShape.IsNull() )
@@ -852,10 +860,10 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1,
     {
       if ( uvOK[0] && uvOK[1] )
       {
-        if ( IsDegenShape( Pos1->GetShapeId() ))
+        if ( IsDegenShape( n1->getshapeId() ))
           if ( myParIndex & U_periodic ) uv[0].SetCoord( 1, uv[1].Coord( 1 ));
           else                           uv[0].SetCoord( 2, uv[1].Coord( 2 ));
-        else if ( IsDegenShape( Pos2->GetShapeId() ))
+        else if ( IsDegenShape( n2->getshapeId() ))
           if ( myParIndex & U_periodic ) uv[1].SetCoord( 1, uv[0].Coord( 1 ));
           else                           uv[1].SetCoord( 2, uv[0].Coord( 2 ));
 
@@ -894,11 +902,13 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1,
       }
     }
   }
+
   // 3d variant
   double x = ( n1->X() + n2->X() )/2.;
   double y = ( n1->Y() + n2->Y() )/2.;
   double z = ( n1->Z() + n2->Z() )/2.;
   n12 = meshDS->AddNode(x,y,z);
+
   if ( !F.IsNull() )
   {
     gp_XY UV = ( uv[0] + uv[1] ) / 2.;
@@ -915,6 +925,7 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1,
   {
     meshDS->SetNodeInVolume(n12, myShapeID);
   }
+
   myTLinkNodeMap.insert( make_pair( link, n12 ));
   return n12;
 }
index 7cfe10d1125448f18e4c5e12ff5fed4a33e6a038..1ddb87f89113e4a03d297b0b051d66828a684d1c 100644 (file)
@@ -24,7 +24,7 @@
 //  inherites global class SMESH_Octree
 //  File      : SMESH_OctreeNode.cxx
 //  Created   : Tue Jan 16 16:00:00 2007
-//  Author    : Nicolas Geimer & Aurélien Motteux (OCC)
+//  Author    : Nicolas Geimer & Aurelien Motteux (OCC)
 //  Module    : SMESH
 //
 #include "SMESH_OctreeNode.hxx"
@@ -106,9 +106,8 @@ Bnd_B3d* SMESH_OctreeNode::buildRootBox()
  */
 //====================================================================================
 
-const bool SMESH_OctreeNode::isInside (const SMDS_MeshNode * Node, const double precision)
+const bool SMESH_OctreeNode::isInside (const gp_XYZ& p, const double precision)
 {
-  gp_XYZ p (Node->X(),Node->Y(),Node->Z());
   if (precision <= 0.)
     return !(getBox().IsOut(p));
   Bnd_B3d BoxWithPrecision = getBox();
@@ -158,7 +157,8 @@ void SMESH_OctreeNode::NodesAround (const SMDS_MeshNode * Node,
                                     list<const SMDS_MeshNode*>* Result,
                                     const double precision)
 {
-  if (isInside(Node,precision))
+  gp_XYZ p(Node->X(), Node->Y(), Node->Z());
+  if (isInside(p, precision))
   {
     if (isLeaf())
     {
@@ -185,7 +185,7 @@ void SMESH_OctreeNode::NodesAround (const SMDS_MeshNode * Node,
  */
 //================================================================================
 
-bool SMESH_OctreeNode::NodesAround(const SMDS_MeshNode *              node,
+bool SMESH_OctreeNode::NodesAround(const gp_XYZ &node,
                                    map<double, const SMDS_MeshNode*>& dist2Nodes,
                                    double                             precision)
 {
@@ -194,13 +194,14 @@ bool SMESH_OctreeNode::NodesAround(const SMDS_MeshNode *              node,
   else if ( precision == 0. )
     precision = maxSize() / 2;
 
-  if (isInside(node,precision))
+  //gp_XYZ p(node->X(), node->Y(), node->Z());
+  if (isInside(node, precision))
   {
     if (!isLeaf())
     {
       // first check a child containing node
       gp_XYZ mid = (getBox().CornerMin() + getBox().CornerMax()) / 2.;
-      int nodeChild  = getChildIndex( node->X(), node->Y(), node->Z(), mid );
+      int nodeChild  = getChildIndex( node.X(), node.Y(), node.Z(), mid );
       if ( ((SMESH_OctreeNode*) myChildren[nodeChild])->NodesAround(node, dist2Nodes, precision))
         return true;
       
@@ -212,8 +213,8 @@ bool SMESH_OctreeNode::NodesAround(const SMDS_MeshNode *              node,
     else if ( NbNodes() > 0 )
     {
       double minDist = precision * precision;
-      gp_Pnt p1 ( node->X(), node->Y(), node->Z() );
-      TIDSortedNodeSet::iterator nIt = myNodes.begin();
+      gp_Pnt p1 ( node.X(), node.Y(), node.Z() );
+      set<const SMDS_MeshNode*>::iterator nIt = myNodes.begin();
       for ( ; nIt != myNodes.end(); ++nIt )
       {
         gp_Pnt p2 ( (*nIt)->X(), (*nIt)->Y(), (*nIt)->Z() );
@@ -319,7 +320,8 @@ void SMESH_OctreeNode::FindCoincidentNodes (const SMDS_MeshNode * Node,
                                             list<const SMDS_MeshNode*>* Result,
                                             const double precision)
 {
-  bool isInsideBool = isInside(Node,precision);
+  gp_XYZ p(Node->X(), Node->Y(), Node->Z());
+  bool isInsideBool = isInside(p, precision);
 
   if (isInsideBool)
   {
@@ -385,8 +387,7 @@ void SMESH_OctreeNode::UpdateByMoveNode( const SMDS_MeshNode* node, const gp_Pnt
     TIDSortedNodeSet::iterator pNode = myNodes.find( node );
     bool nodeInMe = ( pNode != myNodes.end() );
 
-    SMDS_MeshNode pointNode( toPnt.X(), toPnt.Y(), toPnt.Z() );
-    bool pointInMe = isInside( &pointNode, 1e-10 );
+    bool pointInMe = isInside( toPnt.Coord(), 1e-10 );
 
     if ( pointInMe != nodeInMe )
     {
index 951d2bc1444fb29787ea3df6386a7833840978e1..3e837e9483751ba4422bed436f42287e0e914f33 100644 (file)
 //  inherites global class SMESH_Octree
 //  File      : SMESH_OctreeNode.hxx
 //  Created   : Tue Jan 16 16:00:00 2007
-//  Author    : Nicolas Geimer & Aurélien Motteux  (OCC)
+//  Author    : Nicolas Geimer & Aurelien Motteux  (OCC)
 //  Module    : SMESH
 //
 #ifndef _SMESH_OCTREENODE_HXX_
 #define _SMESH_OCTREENODE_HXX_
 
 #include "SMESH_Octree.hxx"
+#include <gp_Pnt.hxx>
 #include "SMDS_MeshNode.hxx"
 
 #include <list>
@@ -63,7 +64,7 @@ public:
   virtual ~SMESH_OctreeNode () {};
 
   // Tells us if Node is inside the current box with the precision "precision"
-  virtual const bool isInside(const SMDS_MeshNode * Node, const double precision = 0.);
+  virtual const bool isInside(const gp_XYZ& p, const double precision = 0.);
 
   // Return in Result a list of Nodes potentials to be near Node
   void               NodesAround(const SMDS_MeshNode *            Node,
@@ -71,7 +72,7 @@ public:
                                  const double                     precision = 0.);
 
   // Return in dist2Nodes nodes mapped to their square distance from Node
-  bool               NodesAround(const SMDS_MeshNode *                   Node,
+  bool               NodesAround(const gp_XYZ& node,
                                  std::map<double, const SMDS_MeshNode*>& dist2Nodes,
                                  double                                  precision);
 
index 0857f545d4ec09ebd2dd52337417f2620fe1c4f6..6164ed8e985e53b8934ed494faa2c5a9d3f92084 100644 (file)
@@ -463,8 +463,7 @@ template <class TFaceIterator> bool areNodesBound( TFaceIterator & faceItr )
     while ( nIt->more() )
     {
       const SMDS_MeshNode* node = smdsNode( nIt->next() );
-      SMDS_PositionPtr pos = node->GetPosition();
-      if ( !pos || !pos->GetShapeId() ) {
+      if (node->getshapeId() <0) {
         return false;
       }
     }
@@ -740,7 +739,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
         {
           const SMDS_MeshNode* node = smdsNode( nIt->next() );
           const SMDS_EdgePosition* epos =
-            static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+            static_cast<const SMDS_EdgePosition*>(node->GetPosition());
           double u = epos->GetUParameter();
           paramNodeMap.insert( make_pair( u, node ));
         }
@@ -862,7 +861,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
           p->myInitUV = project( node, projector );
         else {
           const SMDS_FacePosition* pos =
-            static_cast<const SMDS_FacePosition*>(node->GetPosition().get());
+            static_cast<const SMDS_FacePosition*>(node->GetPosition());
           p->myInitUV.SetCoord( pos->GetUParameter(), pos->GetVParameter() );
         }
         p->myInitXYZ.SetCoord( p->myInitUV.X(), p->myInitUV.Y(), 0 );
@@ -882,7 +881,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
           const SMDS_MeshNode* node = smdsNode( nIt->next() );
           iPoint = nodePointIDMap[ node ]; // point index of interest
           // for a node on a seam edge there are two points
-          if ( helper.IsRealSeam( node->GetPosition()->GetShapeId() ) &&
+          if ( helper.IsRealSeam( node->getshapeId() ) &&
                ( n_id = closeNodePointIDMap.find( node )) != not_found )
           {
             TPoint & p1 = myPoints[ iPoint ];
@@ -893,7 +892,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
             // find node not on a seam edge
             while ( nIt2->more() && !notSeamNode ) {
               const SMDS_MeshNode* n = smdsNode( nIt2->next() );
-              if ( !helper.IsSeamShape( n->GetPosition()->GetShapeId() ))
+              if ( !helper.IsSeamShape( n->getshapeId() ))
                 notSeamNode = n;
             }
             gp_Pnt2d uv = helper.GetNodeUV( theFace, node, notSeamNode );
@@ -3220,7 +3219,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh*         theMesh,
       {
         const SMDS_MeshNode* node = smdsNode( nIt->next() );
         const SMDS_EdgePosition* epos =
-          static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+          static_cast<const SMDS_EdgePosition*>(node->GetPosition());
         double u = ( epos->GetUParameter() - f ) / ( l - f );
         (*pIt)->myInitXYZ.SetCoord( iCoord, isForward ? u : 1 - u );
       }
@@ -4119,7 +4118,7 @@ void SMESH_Pattern::createElements(SMESH_Mesh*                            theMes
         SMDS_ElemIteratorPtr noIt = elem->nodesIterator();
         while ( noIt->more() ) {
           SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>(smdsNode( noIt->next() ));
-          if (!node->GetPosition()->GetShapeId() &&
+          if (!node->getshapeId() &&
               shellNodes.find( node ) == shellNodes.end() ) {
             if ( S.ShapeType() == TopAbs_FACE )
               aMeshDS->SetNodeOnFace( node, shapeID );
index 2929c023fe70999961b1e71f2d4bbedeae774ce3..58318b1e1b167a92e50ed25c16a47c4d88942a48 100644 (file)
@@ -24,6 +24,7 @@
 //  File   : SMESH_subMesh.hxx
 //  Author : Paul RASCLE, EDF
 //  Module : SMESH
+//  $Header$
 //
 #ifndef _SMESH_SUBMESH_HXX_
 #define _SMESH_SUBMESH_HXX_
diff --git a/src/SMESH/memoire.h b/src/SMESH/memoire.h
new file mode 100644 (file)
index 0000000..f9323bc
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef _MEMOIRE_H_
+#define _MEMOIRE_H_
+
+#include <malloc.h>
+#include <iostream>
+
+void memostat(const char* f, int l);
+
+void memostat(const char* f, int l)
+{
+  /*  struct mallinfo mem = mallinfo(); */
+  /*  std::cerr << f << ":"<< l << " " << mem.arena << " " << mem.ordblks << " " << mem.hblks << " " << mem.hblkhd << " "  << mem.uordblks << " "  << mem.fordblks << " " << mem.keepcost << std::endl; */
+  std::cerr << f << ":" << l << " --------------------------" << std::endl;
+  malloc_stats();
+  std::cerr << f << ":" << l << " --------------------------" << std::endl;
+}
+
+#define MEMOSTAT memostat( __FILE__, __LINE__ )
+
+#endif
index beb28b056ebfb56fb66d68d45d988dbb7d2faebc..b9a7174b8fe594637f5a8da85b6c5a60c0293039 100644 (file)
@@ -45,6 +45,7 @@ libSMESHClient_la_CPPFLAGS = \
        $(MED_CXXFLAGS) \
        $(GEOM_CXXFLAGS) \
        $(BOOST_CPPFLAGS) \
+        $(VTK_INCLUDES) \
        $(CAS_CPPFLAGS) \
        $(CORBA_CXXFLAGS) \
        $(CORBA_INCLUDES) \
index 7124ca61583e3af4dda005511f332e7c2a86ee7a..061028c303c7acc452a79627d5bcab39ad170983 100644 (file)
@@ -55,7 +55,7 @@
 #endif
 
 #ifdef _DEBUG_
-static int MYDEBUG = 0;
+static int MYDEBUG = 1;
 #else
 static int MYDEBUG = 0;
 #endif
@@ -635,6 +635,7 @@ SMESH_Client::SMESH_Client(CORBA::ORB_ptr theORB,
   mySMESHDSMesh(NULL),
   mySMDSMesh(NULL)
 {
+  MESSAGE("SMESH_Client::SMESH_Client");
   myMeshServer->Register();
 
   CORBA::Boolean anIsEmbeddedMode;
@@ -650,7 +651,8 @@ SMESH_Client::SMESH_Client(CORBA::ORB_ptr theORB,
     SMESH_Mesh* aMesh = reinterpret_cast<SMESH_Mesh*> (pointeur);
     if ( MYDEBUG )
       MESSAGE("SMESH_Client::SMESH_Client aMesh "<<aMesh);
-    if(aMesh->GetMeshDS()->IsEmbeddedMode()){
+    //if(aMesh->GetMeshDS()->IsEmbeddedMode()){
+    if(anIsEmbeddedMode){
       mySMESHDSMesh = aMesh->GetMeshDS();
       mySMDSMesh = mySMESHDSMesh;
     }
@@ -705,10 +707,12 @@ SMESH_Client::Update(bool theIsClear)
 {
   bool anIsModified = true;
   if(mySMESHDSMesh){
+       MESSAGE("Update mySMESHDSMesh");
     SMESHDS_Script* aScript = mySMESHDSMesh->GetScript();
     anIsModified = aScript->IsModified();
     aScript->SetModified(false);
   }else{
+       MESSAGE("Update CORBA");
     SMESH::log_array_var aSeq = myMeshServer->GetLog( theIsClear );
     CORBA::Long aLength = aSeq->length();
     anIsModified = aLength > 0;
index aaa9166866a52bdf7ce05e4871bf49d51f1b4374..91b485dae984fd351aec786a086f842dc0d6cd79 100644 (file)
@@ -58,6 +58,7 @@ dist_libSMESHDS_la_SOURCES = \
 libSMESHDS_la_CPPFLAGS = \
        $(KERNEL_CXXFLAGS) \
        $(CAS_CPPFLAGS) \
+        $(VTK_INCLUDES) \
        $(BOOST_CPPFLAGS) \
        -I$(srcdir)/../SMDS
 
index 0ae03d0c56940461a82c0f666b4e44288b204ec2..93a428be3fd1dcd856fbc3be1ec9f2cb16068826 100644 (file)
@@ -33,6 +33,7 @@
 #include "SMDS_EdgePosition.hxx"
 #include "SMDS_FacePosition.hxx"
 #include "SMDS_SpacePosition.hxx"
+#include "SMDS_Downward.hxx"
 #include "SMESHDS_GroupOnGeom.hxx"
 
 #include <Standard_ErrorHandler.hxx>
@@ -109,7 +110,7 @@ void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S)
       if ( !i_sub->second->IsComplexSubmesh() ) {
         SMDS_NodeIteratorPtr nIt = i_sub->second->GetNodes();
         while ( nIt->more() )
-          nIt->next()->GetPosition()->SetShapeId( 0 );
+          i_sub->second->RemoveNode(nIt->next(), false);
       }
     }
     // - sub-meshes
@@ -215,6 +216,7 @@ bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
                                       const SMDS_MeshNode    * nodes[],
                                       const int                nbnodes)
 {
+  MESSAGE("SMESHDS_Mesh::ChangeElementNodes");
   if ( ! SMDS_Mesh::ChangeElementNodes( elem, nodes, nbnodes ))
     return false;
 
@@ -270,8 +272,11 @@ bool SMESHDS_Mesh::ChangePolyhedronNodes
 
 void SMESHDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)
 {
-  SMDS_Mesh::Renumber( isNodes, startID, deltaID );
-  myScript->Renumber( isNodes, startID, deltaID );
+  // TODO not possible yet to have node numbers not starting to O and continuous.
+  if (!this->isCompacted())
+    this->compactMesh();
+//  SMDS_Mesh::Renumber( isNodes, startID, deltaID );
+//  myScript->Renumber( isNodes, startID, deltaID );
 }
 
 //=======================================================================
@@ -748,7 +753,7 @@ void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
   {
     SMESHDS_SubMesh* subMesh=0;
     map<int,SMESHDS_SubMesh*>::iterator SubIt =
-      myShapeIndexToSubMesh.find( n->GetPosition()->GetShapeId() );
+      myShapeIndexToSubMesh.find( n->getshapeId() );
     if ( SubIt != myShapeIndexToSubMesh.end() )
       subMesh = SubIt->second;
     else
@@ -819,7 +824,7 @@ void SMESHDS_Mesh::RemoveElement(const SMDS_MeshElement * elt)
     for ( ; !subMesh && SubIt != myShapeIndexToSubMesh.end(); SubIt++ )
       if (!SubIt->second->IsComplexSubmesh() && SubIt->second->Contains( elt ))
         subMesh = SubIt->second;
-
+    //MESSAGE("subMesh " << elt->getshapeId());
     RemoveFreeElement( elt, subMesh, true);
     return;
   }
@@ -842,6 +847,7 @@ void SMESHDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elt,
                                      SMESHDS_SubMesh *        subMesh,
                                      bool                     fromGroups)
 {
+  //MESSAGE(" --------------------------------> SMESHDS_Mesh::RemoveFreeElement " << subMesh << " " << fromGroups);
   if (elt->GetType() == SMDSAbs_Node) {
     RemoveFreeNode( static_cast<const SMDS_MeshNode*>(elt), subMesh);
     return;
@@ -937,7 +943,7 @@ SMESHDS_SubMesh* SMESHDS_Mesh::getSubmesh( const int Index )
   if ( Index != myCurSubID ) {
     map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
     if ( it == myShapeIndexToSubMesh.end() )
-      it = myShapeIndexToSubMesh.insert( make_pair(Index, new SMESHDS_SubMesh() )).first;
+      it = myShapeIndexToSubMesh.insert( make_pair(Index, new SMESHDS_SubMesh(this, Index) )).first;
     myCurSubMesh = it->second;
     myCurSubID = Index;
     myCurSubShape.Nullify(); // myCurSubShape no more corresponds to submesh
@@ -965,22 +971,6 @@ bool SMESHDS_Mesh::add(const SMDS_MeshElement* elem, SMESHDS_SubMesh* subMesh )
   return false;
 }
 
-namespace {
-
-  //================================================================================
-  /*!
-   * \brief Creates a node position in volume
-   */
-  //================================================================================
-
-  inline SMDS_PositionPtr volumePosition(int volId)
-  {
-    SMDS_SpacePosition* pos = new SMDS_SpacePosition();
-    pos->SetShapeId( volId );
-    return SMDS_PositionPtr(pos);
-  }
-}
-
 //=======================================================================
 //function : SetNodeOnVolume
 //purpose  : 
@@ -989,8 +979,9 @@ void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode *      aNode,
                                    const TopoDS_Shell & S)
 {
   if ( add( aNode, getSubmesh(S) ))
-    aNode->SetPosition ( volumePosition( myCurSubID ));
+    aNode->SetPosition ( SMDS_SpacePosition::originSpacePosition() );
 }
+
 //=======================================================================
 //function : SetNodeOnVolume
 //purpose  : 
@@ -999,7 +990,7 @@ void SMESHDS_Mesh::SetNodeInVolume(SMDS_MeshNode *      aNode,
                                    const TopoDS_Solid & S)
 {
   if ( add( aNode, getSubmesh(S) ))
-    aNode->SetPosition ( volumePosition( myCurSubID ));
+    aNode->SetPosition ( SMDS_SpacePosition::originSpacePosition() );
 }
 
 //=======================================================================
@@ -1012,7 +1003,7 @@ void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode *     aNode,
                                  double              v)
 {
   if ( add( aNode, getSubmesh(S) ))
-    aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(myCurSubID, u, v)));
+    aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v)));
 }
 
 //=======================================================================
@@ -1024,7 +1015,7 @@ void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode *     aNode,
                                  double              u)
 {
   if ( add( aNode, getSubmesh(S) ))
-    aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(myCurSubID, u)));
+    aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u)));
 }
 
 //=======================================================================
@@ -1035,7 +1026,7 @@ void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode *       aNode,
                                    const TopoDS_Vertex & S)
 {
   if ( add( aNode, getSubmesh(S) ))
-    aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(myCurSubID)));
+    aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition()));
 }
 
 //=======================================================================
@@ -1044,12 +1035,13 @@ void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode *       aNode,
 //=======================================================================
 void SMESHDS_Mesh::UnSetNodeOnShape(const SMDS_MeshNode* aNode)
 {
-  if ( aNode && aNode->GetPosition() ) {
-    map<int,SMESHDS_SubMesh*>::iterator it =
-      myShapeIndexToSubMesh.find( aNode->GetPosition()->GetShapeId() );
-    if ( it != myShapeIndexToSubMesh.end() )
-      it->second->RemoveNode( aNode, /*deleted=*/false );
-  }
+  int shapeId = aNode->getshapeId();
+  if (shapeId >= 0)
+    {
+      map<int, SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find(shapeId);
+      if (it != myShapeIndexToSubMesh.end())
+        it->second->RemoveNode(aNode, /*deleted=*/false);
+    }
 }
 
 //=======================================================================
@@ -1209,7 +1201,7 @@ SMESHDS_SubMesh * SMESHDS_Mesh::NewSubMesh(int Index)
   TShapeIndexToSubMesh::iterator anIter = myShapeIndexToSubMesh.find(Index);
   if (anIter == myShapeIndexToSubMesh.end())
   {
-    SM = new SMESHDS_SubMesh();
+    SM = new SMESHDS_SubMesh(this, Index);
     myShapeIndexToSubMesh[Index]=SM;
   }
   else
@@ -1301,8 +1293,9 @@ int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const
 //=======================================================================
 void SMESHDS_Mesh::SetNodeInVolume(const SMDS_MeshNode* aNode, int Index)
 {
+  //add(aNode, getSubmesh(Index));
   if ( add( aNode, getSubmesh( Index )))
-    ((SMDS_MeshNode*) aNode)->SetPosition( volumePosition( Index ));
+    ((SMDS_MeshNode*) aNode)->SetPosition( SMDS_SpacePosition::originSpacePosition());
 }
 
 //=======================================================================
@@ -1313,7 +1306,7 @@ void SMESHDS_Mesh::SetNodeOnFace(SMDS_MeshNode* aNode, int Index, double u, doub
 {
   //Set Position on Node
   if ( add( aNode, getSubmesh( Index )))
-    aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition(Index, u, v)));
+    aNode->SetPosition(SMDS_PositionPtr(new SMDS_FacePosition( u, v)));
 }
 
 //=======================================================================
@@ -1326,7 +1319,7 @@ void SMESHDS_Mesh::SetNodeOnEdge(SMDS_MeshNode* aNode,
 {
   //Set Position on Node
   if ( add( aNode, getSubmesh( Index )))
-    aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(Index, u)));
+    aNode->SetPosition(SMDS_PositionPtr(new SMDS_EdgePosition(u)));
 }
 
 //=======================================================================
@@ -1337,7 +1330,7 @@ void SMESHDS_Mesh::SetNodeOnVertex(SMDS_MeshNode* aNode, int Index)
 {
   //Set Position on Node
   if ( add( aNode, getSubmesh( Index )))
-    aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition(Index)));
+    aNode->SetPosition(SMDS_PositionPtr(new SMDS_VertexPosition()));
 }
 
 //=======================================================================
@@ -1818,4 +1811,201 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1,
                          ID);
 }
 
+void SMESHDS_Mesh::compactMesh()
+{
+  int newNodeSize = 0;
+  int nbNodes = myNodes.size();
+  int nbVtkNodes = myGrid->GetNumberOfPoints();
+  MESSAGE("nbNodes=" << nbNodes << " nbVtkNodes=" << nbVtkNodes);
+  int nbNodeTemp = nbVtkNodes;
+  if (nbNodes > nbVtkNodes)
+    nbNodeTemp = nbNodes;
+  vector<int> idNodesOldToNew;
+  idNodesOldToNew.clear();
+  idNodesOldToNew.resize(nbNodeTemp, -1); // all unused id will be -1
+
+  for (int i = 0; i < nbNodes; i++)
+    {
+      if (myNodes[i])
+        {
+          int vtkid = myNodes[i]->getVtkId();
+          idNodesOldToNew[vtkid] = i; // old vtkId --> old smdsId (valid smdsId are >= 0)
+          newNodeSize++;
+        }
+    }
+  bool areNodesModified = (newNodeSize < nbVtkNodes);
+  MESSAGE("------------------------- compactMesh Nodes Modified: " << areNodesModified);
+  areNodesModified = true;
+
+  int newCellSize = 0;
+  int nbCells = myCells.size();
+  int nbVtkCells = myGrid->GetNumberOfCells();
+  MESSAGE("nbCells=" << nbCells << " nbVtkCells=" << nbVtkCells);
+  int nbCellTemp = nbVtkCells;
+  if (nbCells > nbVtkCells)
+    nbCellTemp = nbCells;
+  vector<int> idCellsOldToNew;
+  idCellsOldToNew.clear();
+  idCellsOldToNew.resize(nbCellTemp, -1); // all unused id will be -1
+
+  for (int i = 0; i < nbCells; i++)
+    {
+      if (myCells[i])
+        {
+//          //idCellsOldToNew[i] = myCellIdVtkToSmds[i]; // valid vtk indexes are > = 0
+//          int vtkid = myCells[i]->getVtkId();
+//          idCellsOldToNew[vtkid] = i; // old vtkId --> old smdsId (not used in input)
+          newCellSize++;
+        }
+    }
+  if (areNodesModified)
+    myGrid->compactGrid(idNodesOldToNew, newNodeSize, idCellsOldToNew, newCellSize);
+  else
+    myGrid->compactGrid(idNodesOldToNew, 0, idCellsOldToNew, newCellSize);
+
+  int nbVtkPts = myGrid->GetNumberOfPoints();
+  nbVtkCells = myGrid->GetNumberOfCells();
+  if (nbVtkPts != newNodeSize)
+    {
+      MESSAGE("===> nbVtkPts != newNodeSize " << nbVtkPts << " " << newNodeSize);
+      if (nbVtkPts > newNodeSize) newNodeSize = nbVtkPts; // several points with same SMDS Id
+    }
+  if (nbVtkCells != newCellSize)
+    {
+      MESSAGE("===> nbVtkCells != newCellSize " << nbVtkCells << " " << newCellSize);
+      if (nbVtkCells > newCellSize) newCellSize = nbVtkCells; // several cells with same SMDS Id
+    }
+
+  // --- SMDS_MeshNode and myNodes (id in SMDS and in VTK are the same), myNodeIdFactory
+
+  if (areNodesModified)
+    {
+      MESSAGE("-------------- modify myNodes");
+      SetOfNodes newNodes;
+      newNodes.resize(newNodeSize+1,0); // 0 not used, SMDS numbers 1..n
+      int newSmdsId = 0;
+      for (int i = 0; i < nbNodes; i++)
+        {
+          if (myNodes[i])
+            {
+              newSmdsId++; // SMDS id start to 1
+              int oldVtkId = myNodes[i]->getVtkId();
+              int newVtkId = idNodesOldToNew[oldVtkId];
+              //MESSAGE("myNodes["<< i << "] vtkId " << oldVtkId << " --> " << newVtkId);
+              myNodes[i]->setVtkId(newVtkId);
+              myNodes[i]->setId(newSmdsId);
+              newNodes[newSmdsId] = myNodes[i];
+              //MESSAGE("myNodes["<< i << "] --> newNodes[" << newSmdsId << "]");
+            }
+        }
+      myNodes.swap(newNodes);
+      this->myNodeIDFactory->emptyPool(newSmdsId); // newSmdsId = number of nodes
+      MESSAGE("myNodes.size " << myNodes.size());
+    }
+
+  // --- SMDS_MeshCell, myCellIdVtkToSmds, myCellIdSmdsToVtk, myCells
+
+  int vtkIndexSize = myCellIdVtkToSmds.size();
+  int maxVtkId = -1;
+  for (int oldVtkId = 0; oldVtkId < vtkIndexSize; oldVtkId++)
+    {
+      int oldSmdsId = this->myCellIdVtkToSmds[oldVtkId];
+      if (oldSmdsId > 0)
+        {
+          int newVtkId = idCellsOldToNew[oldVtkId];
+          if (newVtkId > maxVtkId)
+            maxVtkId = newVtkId;
+          //MESSAGE("myCells["<< oldSmdsId << "] vtkId " << oldVtkId << " --> " << newVtkId);
+          myCells[oldSmdsId]->setVtkId(newVtkId);
+        }
+    }
+//  MESSAGE("myCells.size()=" << myCells.size()
+//          << " myCellIdSmdsToVtk.size()=" << myCellIdSmdsToVtk.size()
+//          << " myCellIdVtkToSmds.size()=" << myCellIdVtkToSmds.size() );
+
+  SetOfCells newCells;
+  //vector<int> newSmdsToVtk;
+  vector<int> newVtkToSmds;
+
+  assert(maxVtkId < newCellSize);
+  newCells.resize(newCellSize+1, 0); // 0 not used, SMDS numbers 1..n
+  //newSmdsToVtk.resize(newCellSize+1, -1);
+  newVtkToSmds.resize(newCellSize+1, -1);
+
+  int myCellsSize = myCells.size();
+  int newSmdsId = 0;
+  for (int i = 0; i < myCellsSize; i++)
+    {
+      if (myCells[i])
+        {
+          newSmdsId++; // SMDS id start to 1
+          assert(newSmdsId <= newCellSize);
+          newCells[newSmdsId] = myCells[i];
+          newCells[newSmdsId]->setId(newSmdsId);
+          //MESSAGE("myCells["<< i << "] --> newCells[" << newSmdsId << "]");
+          int idvtk = myCells[i]->getVtkId();
+          //newSmdsToVtk[newSmdsId] = idvtk;
+          assert(idvtk < newCellSize);
+          newVtkToSmds[idvtk] = newSmdsId;
+        }
+    }
+
+  myCells.swap(newCells);
+  //myCellIdSmdsToVtk.swap(newSmdsToVtk);
+  myCellIdVtkToSmds.swap(newVtkToSmds);
+  MESSAGE("myCells.size()=" << myCells.size()
+          << " myCellIdVtkToSmds.size()=" << myCellIdVtkToSmds.size() );
+  this->myElementIDFactory->emptyPool(newSmdsId);
+
+  this->myScript->SetModified(true); // notify GUI client for buildPrs when update
+
+  // --- compact list myNodes and myElements in submeshes
+
+  map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.begin();
+  for(; it != myShapeIndexToSubMesh.end(); ++it)
+    {
+      (*it).second->compactList();
+    }
+
+}
+
+void SMESHDS_Mesh::BuildDownWardConnectivity(bool withEdges)
+{
+  myGrid->BuildDownwardConnectivity(withEdges);
+}
+
+/*! change some nodes in cell without modifying type or internal connectivity.
+ * Nodes inverse connectivity is maintained up to date.
+ * @param vtkVolId vtk id of the cell.
+ * @param localClonedNodeIds map old node id to new node id.
+ * @return ok if success.
+ */
+bool SMESHDS_Mesh::ModifyCellNodes(int vtkVolId, std::map<int,int> localClonedNodeIds)
+{
+  myGrid->ModifyCellNodes(vtkVolId, localClonedNodeIds);
+  return true;
+}
+
+/*! Create a volume (prism or hexahedron) by duplication of a face.
+ * the nodes of the new face are already created.
+ * @param vtkVolId vtk id of a volume containing the face, to get an orientation for the face.
+ * @param localClonedNodeIds map old node id to new node id. The old nodes define the face in the volume.
+ * @return ok if success.
+ */
+bool SMESHDS_Mesh::extrudeVolumeFromFace(int vtkVolId, std::map<int,int>& localClonedNodeIds)
+{
+  //MESSAGE("extrudeVolumeFromFace " << vtkVolId);
+  vector<int> orderedNodes;
+  orderedNodes.clear();
+  map<int, int>::const_iterator it = localClonedNodeIds.begin();
+  for (; it != localClonedNodeIds.end(); ++it)
+    orderedNodes.push_back(it->first);
 
+  int nbNodes = myGrid->getOrderedNodesOfFace(vtkVolId, orderedNodes);
+  for (int i=0; i<nbNodes; i++)
+    orderedNodes.push_back(localClonedNodeIds[orderedNodes[i]]);
+  SMDS_MeshVolume *vol = this->AddVolumeFromVtkIds(orderedNodes);
+
+  // TODO update subshape list of elements and nodes
+  return vol;
+}
index 7e852c774b307c180c60e5195066a91babbdf6d9..3c3f4d4ca7f9c36d2ab6966af29a102701b65e24 100644 (file)
@@ -56,6 +56,7 @@
 #include "SMESHDS_DataMapOfShape.hxx"
 
 class SMESHDS_GroupBase;
+class DownIdType;
 
 class SMESHDS_EXPORT SMESHDS_Mesh:public SMDS_Mesh{
 public:
@@ -399,6 +400,8 @@ public:
   bool ChangePolyhedronNodes(const SMDS_MeshElement * elem,
                              std::vector<const SMDS_MeshNode*> nodes,
                              std::vector<int>                  quantities);
+  bool ModifyCellNodes(int smdsVolId, std::map<int,int> localClonedNodeIds);
+  bool extrudeVolumeFromFace(int vtkVolId, std::map<int,int>& localClonedNodeIds);
   void Renumber (const bool isNodes, const int startID=1, const int deltaID=1);
 
   void SetNodeInVolume(SMDS_MeshNode * aNode, const TopoDS_Shell & S);
@@ -442,6 +445,9 @@ public:
 
   bool IsGroupOfSubShapes (const TopoDS_Shape& aSubShape) const;
 
+  virtual void compactMesh();
+  void BuildDownWardConnectivity(bool withEdges);
+
   ~SMESHDS_Mesh();
   
 private:
@@ -450,7 +456,7 @@ private:
     //Update or build submesh
     std::map<int,SMESHDS_SubMesh*>::iterator it = myShapeIndexToSubMesh.find( Index );
     if ( it == myShapeIndexToSubMesh.end() )
-      it = myShapeIndexToSubMesh.insert( std::make_pair(Index, new SMESHDS_SubMesh() )).first;
+      it = myShapeIndexToSubMesh.insert( std::make_pair(Index, new SMESHDS_SubMesh(this, Index) )).first;
     it->second->AddNode( aNode ); // add aNode to submesh
   }
   
index 8474e1116beba7ec34dd3cb27163c1a00a9ca0ec..21183a18f730898cd3dc3cbc30987fb696f2a4c4 100644 (file)
@@ -27,6 +27,7 @@
 //  $Header: 
 //
 #include "SMESHDS_Script.hxx"
+#include <iostream>
 
 using namespace std;
 
@@ -36,7 +37,9 @@ using namespace std;
 //=======================================================================
 SMESHDS_Script::SMESHDS_Script(bool theIsEmbeddedMode):
   myIsEmbeddedMode(theIsEmbeddedMode)
-{}
+{
+  cerr << "=========================== myIsEmbeddedMode " << myIsEmbeddedMode << endl;
+}
 
 //=======================================================================
 //function : Destructor
index 92704eb37654f030adc9efa828bb642e797a836e..aa85c9c96136940bedb952ebe519e8ff02d1076a 100644 (file)
 //  $Header: 
 //
 #include "SMESHDS_SubMesh.hxx"
+#include "SMESHDS_Mesh.hxx"
 
 #include "utilities.h"
 #include "SMDS_SetIterator.hxx"
+#include <iostream>
+#include <cassert>
 
 using namespace std;
 
+SMESHDS_SubMesh::SMESHDS_SubMesh(SMESHDS_Mesh *parent, int index)
+{
+  myParent = parent;
+  myElements.clear();
+  myNodes.clear();
+  myIndex = index;
+  myUnusedIdNodes = 0;
+  myUnusedIdElements = 0;
+}
+
 //=======================================================================
 //function : AddElement
 //purpose  : 
 //=======================================================================
 void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * ME)
 {
-  if ( !IsComplexSubmesh() )
-    myElements.insert(ME);
+  if (!IsComplexSubmesh())
+    {
+      //MESSAGE("in " << myIndex << " AddElement "<< ME->GetID());
+      int idInSubShape = ME->getIdInShape();
+      if (idInSubShape != -1)
+        {
+          MESSAGE("add element in subshape already belonging to a subshape "
+              << ME->GetID() << "  " << ME->getIdInShape() << " " << ME->getshapeId());
+          throw SALOME_Exception(LOCALIZED("add element in subshape already belonging to a subshape"));
+        }
+      SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME);
+      elem->setShapeId(myIndex);
+      elem->setIdInShape(myElements.size());
+      myElements.push_back(ME);
+    }
 }
 
 //=======================================================================
@@ -49,19 +75,31 @@ void SMESHDS_SubMesh::AddElement(const SMDS_MeshElement * ME)
 //=======================================================================
 bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME, bool isElemDeleted)
 {
-  if ( !IsComplexSubmesh() && NbElements() ) {
-
-    if (!isElemDeleted) // alive element has valid ID and can be found
-      return myElements.erase(ME);
-
-    TElemSet::iterator e = myElements.begin(), eEnd = myElements.end();
-    for ( ; e != eEnd; ++e )
-      if ( ME == *e ) {
-        myElements.erase( e );
-        return true;
-      }
-  }
-  
+  if (!ME)
+    {
+      MESSAGE("-----------------> Remove Null Element " << isElemDeleted);
+      return false;
+    }
+  //MESSAGE("-----------------> RemoveElement "<< ME->GetID() << " " << isElemDeleted);
+  if (!IsComplexSubmesh())
+    {
+      //      if (!isElemDeleted) // alive element has valid ID and can be found
+      //  {
+      int idInSubShape = ME->getIdInShape();
+      //MESSAGE("in "<< myIndex << " RemoveElement " << ME->GetID() << " " << idInSubShape << " " << myUnusedIdElements);
+      SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME);
+      elem->setShapeId(0);
+      elem->setIdInShape(-1);
+      if ((idInSubShape >= 0) && (idInSubShape < myElements.size()))
+        {
+          myElements[idInSubShape] = 0; // this vector entry is no more used
+          myUnusedIdElements++;
+          return true;
+        }
+      return false;
+      //  }
+    }
+  MESSAGE("Try to remove an element from a complex submesh ");
   return false;
 }
 
@@ -72,7 +110,22 @@ bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME, bool isElemDele
 void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N)
 {
   if ( !IsComplexSubmesh() )
-    myNodes.insert(N);
+    {
+      int idInSubShape = N->getIdInShape();
+      int shapeId = N->getshapeId();
+      if ((shapeId > 0) && (idInSubShape >= 0))
+        {
+          MESSAGE("========== AddNode already belonging to other subShape " << N->GetID());
+          // OK for vertex nodes
+          //this->getParent()->UnSetNodeOnShape(N);
+        }
+      SMDS_MeshNode* node = (SMDS_MeshNode*)(N);
+      node->setShapeId(myIndex);
+      node->setIdInShape(myNodes.size());
+      myNodes.push_back(N);
+      //MESSAGE("in "<< myIndex << " AddNode " << node->GetID());
+    }
+  //MESSAGE("try to add node in a complex submesh " << N->GetID());
 }
 
 //=======================================================================
@@ -82,19 +135,26 @@ void SMESHDS_SubMesh::AddNode(const SMDS_MeshNode * N)
 
 bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N, bool isNodeDeleted)
 {
-  if ( !IsComplexSubmesh() && NbNodes() ) {
-
-    if (!isNodeDeleted) // alive node has valid ID and can be found
-      return myNodes.erase(N);
-
-    TElemSet::iterator e = myNodes.begin(), eEnd = myNodes.end();
-    for ( ; e != eEnd; ++e )
-      if ( N == *e ) {
-        myNodes.erase( e );
-        return true;
-      }
-  }
-
+  if (!IsComplexSubmesh())
+    {
+      // if (!isNodeDeleted) // alive node has valid ID and can be found
+      // {
+      int idInSubShape = N->getIdInShape();
+      int shapeId = N->getshapeId();
+      //MESSAGE("in "<< myIndex << " RemoveNode " << shapeId << " " << idInSubShape << " " << N->GetID());
+      SMDS_MeshNode* node = (SMDS_MeshNode*) (N);
+      node->setShapeId(0);
+      node->setIdInShape(-1);
+      if ((idInSubShape >= 0) && (idInSubShape < myNodes.size()))
+        {
+          myNodes[idInSubShape] = 0; // this vector entry is no more used
+          myUnusedIdNodes++;
+          return true;
+        }
+      return false;
+      // }
+    }
+  MESSAGE("Try to remove a node from a complex submesh");
   return false;
 }
 
@@ -104,8 +164,9 @@ bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N, bool isNodeDeleted)
 //=======================================================================
 int SMESHDS_SubMesh::NbElements() const
 {
+  //MESSAGE(this << " NbElements " << IsComplexSubmesh() << " " << myElements.size() - myUnusedIdElements);
   if ( !IsComplexSubmesh() )
-    return myElements.size();
+    return myElements.size() - myUnusedIdElements;
 
   int nbElems = 0;
   set<const SMESHDS_SubMesh*>::const_iterator it = mySubMeshes.begin();
@@ -122,8 +183,9 @@ int SMESHDS_SubMesh::NbElements() const
 
 int SMESHDS_SubMesh::NbNodes() const
 {
- if ( !IsComplexSubmesh() )
-   return myNodes.size(); 
+  //MESSAGE(this << " NbNodes " << IsComplexSubmesh() << " " << myNodes.size() - myUnusedIdNodes);
+  if ( !IsComplexSubmesh() )
+    return myNodes.size() - myUnusedIdNodes;
 
   int nbElems = 0;
   set<const SMESHDS_SubMesh*>::const_iterator it = mySubMeshes.begin();
@@ -133,18 +195,41 @@ int SMESHDS_SubMesh::NbNodes() const
   return nbElems;
 }
 
-// =====================
-// class MySetIterator
-// =====================
-
-template<class ELEM, typename TSET> class MySetIterator:
-  public SMDS_SetIterator<ELEM, typename TSET::const_iterator >
+/*!
+ * template class used for iteration on submesh elements. Interface of iterator remains
+ * unchanged after redesign of SMDS to avoid modification everywhere in SMESH.
+ * instances are stored in shared_ptr for automatic destruction.
+ * Container is copied for iteration, because original can be modified
+ * by addition of elements, for instance, and then reallocated (vector)
+ */
+template <class ELEM, typename TSET> class MySetIterator : public SMDS_Iterator<ELEM>
 {
-  typedef SMDS_SetIterator<ELEM, typename TSET::const_iterator > TFather;
-  public:
-        MySetIterator(const TSET& s):TFather(s.begin(),s.end())
-        {
-        }
+protected:
+  typename TSET::const_iterator _it, _end;
+  TSET _table;
+public:
+  MySetIterator(const TSET& table)
+  {
+    _table = table;
+    _it = _table.begin();
+    _end = _table.end();
+    while ((_it != _end) && (*_it == 0))
+      _it++;
+  }
+
+  virtual bool more()
+  {
+    while ((_it != _end) && (*_it == 0))
+      _it++;
+    return (_it != _end);
+  }
+
+  virtual ELEM next()
+  {
+    ELEM e = *_it;
+    _it++;
+    return e;
+  }
 };
 
 // =====================
@@ -219,8 +304,7 @@ SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements() const
 {
   if ( IsComplexSubmesh() )
     return SMDS_ElemIteratorPtr( new MyElemIterator( mySubMeshes ));
-
-  return SMDS_ElemIteratorPtr(new MySetIterator<const SMDS_MeshElement*,TElemSet>(myElements));
+  return SMDS_ElemIteratorPtr(new MySetIterator<const SMDS_MeshElement*, std::vector<const SMDS_MeshElement*> >(myElements));
 }
 
 //=======================================================================
@@ -233,7 +317,7 @@ SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const
   if ( IsComplexSubmesh() )
     return SMDS_NodeIteratorPtr( new MyNodeIterator( mySubMeshes ));
 
-  return SMDS_NodeIteratorPtr(new MySetIterator<const SMDS_MeshNode*,TElemSet>(myNodes));
+  return SMDS_NodeIteratorPtr(new MySetIterator<const SMDS_MeshNode*, std::vector<const SMDS_MeshNode*> >(myNodes));
 }
 
 //=======================================================================
@@ -245,22 +329,33 @@ bool SMESHDS_SubMesh::Contains(const SMDS_MeshElement * ME) const
 {
   // DO NOT TRY TO FIND A REMOVED ELEMENT !!
   //if ( IsComplexSubmesh() || !ME )
-  if (!ME )
-    return false;
-
-  if ( IsComplexSubmesh() )
-  {
-    set<const SMESHDS_SubMesh*>::const_iterator aSubIt = mySubMeshes.begin();
-    for ( ; aSubIt != mySubMeshes.end(); aSubIt++ )
-      if ( (*aSubIt)->Contains( ME ))
-        return true;
+  if (!ME)
     return false;
-  }
 
-  if ( ME->GetType() == SMDSAbs_Node )
-    return ( myNodes.find( ME ) != myNodes.end() );
+  if (IsComplexSubmesh())
+    {
+      set<const SMESHDS_SubMesh*>::const_iterator aSubIt = mySubMeshes.begin();
+      for (; aSubIt != mySubMeshes.end(); aSubIt++)
+        if ((*aSubIt)->Contains(ME))
+          return true;
+      return false;
+    }
 
-  return ( myElements.find( ME ) != myElements.end() );
+  if (ME->GetType() == SMDSAbs_Node)
+    {
+      int idInShape = ME->getIdInShape();
+      if ((idInShape >= 0) && (idInShape < myNodes.size()))
+        if (myNodes[idInShape] == ME)
+          return true;
+    }
+  else
+    {
+      int idInShape = ME->getIdInShape();
+      if ((idInShape >= 0) && (idInShape < myElements.size()))
+        if (myElements[idInShape] == ME)
+          return true;
+    }
+  return false;
 }
 
 //=======================================================================
@@ -316,9 +411,66 @@ void SMESHDS_SubMesh::Clear()
 {
   myElements.clear();
   myNodes.clear();
+  myUnusedIdNodes = 0;
+  myUnusedIdElements = 0;
   SMESHDS_SubMeshIteratorPtr sub = GetSubMeshIterator();
   while ( sub->more() ) {
     if ( SMESHDS_SubMesh* sm = (SMESHDS_SubMesh*) sub->next())
       sm->Clear();
   }
 }
+
+int SMESHDS_SubMesh::getSize()
+{
+  int c = NbNodes();
+  int d = NbElements();
+  //cerr << "SMESHDS_SubMesh::NbNodes " << c << endl;
+  //cerr << "SMESHDS_SubMesh::NbElements " << d << endl;
+  return c+d;
+}
+
+void SMESHDS_SubMesh::compactList()
+{
+  //MESSAGE("compactList old: nodes " << myNodes.size() << " elements " << myElements.size());
+  //stringstream a;
+  //stringstream b;
+  //stringstream c;
+  //stringstream d;
+
+  std::vector<const SMDS_MeshElement*> newElems;
+  newElems.clear();
+  for (int i = 0; i < myElements.size(); i++)
+    if (myElements[i])
+      {
+        SMDS_MeshElement* elem = (SMDS_MeshElement*)myElements[i];
+        elem->setIdInShape(newElems.size());
+        newElems.push_back(elem);
+        //a << elem->GetID() << " ";
+        //b << elem->GetID() << " ";
+      }
+    //else
+    //  a << "_ ";
+  myElements.swap(newElems);
+  myUnusedIdElements = 0;
+  //MESSAGE("in " << myIndex << " oldElems " << a.str());
+  //MESSAGE("in " << myIndex << " newElems " << b.str());
+
+  std::vector<const SMDS_MeshNode*> newNodes;
+  newNodes.clear();
+  for (int i = 0; i < myNodes.size(); i++)
+    if (myNodes[i])
+      {
+        SMDS_MeshNode* node = (SMDS_MeshNode*)myNodes[i];
+        node->setIdInShape(newNodes.size());
+        newNodes.push_back(node);
+        //c << node->GetID() << " ";
+        //d << node->GetID() << " ";
+      }
+    //else
+    //  c << "_ ";
+  myNodes.swap(newNodes);
+  myUnusedIdNodes = 0;
+  //MESSAGE("in " << myIndex << " oldNodes " << c.str());
+  //MESSAGE("in " << myIndex << " newNodes " << d.str());
+  //MESSAGE("compactList new: nodes " << myNodes.size() << " elements " << myElements.size());
+}
index de086ddaa233b88a2cf1ab9e38a10c1e8d5e2554..53493254c3fe937b7f734d33d90e9a2adae24af0 100644 (file)
 
 #include "SMDS_Mesh.hxx"
 #include <set>
+#include <vector>
 
 class SMESHDS_SubMesh;
 typedef SMDS_Iterator<const SMESHDS_SubMesh*> SMESHDS_SubMeshIterator;
 typedef boost::shared_ptr< SMESHDS_SubMeshIterator > SMESHDS_SubMeshIteratorPtr;
 
+class SMESHDS_Mesh;
+
 class SMESHDS_EXPORT SMESHDS_SubMesh
 {
  public:
+  SMESHDS_SubMesh(SMESHDS_Mesh *parent, int index);
 
   bool IsComplexSubmesh() const { return !mySubMeshes.empty(); }
 
@@ -64,11 +68,19 @@ class SMESHDS_EXPORT SMESHDS_SubMesh
 
   // clear the contents
   void Clear();
+  int getSize();
+  void compactList();
+
+  inline SMESHDS_Mesh *getParent() {return myParent; };
 
  private:
+  SMESHDS_Mesh * myParent;
+  std::vector<const SMDS_MeshElement*> myElements;
+  std::vector<const SMDS_MeshNode*> myNodes;
 
-  typedef std::set<const SMDS_MeshElement*, TIDCompare > TElemSet;
-  TElemSet myElements, myNodes;
+  int myUnusedIdNodes;
+  int myUnusedIdElements;
+  int myIndex;
 
   std::set<const SMESHDS_SubMesh*> mySubMeshes;
 };
index 6ea18bbf09749d9fc227f9b67fd3a55c50876252..efc9c9ea1424c235a665ab1d85176464048c59ab 100644 (file)
@@ -1433,6 +1433,7 @@ LightApp_Module( "SMESH" )
   {
     CORBA::Boolean anIsEmbeddedMode;
     myComponentSMESH = SMESH_Client::GetSMESHGen(getApp()->orb(),anIsEmbeddedMode);
+    MESSAGE("-------------------------------> anIsEmbeddedMode=" << anIsEmbeddedMode);
 
     //  0019923: EDF 765 SMESH : default values of hypothesis
     SUIT_ResourceMgr* aResourceMgr = SMESH::GetResourceMgr(this);
@@ -1927,7 +1928,10 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
         aSel->selectedObjects( sel_objects );
 
       if( theCommandID==302 )
+      {
+       MESSAGE("anAction = SMESH::eDisplayOnly");
         startOperation( myEraseAll );
+      }
 
       extractContainers( sel_objects, to_process );
 
@@ -1938,20 +1942,26 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
         if (vtkwnd) {
           SALOME_ListIteratorOfListIO It( to_process );
           for ( ; It.More(); It.Next()) {
+               MESSAGE("---");
             Handle(SALOME_InteractiveObject) IOS = It.Value();
             if (IOS->hasEntry()) {
+               MESSAGE("---");
               if (!SMESH::UpdateView(anAction, IOS->getEntry())) {
                 SMESHGUI::GetSMESHGUI()->EmitSignalVisibilityChanged();
                 break; // PAL16774 (Crash after display of many groups)
               }
               if (anAction == SMESH::eDisplayOnly)
+              {
+               MESSAGE("anAction = SMESH::eDisplayOnly");
                 anAction = SMESH::eDisplay;
+              }
             }
           }
         }
 
         // PAL13338 + PAL15161 -->
         if ( ( theCommandID==301 || theCommandID==302 ) && !checkLock(aStudy)) {
+               MESSAGE("anAction = SMESH::eDisplayOnly");
           SMESH::UpdateView();
           SMESHGUI::GetSMESHGUI()->EmitSignalVisibilityChanged();
         }
@@ -1962,6 +1972,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       }
 
       if (anAction == SMESH::eErase) {
+       MESSAGE("anAction == SMESH::eErase");
         SALOME_ListIO l1;
         aSel->setSelectedObjects( l1 );
       }
index b31a1b8e9685f65a227f377bb0664455697bc335..147d19bb99f04fd3b6c4943c649e6b355b1a9d5a 100644 (file)
@@ -710,6 +710,7 @@ void SMESHGUI_BaseComputeOp::computeMesh()
 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
       OCC_CATCH_SIGNALS;
 #endif
+      SMESH::UpdateNulData(myIObject, true);
       if (gen->Compute(myMesh, myMainShape))
         computeFailed = false;
     }
index c663c74da3ff9bedb28fbc0e97251ee23ee3bcb1..772dd80f5eb891eafba45d0ee7387d9df301b585 100644 (file)
@@ -122,7 +122,7 @@ namespace SMESH
       TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.find(aKey);
       if(anIter != VISUAL_OBJ_CONT.end()) {
         // for unknown reason, object destructor is not called, so clear object manually
-        anIter->second->GetUnstructuredGrid()->SetCells(0,0,0);
+        anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0);
         anIter->second->GetUnstructuredGrid()->SetPoints(0);
       }
       VISUAL_OBJ_CONT.erase(aKey);
@@ -164,7 +164,7 @@ namespace SMESH
     TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.begin();
     for ( ; anIter != VISUAL_OBJ_CONT.end(); ++anIter ) {
       // for unknown reason, object destructor is not called, so clear object manually
-      anIter->second->GetUnstructuredGrid()->SetCells(0,0,0);
+      anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0);
       anIter->second->GetUnstructuredGrid()->SetPoints(0);
     }
     VISUAL_OBJ_CONT.clear();
@@ -209,7 +209,7 @@ namespace SMESH
       int curId = anIter->first.first;
       if ( curId == studyID ) {
         // for unknown reason, object destructor is not called, so clear object manually
-        anIter->second->GetUnstructuredGrid()->SetCells(0,0,0);
+        anIter->second->GetUnstructuredGrid()->SetCells(0,0,0,0,0);
         anIter->second->GetUnstructuredGrid()->SetPoints(0);
         VISUAL_OBJ_CONT.erase( anIter++ ); // anIter++ returns a copy of self before incrementing
       }
@@ -257,7 +257,7 @@ namespace SMESH
    */
   //================================================================================
 
-  TVisualObjPtr GetVisualObj(int theStudyId, const char* theEntry){
+  TVisualObjPtr GetVisualObj(int theStudyId, const char* theEntry, bool nulData){
     TVisualObjPtr aVisualObj;
     TVisualObjCont::key_type aKey(theStudyId,theEntry);
     try{
@@ -331,7 +331,11 @@ namespace SMESH
 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
         OCC_CATCH_SIGNALS;
 #endif
-        objModified = aVisualObj->Update();
+        //MESSAGE("GetVisualObj");
+        if (nulData)
+               objModified = aVisualObj->NulData();
+        else
+          objModified = aVisualObj->Update();
       }
       catch (...) {
 #ifdef _DEBUG_
@@ -355,24 +359,24 @@ namespace SMESH
         MESSAGE ( "SMESHGUI_VTKUtils::GetVisualObj(), freeMB=" << freeMB
                << ", usedMB=" << usedMB );
 #endif
-        bool continu = false;
-        if ( usedMB * 10 > freeMB )
-          // even dont try to show
-          SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"),
-                                   QObject::tr("SMESH_NO_MESH_VISUALIZATION"));
-        else
-          // there is a chance to succeed
-          continu = SUIT_MessageBox::warning
-            (SMESHGUI::desktop(),
-             QObject::tr("SMESH_WRN_WARNING"),
-             QObject::tr("SMESH_CONTINUE_MESH_VISUALIZATION"),
-             SUIT_MessageBox::Yes | SUIT_MessageBox::No, 
-             SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes;
-        if ( !continu ) {
-          // remove the corresponding actors from all views
-          RemoveVisualObjectWithActors( theEntry );
-          aVisualObj.reset();
-        }
+//        bool continu = false;
+//        if ( usedMB * 10 > freeMB )
+//          // even dont try to show
+//          SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"),
+//                                   QObject::tr("SMESH_NO_MESH_VISUALIZATION"));
+//        else
+//          // there is a chance to succeed
+//          continu = SUIT_MessageBox::warning
+//            (SMESHGUI::desktop(),
+//             QObject::tr("SMESH_WRN_WARNING"),
+//             QObject::tr("SMESH_CONTINUE_MESH_VISUALIZATION"),
+//             SUIT_MessageBox::Yes | SUIT_MessageBox::No,
+//             SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes;
+//        if ( !continu ) {
+//          // remove the corresponding actors from all views
+//          RemoveVisualObjectWithActors( theEntry );
+//          aVisualObj.reset();
+//        }
       }
     }
 
@@ -606,6 +610,7 @@ namespace SMESH
         }
       }
     }
+    MESSAGE("CreateActor " << anActor);
     if( anActor )
       if( SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI() )
         aSMESHGUI->addActorAsObserver( anActor );
@@ -619,6 +624,7 @@ namespace SMESH
 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
         OCC_CATCH_SIGNALS;
 #endif
+        MESSAGE("DisplayActor " << theActor);
         vtkWnd->AddActor(theActor);
         vtkWnd->Repaint();
       }
@@ -634,6 +640,7 @@ namespace SMESH
 
   void RemoveActor( SUIT_ViewWindow *theWnd, SMESH_Actor* theActor){
     if(SVTK_ViewWindow* vtkWnd = GetVtkViewWindow(theWnd)){
+       MESSAGE("RemoveActor " << theActor);
       vtkWnd->RemoveActor(theActor);
       if(theActor->hasIO()){
         Handle(SALOME_InteractiveObject) anIO = theActor->getIO();
@@ -672,6 +679,7 @@ namespace SMESH
 
   bool UpdateView(SUIT_ViewWindow *theWnd, EDisplaing theAction, const char* theEntry)
   {
+       //MESSAGE("UpdateView");
     bool OK = false;
     SVTK_ViewWindow* aViewWnd = GetVtkViewWindow(theWnd);
     if (!aViewWnd)
@@ -688,6 +696,7 @@ namespace SMESH
       case eDisplayAll: {
         while (vtkActor *anAct = aCollection->GetNextActor()) {
           if (SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)) {
+               MESSAGE("--- display " << anActor);
             anActor->SetVisibility(true);
           }
         }
@@ -695,8 +704,10 @@ namespace SMESH
       }
       case eDisplayOnly:
       case eEraseAll: {
+       //MESSAGE("---case eDisplayOnly");
         while (vtkActor *anAct = aCollection->GetNextActor()) {
           if (SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)) {
+               //MESSAGE("--- erase " << anActor);
             anActor->SetVisibility(false);
           }
         }
@@ -706,10 +717,12 @@ namespace SMESH
           switch (theAction) {
             case eDisplay:
             case eDisplayOnly:
+               //MESSAGE("--- display " << anActor);
               anActor->SetVisibility(true);
               if (theAction == eDisplayOnly) aRenderer->ResetCameraClippingRange();
               break;
             case eErase:
+               //MESSAGE("--- erase " << anActor);
               anActor->SetVisibility(false);
               break;
           }
@@ -718,6 +731,7 @@ namespace SMESH
           case eDisplay:
           case eDisplayOnly:
             {
+               //MESSAGE("---");
               SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>(theWnd->getViewManager()->study());
               _PTR(Study) aDocument = aStudy->studyDS();
               // Pass non-visual objects (hypotheses, etc.), return true in this case
@@ -746,6 +760,7 @@ namespace SMESH
 
 
   bool UpdateView(EDisplaing theAction, const char* theEntry){
+       //MESSAGE("UpdateView");
     SalomeApp_Study* aStudy = dynamic_cast< SalomeApp_Study* >( GetActiveStudy() );
     SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( aStudy->application() );
     SUIT_ViewWindow *aWnd = app->activeViewManager()->getActiveView();
@@ -784,6 +799,7 @@ namespace SMESH
 
   bool Update(const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay)
   {
+       MESSAGE("Update");
     _PTR(Study) aStudy = GetActiveStudyDocument();
     CORBA::Long anId = aStudy->StudyId();
     if ( TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,theIO->getEntry())) {
@@ -794,6 +810,18 @@ namespace SMESH
     return false;
   }
 
+  bool UpdateNulData(const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay)
+  {
+       MESSAGE("UpdateNulData");
+    _PTR(Study) aStudy = GetActiveStudyDocument();
+    CORBA::Long anId = aStudy->StudyId();
+    if ( TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,theIO->getEntry(), true)) {
+      if ( theDisplay )
+        UpdateView(SMESH::eDisplay,theIO->getEntry());
+      return true;
+    }
+    return false;
+  }
 
   void UpdateSelectionProp( SMESHGUI* theModule ) {
     if( !theModule )
index 5a9b09c25eccb9a48040e389f2a991a22032d0ad..712e33a054fb3ce7bf9407b670e6cba5f1fcdb62 100644 (file)
@@ -65,7 +65,7 @@ namespace SMESH
   typedef std::pair<int,std::string> TKeyOfVisualObj;
   
 SMESHGUI_EXPORT
-  TVisualObjPtr GetVisualObj( int, const char* );
+  TVisualObjPtr GetVisualObj( int, const char*, bool nulData =false );
 SMESHGUI_EXPORT
   void OnVisuException(); // PAL16631
 
@@ -122,7 +122,10 @@ SMESHGUI_EXPORT
   void UpdateView();
 
 SMESHGUI_EXPORT
-  bool Update( const Handle(SALOME_InteractiveObject)&, bool );
+  bool UpdateNulData( const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay);
+
+SMESHGUI_EXPORT
+  bool Update( const Handle(SALOME_InteractiveObject)& theIO, bool theDisplay);
 
   //----------------------------------------------------------------------------
 SMESHGUI_EXPORT  
index 53f2855287fc93c18661d779da406f69fe69eb58..32c44b368a1fc411d5abf2a171585aa0263d1244 100644 (file)
@@ -92,6 +92,7 @@ libSMESHEngine_la_CPPFLAGS = \
        $(CORBA_INCLUDES) \
        $(CAS_CPPFLAGS) \
        @HDF5_INCLUDES@ \
+        $(VTK_INCLUDES) \
        $(BOOST_CPPFLAGS) \
        $(KERNEL_CXXFLAGS) \
        $(GUI_CXXFLAGS) \
@@ -108,6 +109,7 @@ libSMESHEngine_la_CPPFLAGS = \
 libSMESHEngine_la_LDFLAGS  = \
        ../../idl/libSalomeIDLSMESH.la \
        ../SMESH/libSMESHimpl.la \
+       ../SMDS/libSMDS.la \
        ../Controls/libSMESHControls.la \
        $(KERNEL_LDFLAGS) \
        -lSalomeContainer \
index a0ce885aa9b82da691eb9324039d8106acf82db3..47e0fad99c6b3408bb26a257707cc5cd3bebdc29 100644 (file)
 
 #include "GEOM_Client.hxx"
 #include "Utils_ExceptHandlers.hxx"
+#include "memoire.h"
 #include "Basics_Utils.hxx"
 
 #include <map>
@@ -484,6 +485,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::createMesh()
     // create a new mesh object servant, store it in a map in study context
     SMESH_Mesh_i* meshServant = new SMESH_Mesh_i( GetPOA(), this, GetCurrentStudyID() );
     // create a new mesh object
+    MESSAGE("myIsEmbeddedMode " << myIsEmbeddedMode);
     meshServant->SetImpl( myGen.CreateMesh( GetCurrentStudyID(), myIsEmbeddedMode ));
 
     // activate the CORBA servant of Mesh
@@ -541,6 +543,7 @@ void SMESH_Gen_i::SetGeomEngine( GEOM::GEOM_Gen_ptr geomcompo )
 void SMESH_Gen_i::SetEmbeddedMode( CORBA::Boolean theMode )
 {
   myIsEmbeddedMode = theMode;
+  MESSAGE("myIsEmbeddedMode " << myIsEmbeddedMode);
 
   if ( !myIsEmbeddedMode ) {
     //PAL10867: disable signals catching with "noexcepthandler" option
@@ -900,6 +903,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName
   // Dump creation of groups
   aServant->GetGroups();
 
+  aServant->GetImpl().GetMeshDS()->Modified();
   return aMesh._retn();
 }
 
@@ -968,6 +972,7 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName,
         theStatus = status1;
 
       aResult[i++] = SMESH::SMESH_Mesh::_duplicate( mesh );
+      meshServant->GetImpl().GetMeshDS()->Modified();
     }
     aStudyBuilder->CommitCommand();
   }
@@ -1014,6 +1019,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName
   SMESH_Mesh_i* aServant = dynamic_cast<SMESH_Mesh_i*>( GetServant( aMesh ).in() );
   ASSERT( aServant );
   aServant->ImportSTLFile( theFileName );
+  aServant->GetImpl().GetMeshDS()->Modified();
   return aMesh._retn();
 }
 
@@ -1396,6 +1402,7 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
                                      GEOM::GEOM_Object_ptr theShapeObject )
      throw ( SALOME::SALOME_Exception )
 {
+  MEMOSTAT;
   Unexpect aCatch(SALOME_SalomeException);
   if(MYDEBUG) MESSAGE( "SMESH_Gen_i::Compute" );
 
@@ -1428,6 +1435,7 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh,
       ::SMESH_Mesh& myLocMesh = meshServant->GetImpl();
       bool ok = myGen.Compute( myLocMesh, myLocShape);
       meshServant->CreateGroupServants(); // algos can create groups (issue 0020918)
+      myLocMesh.GetMeshDS()->Modified();
       return ok;
     }
   }
@@ -1917,11 +1925,12 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
   // create mesh
   SMESH::SMESH_Mesh_var aNewMesh = CreateEmptyMesh();
   
+  SMESHDS_Mesh* aNewMeshDS = 0;
   if ( !aNewMesh->_is_nil() ) {
     SMESH_Mesh_i* aNewImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( aNewMesh ).in() );
     if ( aNewImpl ) {
       ::SMESH_Mesh& aLocMesh = aNewImpl->GetImpl();
-      SMESHDS_Mesh* aNewMeshDS = aLocMesh.GetMeshDS();
+      aNewMeshDS = aLocMesh.GetMeshDS();
 
       TGroupsMap aGroupsMap;
       TListOfNewGroups aListOfNewGroups;
@@ -1990,11 +1999,11 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
               // creates a corresponding element on existent nodes in new mesh
               if ( anElem->IsPoly() && anElemType == SMDSAbs_Volume )
                 {
-                  const SMDS_PolyhedralVolumeOfNodes* aVolume =
-                    dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem);
+                  const SMDS_VtkVolume* aVolume =
+                    dynamic_cast<const SMDS_VtkVolume*> (anElem);
                   if ( aVolume ) {
                     aNewElem = aNewMeshDS->AddPolyhedralVolume(aNodesArray, 
-                                                               aVolume->GetQuanities());
+                                                               aVolume->GetQuantities());
                     elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
                     if( theCommonGroups )
                       anIDsVolumes[anNbVolumes++] = aNewElem->GetID();
@@ -2197,7 +2206,8 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
     SALOMEDS::AttributePixMap_var aPixmap = SALOMEDS::AttributePixMap::_narrow(anAttr);
     aPixmap->SetPixMap("ICON_SMESH_TREE_MESH");
   }
-
+  if (aNewMeshDS)
+    aNewMeshDS->Modified();
   return aNewMesh._retn();
 }
 
@@ -3132,7 +3142,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                       const SMDS_PositionPtr pos = node->GetPosition();
                       if ( onFace ) { // on FACE
                         const SMDS_FacePosition* fPos =
-                          dynamic_cast<const SMDS_FacePosition*>( pos.get() );
+                          dynamic_cast<const SMDS_FacePosition*>( pos );
                         if ( fPos ) {
                           aUPos[ iNode ] = fPos->GetUParameter();
                           aVPos[ iNode ] = fPos->GetVParameter();
@@ -3143,7 +3153,7 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent,
                       }
                       else { // on EDGE
                         const SMDS_EdgePosition* ePos =
-                          dynamic_cast<const SMDS_EdgePosition*>( pos.get() );
+                          dynamic_cast<const SMDS_EdgePosition*>( pos );
                         if ( ePos ) {
                           aUPos[ iNode ] = ePos->GetUParameter();
                           iNode++;
@@ -4043,7 +4053,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                 // add
                 if ( isNode ) {
                   SMDS_PositionPtr pos = aPositionCreator.MakePosition( smType[ smID ]);
-                  pos->SetShapeId( smID );
                   SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>( static_cast<const SMDS_MeshNode*>( elem ));
                   node->SetPosition( pos );
                   sm->AddNode( node );
@@ -4147,7 +4156,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                 // not fixed bugs in SMDS_MeshInfo
                 if ( aPos->GetTypeOfPosition() == SMDS_TOP_FACE ) {
                   SMDS_FacePosition* fPos = const_cast<SMDS_FacePosition*>
-                    ( static_cast<const SMDS_FacePosition*>( aPos.get() ));
+                    ( static_cast<const SMDS_FacePosition*>( aPos ));
                   fPos->SetUParameter( aUPos[ iNode ]);
                   fPos->SetVParameter( aVPos[ iNode ]);
                 }
@@ -4156,7 +4165,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                 // ASSERT( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE );-- issue 20182
                 if ( aPos->GetTypeOfPosition() == SMDS_TOP_EDGE ) {
                   SMDS_EdgePosition* fPos = const_cast<SMDS_EdgePosition*>
-                    ( static_cast<const SMDS_EdgePosition*>( aPos.get() ));
+                    ( static_cast<const SMDS_EdgePosition*>( aPos ));
                   fPos->SetUParameter( aUPos[ iNode ]);
                 }
               }
index d442601d597f747ae8c01a51930eba581c1825e6..d6185e1078a877d377fd1eafbf3e1d0abd4de411 100644 (file)
@@ -32,7 +32,7 @@
 #include "SMESH_MeshEditor_i.hxx"
 
 #include "SMDS_Mesh0DElement.hxx"
-#include "SMDS_MeshEdge.hxx"
+#include "SMDS_LinearEdge.hxx"
 #include "SMDS_MeshFace.hxx"
 #include "SMDS_MeshVolume.hxx"
 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
@@ -134,11 +134,11 @@ namespace {
       SMDS_MeshElement* anElemCopy = 0;
       if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
       {
-        const SMDS_PolyhedralVolumeOfNodes* ph =
-          dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem);
+        const SMDS_VtkVolume* ph =
+          dynamic_cast<const SMDS_VtkVolume*> (anElem);
         if ( ph )
           anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
-            (anElemNodesID, ph->GetQuanities(),anElem->GetID());
+            (anElemNodesID, ph->GetQuantities(),anElem->GetID());
       }
       else {
         anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
@@ -416,11 +416,12 @@ SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
   // Update Python script
   TPythonDump() << "isDone = " << this << ".RemoveElements( " << IDsOfElements << " )";
 
+  // Remove Elements
+  bool ret = anEditor.Remove( IdList, false );
+  myMesh->GetMeshDS()->Modified();
   if ( IDsOfElements.length() )
     myMesh->SetIsModified( true ); // issue 0020693
-
-  // Remove Elements
-  return anEditor.Remove( IdList, false );
+  return ret;
 }
 
 //=============================================================================
@@ -441,10 +442,11 @@ CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNo
   // Update Python script
   TPythonDump() << "isDone = " << this << ".RemoveNodes( " << IDsOfNodes << " )";
 
+  bool ret = anEditor.Remove( IdList, true );
+  myMesh->GetMeshDS()->Modified();
   if ( IDsOfNodes.length() )
     myMesh->SetIsModified( true ); // issue 0020693
-
-  return anEditor.Remove( IdList, true );
+  return ret;
 }
 
 //=============================================================================
@@ -495,8 +497,8 @@ CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
   TPythonDump() << "nodeID = " << this << ".AddNode( "
                 << x << ", " << y << ", " << z << " )";
 
+  myMesh->GetMeshDS()->Modified();
   myMesh->SetIsModified( true ); // issue 0020693
-
   return N->GetID();
 }
 
@@ -515,6 +517,7 @@ CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
   // Update Python script
   TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
 
+  myMesh->GetMeshDS()->Modified();
   myMesh->SetIsModified( true ); // issue 0020693
 
   if (elem)
@@ -557,6 +560,7 @@ CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
                   <<n1<<", "<<n2<<", "<<n12<<" ])";
   }
 
+  myMesh->GetMeshDS()->Modified();
   if(elem)
     return myMesh->SetIsModified( true ), elem->GetID();
 
@@ -605,6 +609,7 @@ CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
   // Update Python script
   TPythonDump() << "faceID = " << this << ".AddFace( " << IDsOfNodes << " )";
 
+  myMesh->GetMeshDS()->Modified();
   if(elem)
     return myMesh->SetIsModified( true ), elem->GetID();
 
@@ -630,6 +635,7 @@ CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsO
   // Update Python script
   TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
 
+  myMesh->GetMeshDS()->Modified();
   return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
 }
 
@@ -673,6 +679,7 @@ CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
   // Update Python script
   TPythonDump() << "volID = " << this << ".AddVolume( " << IDsOfNodes << " )";
 
+  myMesh->GetMeshDS()->Modified();
   if(elem)
     return myMesh->SetIsModified( true ), elem->GetID();
 
@@ -692,7 +699,11 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & I
   int NbNodes = IDsOfNodes.length();
   std::vector<const SMDS_MeshNode*> n (NbNodes);
   for (int i = 0; i < NbNodes; i++)
-    n[i] = GetMeshDS()->FindNode(IDsOfNodes[i]);
+    {
+      const SMDS_MeshNode* aNode = GetMeshDS()->FindNode(IDsOfNodes[i]);
+      if (!aNode) return 0;
+      n[i] = aNode;
+    }
 
   int NbFaces = Quantities.length();
   std::vector<int> q (NbFaces);
@@ -704,6 +715,7 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume (const SMESH::long_array & I
   // Update Python script
   TPythonDump() << "volID = " << this << ".AddPolyhedralVolume( "
                 << IDsOfNodes << ", " << Quantities << " )";
+  myMesh->GetMeshDS()->Modified();
 
   return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
 }
@@ -736,6 +748,7 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_ar
   // Update Python script
   TPythonDump() << "volID = " << this << ".AddPolyhedralVolumeByFaces( "
                 << IdsOfFaces << " )";
+  myMesh->GetMeshDS()->Modified();
 
   return elem ? ( myMesh->SetIsModified( true ), elem->GetID()) : 0;
 }
@@ -856,7 +869,6 @@ void SMESH_MeshEditor_i::SetNodeOnFace(CORBA::Long NodeID, CORBA::Long FaceID,
   }
 
   mesh->SetNodeOnFace( node, FaceID, u, v );
-
   myMesh->SetIsModified( true );
 }
 
@@ -947,10 +959,12 @@ CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
   TPythonDump() << "isDone = " << this << ".InverseDiag( "
                 << NodeID1 << ", " << NodeID2 << " )";
 
-  myMesh->SetIsModified( true );
 
   ::SMESH_MeshEditor aMeshEditor( myMesh );
-  return aMeshEditor.InverseDiag ( n1, n2 );
+  int ret =  aMeshEditor.InverseDiag ( n1, n2 );
+  myMesh->GetMeshDS()->Modified();
+  myMesh->SetIsModified( true );
+  return ret;
 }
 
 //=============================================================================
@@ -977,6 +991,7 @@ CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
 
   bool stat = aMeshEditor.DeleteDiag ( n1, n2 );
 
+  myMesh->GetMeshDS()->Modified();
   if ( stat )
     myMesh->SetIsModified( true ); // issue 0020693
     
@@ -1006,6 +1021,7 @@ CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfEleme
   // Update Python script
   TPythonDump() << "isDone = " << this << ".Reorient( " << IDsOfElements << " )";
 
+  myMesh->GetMeshDS()->Modified();
   if ( IDsOfElements.length() )
     myMesh->SetIsModified( true ); // issue 0020693
 
@@ -1064,6 +1080,7 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array &   IDsOfE
   ::SMESH_MeshEditor anEditor( myMesh );
 
   bool stat = anEditor.TriToQuad( faces, aCrit, MaxAngle );
+  myMesh->GetMeshDS()->Modified();
   if ( stat )
     myMesh->SetIsModified( true ); // issue 0020693
 
@@ -1127,6 +1144,7 @@ CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array &   IDsOfE
 
   ::SMESH_MeshEditor anEditor( myMesh );
   CORBA::Boolean stat = anEditor.QuadToTri( faces, aCrit );
+  myMesh->GetMeshDS()->Modified();
   if ( stat )
     myMesh->SetIsModified( true ); // issue 0020693
 
@@ -1181,6 +1199,7 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfEle
 
   ::SMESH_MeshEditor anEditor( myMesh );
   CORBA::Boolean stat = anEditor.QuadToTri( faces, Diag13 );
+  myMesh->GetMeshDS()->Modified();
   if ( stat )
     myMesh->SetIsModified( true ); // issue 0020693
 
@@ -1261,6 +1280,7 @@ void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems,
   
   ::SMESH_MeshEditor anEditor (myMesh);
   anEditor.SplitVolumesIntoTetra( elemSet, int( methodFlags ));
+  myMesh->GetMeshDS()->Modified();
 
   storeResult(anEditor);
 
@@ -1375,6 +1395,7 @@ SMESH_MeshEditor_i::smooth(const SMESH::long_array &              IDsOfElements,
   anEditor.Smooth(elements, fixedNodes, method,
                   MaxNbOfIterations, MaxAspectRatio, IsParametric );
 
+  myMesh->GetMeshDS()->Modified();
   myMesh->SetIsModified( true ); // issue 0020693
 
   storeResult(anEditor);
@@ -1514,6 +1535,7 @@ SMESH_MeshEditor_i::rotationSweep(const SMESH::long_array & theIDsOfElements,
       anEditor.RotationSweep (*workElements, Ax1, theAngleInRadians,
                               theNbOfSteps, theTolerance, theMakeGroups, makeWalls);
   storeResult(anEditor);
+  myMesh->GetMeshDS()->Modified();
 
   //  myMesh->SetIsModified( true ); -- it does not influence Compute()
 
@@ -1792,6 +1814,7 @@ SMESH_MeshEditor_i::extrusionSweep(const SMESH::long_array & theIDsOfElements,
     ::SMESH_MeshEditor::PGroupIDs groupIds =
         anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory, theMakeGroups);
 
+    myMesh->GetMeshDS()->Modified();
     storeResult(anEditor);
 
     return theMakeGroups ? getGroups(groupIds.get()) : 0;
@@ -2090,6 +2113,7 @@ SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array &   theIDsOfEleme
                                        SMESH::SMESH_MeshEditor::Extrusion_Error & theError,
                                        const SMDSAbs_ElementType   theElementType)
 {
+  MESSAGE("extrusionAlongPath");
   initData();
 
   if ( thePathMesh->_is_nil() || thePathShape->_is_nil() ) {
@@ -2129,6 +2153,7 @@ SMESH_MeshEditor_i::extrusionAlongPath(const SMESH::long_array &   theIDsOfEleme
       anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
                                     theHasAngles, angles, false,
                                     theHasRefPoint, refPnt, theMakeGroups );
+  myMesh->GetMeshDS()->Modified();
   storeResult(anEditor);
   theError = convExtrError( error );
 
@@ -2195,6 +2220,7 @@ SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array &  IDsOfElements
     error = anEditor.ExtrusionAlongTrack( elements, &(aMeshImp->GetImpl()), aNodeStart,
                                           HasAngles, angles, LinearVariation,
                                           HasRefPoint, refPnt, MakeGroups );
+    myMesh->GetMeshDS()->Modified();
   }
   else {
     SMESH_subMesh_i* aSubMeshImp = SMESH::DownCast<SMESH_subMesh_i*>( Path );
@@ -2213,6 +2239,7 @@ SMESH_MeshEditor_i::extrusionAlongPathX(const SMESH::long_array &  IDsOfElements
       error = anEditor.ExtrusionAlongTrack( elements, aSubMesh, aNodeStart,
                                             HasAngles, angles, LinearVariation,
                                             HasRefPoint, refPnt, MakeGroups );
+      myMesh->GetMeshDS()->Modified();
     }
     else {
       SMESH_Group_i* aGroupImp = SMESH::DownCast<SMESH_Group_i*>( Path );
@@ -2256,6 +2283,7 @@ SMESH_MeshEditor_i::ExtrusionAlongPath(const SMESH::long_array &   theIDsOfEleme
                                        CORBA::Boolean              theHasRefPoint,
                                        const SMESH::PointStruct &  theRefPoint)
 {
+  MESSAGE("ExtrusionAlongPath");
   if ( !myPreviewMode ) {
     TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
                   << theIDsOfElements << ", "
@@ -2867,7 +2895,10 @@ SMESH_MeshEditor_i::mirror(TIDSortedElemSet &                  theElements,
   if(theCopy)
     storeResult(anEditor);
   else
-    myMesh->SetIsModified( true );
+    {
+      myMesh->GetMeshDS()->Modified();
+      myMesh->SetIsModified( true );
+    }
 
   return theMakeGroups ? getGroups(groupIds.get()) : 0;
 }
@@ -3093,7 +3124,10 @@ SMESH_MeshEditor_i::translate(TIDSortedElemSet        & theElements,
   if(theCopy)
     storeResult(anEditor);
   else
-    myMesh->SetIsModified( true );
+    {
+      myMesh->GetMeshDS()->Modified();
+      myMesh->SetIsModified( true );
+    }
 
   return theMakeGroups ? getGroups(groupIds.get()) : 0;
 }
@@ -3309,7 +3343,10 @@ SMESH_MeshEditor_i::rotate(TIDSortedElemSet &        theElements,
   if(theCopy) 
     storeResult(anEditor);
   else
-    myMesh->SetIsModified( true );
+    {
+      myMesh->GetMeshDS()->Modified();
+      myMesh->SetIsModified( true );
+    }
 
   return theMakeGroups ? getGroups(groupIds.get()) : 0;
 }
@@ -3550,8 +3587,10 @@ SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr  theObject,
   if(theCopy)
     storeResult(anEditor);
   else
-    myMesh->SetIsModified( true );
-
+    {
+      myMesh->GetMeshDS()->Modified();
+      myMesh->SetIsModified( true );
+    }
   return theMakeGroups ? getGroups(groupIds.get()) : 0;
 }
 
@@ -3796,7 +3835,7 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN
   anEditor.MergeNodes( aListOfListOfNodes );
 
   aTPythonDump <<  "])";
-
+  myMesh->GetMeshDS()->Modified();
   myMesh->SetIsModified( true );
 }
 
@@ -3878,7 +3917,7 @@ void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsO
 
   ::SMESH_MeshEditor anEditor( myMesh );
   anEditor.MergeElements(aListOfListOfElementsID);
-
+  myMesh->GetMeshDS()->Modified();
   myMesh->SetIsModified( true );
 
   aTPythonDump << "] )";
@@ -3926,15 +3965,15 @@ CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long   NodeID,
     TIDSortedElemSet linkedNodes;
     ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
     TIDSortedElemSet::iterator nIt = linkedNodes.begin();
+    SMDS_MeshNode *nodeCpy1 = tmpMesh.Copy(node);
     for ( ; nIt != linkedNodes.end(); ++nIt )
     {
-      SMDS_MeshEdge edge( node, cast2Node( *nIt ));
-      tmpMesh.Copy( &edge );
+      SMDS_MeshNode *nodeCpy2 = tmpMesh.Copy ( cast2Node( *nIt ));
+      tmpMesh.GetMeshDS()->AddEdge(nodeCpy1, nodeCpy2);
     }
     // move copied node
-    node = tmpMesh.GetMeshDS()->FindNode( NodeID );
-    if ( node )
-      tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
+    if ( nodeCpy1 )
+      tmpMesh.GetMeshDS()->MoveNode(nodeCpy1, x, y, z);
     // fill preview data
     ::SMESH_MeshEditor anEditor( & tmpMesh );
     storeResult( anEditor );
@@ -3949,7 +3988,7 @@ CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long   NodeID,
     // Update Python script
     TPythonDump() << "isDone = " << this << ".MoveNode( "
                   << NodeID << ", " << x << ", " << y << ", " << z << " )";
-
+    myMesh->GetMeshDS()->Modified();
     myMesh->SetIsModified( true );
   }
 
@@ -4021,7 +4060,7 @@ CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
       TIDSortedElemSet::iterator nIt = linkedNodes.begin();
       for ( ; nIt != linkedNodes.end(); ++nIt )
       {
-        SMDS_MeshEdge edge( node, cast2Node( *nIt ));
+        SMDS_LinearEdge edge( node, cast2Node( *nIt ));
         tmpMesh.Copy( &edge );
       }
       // move copied node
@@ -4048,6 +4087,7 @@ CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
                   << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z
                   << ", " << nodeID << " )";
 
+    myMesh->GetMeshDS()->Modified();
     myMesh->SetIsModified( true );
   }
 
@@ -4193,6 +4233,7 @@ SMESH_MeshEditor_i::SewFreeBorders(CORBA::Long FirstNodeID1,
 
   storeResult(anEditor);
 
+  myMesh->GetMeshDS()->Modified();
   myMesh->SetIsModified( true );
 
   return error;
@@ -4250,6 +4291,7 @@ SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
 
   storeResult(anEditor);
 
+  myMesh->GetMeshDS()->Modified();
   myMesh->SetIsModified( true );
 
   return error;
@@ -4312,6 +4354,7 @@ SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
 
   storeResult(anEditor);
 
+  myMesh->GetMeshDS()->Modified();
   myMesh->SetIsModified( true );
 
   return error;
@@ -4369,6 +4412,7 @@ SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
 
   storeResult(anEditor);
 
+  myMesh->GetMeshDS()->Modified();
   myMesh->SetIsModified( true );
 
   return error;
@@ -4405,8 +4449,10 @@ CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
   TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
                 << ide << ", " << newIDs << " )";
 
+  MESSAGE("ChangeElementNodes");
   bool res = GetMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
 
+  myMesh->GetMeshDS()->Modified();
   if ( res )
     myMesh->SetIsModified( true );
 
@@ -4558,6 +4604,7 @@ void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
   ::SMESH_MeshEditor anEditor( myMesh );
   anEditor.ConvertToQuadratic(theForce3d);
   TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
+  myMesh->GetMeshDS()->Modified();
   myMesh->SetIsModified( true );
 }
 
@@ -4571,6 +4618,7 @@ CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
   ::SMESH_MeshEditor anEditor( myMesh );
   CORBA::Boolean isDone = anEditor.ConvertFromQuadratic();
   TPythonDump() << this << ".ConvertFromQuadratic()";
+  myMesh->GetMeshDS()->Modified();
   if ( isDone )
     myMesh->SetIsModified( true );
   return isDone;
@@ -4675,6 +4723,7 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNode
 
   bool aResult = aMeshEditor.DoubleNodes( aListOfNodes, aListOfElems );
 
+  myMesh->GetMeshDS()->Modified();
   storeResult( aMeshEditor) ;
   if ( aResult )
     myMesh->SetIsModified( true );
@@ -4843,6 +4892,7 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& t
 
   storeResult( aMeshEditor) ;
 
+  myMesh->GetMeshDS()->Modified();
   if ( aResult )
     myMesh->SetIsModified( true );
 
@@ -4884,6 +4934,7 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theE
 
   storeResult( aMeshEditor) ;
 
+  myMesh->GetMeshDS()->Modified();
   if ( aResult )
     myMesh->SetIsModified( true );
 
@@ -4926,6 +4977,7 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_ar
 
   storeResult( aMeshEditor) ;
 
+  myMesh->GetMeshDS()->Modified();
   if ( aResult )
     myMesh->SetIsModified( true );
 
@@ -4968,6 +5020,7 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_pt
 
   storeResult( aMeshEditor) ;
 
+  myMesh->GetMeshDS()->Modified();
   if ( aResult )
     myMesh->SetIsModified( true );
 
@@ -5066,6 +5119,7 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_Grou
 
   storeResult( aMeshEditor) ;
 
+  myMesh->GetMeshDS()->Modified();
   if ( aResult )
     myMesh->SetIsModified( true );
 
@@ -5123,6 +5177,7 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroup
 
   storeResult( aMeshEditor) ;
 
+  myMesh->GetMeshDS()->Modified();
   if ( aResult )
     myMesh->SetIsModified( true );
 
@@ -5165,6 +5220,7 @@ SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theE
 
   storeResult( aMeshEditor) ;
 
+  myMesh->GetMeshDS()->Modified();
   if ( aResult )
     myMesh->SetIsModified( true );
 
@@ -5189,11 +5245,60 @@ CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D()
   ::SMESH_MeshEditor aMeshEditor( myMesh );
   bool aResult = aMeshEditor.Make2DMeshFrom3D();
   storeResult( aMeshEditor) ;
-
+  myMesh->GetMeshDS()->Modified();
   TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()";
   return aResult;
 }
 
+//================================================================================
+/*!
+ * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
+ * The list of groups must describe a partition of the mesh volumes.
+ * The nodes of the internal faces at the boundaries of the groups are doubled.
+ * In option, the internal faces are replaced by flat elements.
+ * Triangles are transformed in prisms, and quadrangles in hexahedrons.
+ * @param theDomains - list of groups of volumes
+ * @param createJointElems - if TRUE, create the elements
+ * @return TRUE if operation has been completed successfully, FALSE otherwise
+ */
+//================================================================================
+
+CORBA::Boolean SMESH_MeshEditor_i::DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
+                                                                 CORBA::Boolean createJointElems )
+{
+  initData();
+
+  ::SMESH_MeshEditor aMeshEditor( myMesh );
+
+  SMESHDS_Mesh* aMeshDS = GetMeshDS();
+
+  vector<TIDSortedElemSet> domains;
+  domains.clear();
+
+  for ( int i = 0, n = theDomains.length(); i < n; i++ )
+  {
+    SMESH::SMESH_GroupBase_var aGrp = theDomains[ i ];
+    if ( !CORBA::is_nil( aGrp ) && ( aGrp->GetType() != SMESH::NODE ) )
+    {
+      TIDSortedElemSet domain;
+      domain.clear();
+      domains.push_back(domain);
+      SMESH::long_array_var anIDs = aGrp->GetIDs();
+      arrayToSet( anIDs, aMeshDS, domains[ i ], SMDSAbs_All );
+    }
+  }
+
+  bool aResult = aMeshEditor.DoubleNodesOnGroupBoundaries( domains, createJointElems );
+
+  storeResult( aMeshEditor) ;
+  myMesh->GetMeshDS()->Modified();
+
+  // Update Python script
+  TPythonDump() << "isDone = " << this << ".DoubleNodesOnGroupBoundaries( " << &theDomains
+      << ", " << createJointElems << " )";
+  return aResult;
+}
+
 // issue 20749 ===================================================================
 /*!
  * \brief Creates missing boundary elements
index 3a96b87cdf8056c5afd8cbbe5704cbeed3327d3e..e90fe857eca44396a104d03fc362d1f90810bb95 100644 (file)
@@ -686,6 +686,20 @@ public:
                                          CORBA::Boolean            toCopyMissingBondary,
                                          SMESH::SMESH_Group_out    group);
 
+    /*!
+     * \brief Double nodes on shared faces between groups of volumes and create flat elements on demand.
+     * The list of groups must describe a partition of the mesh volumes.
+     * The nodes of the internal faces at the boundaries of the groups are doubled.
+     * In option, the internal faces are replaced by flat elements.
+     * Triangles are transformed in prisms, and quadrangles in hexahedrons.
+     * @param theDomains - list of groups of volumes
+     * @param createJointElems - if TRUE, create the elements
+     * @return TRUE if operation has been completed successfully, FALSE otherwise
+     */
+  CORBA::Boolean DoubleNodesOnGroupBoundaries( const SMESH::ListOfGroups& theDomains,
+                                               CORBA::Boolean createJointElems );
+
+
 private: //!< private methods
 
   SMESHDS_Mesh * GetMeshDS() { return myMesh->GetMeshDS(); }
index c3be622ae71d0608e1796a3b5957f6c297dd7667..1733a315eeaacb11721b63ef43917214c1870a7b 100644 (file)
@@ -1007,7 +1007,7 @@ throw (SALOME::SALOME_Exception)
 
   try
   {
-    NCollection_Map< int > anIds;
+    vector< int > anIds;
     SMESH::ElementType aType = SMESH::ALL;
     for ( int g = 0, n = theGroups.length(); g < n; g++ )
     {
@@ -1030,7 +1030,7 @@ throw (SALOME::SALOME_Exception)
       for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
       {
         int aCurrId = aCurrIds[ i ];
-        anIds.Add( aCurrId );
+        anIds.push_back( aCurrId );
       }
     }
 
@@ -1041,12 +1041,12 @@ throw (SALOME::SALOME_Exception)
     
     // Create array of identifiers
     SMESH::long_array_var aResIds = new SMESH::long_array;
-    aResIds->length( anIds.Extent() );
+    aResIds->length( anIds.size() );
     
-    NCollection_Map< int >::Iterator anIter( anIds );
-    for ( int i = 0; anIter.More(); anIter.Next(), i++ )
+    //NCollection_Map< int >::Iterator anIter( anIds );
+    for ( int i = 0; i<anIds.size(); i++ )
     {
-      aResIds[ i ] = anIter.Value();
+      aResIds[ i ] = anIds[i];
     }
     aResGrp->Add( aResIds );
 
@@ -1172,14 +1172,14 @@ throw (SALOME::SALOME_Exception)
     
     // create map of ids
     int nbGrp = theGroups.length();
-    NCollection_Map< int > anIds;
+    vector< int > anIds;
     NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
     for ( ; anIter.More(); anIter.Next() )
     {
       int aCurrId = anIter.Key();
       int aCurrNb = anIter.Value();
       if ( aCurrNb == nbGrp )
-        anIds.Add( aCurrId );
+        anIds.push_back( aCurrId );
     }
 
     // Create group
@@ -1189,12 +1189,12 @@ throw (SALOME::SALOME_Exception)
     
     // Create array of identifiers
     SMESH::long_array_var aResIds = new SMESH::long_array;
-    aResIds->length( anIds.Extent() );
+    aResIds->length( anIds.size() );
     
-    NCollection_Map< int >::Iterator aListIter( anIds );
-    for ( int i = 0; aListIter.More(); aListIter.Next(), i++ )
+    //NCollection_Map< int >::Iterator aListIter( anIds );
+    for ( int i = 0; i<anIds.size(); i++ )
     {
-      aResIds[ i ] = aListIter.Value();
+      aResIds[ i ] = anIds[i];
     }
     aResGrp->Add( aResIds );
 
@@ -1291,7 +1291,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
 
   try
   {
-    NCollection_Map< int > aToolIds;
+    set< int > aToolIds;
     SMESH::ElementType aType = SMESH::ALL;
     int g, n;
     // iterate through tool groups
@@ -1316,11 +1316,11 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
       for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
       {
         int aCurrId = aCurrIds[ i ];
-        aToolIds.Add( aCurrId );
+        aToolIds.insert( aCurrId );
       }
     }
 
-    NCollection_Map< int > anIds; // result
+    vector< int > anIds; // result
 
     // Iterate through main group 
     for ( g = 0, n = theMainGroups.length(); g < n; g++ )
@@ -1344,8 +1344,8 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
       for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
       {
         int aCurrId = aCurrIds[ i ];
-        if ( !aToolIds.Contains( aCurrId ) )
-          anIds.Add( aCurrId );
+        if ( !aToolIds.count( aCurrId ) )
+          anIds.push_back( aCurrId );
       }
     }
 
@@ -1356,12 +1356,11 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
     
     // Create array of identifiers
     SMESH::long_array_var aResIds = new SMESH::long_array;
-    aResIds->length( anIds.Extent() );
+    aResIds->length( anIds.size() );
     
-    NCollection_Map< int >::Iterator anIter( anIds );
-    for ( int i = 0; anIter.More(); anIter.Next(), i++ )
+    for (int i=0; i<anIds.size(); i++ )
     {
-      aResIds[ i ] = anIter.Value();
+      aResIds[ i ] = anIds[i];
     }
     aResGrp->Add( aResIds );
 
@@ -1413,7 +1412,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
   {
     // Create map of nodes from all groups 
 
-    NCollection_Map< int > aNodeMap;
+    set< int > aNodeMap;
     
     for ( int g = 0, n = theGroups.length(); g < n; g++ )
     {
@@ -1432,7 +1431,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
           int aCurrId = aCurrIds[ i ];
           const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
           if ( aNode )
-            aNodeMap.Add( aNode->GetID() );
+            aNodeMap.insert( aNode->GetID() );
         }
       }
       else 
@@ -1450,7 +1449,7 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
             const SMDS_MeshNode* aNode = 
               dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
             if ( aNode )
-              aNodeMap.Add( aNode->GetID() );
+              aNodeMap.insert( aNode->GetID() );
           }
         }
       }
@@ -1458,22 +1457,25 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
 
     // Get result identifiers 
 
-    NCollection_Map< int > aResultIds;
+    vector< int > aResultIds;
     if ( theElemType == SMESH::NODE )
     {
-      NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
-      for ( ; aNodeIter.More(); aNodeIter.Next() )
-        aResultIds.Add( aNodeIter.Value() );
+      //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
+      set<int>::iterator iter = aNodeMap.begin();
+      for ( ; iter != aNodeMap.end(); iter++ )
+        aResultIds.push_back( *iter);
     }
     else
     {
       // Create list of elements of given dimension constructed on the nodes
-      NCollection_Map< int > anElemList;
-      NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
-      for ( ; aNodeIter.More(); aNodeIter.Next() )
+      vector< int > anElemList;
+      //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
+      //for ( ; aNodeIter.More(); aNodeIter.Next() )
+      set<int>::iterator iter = aNodeMap.begin();
+      for ( ; iter != aNodeMap.end(); iter++ )
       {
         const SMDS_MeshElement* aNode = 
-          dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( aNodeIter.Value() ) );
+          dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( *iter ) );
         if ( !aNode )
           continue;
 
@@ -1483,15 +1485,16 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
           const SMDS_MeshElement* anElem = 
             dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
           if ( anElem && anElem->GetType() == anElemType )
-            anElemList.Add( anElem->GetID() );
+            anElemList.push_back( anElem->GetID() );
         }
       }
 
       // check whether all nodes of elements are present in nodes map
-      NCollection_Map< int >::Iterator anIter( anElemList );
-      for ( ; anIter.More(); anIter.Next() )
+      //NCollection_Map< int >::Iterator anIter( anElemList );
+      //for ( ; anIter.More(); anIter.Next() )
+      for (int i=0; i< anElemList.size(); i++)
       {
-        const SMDS_MeshElement* anElem = aMeshDS->FindElement( anIter.Value() );
+        const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] );
         if ( !anElem )
           continue;
 
@@ -1501,14 +1504,14 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
         {
           const SMDS_MeshNode* aNode = 
             dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
-          if ( !aNode || !aNodeMap.Contains( aNode->GetID() ) )
+          if ( !aNode || !aNodeMap.count( aNode->GetID() ) )
           {
             isOk = false;
             break;
           }
         } 
         if ( isOk )
-          aResultIds.Add( anElem->GetID() );
+          aResultIds.push_back( anElem->GetID() );
       }
     }
 
@@ -1520,11 +1523,12 @@ SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
     
     // Create array of identifiers
     SMESH::long_array_var aResIds = new SMESH::long_array;
-    aResIds->length( aResultIds.Extent() );
+    aResIds->length( aResultIds.size() );
     
-    NCollection_Map< int >::Iterator aResIter( aResultIds );
-    for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
-      aResIds[ i ] = aResIter.Value();
+    //NCollection_Map< int >::Iterator aResIter( aResultIds );
+    //for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
+    for (int i=0; i< aResultIds.size(); i++)
+      aResIds[ i ] = aResultIds[i];
     aResGrp->Add( aResIds );
 
     // Remove strings corresponding to group creation
@@ -3037,21 +3041,21 @@ SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
   {
     if ( SMDS_PositionPtr pos = aNode->GetPosition() )
     {
-      aNodePosition->shapeID = pos->GetShapeId();
+      aNodePosition->shapeID = aNode->getshapeId();
       switch ( pos->GetTypeOfPosition() ) {
       case SMDS_TOP_EDGE:
         aNodePosition->shapeType = GEOM::EDGE;
         aNodePosition->params.length(1);
         aNodePosition->params[0] =
-          static_cast<SMDS_EdgePosition*>( pos.get() )->GetUParameter();
+          static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
         break;
       case SMDS_TOP_FACE:
         aNodePosition->shapeType = GEOM::FACE;
         aNodePosition->params.length(2);
         aNodePosition->params[0] =
-          static_cast<SMDS_FacePosition*>( pos.get() )->GetUParameter();
+          static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
         aNodePosition->params[1] =
-          static_cast<SMDS_FacePosition*>( pos.get() )->GetVParameter();
+          static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
         break;
       case SMDS_TOP_VERTEX:
         aNodePosition->shapeType = GEOM::VERTEX;
@@ -3085,11 +3089,7 @@ CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
   // try to find node
   const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
   if(aNode) {
-    SMDS_PositionPtr pos = aNode->GetPosition();
-    if(!pos)
-      return -1;
-    else
-      return pos->GetShapeId();
+    return aNode->getshapeId();
   }
 
   return -1;
index 2a799a5b6d5cf5b23e434847a3e31e013f6c1eff..fec31a820c53534012e5d9161df9f48cd20d0c07 100644 (file)
@@ -215,7 +215,6 @@ SMESH::point_array* SMESH_Pattern_i::ApplyToFace(GEOM::GEOM_Object_ptr theFace,
       (*xyzIt)->Coord( p.x, p.y, p.z );
     }
   }
-
   // Update Python script
   TPythonDump() << "pattern.ApplyToFace( " << theFace << ", "
                 << theVertexOnKeyPoint1 << ", " << theReverse << " )";
@@ -392,8 +391,10 @@ CORBA::Boolean SMESH_Pattern_i::MakeMesh (SMESH::SMESH_Mesh_ptr theMesh,
   bool res = myPattern.MakeMesh( aMesh, CreatePolygons, CreatePolyedrs );
 
   if ( nb > 0 && nb != aMesh->NbNodes() + aMesh->NbEdges() + aMesh->NbFaces() + aMesh->NbVolumes())
-    aMesh->SetIsModified(true);
-
+    {
+      aMesh->SetIsModified(true);
+      aMesh->GetMeshDS()->Modified();
+    }
   return res;
 }
 
index 2e5ae0bfcc87af61b7df5203424d471a50b0f73d..ae7ef426556b7e06b4e025ca448a63516be02f14 100644 (file)
@@ -1,4 +1,4 @@
-#  -*- coding: iso-8859-1 -*-
+# -*- coding: utf-8 -*-
 #  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 #  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
@@ -25,6 +25,8 @@ import salome
 import smesh
 import math
 
+salome.salome_init()
+
 def GetNewNodes(mesh,Elems,OldNodes):
     """
     Auxilary function, which return list of nodes from
index 94c0719ffb13b6cd4dad3511c34d1e8e3e9b0d78..85e12a3a7b4aef78685271e80b1a6e504e149764 100644 (file)
@@ -1,4 +1,4 @@
-#  -*- coding: iso-8859-1 -*-
+# -*- coding: utf-8 -*-
 #  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
 #
 #  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
@@ -31,6 +31,7 @@ import salome
 import geompy
 import smesh
 
+salome.salome_init()
 # ---------------------------- GEOM --------------------------------------
 
 # ---- define contigous arcs and segment to define a closed wire
@@ -192,7 +193,7 @@ print "Number of tetrahedrons: ", mesh.NbTetras()
 mesh.SplitQuadObject(submesh2, 1)
 
 #2 cutting of triangles of the group
-FacesTriToQuad = [2381, 2382, 2383, 2384, 2385, 2386, 2387, 2388, 2389, 2390, 2391, 2392, 2393, 2394, 2395, 2396, 2397, 2398, 2399, 2400, 2401, 2402, 2403, 2404, 2405, 2406, 2407, 2408, 2409, 2410, 2411, 2412, 2413, 2414, 2415, 2416, 2417, 2418, 2419, 2420, 2421, 2422]
+FacesTriToQuad = [ 2391, 2824, 2825, 2826, 2827, 2828, 2832, 2833, 2834, 2835, 2836, 2837, 2838, 2839, 2841, 2844, 2845, 2847, 2854, 2861, 2863, 2922, 2923, 2924, 2925, 2926, 2927, 2928, 2929, 2930, 2931, 2932, 2933, 2934, 2935, 2936, 2937, 2938, 2940, 2941, 2946, 2951, 2970, 2971, 2972, 2973, 2974, 2975, 2976, 2977, 2978, 2979, 2980, 2981, 2982, 2983, 2984, 2985 ]
 GroupTriToQuad = mesh.MakeGroupByIds("Group of faces (quad)", smesh.FACE, FacesTriToQuad)
 mesh.TriToQuadObject(GroupTriToQuad, None , 1.57)
 
index a2476107ad5b5eb4a81e490359eb6e37a3ca77ef..f07cf3c238c6233320669275e00497354a4e50b0 100644 (file)
@@ -4059,6 +4059,17 @@ class Mesh:
     #  @ingroup l2_modif_edit
     def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
         return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
+        
+    ## Double nodes on shared faces between groups of volumes and create flat elements on demand.
+    # The list of groups must describe a partition of the mesh volumes.
+    # The nodes of the internal faces at the boundaries of the groups are doubled.
+    # In option, the internal faces are replaced by flat elements.
+    # Triangles are transformed in prisms, and quadrangles in hexahedrons.
+    # @param theDomains - list of groups of volumes
+    # @param createJointElems - if TRUE, create the elements
+    # @return TRUE if operation has been completed successfully, FALSE otherwise
+    def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems ):
+       return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems )
 
     def _valueFromFunctor(self, funcType, elemId):
         fn = self.smeshpyD.GetFunctor(funcType)
index 08c312ead58d3e1f86cb6626e3b6cddc4a4d44a0..abf30eb28e62f7212dc1ab114c5ce0c40ee3632f 100644 (file)
@@ -136,6 +136,7 @@ dist_libStdMeshers_la_SOURCES = \
 libStdMeshers_la_CPPFLAGS = \
        $(CAS_CPPFLAGS) \
        $(BOOST_CPPFLAGS) \
+        $(VTK_INCLUDES) \
        $(KERNEL_CXXFLAGS) \
        $(GUI_CXXFLAGS) \
        -I$(srcdir)/../SMESHImpl \
index 24a1e3fa9908b6371221bf9a270e9542a17306ca..d278711db6614e58b5b708ac352c31954b8e4727 100644 (file)
@@ -1004,8 +1004,8 @@ bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh )
 
   // store the rest nodes row by row
 
-  SMDS_MeshNode dummy(0,0,0);
-  const SMDS_MeshElement* firstQuad = &dummy;// most left face above the last row of found nodes
+  const SMDS_MeshNode* dummy = mesh.GetMeshDS()->AddNode(0,0,0);
+  const SMDS_MeshElement* firstQuad = dummy; // most left face above the last row of found nodes
   
   int nbFoundNodes = myIndexer._xSize;
   while ( nbFoundNodes != myGrid.size() )
@@ -1072,7 +1072,7 @@ bool _QuadFaceGrid::LoadGrid( SMESH_Mesh& mesh )
       n1up   = n2up;
     }
   }
-
+  mesh.GetMeshDS()->RemoveNode(dummy);
   DumpGrid(); // debug
 
   return true;
index f882f5c92c98a59b932147c5e588b577d1eba25a..dc436d74fcc81b02102b408237ae31821982b506 100644 (file)
@@ -341,7 +341,7 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool   isXConst,
         paramSize = myNormPar[ EdgeIndex ] - prevNormPar;
       }
       const SMDS_EdgePosition* epos =
-        dynamic_cast<const SMDS_EdgePosition*>(uvPt.node->GetPosition().get());
+        dynamic_cast<const SMDS_EdgePosition*>(uvPt.node->GetPosition());
       if ( epos ) {
         uvPt.param = epos->GetUParameter();
       }
index 7745eee729fd448a27de068dc0c93a6a7047fb31..4701c050d0d13472d68147104fdd1ebad40ab0d6 100644 (file)
@@ -165,7 +165,7 @@ inline bool isCloser(const int i, const int j, const int nbhoriz,
 static bool findIJ (const SMDS_MeshNode* node, const FaceQuadStruct * quad, int& I, int& J)
 {
   const SMDS_FacePosition* fpos =
-    static_cast<const SMDS_FacePosition*>(node->GetPosition().get());
+    static_cast<const SMDS_FacePosition*>(node->GetPosition());
   if ( ! fpos ) return false;
   gp_Pnt2d uv( fpos->GetUParameter(), fpos->GetVParameter() );
 
@@ -210,9 +210,9 @@ static bool findIJ (const SMDS_MeshNode* node, const FaceQuadStruct * quad, int&
  * -0.  - shape and face mesh verification
  * -1.  - identify faces and vertices of the "cube"
  * -2.  - Algorithm from:
- * "Application de l'interpolation transfinie à la création de maillages
+ * "Application de l'interpolation transfinie a la creation de maillages
  *  C0 ou G1 continus sur des triangles, quadrangles, tetraedres, pentaedres
- *  et hexaedres déformés."
+ *  et hexaedres deformes."
  * Alain PERONNET - 8 janvier 1999
  */
 //=============================================================================
@@ -411,6 +411,9 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh &         aMesh,
 
   int i1, j1, nbxyz = nbx * nby * nbz;
   Point3DStruct *np = new Point3DStruct[nbxyz];
+  
+  aMesh.GetMeshDS()->incrementNodesCapacity(nbx * nby * nbz);
+  aMesh.GetMeshDS()->incrementCellsCapacity((nbx-1) * (nby-1) * (nbz-1));
 
   // 1.9 - store node indexes of faces
 
index fe0f05476282c6cb03a0812a318d78ef01481d5f..b3dac25ab5a604d2ae43fbcbc4c81420e5cb440c 100644 (file)
@@ -575,7 +575,7 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th
 
     SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
     vector<const SMDS_MeshNode*> newNodes;
-    SMDS_MeshNode tmpNode(0,0,0);
+    SMDS_MeshNode *tmpNode = helper.AddNode(0,0,0);
     double u;
     while ( srcElems->more() ) // loop on group contents
     {
@@ -589,7 +589,7 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th
         TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first;
         if ( n2nIt->second )
         {
-          if ( !subShapeIDs.count( n2nIt->second->GetPosition()->GetShapeId() ))
+          if ( !subShapeIDs.count( n2nIt->second->getshapeId() ))
             break;
         }
         else
@@ -606,8 +606,8 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th
         if ( !n2nIt->second )
         {
           // find out if node lies on theShape
-          tmpNode.setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z());
-          if ( helper.CheckNodeU( geomEdge, &tmpNode, u, 10 * edgeTol, /*force=*/true ))
+          tmpNode->setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z());
+          if ( helper.CheckNodeU( geomEdge, tmpNode, u, 10 * edgeTol, /*force=*/true ))
           {
             SMDS_MeshNode* newNode = tgtMesh->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z());
             n2nIt->second = newNode;
@@ -629,6 +629,7 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th
       tgtMesh->SetMeshElementOnShape( newEdge, shapeID );
       e2e->insert( make_pair( edge, newEdge ));
     }
+    helper.GetMeshDS()->RemoveNode(tmpNode);
   }
   if ( n2n->empty())
     return error("Empty source groups");
@@ -892,7 +893,7 @@ bool StdMeshers_Import_1D::Evaluate(SMESH_Mesh &         theMesh,
     {
       const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
       SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
-      SMDS_MeshNode tmpNode(0,0,0);
+      SMDS_MeshNode *tmpNode = helper.AddNode(0,0,0);
       while ( srcElems->more() ) // loop on group contents
       {
         const SMDS_MeshElement* edge = srcElems->next();
@@ -901,11 +902,12 @@ bool StdMeshers_Import_1D::Evaluate(SMESH_Mesh &         theMesh,
         SMESH_MeshEditor::TNodeXYZ p1( edge->GetNode(0));
         SMESH_MeshEditor::TNodeXYZ p2( edge->GetNode(1));
         gp_XYZ middle = ( p1 + p2 ) / 2.;
-        tmpNode.setXYZ( middle.X(), middle.Y(), middle.Z());
+        tmpNode->setXYZ( middle.X(), middle.Y(), middle.Z());
         double u = 0;
-        if ( helper.CheckNodeU( geomEdge, &tmpNode, u, 10 * edgeTol, /*force=*/true ))
+        if ( helper.CheckNodeU( geomEdge, tmpNode, u, 10 * edgeTol, /*force=*/true ))
           ++( edge->IsQuadratic() ? nbQuadEdges : nbEdges);
       }
+      helper.GetMeshDS()->RemoveNode(tmpNode);
     }
 
     int nbNodes = nbEdges + 2 * nbQuadEdges - 1;
index 5513a1077c85d41ba9e227107fb9a1ecafad5a55..5d89cd1282e9a291ca504e885b00f682b763355f 100644 (file)
@@ -200,7 +200,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
     StdMeshers_Import_1D::getMaps( srcMesh, &theMesh, n2n, e2e );
 
     SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
-    SMDS_MeshNode tmpNode(0,0,0);
+    SMDS_MeshNode *tmpNode = helper.AddNode(0,0,0);
     gp_XY uv;
     while ( srcElems->more() ) // loop on group contents
     {
@@ -215,7 +215,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
         TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first;
         if ( n2nIt->second )
         {
-          if ( !subShapeIDs.count( n2nIt->second->GetPosition()->GetShapeId() ))
+          if ( !subShapeIDs.count( n2nIt->second->getshapeId() ))
             break;
         }
         else
@@ -232,8 +232,8 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
         if ( !n2nIt->second )
         {
           // find out if node lies on theShape
-          tmpNode.setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z());
-          if ( helper.CheckNodeUV( geomFace, &tmpNode, uv, 10 * faceTol, /*force=*/true ))
+          tmpNode->setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z());
+          if ( helper.CheckNodeUV( geomFace, tmpNode, uv, 10 * faceTol, /*force=*/true ))
           {
             SMDS_MeshNode* newNode = tgtMesh->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z());
             n2nIt->second = newNode;
@@ -315,6 +315,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
         ++link2Nb->second;
       }
     }
+    helper.GetMeshDS()->RemoveNode(tmpNode);
   }
 
   // ==========================================================
@@ -346,7 +347,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
         for ( int is1stN = 0; is1stN < 2 && nodesOnBoundary; ++is1stN )
         {
           const SMDS_MeshNode* n = is1stN ? link.node1() : link.node2();
-          if ( !subShapeIDs.count( n->GetPosition()->GetShapeId() ))
+          if ( !subShapeIDs.count( n->getshapeId() ))
           {
             for ( unsigned iE = 0; iE < edges.size(); ++iE )
               if ( helper.CheckNodeU( edges[iE], n, u, 10 * faceTol, /*force=*/true ))
@@ -358,7 +359,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
                 tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)n, edges[iE], u );
                 break;
               }
-            nodesOnBoundary = subShapeIDs.count( n->GetPosition()->GetShapeId());
+            nodesOnBoundary = subShapeIDs.count( n->getshapeId());
           }
           if ( nodesOnBoundary )
           {
@@ -554,7 +555,7 @@ bool StdMeshers_Import_1D2D::Evaluate(SMESH_Mesh &         theMesh,
     {
       const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
       SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
-      SMDS_MeshNode tmpNode(0,0,0);
+      SMDS_MeshNode *tmpNode =helper.AddNode(0,0,0);
       while ( srcElems->more() ) // loop on group contents
       {
         const SMDS_MeshElement* face = srcElems->next();
@@ -562,8 +563,8 @@ bool StdMeshers_Import_1D2D::Evaluate(SMESH_Mesh &         theMesh,
         // a gravity center of face to geomFace
         gp_XYZ gc(0,0,0);
         gc = accumulate( TXyzIterator(face->nodesIterator()), TXyzIterator(), gc)/face->NbNodes();
-        tmpNode.setXYZ( gc.X(), gc.Y(), gc.Z());
-        if ( helper.CheckNodeUV( geomFace, &tmpNode, uv, 10 * faceTol, /*force=*/true ))
+        tmpNode->setXYZ( gc.X(), gc.Y(), gc.Z());
+        if ( helper.CheckNodeUV( geomFace, tmpNode, uv, 10 * faceTol, /*force=*/true ))
         {
           ++aVec[ face->GetEntityType() ];
 
@@ -585,6 +586,7 @@ bool StdMeshers_Import_1D2D::Evaluate(SMESH_Mesh &         theMesh,
           }
         }
       }
+      helper.GetMeshDS()->RemoveNode(tmpNode);
     }
 
     int nbNodes = allNodes.size();
index 46f7b9e3980bedead2258c84c1bb7095c9bfbddb..894899686d696a6729410de9219bdb95088d4989 100644 (file)
@@ -512,7 +512,7 @@ static bool fixCommonVertexUV (R2 &                 theUV,
         if ( theCreateQuadratic && SMESH_MesherHelper::IsMedium( node, SMDSAbs_Edge ))
           continue;
         const SMDS_EdgePosition* epos =
-          static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+          static_cast<const SMDS_EdgePosition*>(node->GetPosition());
         double u = epos->GetUParameter();
         if ( u < umin )
           umin = u;
@@ -613,9 +613,9 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(TWireVector &                 wires,
       case SMDS_TOP_EDGE:
         // In order to detect degenerated faces easily, we replace
         // nodes on a degenerated edge by node on the vertex of that edge
-        if ( myTool->IsDegenShape( uvPt->node->GetPosition()->GetShapeId() ))
+        if ( myTool->IsDegenShape( uvPt->node->getshapeId() ))
         {
-          int edgeID = uvPt->node->GetPosition()->GetShapeId();
+          int edgeID = uvPt->node->getshapeId();
           SMESH_subMesh* edgeSM = myTool->GetMesh()->GetSubMeshContaining( edgeID );
           SMESH_subMeshIteratorPtr smIt = edgeSM->getDependsOnIterator( /*includeSelf=*/0,
                                                                         /*complexShapeFirst=*/0);
@@ -640,7 +640,7 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(TWireVector &                 wires,
       int m = *mIt;
       if ( iW && !VWMap.IsEmpty()) { // except outer wire
         // avoid passing same uv point for a vertex common to 2 wires
-        int vID = mefistoToDS[m]->GetPosition()->GetShapeId();
+        int vID = mefistoToDS[m]->getshapeId();
         TopoDS_Vertex V = TopoDS::Vertex( myTool->GetMeshDS()->IndexToShape( vID ));
         if ( fixCommonVertexUV( uvslf[m], V, F, VWMap, *myTool->GetMesh(),
                                 scalex, scaley, _quadraticMesh )) {
index b9d46da9ef1e25d40e2b67a6f59e460a4bc6bc04..2ad53b1d7c32a81b23a11088652c6b18e6e71fff 100644 (file)
@@ -235,7 +235,7 @@ void StdMeshers_Penta_3D::MakeNodes()
       //
       if ( SMESH_Block::IsEdgeID (aSID)) {
         const SMDS_EdgePosition* epos =
-          static_cast<const SMDS_EdgePosition*>(aNode->GetPosition().get());
+          static_cast<const SMDS_EdgePosition*>(aNode->GetPosition());
         myBlock.ComputeParameters( epos->GetUParameter(), aS, aCoords );
       }
       else {
@@ -1465,7 +1465,7 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
     if(myTool->IsMedium(node))
       continue;
     const SMDS_EdgePosition* pos =
-      dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition().get() );
+      dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition() );
     if ( !pos ) {
       return false;
     }
@@ -1488,7 +1488,7 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
     if(myTool->IsMedium(node))
       continue;
     const SMDS_EdgePosition* pos =
-      dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition().get() );
+      dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition() );
     if ( !pos ) {
       return false;
     }
index c7bf42004ed9a15dc3a9b87437b0875b257ffa7e..5a2a1a3fee22225c205d54bd223ca48199075ad9 100644 (file)
@@ -478,7 +478,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
         if ( !myBlock.ComputeParameters( topCoords, topParams, ID_TOP_FACE, topParams ))
           return error(TCom("Can't compute normalized parameters ")
                        << "for node " << column.back()->GetID()
-                       << " on the face #"<< column.back()->GetPosition()->GetShapeId() );
+                       << " on the face #"<< column.back()->getshapeId() );
       }
 
       // vertical loop
@@ -806,6 +806,8 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top()
        botSMDS->NbElements() != topSMDS->NbElements() ||
        botSMDS->NbNodes()    != topSMDS->NbNodes())
   {
+    MESSAGE("nb elem bot " << botSMDS->NbElements() << " top " << topSMDS->NbElements());
+    MESSAGE("nb node bot " << botSMDS->NbNodes() << " top " << topSMDS->NbNodes());
     if ( myBlock.HasNotQuadElemOnTop() )
       return error(TCom("Mesh on faces #") << botSM->GetId()
                    <<" and #"<< topSM->GetId() << " seems different" );
@@ -1208,6 +1210,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
   }
 
   myNotQuadOnTop = ( nbNotQuadMeshed > 1 );
+  MESSAGE("myNotQuadOnTop " << myNotQuadOnTop << " nbNotQuadMeshed " << nbNotQuadMeshed);
  
   // ----------------------------------------------------------
 
@@ -1364,11 +1367,11 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
     // columns for vertices
     // 1
     const SMDS_MeshNode* n0 = faceColumns.begin()->second.front();
-    id = n0->GetPosition()->GetShapeId();
+    id = n0->getshapeId();
     myShapeIndex2ColumnMap[ id ] = make_pair( & faceColumns, isForward );
     // 2
     const SMDS_MeshNode* n1 = faceColumns.rbegin()->second.front();
-    id = n1->GetPosition()->GetShapeId();
+    id = n1->getshapeId();
     myShapeIndex2ColumnMap[ id ] = make_pair( & faceColumns, isForward );
 //     SHOWYXZ("\np1 F "<<iE, gpXYZ(faceColumns.begin()->second.front() ));
 //     SHOWYXZ("p2 F "<<iE, gpXYZ(faceColumns.rbegin()->second.front() ));
@@ -1578,11 +1581,11 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
 
       // columns for vertices
       const SMDS_MeshNode* n0 = cols->begin()->second.front();
-      id = n0->GetPosition()->GetShapeId();
+      id = n0->getshapeId();
       myShapeIndex2ColumnMap[ id ] = make_pair( cols, isForward );
 
       const SMDS_MeshNode* n1 = cols->rbegin()->second.front();
-      id = n1->GetPosition()->GetShapeId();
+      id = n1->getshapeId();
       myShapeIndex2ColumnMap[ id ] = make_pair( cols, !isForward );
     }
   }
@@ -1609,7 +1612,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
 
 const TNodeColumn* StdMeshers_PrismAsBlock::GetNodeColumn(const SMDS_MeshNode* node) const
 {
-  int sID = node->GetPosition()->GetShapeId();
+  int sID = node->getshapeId();
 
   map<int, pair< TParam2ColumnMap*, bool > >::const_iterator col_frw =
     myShapeIndex2ColumnMap.find( sID );
index 38028c2d7f4f0e7e2e92ada647baee16717ee403..86edbacfda44b4c686139bcbf8486f20d54ecd49 100644 (file)
@@ -1753,7 +1753,7 @@ FindMatchingNodesOnFaces( const TopoDS_Face&     face1,
         const SMDS_MeshElement* f = ( iF ? f2 : f1 );
         for ( int i = 0; !notSeamNode[ iF ] && i < f->NbNodes(); ++i ) {
           const SMDS_MeshNode* node = f->GetNode( i );
-          if ( !helper->IsSeamShape( node->GetPosition()->GetShapeId() ))
+          if ( !helper->IsSeamShape( node->getshapeId() ))
             notSeamNode[ iF ] = node;
         }
       }
@@ -1821,7 +1821,7 @@ FindMatchingNodesOnFaces( const TopoDS_Face&     face1,
       while ( nIt->more() ) {
         const SMDS_MeshNode* node = nIt->next();
         const SMDS_EdgePosition* pos =
-          static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+          static_cast<const SMDS_EdgePosition*>(node->GetPosition());
         pos2nodes.insert( make_pair( pos->GetUParameter(), node ));
       }
       if ( pos2nodes.size() != edgeSM->NbNodes() )
index e234d0a91732210f2871066f22c3048f4be63f71..db8cec56881471f9bf076423ca5e8bf32c5f5939 100644 (file)
@@ -341,7 +341,7 @@ namespace {
           RETURN_BAD_RESULT("Bad node position type: node " << node->GetID() <<
                             " pos type " << node->GetPosition()->GetTypeOfPosition());
         const SMDS_EdgePosition* pos =
-          static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+          static_cast<const SMDS_EdgePosition*>(node->GetPosition());
         u2nodes.insert( make_pair( pos->GetUParameter(), node ));
         seamNodes.insert( node );
       }
@@ -374,7 +374,8 @@ namespace {
                       SMESH_Mesh *                      srcMesh,
                       const TAssocTool::TShapeShapeMap& shape2ShapeMap)
   {
-    const double tol = 1e-6;
+    MESSAGE("projectPartner");
+    const double tol = 1.e-7*srcMesh->GetMeshDS()->getMaxDim();
 
     gp_Trsf trsf; // transformation to get location of target nodes from source ones
     if ( tgtFace.IsPartner( srcFace ))
@@ -406,12 +407,13 @@ namespace {
           {
           case 0: pOK = true; break;
 
-          case 1: pOK = ( srcPP[0].SquareDistance( p ) > tol ); break;
+          case 1: pOK = ( srcPP[0].SquareDistance( p ) > 10*tol ); break;
             
           case 2:
             {
               gp_Vec p0p1( srcPP[0], srcPP[1] ), p0p( srcPP[0], p );
-              pOK = !p0p1.IsParallel( p0p, tol );
+              // pOK = !p0p1.IsParallel( p0p, tol );
+              pOK = !p0p1.IsParallel( p0p, 3.14/20 ); // angle min 18 degrees
               break;
             }
           }
@@ -434,6 +436,7 @@ namespace {
             {
               double srcDist = srcPP[0].Distance( p );
               double eTol = BRep_Tool::Tolerance( TopoDS::Edge( tgtShape ));
+              if (eTol < tol) eTol = tol;
               SMDS_NodeIteratorPtr nItT = tgtSmds->GetNodes();
               while ( nItT->more() && !pOK )
               {
@@ -490,7 +493,7 @@ namespace {
 
       if ( !tgtEdge.IsPartner( srcEdge.Current() ))
       {
-        // check that transormation is OK by three nodes
+        // check that transformation is OK by three nodes
         gp_Pnt p0S = SMESH_MeshEditor::TNodeXYZ( (srcNodes.begin())  ->second);
         gp_Pnt p1S = SMESH_MeshEditor::TNodeXYZ( (srcNodes.rbegin()) ->second);
         gp_Pnt p2S = SMESH_MeshEditor::TNodeXYZ( (++srcNodes.begin())->second);
@@ -499,7 +502,7 @@ namespace {
         gp_Pnt p1T = SMESH_MeshEditor::TNodeXYZ( (tgtNodes.rbegin()) ->second);
         gp_Pnt p2T = SMESH_MeshEditor::TNodeXYZ( (++tgtNodes.begin())->second);
 
-        // transform source points, they must coinside with target ones
+        // transform source points, they must coincide with target ones
         if ( p0T.SquareDistance( p0S.Transformed( trsf )) > tol ||
              p1T.SquareDistance( p1S.Transformed( trsf )) > tol ||
              p2T.SquareDistance( p2S.Transformed( trsf )) > tol )
@@ -522,6 +525,7 @@ namespace {
 
     // prepare the helper adding quadratic elements if necessary
     SMESH_MesherHelper helper( *tgtMesh );
+    helper.SetSubShape( tgtFace );
     helper.IsQuadraticSubMesh( tgtFace );
     helper.SetElementsOnShape( true );
 
@@ -538,20 +542,31 @@ namespace {
       while ( nodeIt->more() ) // loop on nodes of the source element
       {
         const SMDS_MeshNode* srcNode = (const SMDS_MeshNode*) nodeIt->next();
+        if (elem->IsMediumNode(srcNode))
+          continue;
         srcN_tgtN = src2tgtNodes.insert( make_pair( srcNode, nullNode )).first;
         if ( srcN_tgtN->second == nullNode )
         {
           // create a new node
           gp_Pnt tgtP = gp_Pnt(srcNode->X(),srcNode->Y(),srcNode->Z()).Transformed( trsf );
           srcN_tgtN->second = helper.AddNode( tgtP.X(), tgtP.Y(), tgtP.Z() );
+          //MESSAGE(tgtP.X() << " " << tgtP.Y() << " " <<  tgtP.Z());
         }
         tgtFaceNodes.push_back( srcN_tgtN->second );
       }
       // create a new face (with reversed orientation)
-      if ( tgtFaceNodes.size() == 3 )
-        helper.AddFace( tgtFaceNodes[0],tgtFaceNodes[2],tgtFaceNodes[1]);
-      else
-        helper.AddFace( tgtFaceNodes[0],tgtFaceNodes[3],tgtFaceNodes[2],tgtFaceNodes[1]);
+      //MESSAGE("tgtFaceNodes.size() " << tgtFaceNodes.size());
+      switch (tgtFaceNodes.size())
+         {
+            case 3:
+            case 6:
+              helper.AddFace(tgtFaceNodes[0], tgtFaceNodes[2], tgtFaceNodes[1]);
+              break;
+            case 4:
+            case 8:
+              helper.AddFace(tgtFaceNodes[0], tgtFaceNodes[3], tgtFaceNodes[2], tgtFaceNodes[1]);
+              break;
+         }
     }
     return true;
   }
@@ -566,6 +581,7 @@ namespace {
 
 bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theShape)
 {
+  MESSAGE("Projection_2D Compute");
   if ( !_sourceHypo )
     return false;
 
@@ -752,7 +768,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
       }
       case  SMDS_TOP_EDGE:   {
         const SMDS_EdgePosition* pos =
-          static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+          static_cast<const SMDS_EdgePosition*>(node->GetPosition());
         pos2nodes.insert( make_pair( pos->GetUParameter(), node ));
         break;
       }
index e30980e32d1989c6d7143a6e26f1b33d0193f182..689c920064da60417f5ebc88763342081e344308 100644 (file)
@@ -407,11 +407,13 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
                                  nodes[6],
                                  nodes[7], id, force3d); break;
     default: // polyhedron
-      const SMDS_PolyhedralVolumeOfNodes * poly =
-        dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>( srcVol );
+      const SMDS_VtkVolume * poly =
+        dynamic_cast<const SMDS_VtkVolume*>( srcVol );
       if ( !poly )
         RETURN_BAD_RESULT("Unexpected volume type");
-      tgtVol = tgtMeshDS->AddPolyhedralVolume( nodes, poly->GetQuanities() );
+      if ( !poly->IsPoly())
+        RETURN_BAD_RESULT("Unexpected volume type");
+      tgtVol = tgtMeshDS->AddPolyhedralVolume( nodes, poly->GetQuantities() );
     }
     if ( tgtVol ) {
       tgtMeshDS->SetMeshElementOnShape( tgtVol, helper.GetSubShapeID() );
index 8e2718dd0a40a36830a1898621c158b64edf9b4f..25b472c3eed3d427ee6152666f49627d9f60f2b7 100644 (file)
@@ -51,53 +51,6 @@ typedef SMDS_StdIterator< SMESH_MeshEditor::TNodeXYZ, SMDS_ElemIteratorPtr > TXy
 
 namespace
 {
-  const int Q2TAbs_TmpTriangle = SMDSEntity_Last + 1;
-
-  //================================================================================
-  /*!
-   * \brief Temporary face. It's key feature is that it adds itself to an apex node
-   * as inverse element, so that tmp triangles of a piramid can be easily found
-   */
-  //================================================================================
-
-  class STDMESHERS_EXPORT Q2TAdaptor_Triangle : public SMDS_MeshFace
-  {
-    const SMDS_MeshNode* _nodes[3];
-  public:
-    Q2TAdaptor_Triangle(const SMDS_MeshNode* apexNode,
-                        const SMDS_MeshNode* node2,
-                        const SMDS_MeshNode* node3)
-    {
-      _nodes[0]=0; ChangeApex(apexNode);
-      _nodes[1]=node2;
-      _nodes[2]=node3;
-    }
-    ~Q2TAdaptor_Triangle() { MarkAsRemoved(); }
-    void ChangeApex(const SMDS_MeshNode* node)
-    {
-      MarkAsRemoved();
-      _nodes[0]=node;
-      const_cast<SMDS_MeshNode*>(node)->AddInverseElement(this);
-    }
-    void MarkAsRemoved()
-    {
-      if ( _nodes[0] )
-        const_cast<SMDS_MeshNode*>(_nodes[0])->RemoveInverseElement(this), _nodes[0] = 0;
-    }
-    bool IsRemoved() const { return !_nodes[0]; }
-    virtual int NbNodes() const { return 3; }
-    virtual const SMDS_MeshNode* GetNode(const int ind) const { return _nodes[ind]; }
-    virtual SMDSAbs_EntityType   GetEntityType() const
-    {
-      return SMDSAbs_EntityType( Q2TAbs_TmpTriangle );
-    }
-    virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const
-    {
-      if ( type == SMDSAbs_Node )
-        return SMDS_ElemIteratorPtr( new SMDS_NodeArrayElemIterator( _nodes, _nodes+3 ));
-      throw SALOME_Exception(LOCALIZED("Not implemented"));
-    }
-  };
 
   //================================================================================
   /*!
@@ -118,9 +71,10 @@ namespace
    */
   //================================================================================
 
-  void MergePiramids( const SMDS_MeshElement*     PrmI,
+  void MergePyramids( const SMDS_MeshElement*     PrmI,
                       const SMDS_MeshElement*     PrmJ,
                       SMESHDS_Mesh*               meshDS,
+                      TRemTrias&                  tempTrias,
                       set<const SMDS_MeshNode*> & nodesToMove)
   {
     const SMDS_MeshNode* Nrem = PrmJ->GetNode(4); // node to remove
@@ -131,6 +85,7 @@ namespace
     SMDS_MeshNode* CommonNode = const_cast<SMDS_MeshNode*>(PrmI->GetNode(4));
     if ( CommonNode == Nrem ) return; // already merged
     int nbI = CommonNode->NbInverseElements( SMDSAbs_Volume );
+    //cerr << __LINE__ << " " << nbI << " " << nbJ << endl;
     SMESH_MeshEditor::TNodeXYZ Pi( CommonNode );
     gp_XYZ Pnew = ( nbI*Pi + nbJ*Pj ) / (nbI+nbJ);
     CommonNode->setXYZ( Pnew.X(), Pnew.Y(), Pnew.Z() );
@@ -153,12 +108,15 @@ namespace
       }
       if ( FJEqual )
       {
-        ((Q2TAdaptor_Triangle*) FI)->MarkAsRemoved();
-        ((Q2TAdaptor_Triangle*) FJEqual)->MarkAsRemoved();
+        //meshDS->RemoveFreeElement(FI, 0, false);
+        //meshDS->RemoveFreeElement(FJEqual, 0, false);
+        tempTrias[FI] = false;
+        tempTrias[FJEqual] = false;
       }
     }
 
     // set the common apex node to pyramids and triangles merged with J
+    //cerr <<  __LINE__ << " NbInverseElements " << Nrem->NbInverseElements() << endl;
     SMDS_ElemIteratorPtr itJ = Nrem->GetInverseElementIterator();
     while ( itJ->more() )
     {
@@ -166,17 +124,25 @@ namespace
       if ( elem->GetType() == SMDSAbs_Volume ) // pyramid
       {
         vector< const SMDS_MeshNode* > nodes( elem->begin_nodes(), elem->end_nodes() );
+        //cerr << __LINE__ << " volId " << elem->GetID() << " nbNodes " << nodes.size() << endl;
         nodes[4] = CommonNode;
+        MESSAGE("ChangeElementNodes");
         meshDS->ChangeElementNodes( elem, &nodes[0], nodes.size());
       }
-      else if ( elem->GetEntityType() == Q2TAbs_TmpTriangle ) // tmp triangle
+      else if ( tempTrias.count(elem) ) // tmp triangles
       {
-        ((Q2TAdaptor_Triangle*) elem )->ChangeApex( CommonNode );
+        //cerr << __LINE__ << " triaId " << elem->GetID() << endl;
+        ((SMDS_VtkFace*) elem )->ChangeApex( CommonNode );
       }
+//      else
+//        {
+//          cerr <<  __LINE__ << " other " << elem->GetVtkType() << endl;
+//        }
     }
+    //cerr <<  __LINE__ << " NbInverseElements " << Nrem->NbInverseElements() << endl;
     ASSERT( Nrem->NbInverseElements() == 0 );
     meshDS->RemoveFreeNode( Nrem,
-                            meshDS->MeshElements( Nrem->GetPosition()->GetShapeId()),
+                            meshDS->MeshElements( Nrem->getshapeId()),
                             /*fromGroups=*/false);
   }
 
@@ -194,7 +160,7 @@ namespace
     const SMDS_MeshNode* nApexI = PrmI->GetNode(4);
     const SMDS_MeshNode* nApexJ = PrmJ->GetNode(4);
     if ( nApexI == nApexJ ||
-         nApexI->GetPosition()->GetShapeId() != nApexJ->GetPosition()->GetShapeId() )
+         nApexI->getshapeId() != nApexJ->getshapeId() )
       return false;
 
     // Find two common base nodes and their indices within PrmI and PrmJ
@@ -295,6 +261,7 @@ namespace
 
   void MergeAdjacent(const SMDS_MeshElement*    PrmI,
                      SMESH_Mesh&                mesh,
+                     TRemTrias &                tempTrias,
                      set<const SMDS_MeshNode*>& nodesToMove)
   {
     TIDSortedElemSet adjacentPyrams, mergedPyrams;
@@ -309,7 +276,7 @@ namespace
           continue;
         if ( PrmI != PrmJ && TooCloseAdjacent( PrmI, PrmJ, mesh.HasShapeToMesh() ))
         {
-          MergePiramids( PrmI, PrmJ, mesh.GetMeshDS(), nodesToMove );
+          MergePyramids( PrmI, PrmJ, mesh.GetMeshDS(), tempTrias, nodesToMove );
           mergedPyrams.insert( PrmJ );
         }
       }
@@ -318,10 +285,10 @@ namespace
     {
       TIDSortedElemSet::iterator prm;
 //       for (prm = mergedPyrams.begin(); prm != mergedPyrams.end(); ++prm)
-//         MergeAdjacent( *prm, mesh, nodesToMove );
+//         MergeAdjacent( *prm, mesh, tempTrias, nodesToMove );
 
       for (prm = adjacentPyrams.begin(); prm != adjacentPyrams.end(); ++prm)
-        MergeAdjacent( *prm, mesh, nodesToMove );
+        MergeAdjacent( *prm, mesh, tempTrias, nodesToMove );
     }
   }
 }
@@ -352,7 +319,10 @@ StdMeshers_QuadToTriaAdaptor::~StdMeshers_QuadToTriaAdaptor()
     TTriaList& fList = f_f->second;
     TTriaList::iterator f = fList.begin(), fEnd = fList.end();
     for ( ; f != fEnd; ++f )
-      delete *f;
+      {
+        const SMDS_MeshElement *elem = *f;
+        SMDS_Mesh::_meshList[elem->getMeshId()]->RemoveFreeElement(elem);
+      }
   }
   myResMap.clear();
 
@@ -735,9 +705,10 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape
           // add triangles to result map
           SMDS_MeshFace* NewFace;
           if(!isRev)
-            NewFace = new Q2TAdaptor_Triangle( FNodes[0], FNodes[1], FNodes[2] );
+            NewFace = meshDS->AddFace( FNodes[0], FNodes[1], FNodes[2] );
           else
-            NewFace = new Q2TAdaptor_Triangle( FNodes[0], FNodes[2], FNodes[1] );
+            NewFace = meshDS->AddFace( FNodes[0], FNodes[2], FNodes[1] );
+          myTempTriangles[NewFace] =true;
           TTriaList aList( 1, NewFace );
           myResMap.insert(make_pair(face,aList));
           continue;
@@ -794,7 +765,11 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape
         // add triangles to result map
         TTriaList& triaList = myResMap.insert( make_pair( face, TTriaList() ))->second;
         for(i=0; i<4; i++)
-          triaList.push_back( new Q2TAdaptor_Triangle( NewNode, FNodes[i], FNodes[i+1] ));
+          {
+            SMDS_MeshFace* newFace =meshDS->AddFace( NewNode, FNodes[i], FNodes[i+1] );
+            triaList.push_back( newFace );
+            myTempTriangles[newFace] = true;
+          }
 
         // create a pyramid
         if ( isRev ) swap( FNodes[1], FNodes[3]);
@@ -916,9 +891,10 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh)
         }
       }
       if(!IsRev)
-        NewFace = new Q2TAdaptor_Triangle( FNodes[0], FNodes[1], FNodes[2] );
+        NewFace = meshDS->AddFace( FNodes[0], FNodes[1], FNodes[2] );
       else
-        NewFace = new Q2TAdaptor_Triangle( FNodes[0], FNodes[2], FNodes[1] );
+        NewFace = meshDS->AddFace( FNodes[0], FNodes[2], FNodes[1] );
+      myTempTriangles[NewFace] = true;
       aList.push_back(NewFace);
       myResMap.insert(make_pair(face,aList));
       continue;
@@ -996,9 +972,10 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh)
       for(i=0; i<4; i++) {
         SMDS_MeshFace* NewFace;
         if(isRev)
-          NewFace = new Q2TAdaptor_Triangle( NewNode, FNodes[i], FNodes[i+1] );
+          NewFace = meshDS->AddFace( NewNode, FNodes[i], FNodes[i+1] );
         else
-          NewFace = new Q2TAdaptor_Triangle( NewNode, FNodes[i+1], FNodes[i] );
+          NewFace = meshDS->AddFace( NewNode, FNodes[i+1], FNodes[i] );
+        myTempTriangles[NewFace] = true;
         aList.push_back(NewFace);
       }
       // create a pyramid
@@ -1026,7 +1003,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh)
     return true;
 
   SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
-  int i, j, k, myShapeID = myPyramids[0]->GetNode(4)->GetPosition()->GetShapeId();
+  int i, j, k, myShapeID = myPyramids[0]->GetNode(4)->getshapeId();
 
   if ( !myElemSearcher )
     myElemSearcher = SMESH_MeshEditor(&aMesh).GetElementSearcher();
@@ -1039,7 +1016,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh)
   for ( i = 0; i <  myPyramids.size(); ++i )
   {
     const SMDS_MeshElement* PrmI = myPyramids[i];
-    MergeAdjacent( PrmI, aMesh, nodesToMove );
+    MergeAdjacent( PrmI, aMesh, myTempTriangles, nodesToMove );
   }
 
   // iterate on all pyramids
@@ -1076,7 +1053,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh)
         const SMDS_MeshElement* PrmJ = suspectPyrams[j];
         if ( PrmJ == PrmI || PrmJ->NbCornerNodes() != 5 )
           continue;
-        if ( myShapeID != PrmJ->GetNode(4)->GetPosition()->GetShapeId())
+        if ( myShapeID != PrmJ->GetNode(4)->getshapeId())
           continue; // pyramid from other SOLID
         if ( PrmI->GetNode(4) == PrmJ->GetNode(4) )
           continue; // pyramids PrmI and PrmJ already merged
@@ -1116,7 +1093,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh)
           if(nbc>0)
           {
             // Merge the two pyramids and others already merged with them
-            MergePiramids( PrmI, PrmJ, meshDS, nodesToMove );
+            MergePyramids( PrmI, PrmJ, meshDS, myTempTriangles, nodesToMove );
           }
           else { // nbc==0
 
@@ -1149,8 +1126,8 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh)
             nodesToMove.insert( aNode2 );
           }
           // fix intersections that could appear after apex movement
-          MergeAdjacent( PrmI, aMesh, nodesToMove );
-          MergeAdjacent( PrmJ, aMesh, nodesToMove );
+          MergeAdjacent( PrmI, aMesh, myTempTriangles, nodesToMove );
+          MergeAdjacent( PrmJ, aMesh, myTempTriangles, nodesToMove );
 
         } // end if(hasInt)
       } // loop on suspectPyrams
@@ -1171,18 +1148,34 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh)
   for ( ++q2t; q2t != myResMap.end(); ++q2t, ++q2tPrev )
   {
     if ( q2t->first == q2tPrev->first )
-      q2tPrev->second.splice( q2tPrev->second.end(), q2t->second );
+      {
+        //cerr << __LINE__ << " splice" << endl;
+        q2tPrev->second.splice( q2tPrev->second.end(), q2t->second );
+      }
   }
   // delete removed triangles and count resulting nb of triangles
-  for ( q2t = myResMap.begin(); q2t != myResMap.end(); ++q2t )
-  {
-    TTriaList & trias = q2t->second;
-    for ( TTriaList::iterator tri = trias.begin(); tri != trias.end(); )
-      if ( ((const Q2TAdaptor_Triangle*) *tri)->IsRemoved() )
-        delete *tri, trias.erase( tri++ );
-      else
-        tri++, myNbTriangles++;
-  }
+  for (q2t = myResMap.begin(); q2t != myResMap.end(); ++q2t)
+    {
+      TTriaList & trias = q2t->second;
+      vector<const SMDS_MeshFace*> faceToErase;
+      faceToErase.clear();
+      //cerr << __LINE__ << " " << trias.size() << endl;
+      for (TTriaList::iterator tri = trias.begin(); tri != trias.end(); ++tri)
+        {
+          //cerr <<  "  " << __LINE__ << endl;
+          const SMDS_MeshFace* face = *tri;
+          if (myTempTriangles.count(face) && (myTempTriangles[face] == false))
+            faceToErase.push_back(face);
+          else
+            myNbTriangles++;
+        }
+      for (vector<const SMDS_MeshFace*>::iterator it = faceToErase.begin(); it != faceToErase.end(); ++it)
+        {
+          const SMDS_MeshFace *face = dynamic_cast<const SMDS_MeshFace*>(*it);
+          if (face) trias.remove(face);
+          meshDS->RemoveFreeElement(face, 0, false);
+        }
+    }
 
   myPyramids.clear(); // no more needed
   myDegNodes.clear();
index ceccb2542a4e98184bc9bc0af760bbaccb8f738c..95ed9a62256efeaa5976fe6aedee7f93c7d11b75 100644 (file)
@@ -43,6 +43,8 @@ class gp_Vec;
 
 #include <TopoDS_Shape.hxx>
 
+typedef std::map<const SMDS_MeshElement*, bool>               TRemTrias;
+
 /*!
  * \brief "Transforms" quadrilateral faces into triangular ones by creation of pyramids
  */
@@ -87,8 +89,9 @@ protected:
 
   typedef std::list<const SMDS_MeshFace* >                   TTriaList;
   typedef std::multimap<const SMDS_MeshElement*, TTriaList > TQuad2Trias;
-
   TQuad2Trias  myResMap;
+  TRemTrias myTempTriangles;
+
   std::vector<const SMDS_MeshElement*> myPyramids;
 
   std::list< const SMDS_MeshNode* > myDegNodes;
index 1075db412219861a94ee8a70f3dce65c82c8814a..174a2441128de1ef6d992212dd4f9a75eebd0246 100644 (file)
@@ -1186,10 +1186,10 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
                                                   const TopoDS_Shape& aShape,
                                                   FaceQuadStruct* & quad) //throw (SALOME_Exception)
 {
-  // Algorithme décrit dans "Génération automatique de maillages"
-  // P.L. GEORGE, MASSON, § 6.4.1 p. 84-85
-  // traitement dans le domaine paramétrique 2d u,v
-  // transport - projection sur le carré unité
+  // Algorithme décrit dans "Génération automatique de maillages"
+  // P.L. GEORGE, MASSON, Â§ 6.4.1 p. 84-85
+  // traitement dans le domaine paramétrique 2d u,v
+  // transport - projection sur le carré unité
 
 //  MESSAGE("StdMeshers_Quadrangle_2D::SetNormalizedGrid");
 //  const TopoDS_Face& F = TopoDS::Face(aShape);
index 17d7c9f6fafbd543c9473629162f8cb6e81b1e2d..ab1e6c9c0156ed2af1d160e9f18832a9eabf3fa7 100644 (file)
@@ -123,6 +123,7 @@ libStdMeshersEngine_la_CPPFLAGS = \
        $(GEOM_CXXFLAGS) \
        $(MED_CXXFLAGS) \
        $(BOOST_CPPFLAGS) \
+        $(VTK_INCLUDES) \
        $(CORBA_CXXFLAGS) \
        $(CORBA_INCLUDES) \
        -I$(srcdir)/../SMESHImpl \