Salome HOME
Merging from V3_2_6pre4
authorabd <abd@opencascade.com>
Wed, 18 Apr 2007 15:44:59 +0000 (15:44 +0000)
committerabd <abd@opencascade.com>
Wed, 18 Apr 2007 15:44:59 +0000 (15:44 +0000)
218 files changed:
adm_local/unix/config_files/check_Platform.m4 [new file with mode: 0755]
configure.in.base [deleted file]
doc/salome/gui/SMESH/about_viewing_meshes.htm
doc/salome/gui/SMESH/building_compounds.htm [new file with mode: 0755]
doc/salome/gui/SMESH/files/about_meshing_algorithms.htm
doc/salome/gui/SMESH/files/constructing_meshes.htm
doc/salome/gui/SMESH/files/constructing_submeshes.htm
doc/salome/gui/SMESH/files/merging_nodes.htm
doc/salome/gui/SMESH/files/reassigning_hypotheses_and_algorithms.htm
doc/salome/gui/SMESH/files/vtk_3d_viewer.htm [deleted file]
doc/salome/gui/SMESH/image159.gif [new file with mode: 0755]
doc/salome/gui/SMESH/image160.gif [new file with mode: 0755]
doc/salome/gui/SMESH/image161.gif [new file with mode: 0755]
doc/salome/gui/SMESH/mesh_through_point.htm [new file with mode: 0755]
doc/salome/gui/SMESH/modifying_meshes.htm
doc/salome/gui/SMESH/pics/buildcompound.png [new file with mode: 0755]
doc/salome/gui/SMESH/pics/createmesh-inv.png
doc/salome/gui/SMESH/pics/createmesh-inv2.png
doc/salome/gui/SMESH/pics/createmesh-inv3.png
doc/salome/gui/SMESH/pics/lengthnearvertex.png [new file with mode: 0755]
doc/salome/gui/SMESH/pics/mergenodes.png
doc/salome/gui/SMESH/pics/meshtopass.png [new file with mode: 0755]
doc/salome/gui/SMESH/prism_3d_algorithm.htm
doc/salome/gui/SMESH/segments_around_vertex_algorithm.htm [new file with mode: 0755]
doc/salome/gui/SMESH/smesh.log
doc/salome/gui/SMESH/whdata/whftdata0.htm
doc/salome/gui/SMESH/whdata/whfwdata0.htm
doc/salome/gui/SMESH/whdata/whtdata0.htm
doc/salome/gui/SMESH/whxdata/whftdata0.xml
doc/salome/gui/SMESH/whxdata/whfwdata0.xml
doc/salome/gui/SMESH/whxdata/whtdata0.xml
idl/Makefile.am
idl/SMESH_BasicHypothesis.idl
idl/SMESH_Filter.idl
idl/SMESH_Gen.idl
idl/SMESH_Hypothesis.idl
idl/SMESH_Mesh.idl
idl/SMESH_MeshEditor.idl [new file with mode: 0644]
resources/Makefile.am
resources/SMESH_en.xml
resources/SMESH_fr.xml
resources/StdMeshers.xml
resources/mesh_build_compound.png [new file with mode: 0644]
resources/mesh_merge_elements.png
resources/mesh_node_to_point.png [new file with mode: 0644]
resources/mesh_tree_mesh_partial.png [new file with mode: 0755]
src/Controls/SMESH_Controls.cxx
src/Controls/SMESH_ControlsDef.hxx
src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx
src/DriverUNV/DriverUNV_W_SMDS_Mesh.cxx
src/MEFISTO2/Rn.h
src/MEFISTO2/aptrte.cxx
src/MEFISTO2/aptrte.h
src/MEFISTO2/areteideale.f
src/MEFISTO2/trte.f
src/OBJECT/SMESH_Object.cxx
src/SMDS/SMDS_FaceOfNodes.cxx
src/SMDS/SMDS_Mesh.cxx
src/SMDS/SMDS_MeshNode.cxx
src/SMDS/SMDS_MeshNode.hxx
src/SMDS/SMDS_PolygonalFaceOfNodes.cxx
src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx
src/SMDS/SMDS_PolyhedralVolumeOfNodes.hxx
src/SMDS/SMDS_QuadraticFaceOfNodes.cxx
src/SMDS/SMDS_QuadraticVolumeOfNodes.cxx
src/SMDS/SMDS_SetIterator.hxx
src/SMDS/SMDS_VolumeOfNodes.cxx
src/SMDS/SMDS_VolumeTool.cxx
src/SMDS/SMDS_VolumeTool.hxx
src/SMESH/Makefile.am
src/SMESH/SMESH_0D_Algo.cxx [new file with mode: 0644]
src/SMESH/SMESH_0D_Algo.hxx [new file with mode: 0644]
src/SMESH/SMESH_Algo.cxx
src/SMESH/SMESH_Algo.hxx
src/SMESH/SMESH_Block.hxx
src/SMESH/SMESH_Comment.hxx [new file with mode: 0644]
src/SMESH/SMESH_ComputeError.hxx [new file with mode: 0644]
src/SMESH/SMESH_Gen.cxx
src/SMESH/SMESH_Gen.hxx
src/SMESH/SMESH_Hypothesis.cxx
src/SMESH/SMESH_Hypothesis.hxx
src/SMESH/SMESH_Mesh.cxx
src/SMESH/SMESH_Mesh.hxx
src/SMESH/SMESH_MeshEditor.cxx
src/SMESH/SMESH_MeshEditor.hxx
src/SMESH/SMESH_MesherHelper.cxx
src/SMESH/SMESH_MesherHelper.hxx
src/SMESH/SMESH_Octree.cxx
src/SMESH/SMESH_Octree.hxx
src/SMESH/SMESH_OctreeNode.cxx
src/SMESH/SMESH_OctreeNode.hxx
src/SMESH/SMESH_Pattern.cxx
src/SMESH/SMESH_subMesh.cxx
src/SMESH/SMESH_subMesh.hxx
src/SMESH/SMESH_subMeshEventListener.hxx
src/SMESHClient/SMESH_Client.cxx
src/SMESHDS/SMESHDS_Hypothesis.hxx
src/SMESHDS/SMESHDS_Mesh.cxx
src/SMESHDS/SMESHDS_Mesh.hxx
src/SMESHGUI/Makefile.am
src/SMESHGUI/SMESHGUI.cxx
src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx
src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx
src/SMESHGUI/SMESHGUI_BuildCompoundDlg.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_BuildCompoundDlg.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_ComputeDlg.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_ComputeDlg.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_ConvToQuadOp.cxx
src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.cxx
src/SMESHGUI/SMESHGUI_Dialog.cxx
src/SMESHGUI/SMESHGUI_EditMeshDlg.cxx
src/SMESHGUI/SMESHGUI_EditMeshDlg.h
src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.cxx
src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.h
src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx
src/SMESHGUI/SMESHGUI_FilterDlg.cxx
src/SMESHGUI/SMESHGUI_GEOMGenUtils.cxx
src/SMESHGUI/SMESHGUI_GEOMGenUtils.h
src/SMESHGUI/SMESHGUI_GroupDlg.cxx
src/SMESHGUI/SMESHGUI_Hypotheses.cxx
src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx
src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_MergeNodesDlg.cxx
src/SMESHGUI/SMESHGUI_MergeNodesDlg.h
src/SMESHGUI/SMESHGUI_MeshDlg.cxx
src/SMESHGUI/SMESHGUI_MeshDlg.h
src/SMESHGUI/SMESHGUI_MeshEditPreview.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_MeshEditPreview.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_MeshOp.cxx
src/SMESHGUI/SMESHGUI_MeshOp.h
src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx
src/SMESHGUI/SMESHGUI_MultiEditDlg.h
src/SMESHGUI/SMESHGUI_NodesDlg.cxx
src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx
src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx
src/SMESHGUI/SMESHGUI_RenumberingDlg.cxx
src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx
src/SMESHGUI/SMESHGUI_RotationDlg.cxx
src/SMESHGUI/SMESHGUI_SewingDlg.cxx
src/SMESHGUI/SMESHGUI_ShapeByMeshDlg.cxx
src/SMESHGUI/SMESHGUI_ShapeByMeshDlg.h
src/SMESHGUI/SMESHGUI_SingleEditDlg.h
src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx
src/SMESHGUI/SMESHGUI_Swig.cxx
src/SMESHGUI/SMESHGUI_Swig.hxx
src/SMESHGUI/SMESHGUI_Swig.i
src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx
src/SMESHGUI/SMESHGUI_TranslationDlg.cxx
src/SMESHGUI/SMESHGUI_Utils.cxx
src/SMESHGUI/SMESHGUI_Utils.h
src/SMESHGUI/SMESHGUI_VTKUtils.cxx
src/SMESHGUI/SMESHGUI_VTKUtils.h
src/SMESHGUI/SMESHGUI_XmlHandler.cxx
src/SMESHGUI/SMESH_images.po
src/SMESHGUI/SMESH_msg_en.po
src/SMESH_I/Makefile.am
src/SMESH_I/SMESH_0D_Algo_i.cxx [new file with mode: 0644]
src/SMESH_I/SMESH_0D_Algo_i.hxx [new file with mode: 0644]
src/SMESH_I/SMESH_2smeshpy.cxx
src/SMESH_I/SMESH_2smeshpy.hxx
src/SMESH_I/SMESH_DumpPython.cxx
src/SMESH_I/SMESH_Filter_i.cxx
src/SMESH_I/SMESH_Filter_i.hxx
src/SMESH_I/SMESH_Gen_i.cxx
src/SMESH_I/SMESH_Gen_i.hxx
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_Mesh_i.hxx
src/SMESH_I/SMESH_subMesh_i.cxx
src/SMESH_SWIG/SMESH_shared_modules.py
src/SMESH_SWIG/smesh.py
src/StdMeshers/Makefile.am
src/StdMeshers/StdMeshers_AutomaticLength.cxx
src/StdMeshers/StdMeshers_AutomaticLength.hxx
src/StdMeshers/StdMeshers_CompositeSegment_1D.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_CompositeSegment_1D.hxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_Distribution.cxx
src/StdMeshers/StdMeshers_FaceSide.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_FaceSide.hxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_Hexa_3D.cxx
src/StdMeshers/StdMeshers_Hexa_3D.hxx
src/StdMeshers/StdMeshers_MEFISTO_2D.cxx
src/StdMeshers/StdMeshers_MEFISTO_2D.hxx
src/StdMeshers/StdMeshers_Penta_3D.cxx
src/StdMeshers/StdMeshers_Penta_3D.hxx
src/StdMeshers/StdMeshers_Prism_3D.cxx
src/StdMeshers/StdMeshers_Prism_3D.hxx
src/StdMeshers/StdMeshers_ProjectionUtils.cxx
src/StdMeshers/StdMeshers_ProjectionUtils.hxx
src/StdMeshers/StdMeshers_Projection_1D.cxx
src/StdMeshers/StdMeshers_Projection_2D.cxx
src/StdMeshers/StdMeshers_Projection_3D.cxx
src/StdMeshers/StdMeshers_Propagation.cxx
src/StdMeshers/StdMeshers_Propagation.hxx
src/StdMeshers/StdMeshers_Quadrangle_2D.cxx
src/StdMeshers/StdMeshers_Quadrangle_2D.hxx
src/StdMeshers/StdMeshers_RadialPrism_3D.cxx
src/StdMeshers/StdMeshers_RadialPrism_3D.hxx
src/StdMeshers/StdMeshers_Regular_1D.cxx
src/StdMeshers/StdMeshers_Regular_1D.hxx
src/StdMeshers/StdMeshers_SegmentAroundVertex_0D.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_SegmentAroundVertex_0D.hxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_SegmentLengthAroundVertex.cxx [new file with mode: 0644]
src/StdMeshers/StdMeshers_SegmentLengthAroundVertex.hxx [new file with mode: 0644]
src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx
src/StdMeshersGUI/StdMeshers_images.po
src/StdMeshersGUI/StdMeshers_msg_en.po
src/StdMeshers_I/Makefile.am
src/StdMeshers_I/StdMeshers_CompositeSegment_1D_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_CompositeSegment_1D_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_Regular_1D_i.cxx
src/StdMeshers_I/StdMeshers_SegmentAroundVertex_0D_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_SegmentAroundVertex_0D_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_SegmentLengthAroundVertex_i.cxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_SegmentLengthAroundVertex_i.hxx [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_i.cxx

diff --git a/adm_local/unix/config_files/check_Platform.m4 b/adm_local/unix/config_files/check_Platform.m4
new file mode 100755 (executable)
index 0000000..b4cd3d8
--- /dev/null
@@ -0,0 +1,117 @@
+dnl  Copyright (C) 2003  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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
+dnl
+dnl
+dnl
+
+AC_DEFUN([CHECK_PLATFORM],[
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_CPP])dnl
+
+AC_CHECKING(for Platform)
+
+AC_SUBST(PLATFORM_INCLUDES)
+
+PLATFORM_INCLUDES="PCLINUX"
+SUFFIXES=""
+
+f77int="F77INT32"
+case  $host_os in
+   irix5.* | irix6.* | osf4.* | osf5.* | linux*  )
+
+        linux64="true"
+        expr "$host_os" : 'linux' >/dev/null && test ! x"$host_cpu" = x"x86_64" && linux64="false"
+       if test ! x"$linux64" = "xfalse" ; then
+         echo "$as_me:$LINENO: checking for 64bits integers size in F77/F90" >&5
+echo $ECHO_N "checking for 64bits integers size in F77/F90... $ECHO_C" >&6
+         # Check whether --enable-int64 or --disable-int64 was given.
+if test "${enable_int64+set}" = set; then
+  enableval="$enable_int64"
+
+fi;
+         case "X-$enable_int64" in
+           X-no)
+            echo "$as_me:$LINENO: result: \"disabled\"" >&5
+echo "${ECHO_T}\"disabled\"" >&6
+            SUFFIXES="_32"
+            ;;
+           *)
+            echo "$as_me:$LINENO: result: \"enabled\"" >&5
+echo "${ECHO_T}\"enabled\"" >&6
+            SUFFIXES=""
+            f77int="F77INT64"
+            ;;
+         esac
+       fi
+     ;;
+   *)
+     ;;
+esac
+
+case $host_os in
+    linux*)
+        test x"$linux64" = x"true" && \
+          MACHINE="PCLINUX64${SUFFIXES}" || \
+       MACHINE=PCLINUX
+       ;;
+    hpux*)
+       MACHINE=HP9000
+       ;;
+    aix4.*)
+       MACHINE=RS6000
+       host_os_novers=aix4.x
+       ;;
+    irix5.*)
+       MACHINE="IRIX64${SUFFIXES}"
+       host_os_novers=irix5.x
+       ;;
+    irix6.*)
+       MACHINE="IRIX64${SUFFIXES}"
+       host_os_novers=irix6.x
+       ;;
+    osf4.*)
+       MACHINE="OSF1${SUFFIXES}"
+       host_os_novers=osf4.x
+       ;;
+    osf5.*)
+       MACHINE="OSF1${SUFFIXES}"
+        host_os_novers=osf5.x
+        ;;
+    solaris2.*)
+       MACHINE=SUN4SOL2
+        host_os_novers=solaris2.x
+        ;;
+    uxpv*)
+       MACHINE=VPP5000
+        ;;
+    *)
+       MACHINE=
+        host_os_novers=$host_os
+        ;;
+esac
+
+case $host_cpu in
+    ia64*)
+       MACHINE="PCLINUX64"
+       ;;
+esac
+
+PLATFORM_INCLUDES=" -D$MACHINE "
+
+])dnl
diff --git a/configure.in.base b/configure.in.base
deleted file mode 100644 (file)
index 7be9e6e..0000000
+++ /dev/null
@@ -1,427 +0,0 @@
-#
-#  PLEASE DO NOT MODIFY configure.in FILE
-#
-#  ALL CHANGES WILL BE DISCARDED BY THE NEXT
-#  build_configure COMMAND
-#
-#  CHANGES MUST BE MADE IN configure.in.base FILE
-#
-#
-# Author : Marc Tajchman (CEA)
-# Date : 28/06/2001
-# Modified by : Patrick GOLDBRONN (CEA)
-# Modified by : Marc Tajchman (CEA)
-#
-# Created from configure.in.base
-#
-
-AC_INIT(src)
-AC_CONFIG_AUX_DIR(${KERNEL_ROOT_DIR}/salome_adm/unix/config_files)
-AC_CANONICAL_HOST
-
-PACKAGE=salome
-AC_SUBST(PACKAGE)
-
-VERSION=4.0.0
-XVERSION=0x040000
-AC_SUBST(VERSION)
-AC_SUBST(XVERSION)
-
-# set up MODULE_NAME variable for dynamic construction of directories (resources, etc.)
-MODULE_NAME=smesh
-AC_SUBST(MODULE_NAME)
-
-dnl
-dnl Initialize source and build root directories
-dnl
-
-ROOT_BUILDDIR=`pwd`
-ROOT_SRCDIR=`echo $0 | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"`
-cd $ROOT_SRCDIR
-ROOT_SRCDIR=`pwd`
-cd $ROOT_BUILDDIR
-
-AC_SUBST(ROOT_SRCDIR)
-AC_SUBST(ROOT_BUILDDIR)
-
-echo
-echo Source root directory : $ROOT_SRCDIR
-echo Build  root directory : $ROOT_BUILDDIR
-echo
-echo
-
-if test -z "$AR"; then
-   AC_CHECK_PROGS(AR,ar xar,:,$PATH)
-fi
-AC_SUBST(AR)
-
-dnl Export the AR macro so that it will be placed in the libtool file
-dnl correctly.
-export AR
-
-echo
-echo ---------------------------------------------
-echo testing make
-echo ---------------------------------------------
-echo
-
-AC_PROG_MAKE_SET
-AC_PROG_INSTALL
-dnl 
-dnl libtool macro check for CC, LD, NM, LN_S, RANLIB, STRIP + pour les librairies dynamiques !
-
-AC_ENABLE_DEBUG(yes)
-AC_DISABLE_PRODUCTION
-
-echo ---------------------------------------------
-echo testing libtool
-echo ---------------------------------------------
-
-dnl first, we set static to no!
-dnl if we want it, use --enable-static
-AC_ENABLE_STATIC(no)
-
-AC_LIBTOOL_DLOPEN
-AC_PROG_LIBTOOL
-
-dnl Fix up the INSTALL macro if it s a relative path. We want the
-dnl full-path to the binary instead.
-case "$INSTALL" in
-   *install-sh*)
-      INSTALL='\${KERNEL_ROOT_DIR}'/salome_adm/unix/config_files/install-sh
-      ;;
-esac
-
-echo
-echo ---------------------------------------------
-echo testing C/C++
-echo ---------------------------------------------
-echo
-
-cc_ok=no
-dnl inutil car libtool
-dnl AC_PROG_CC
-AC_PROG_CXX
-AC_DEPEND_FLAG
-# AC_CC_WARNINGS([ansi])
-cc_ok=yes
-
-dnl Library libdl :
-AC_CHECK_LIB(dl,dlopen)
-
-dnl add library libm :
-AC_CHECK_LIB(m,ceil)
-
-dnl 
-dnl Well we use sstream which is not in gcc pre-2.95.3
-dnl We must test if it exists. If not, add it in include !
-dnl
-
-AC_CXX_HAVE_SSTREAM
-
-
-
-dnl
-dnl ---------------------------------------------
-dnl testing MPICH
-dnl ---------------------------------------------
-dnl
-
-CHECK_MPICH
-
-echo
-echo ---------------------------------------------
-echo testing LEX \& YACC
-echo ---------------------------------------------
-echo
-
-lex_yacc_ok=no
-AC_PROG_YACC
-AC_PROG_LEX
-lex_yacc_ok=yes
-
-echo
-echo ---------------------------------------------
-echo testing python
-echo ---------------------------------------------
-echo
-
-CHECK_PYTHON
-
-echo
-echo ---------------------------------------------
-echo Testing qwt
-echo ---------------------------------------------
-echo
-
-CHECK_QWT 
-
-dnl echo
-dnl echo ---------------------------------------------
-dnl echo testing java
-dnl echo ---------------------------------------------
-dnl echo
-
-dnl CHECK_JAVA
-
-echo
-echo ---------------------------------------------
-echo testing swig
-echo ---------------------------------------------
-echo
-
-CHECK_SWIG
-
-echo
-echo ---------------------------------------------
-echo testing threads
-echo ---------------------------------------------
-echo
-
-ENABLE_PTHREADS
-
-echo
-echo ---------------------------------------------
-echo testing omniORB
-echo ---------------------------------------------
-echo
-
-CHECK_OMNIORB
-
-dnl echo
-dnl echo ---------------------------------------------
-dnl echo testing mico
-dnl echo ---------------------------------------------
-dnl echo
-
-dnl CHECK_MICO
-
-echo
-echo ---------------------------------------------
-echo default ORB : omniORB
-echo ---------------------------------------------
-echo
-
-DEFAULT_ORB=omniORB
-CHECK_CORBA
-
-AC_SUBST_FILE(CORBA)
-corba=make_$ORB
-CORBA=adm_local/unix/$corba
-
-echo
-echo ---------------------------------------------
-echo testing openGL
-echo ---------------------------------------------
-echo
-
-CHECK_OPENGL
-
-echo
-echo ---------------------------------------------
-echo testing QT
-echo ---------------------------------------------
-echo
-
-CHECK_QT
-
-echo
-echo ---------------------------------------------
-echo testing MSG2QM
-echo ---------------------------------------------
-echo
-
-CHECK_MSG2QM
-
-echo
-echo ---------------------------------------------
-echo testing VTK
-echo ---------------------------------------------
-echo
-
-CHECK_VTK
-
-echo
-echo ---------------------------------------------
-echo testing HDF5
-echo ---------------------------------------------
-echo
-
-CHECK_HDF5
-
-echo
-echo ---------------------------------------------
-echo BOOST Library
-echo ---------------------------------------------
-echo
-
-CHECK_BOOST
-
-echo
-echo ---------------------------------------------
-echo Testing OpenCascade
-echo ---------------------------------------------
-echo
-
-CHECK_CAS
-
-echo
-echo ---------------------------------------------
-echo Testing html generators
-echo ---------------------------------------------
-echo
-
-CHECK_HTML_GENERATORS
-
-echo
-echo ---------------------------------------------
-echo Testing GUI
-echo ---------------------------------------------
-echo
-
-CHECK_SALOME_GUI
-
-echo
-echo ---------------------------------------------
-echo Testing full GUI
-echo ---------------------------------------------
-echo
-
-CHECK_CORBA_IN_GUI
-if test "x${CORBA_IN_GUI}" != "xyes"; then
-  echo "failed : For configure SMESH module necessary full GUI !"
-  exit
-fi
-
-echo
-echo ---------------------------------------------
-echo Testing Kernel
-echo ---------------------------------------------
-echo
-
-CHECK_KERNEL
-
-echo
-echo ---------------------------------------------
-echo Testing Geom
-echo ---------------------------------------------
-echo
-
-CHECK_GEOM
-
-echo
-echo ---------------------------------------------
-echo Testing Med
-echo ---------------------------------------------
-echo
-
-CHECK_MED
-
-echo
-echo ---------------------------------------------
-echo Summary
-echo ---------------------------------------------
-echo
-
-echo Configure
-variables="cc_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok OpenGL_ok qt_ok vtk_ok hdf5_ok omniORB_ok occ_ok doxygen_ok graphviz_ok qwt_ok Kernel_ok Geom_ok Med_ok"
-
-for var in $variables
-do
-   printf "   %10s : " `echo \$var | sed -e "s,_ok,,"`
-   eval echo \$$var
-done
-
-echo
-echo "Default ORB   : $DEFAULT_ORB"
-echo
-
-dnl generals files which could be included in every makefile
-
-AC_SUBST_FILE(COMMENCE) COMMENCE=adm_local/unix/make_commence
-AC_SUBST_FILE(CONCLUDE) CONCLUDE=adm_local/unix/make_conclude
-AC_SUBST_FILE(MODULE) MODULE=salome_adm/unix/make_module
-
-dnl les dependences
-AC_SUBST_FILE(DEPEND) DEPEND=salome_adm/unix/depend
-
-dnl We don t need to say when we re entering directories if we re using
-dnl GNU make becuase make does it for us.
-if test "X$GMAKE" = "Xyes"; then
-   AC_SUBST(SETX) SETX=":"
-else
-   AC_SUBST(SETX) SETX="set -x"
-fi
-
-# make other build directories
-for rep in salome_adm adm_local doc bin/salome include/salome lib${LIB_LOCATION_SUFFIX}/salome share/salome/resources/${MODULE_NAME} idl
-do
-#   if test ! -d $rep ; then
-#      eval mkdir $rep
-#   fi
-    $INSTALL -d $rep
-done
-
-echo 
-echo ---------------------------------------------
-echo copying resource files, shell scripts, and 
-echo xml files
-echo ---------------------------------------------
-echo
-
-
-dnl copy resources directories
-
-#for i in `find $ROOT_SRCDIR -name 'resources' -print`
-#do
-#  local_res=`echo $i | sed -e "s,$ROOT_SRCDIR,.,"`
-#  local_res_dir=`echo $local_res | sed -e "s,[[^/]]*$,,;s,/$,,;s,^$,.,"`
-#  mkdir -p $local_res_dir
-#  cd $local_res_dir
-#  ln -fs $i
-#  echo $local_res
-#  cd $ROOT_BUILDDIR
-#done
-
-dnl copy shells and utilities contained in the bin directory
-dnl excluding .in files (treated in AC-OUTPUT below) and CVS 
-dnl directory
-
-mkdir -p bin/salome
-cd bin/salome
-for i in $ROOT_SRCDIR/bin/*
-do
-  local_bin=`echo $i | sed -e "s,$ROOT_SRCDIR,.,"`
-  case "$local_bin" in
-        *.in | *~)                    ;;
-        ./bin/CVS | ./bin/salome)                    ;;
-        *) /usr/bin/install $i .; echo $local_bin ;;
-  esac
-done
-cd $ROOT_BUILDDIR
-
-AC_SUBST_FILE(ENVSCRIPT) ENVSCRIPT=salome_adm/unix/envScript
-
-dnl copy xml files to the build tree (lib directory)
-dnl pourquoi ????
-
-#cd lib
-#for i in `find $ROOT_SRCDIR -name "*.xml" -print`
-#do
-#  ln -fs $i
-#  echo `echo $i | sed -e "s,$ROOT_SRCDIR,.,"`
-#done
-#cd $ROOT_BUILDDIR
-
-
-echo
-echo ---------------------------------------------
-echo generating Makefiles and configure files
-echo ---------------------------------------------
-echo
-
-AC_OUTPUT_COMMANDS([ \
-       chmod +x ./bin/* \
-])
-
-## do not delete this line
index d47aa94f8f3ae5904ad730af8d9139877d94a84e..fcddab5dbd11177b93c61c7e18d91798c78e61fc 100755 (executable)
@@ -15,10 +15,11 @@ if (navigator.appName !="Netscape")
 <style type="text/css">
 <!--
 img_whs1 { border:none; width:25px; height:24px; border-style:none; }
-p.whs2 { margin-left:40px; }
-img_whs3 { border:none; width:404px; height:413px; border-style:none; }
-ul.whs4 { list-style:disc; }
-p.whs5 { font-weight:bold; }
+p.whs2 { font-weight:normal; }
+p.whs3 { margin-left:40px; }
+img_whs4 { border:none; width:404px; height:413px; border-style:none; }
+ul.whs5 { list-style:disc; }
+p.whs6 { font-weight:bold; }
 -->
 </style><script type="text/javascript" language="JavaScript" title="WebHelpInlineScript">
 <!--
@@ -84,12 +85,16 @@ if (window.writeIntopicBar)
 <p>After definition of algorithms and hypotheses a new mesh is listed in 
  the Object Browser. Right-click on it and select <img src="image28.gif" width="25px" height="24px" border="0" class="img_whs1"> <span 
  style="font-weight: bold;"><B>Compute</B></span> - the mesh will be automatically 
- displayed in the <span style="font-weight: bold;"><B><a href="files/vtk_3d_viewer.htm">VTK 
3D Viewer</a>.</B></span> Alternatively click<span style="font-weight: bold;"><B
Display only</B></span> to hide all other objects at the same time. </p>
+ displayed in the <span style="font-weight: bold;"><B>VTK 3D Viewer.</B></span> 
Alternatively click<span style="font-weight: bold;"><B> Display only</B></span
+ to hide all other objects at the same time. </p>
 
 <p>&nbsp;</p>
 
+<p class="whs2"><span style="font-weight: bold;"><B>VTK 3D 
+ Viewer</B></span> is detailly described in the documentation on <span style="font-weight: bold;"><B>GUI 
+ module</B></span>.</p>
+
 <p>After the mesh has appeared in the Viewer, you can select it with left 
  mouse click and &nbsp;get 
  information about it, change its presentation parameters and access to 
@@ -97,11 +102,11 @@ if (window.writeIntopicBar)
 
 <p>&nbsp;&nbsp;</p>
 
-<p class="whs2"><img src="image15.jpg" width="404px" height="413px" border="0" class="img_whs3"></p>
+<p class="whs3"><img src="image15.jpg" width="404px" height="413px" border="0" class="img_whs4"></p>
 
 <p>&nbsp;</p>
 
-<ul type="disc" class="whs4">
+<ul type="disc" class="whs5">
        
        <li class=kadov-p><p><span style="font-weight: bold;"><B>Erase all</B></span> 
  &nbsp;- allows 
@@ -115,7 +120,7 @@ if (window.writeIntopicBar)
  - &nbsp;provides 
  more detailed information about the mesh. </p></li>
        
-       <li class=kadov-p><p class="whs5"><a href="files/viewing_mesh_info.htm#standard_infos">Standard 
+       <li class=kadov-p><p class="whs6"><a href="files/viewing_mesh_info.htm#standard_infos">Standard 
  Mesh Infos</a> - <span style="font-weight: normal;">provides basic information 
  about the mesh.</span></p></li>
        
@@ -124,7 +129,7 @@ if (window.writeIntopicBar)
  to display the ID numbers of all meshing elements or nodes composing your 
  mesh in the viewer.</p></li>
        
-       <li class=kadov-p><p class="whs5"><a href="presentation.htm" style="font-weight: bold;">Display 
+       <li class=kadov-p><p class="whs6"><a href="presentation.htm" style="font-weight: bold;">Display 
  Mode</a> - <span style="font-weight: normal;">allows to select between 
  Wireframe, Shading and Nodes presentation.</span></p></li>
        
diff --git a/doc/salome/gui/SMESH/building_compounds.htm b/doc/salome/gui/SMESH/building_compounds.htm
new file mode 100755 (executable)
index 0000000..4757596
--- /dev/null
@@ -0,0 +1,160 @@
+<!doctype HTML public "-//W3C//DTD HTML 4.0 Frameset//EN">\r
+\r
+<html>\r
+\r
+<head>\r
+<title>Building Compounds</title>\r
+<meta http-equiv="content-type" content="text/html; charset=windows-1252">\r
+<meta name="generator" content="RoboHelp by eHelp Corporation www.ehelp.com"><style type="text/css">\r
+<!--\r
+p.whs1 { font-family:'Arial Black' , sans-serif; font-style:italic; }\r
+p.whs2 { margin-left:40px; }\r
+img_whs3 { border:none; width:25px; height:24px; border-style:none; }\r
+p.whs4 { margin-left:80px; }\r
+img_whs5 { border:none; width:420px; height:367px; float:none; border-style:none; }\r
+ul.whs6 { list-style:disc; }\r
+p.whs7 { margin-left:80px; margin-top:0pt; margin-bottom:0pt; }\r
+p.whs8 { margin-top:0pt; margin-bottom:0pt; margin-left:120px; }\r
+p.whs9 { margin-left:80px; margin-top:0pt; margin-bottom:0pt; font-weight:bold; }\r
+p.whs10 { margin-top:0pt; margin-bottom:0pt; font-style:italic; margin-left:24px; }\r
+img_whs11 { border:none; width:245px; height:257px; border-style:none; }\r
+-->\r
+</style><script type="text/javascript" language="JavaScript">\r
+<!--\r
+if ((navigator.appName == "Netscape") && (parseInt(navigator.appVersion) == 4))\r
+{\r
+  var strNSS = "<style type='text/css'>";\r
+  strNSS += "p.whs7 {margin-top:1pt;margin-bottom:1pt; }";\r
+  strNSS += "p.whs8 {margin-top:1pt;margin-bottom:1pt; }";\r
+  strNSS += "p.whs9 {margin-top:1pt;margin-bottom:1pt; }";\r
+  strNSS += "p.whs10 {margin-top:1pt;margin-bottom:1pt; }";\r
+  strNSS +="</style>";\r
+  document.write(strNSS);\r
+}\r
+//-->\r
+</script>\r
+<script type="text/javascript" language="JavaScript" title="WebHelpInlineScript">\r
+<!--\r
+function reDo() {\r
+  if (innerWidth != origWidth || innerHeight != origHeight)\r
+     location.reload();\r
+}\r
+if ((parseInt(navigator.appVersion) == 4) && (navigator.appName == "Netscape")) {\r
+       origWidth = innerWidth;\r
+       origHeight = innerHeight;\r
+       onresize = reDo;\r
+}\r
+onerror = null; \r
+//-->\r
+</script>\r
+<style type="text/css">\r
+<!--\r
+div.WebHelpPopupMenu { position:absolute; left:0px; top:0px; z-index:4; visibility:hidden; }\r
+p.WebHelpNavBar { text-align:right; }\r
+-->\r
+</style><script type="text/javascript" language="javascript1.2" src="whmsg.js"></script>\r
+<script type="text/javascript" language="javascript" src="whver.js"></script>\r
+<script type="text/javascript" language="javascript1.2" src="whproxy.js"></script>\r
+<script type="text/javascript" language="javascript1.2" src="whutils.js"></script>\r
+<script type="text/javascript" language="javascript1.2" src="whtopic.js"></script>\r
+<script type="text/javascript" language="javascript1.2">\r
+<!--\r
+if (window.gbWhTopic)\r
+{\r
+       if (window.setRelStartPage)\r
+       {\r
+       addTocInfo("MESH module\nCreating meshes\nBuilding Compounds");\r
+addButton("show",BTN_IMG,"Show","","","","",0,0,"whd_show0.gif","whd_show2.gif","whd_show1.gif");\r
+addButton("hide",BTN_IMG,"Hide","","","","",0,0,"whd_hide0.gif","whd_hide2.gif","whd_hide1.gif");\r
+\r
+       }\r
+\r
+\r
+       if (window.setRelStartPage)\r
+       {\r
+       setRelStartPage("index.htm");\r
+\r
+               autoSync(1);\r
+               sendSyncInfo();\r
+               sendAveInfoOut();\r
+       }\r
+\r
+}\r
+else\r
+       if (window.gbIE4)\r
+               document.location.reload();\r
+//-->\r
+</script>\r
+</head>\r
+<body><script type="text/javascript" language="javascript1.2">\r
+<!--\r
+if (window.writeIntopicBar)\r
+       writeIntopicBar(4);\r
+//-->\r
+</script>\r
+<h1>Building Compounds</h1>\r
+\r
+<p>Compound Mesh is a combination of several meshes.</p>\r
+\r
+<p class="whs1">&nbsp;To \r
+ Build a compound:</p>\r
+\r
+<p class="whs2">From the <span style="font-weight: bold;"><B>Mesh</B></span> \r
+ menu select <span style="font-weight: bold;"><B>Build Compound</B></span> or \r
+ click <img src="image161.gif" width="25px" height="24px" border="0" class="img_whs3"> button in the toolbar. The following dialog box will \r
+ appear: </p>\r
+\r
+<p class="whs4"><img src="pics/buildcompound.png" x-maintain-ratio="TRUE" width="420px" height="367px" border="0" class="img_whs5"></p>\r
+\r
+<ul type="disc" class="whs6">\r
+       \r
+       <li class=kadov-p><p class="whs7"><span style="font-weight: bold;"><B>Name</B></span> \r
+ - allows selecting the name of the resulting <span style="font-weight: bold;"><B>Compound</B></span></p></li>\r
+       \r
+       <li class=kadov-p><p class="whs7"><span style="font-weight: bold;"><B>Meshes \r
+ </B></span>- allows selecting the meshes which will be concatenated. They \r
+ can be chosen in the Object Browser while holding <span style="font-weight: bold;"><B>Ctrl</B></span> \r
+ button.</p></li>\r
+       \r
+       <li class=kadov-p><p class="whs7"><span style="font-weight: bold;"><B>Processing \r
+ identical groups</B></span> - allows selecting the method of processing the \r
+ namesake existing on the united meshes. They can be either </p></li>\r
+       \r
+       <li class=kadov-p><p class="whs8"><span style="font-weight: bold;"><B>United</B></span> \r
+ - all elements of Group1 \r
+ on Mesh_1 and \r
+ Group1 on Mesh_2 \r
+ become the elements of Group1 \r
+ on the Compound_Mesh, \r
+ or</p></li>\r
+       \r
+       <li class=kadov-p><p class="whs8"><span style="font-weight: bold;"><B>Renamed</B></span> \r
+ - Group1 on \r
+ Mesh_1 becomes \r
+ Group1_1 and \r
+ Group1 on Mesh_2 \r
+ becomes Group1_2. \r
+ See <span style="font-weight: bold;"><B><a href="grouping_elements.htm">Creating \r
+ Groups</a></B></span> for more information about groups. </p></li>\r
+       \r
+       <li class=kadov-p><p class="whs9"><span style="font-weight: normal;">You \r
+ can simply unite meshes or choose to</span> Merge coincident nodes and \r
+ elements, <span style="font-weight: normal;">in which case it is possible \r
+ to define the</span> Tolerance <span style="font-weight: normal;">for \r
+ this operation.</span> &nbsp;</p></li>\r
+</ul>\r
+\r
+<p class="whs10">Example:</p>\r
+\r
+<p class="whs4"><img src="image160.gif" width="245px" height="257px" border="0" class="img_whs11"></p>\r
+\r
+<p>&nbsp;</p>\r
+\r
+<script type="text/javascript" language="javascript1.2">\r
+<!--\r
+if (window.writeIntopicBar)\r
+       writeIntopicBar(0);\r
+//-->\r
+</script>\r
+</body>\r
+</html>\r
index 5444163bc011771c7219b82c3d94154fabf11689..ab45f918306225364a25911a471292a8b456f222 100755 (executable)
@@ -16,34 +16,35 @@ if (navigator.appName !="Netscape")
 <!--
 img_whs1 { border:none; width:30px; height:30px; float:none; border-style:none; }
 ul.whs2 { list-style:disc; }
-ul.whs3 { list-style:circle; }
-table.whs4 { x-cell-content-align:top; width:45.771%; border-spacing:0px; }
-col.whs5 { width:42.826%; }
-col.whs6 { width:57.174%; }
-tr.whs7 { x-cell-content-align:top; }
-td.whs8 { width:42.826%; padding-right:10px; padding-left:10px; border-right-style:none; border-left-style:none; border-top-style:none; border-bottom-style:none; }
-p.whs9 { margin-right:2px; }
-img_whs10 { border:none; width:170px; height:170px; border-style:none; }
-td.whs11 { width:57.174%; padding-right:10px; padding-left:10px; border-top-style:none; border-bottom-style:none; border-right-style:none; }
-p.whs12 { margin-right:240px; }
-img_whs13 { border:none; width:182px; height:177px; border-style:none; }
-table.whs14 { x-cell-content-align:top; width:30.595%; border-spacing:0px; }
-col.whs15 { width:50.334%; }
-col.whs16 { width:49.666%; }
-td.whs17 { width:50.334%; padding-right:10px; padding-left:10px; border-right-style:none; border-left-style:none; border-top-style:none; border-bottom-style:none; }
-img_whs18 { border:none; width:119px; height:299px; border-style:none; }
-td.whs19 { width:49.666%; padding-right:10px; padding-left:10px; border-top-style:none; border-bottom-style:none; border-right-style:none; }
-img_whs20 { border:none; width:127px; height:298px; border-style:none; }
-h4.whs21 { margin-left:0px; }
-p.whs22 { margin-left:0px; }
+ol.whs3 { list-style:disc; }
+ul.whs4 { list-style:circle; }
+table.whs5 { x-cell-content-align:top; width:45.771%; border-spacing:0px; }
+col.whs6 { width:42.826%; }
+col.whs7 { width:57.174%; }
+tr.whs8 { x-cell-content-align:top; }
+td.whs9 { width:42.826%; padding-right:10px; padding-left:10px; border-right-style:none; border-left-style:none; border-top-style:none; border-bottom-style:none; }
+p.whs10 { margin-right:2px; }
+img_whs11 { border:none; width:170px; height:170px; border-style:none; }
+td.whs12 { width:57.174%; padding-right:10px; padding-left:10px; border-top-style:none; border-bottom-style:none; border-right-style:none; }
+p.whs13 { margin-right:240px; }
+img_whs14 { border:none; width:182px; height:177px; border-style:none; }
+table.whs15 { x-cell-content-align:top; width:30.595%; border-spacing:0px; }
+col.whs16 { width:50.334%; }
+col.whs17 { width:49.666%; }
+td.whs18 { width:50.334%; padding-right:10px; padding-left:10px; border-right-style:none; border-left-style:none; border-top-style:none; border-bottom-style:none; }
+img_whs19 { border:none; width:119px; height:299px; border-style:none; }
+td.whs20 { width:49.666%; padding-right:10px; padding-left:10px; border-top-style:none; border-bottom-style:none; border-right-style:none; }
+img_whs21 { border:none; width:127px; height:298px; border-style:none; }
+h4.whs22 { margin-left:0px; }
+p.whs23 { margin-left:0px; }
 -->
 </style><script type="text/javascript" language="JavaScript">
 <!--
 if ((navigator.appName == "Netscape") && (parseInt(navigator.appVersion) == 4))
 {
   var strNSS = "<style type='text/css'>";
-  strNSS += "h4.whs21 {margin-left:1pt; }";
-  strNSS += "p.whs22 {margin-left:1pt; }";
+  strNSS += "h4.whs22 {margin-left:1pt; }";
+  strNSS += "p.whs23 {margin-left:1pt; }";
   strNSS +="</style>";
   document.write(strNSS);
 }
@@ -123,15 +124,24 @@ if (window.writeIntopicBar)
 
 <p>&nbsp;</p>
 
-<ul type="disc" class="whs2">
+<ol type="disc" class="whs3">
        
        <ul type="disc" class="whs2">
                
                <li style="list-style: circle;"
                        type=circle
-                       class=kadov-p><p>Wire Discretization meshing algorithm</p></li>
+                       class=kadov-p><p>Wire Discretisation meshing algorithm - splits 
+ a wire into a number of mesh segments following any 1D hypothesis.</p></li>
+               
+               <li style="list-style: circle;"
+                       type=circle
+                       class=kadov-p><p>Composite Side Discretisation algorithm - 
+ allows to apply any 1D hypothesis to a whole side of a geometrical face 
+ even if it is composed of several edges provided that they form C1 curve, 
+ have the same hypotheses assigned and form one side in all faces of the 
+ main shape of a mesh.</p></li>
        </ul>
-</ul>
+</ol>
 
 <p>&nbsp;</p>
 
@@ -142,9 +152,9 @@ if (window.writeIntopicBar)
 
 <p>&nbsp;</p>
 
-<ul type="disc" class="whs2">
+<ol type="disc" class="whs3">
        
-       <ul type="circle" class="whs3">
+       <ul type="circle" class="whs4">
                
                <li class=kadov-p><p>Triangle meshing algorithms (Mefisto and Netgen 
  1D-2D ) - Faces are split into triangular elements.</p></li>
@@ -152,19 +162,19 @@ if (window.writeIntopicBar)
                <li class=kadov-p><p>Quadrangle meshing algorithm (Mapping) - Faces 
  are split into quadrangular elements.</p></li>
        </ul>
-</ul>
+</ol>
 
 <p>&nbsp;</p>
 
-<table x-use-null-cells cellspacing="0" width="45.771%" class="whs4">
-<col class="whs5">
+<table x-use-null-cells cellspacing="0" width="45.771%" class="whs5">
 <col class="whs6">
+<col class="whs7">
 
-<tr valign="top" class="whs7">
-<td width="42.826%" class="whs8">
-<p class="whs9"><img src="../image123.gif" width="170px" height="170px" border="0" class="img_whs10"></td>
-<td width="57.174%" class="whs11">
-<p class="whs12"><img src="../image124.gif" width="182px" height="177px" border="0" class="img_whs13"></td></tr>
+<tr valign="top" class="whs8">
+<td width="42.826%" class="whs9">
+<p class="whs10"><img src="../image123.gif" width="170px" height="170px" border="0" class="img_whs11"></td>
+<td width="57.174%" class="whs12">
+<p class="whs13"><img src="../image124.gif" width="182px" height="177px" border="0" class="img_whs14"></td></tr>
 </table>
 
 <p>&nbsp;</p>
@@ -179,9 +189,9 @@ if (window.writeIntopicBar)
 
 <p>&nbsp;</p>
 
-<ul type="disc" class="whs2">
+<ol type="disc" class="whs3">
        
-       <ul type="circle" class="whs3">
+       <ul type="circle" class="whs4">
                
                <li class=kadov-p><p>Hexahedron meshing algorithm (i,j,k) - Volumes 
  are split into hexahedral (cubic) elements. </p></li>
@@ -189,19 +199,19 @@ if (window.writeIntopicBar)
                <li class=kadov-p><p>Tetrahedron (Netgen) meshing algorithm - Volumes 
  are split into tetrahedral (pyramidal) elements. </p></li>
        </ul>
-</ul>
+</ol>
 
 <p>&nbsp;</p>
 
-<table x-use-null-cells cellspacing="0" width="30.595%" class="whs14">
-<col class="whs15">
+<table x-use-null-cells cellspacing="0" width="30.595%" class="whs15">
 <col class="whs16">
+<col class="whs17">
 
-<tr valign="top" class="whs7">
-<td width="50.334%" class="whs17">
-<p><img src="../image125.gif" width="119px" height="299px" border="0" class="img_whs18"> </td>
-<td width="49.666%" class="whs19">
-<p><img src="../image126.gif" width="127px" height="298px" border="0" class="img_whs20"></td></tr>
+<tr valign="top" class="whs8">
+<td width="50.334%" class="whs18">
+<p><img src="../image125.gif" width="119px" height="299px" border="0" class="img_whs19"> </td>
+<td width="49.666%" class="whs20">
+<p><img src="../image126.gif" width="127px" height="298px" border="0" class="img_whs21"></td></tr>
 </table>
 
 <p>&nbsp;</p>
@@ -222,12 +232,12 @@ if (window.writeIntopicBar)
  prismatic shapes.</a> </p></li>
 </ul>
 
-<h4 class="whs21"><a href="constructing_meshes.htm">Constructing 
+<h4 class="whs22"><a href="constructing_meshes.htm">Constructing 
  meshes</a> <span style="font-weight: normal;">page describes in detail 
  how to apply meshing algorithms.</span><a href="constructing_meshes.htm" style="font-weight: bold;"> 
  </a></h4>
 
-<p class="whs22"><span style="font-weight: bold;"><B>See Also</B></span> 
+<p class="whs23"><span style="font-weight: bold;"><B>See Also</B></span> 
  a sample TUI Script of a <a href="../defining_hypotheses_tui.htm#bookmark8">Define 
  Meshing Algorithm</a> operation. &nbsp;</p>
 
index 1098a35d5ed3efc17f1934fb7cdf423945be7cab..832efd1bdd638a4e05a832b256d93bd61adb70bd 100755 (executable)
@@ -19,7 +19,7 @@ ul.whs2 { list-style:disc; }
 p.whs3 { margin-left:40px; }
 img_whs4 { border:none; width:22px; height:24px; border-style:none; }
 p.whs5 { margin-left:80px; }
-img_whs6 { border:none; border-style:none; width:355px; height:296px; float:none; }
+img_whs6 { border:none; width:370px; height:296px; float:none; }
 img_whs7 { border:none; width:173px; height:88px; border-style:none; }
 img_whs8 { border:none; width:34px; height:29px; border-style:none; }
 img_whs9 { border:none; width:29px; height:28px; border-style:none; }
@@ -124,7 +124,7 @@ if (window.writeIntopicBar)
 
 <p class="whs3">&nbsp;</p>
 
-<p class="whs5"><img src="../pics/createmesh-inv.png" x-maintain-ratio="TRUE" width="355px" height="296px" border="0" class="img_whs6"></p>
+<p class="whs5"><img src="../pics/createmesh-inv.png" x-maintain-ratio="TRUE" width="370px" height="296px" border="0" class="img_whs6"></p>
 
 <p class="whs5">&nbsp;</p>
 
index 9e0adf4081b1bfc938ca78add7d2fce15b8ebed0..53d39c3e7d2a2802ba12ca9b3bcba959b3aa14cb 100755 (executable)
@@ -19,7 +19,7 @@ ul.whs2 { list-style:disc; }
 p.whs3 { margin-left:40px; }
 img_whs4 { border:none; width:27px; height:25px; border-style:none; }
 p.whs5 { margin-left:80px; }
-img_whs6 { border:none; border-style:none; width:355px; height:326px; float:none; }
+img_whs6 { border:none; width:370px; height:326px; float:none; }
 p.whs7 { margin-left:38px; }
 img_whs8 { border:none; width:224px; height:212px; border-style:none; }
 -->
@@ -125,7 +125,7 @@ if (window.writeIntopicBar)
 
 <p class="whs3">&nbsp;</p>
 
-<p class="whs5"><img src="../pics/createmesh-inv2.png" x-maintain-ratio="TRUE" width="355px" height="326px" border="0" class="img_whs6"></p>
+<p class="whs5"><img src="../pics/createmesh-inv2.png" x-maintain-ratio="TRUE" width="370px" height="326px" border="0" class="img_whs6"></p>
 
 <p class="whs7">&nbsp;</p>
 
index b762170ce22b5f122fa2e56b98e24cf323bdef46..66c3f9d0e507d695e31157268fc91730b76889a5 100755 (executable)
@@ -16,7 +16,7 @@ if (navigator.appName !="Netscape")
 <!--
 img_whs1 { border:none; width:30px; height:30px; float:none; border-style:none; }
 p.whs2 { margin-left:40px; }
-img_whs3 { border:none; width:312px; height:488px; float:none; border-style:none; }
+img_whs3 { border:none; width:400px; height:488px; float:none; }
 img_whs4 { border:none; width:341px; height:375px; float:none; border-style:none; }
 img_whs5 { border:none; float:none; width:347px; height:376px; border-style:none; }
 -->
@@ -98,7 +98,7 @@ if (window.writeIntopicBar)
 
 <p>&nbsp;</p>
 
-<p class="whs2"><img src="../pics/mergenodes.png" x-maintain-ratio="TRUE" width="312px" height="488px" border="0" class="img_whs3"></p>
+<p class="whs2"><img src="../pics/mergenodes.png" x-maintain-ratio="TRUE" width="400px" height="488px" border="0" class="img_whs3"></p>
 
 <p class="whs2">&nbsp;</p>
 
index c0b0d06bcd7add9c257ad0c648b76210790b2d22..95141e9ec624c9a743049b612d37b4c3df3ca72d 100755 (executable)
@@ -14,7 +14,7 @@ if (navigator.appName !="Netscape")
 </script>
 <style type="text/css">
 <!--
-img_whs1 { border:none; border-style:none; width:355px; height:296px; float:none; }
+img_whs1 { border:none; width:370px; height:296px; float:none; }
 img_whs2 { border:none; width:30px; height:29px; border-style:none; }
 p.whs3 { margin-left:40px; }
 img_whs4 { border:none; float:none; width:386px; height:336px; border-style:none; }
@@ -105,7 +105,7 @@ if (window.writeIntopicBar)
 <p>&nbsp;</p>
 
 <p class=TODO
-       style="margin-left: 40px;"><img src="../pics/createmesh-inv3.png" x-maintain-ratio="TRUE" width="355px" height="296px" border="0" class="img_whs1"></p>
+       style="margin-left: 40px;"><img src="../pics/createmesh-inv3.png" x-maintain-ratio="TRUE" width="370px" height="296px" border="0" class="img_whs1"></p>
 
 <p>You can also change values for the current hypothesis by clicking the 
  <img src="../image122.gif" width="30px" height="29px" border="0" class="img_whs2"> button. </p>
diff --git a/doc/salome/gui/SMESH/files/vtk_3d_viewer.htm b/doc/salome/gui/SMESH/files/vtk_3d_viewer.htm
deleted file mode 100755 (executable)
index 6979fe9..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-<!doctype HTML public "-//W3C//DTD HTML 4.0 Frameset//EN">
-
-<html>
-
-<head>
-<title>VTK 3D Viewer</title>
-<meta http-equiv="content-type" content="text/html; charset=windows-1252">
-<meta name="generator" content="RoboHelp by eHelp Corporation www.ehelp.com"><style type="text/css">
-<!--
-p.whs1 { margin-top:0pt; margin-bottom:0pt; }
-p.whs2 { margin-top:0pt; margin-bottom:0pt; margin-left:48px; }
-img_whs3 { border:none; width:301px; height:26px; float:none; }
-ul.whs4 { list-style:disc; }
-img_whs5 { border:none; width:26px; height:25px; float:none; border-style:none; }
-img_whs6 { border:none; width:27px; height:25px; float:none; border-style:none; }
-img_whs7 { border:none; width:24px; height:23px; float:none; border-style:none; }
-img_whs8 { border:none; width:24px; height:24px; float:none; border-style:none; }
-img_whs9 { border:none; width:25px; height:24px; float:none; border-style:none; }
-img_whs10 { border:none; width:23px; height:23px; float:none; border-style:none; }
-img_whs11 { border:none; width:20px; height:20px; float:none; }
-p.whs12 { margin-top:0pt; margin-bottom:0pt; margin-left:80px; }
-img_whs13 { border:none; width:410px; height:255px; float:none; }
-img_whs14 { border:none; width:26px; height:26px; float:none; border-style:none; }
-img_whs15 { border:none; width:78px; height:147px; float:none; border-style:none; }
-img_whs16 { border:none; width:28px; height:25px; float:none; border-style:none; }
-img_whs17 { border:none; width:27px; height:27px; float:none; border-style:none; }
-p.whs18 { font-weight:bold; margin-left:80px; margin-top:0pt; margin-bottom:0pt; }
-img_whs19 { border:none; width:350px; height:453px; float:none; border-style:none; }
-p.whs20 { font-weight:bold; margin-top:0pt; margin-bottom:0pt; }
-p.whs21 { font-weight:bold; margin-left:36px; margin-top:0pt; margin-bottom:0pt; }
-p.whs22 { font-weight:bold; margin-left:0px; margin-top:0pt; margin-bottom:0pt; }
-p.whs23 { margin-left:0px; font-weight:bold; margin-top:0pt; margin-bottom:0pt; }
--->
-</style><script type="text/javascript" language="JavaScript">
-<!--
-if ((navigator.appName == "Netscape") && (parseInt(navigator.appVersion) == 4))
-{
-  var strNSS = "<style type='text/css'>";
-  strNSS += "p.whs1 {margin-top:1pt;margin-bottom:1pt; }";
-  strNSS += "p.whs2 {margin-top:1pt;margin-bottom:1pt; }";
-  strNSS += "p.whs12 {margin-top:1pt;margin-bottom:1pt; }";
-  strNSS += "p.whs18 {margin-top:1pt;margin-bottom:1pt; }";
-  strNSS += "p.whs20 {margin-top:1pt;margin-bottom:1pt; }";
-  strNSS += "p.whs21 {margin-top:1pt;margin-bottom:1pt; }";
-  strNSS += "p.whs22 {margin-left:1pt;margin-top:1pt;margin-bottom:1pt; }";
-  strNSS += "p.whs23 {margin-left:1pt;margin-top:1pt;margin-bottom:1pt; }";
-  strNSS +="</style>";
-  document.write(strNSS);
-}
-//-->
-</script>
-<script type="text/javascript" language="JavaScript" title="WebHelpInlineScript">
-<!--
-function reDo() {
-  if (innerWidth != origWidth || innerHeight != origHeight)
-     location.reload();
-}
-if ((parseInt(navigator.appVersion) == 4) && (navigator.appName == "Netscape")) {
-       origWidth = innerWidth;
-       origHeight = innerHeight;
-       onresize = reDo;
-}
-onerror = null; 
-//-->
-</script>
-<style type="text/css">
-<!--
-div.WebHelpPopupMenu { position:absolute; left:0px; top:0px; z-index:4; visibility:hidden; }
-p.WebHelpNavBar { text-align:right; }
--->
-</style><script type="text/javascript" language="javascript1.2" src="../whmsg.js"></script>
-<script type="text/javascript" language="javascript" src="../whver.js"></script>
-<script type="text/javascript" language="javascript1.2" src="../whproxy.js"></script>
-<script type="text/javascript" language="javascript1.2" src="../whutils.js"></script>
-<script type="text/javascript" language="javascript1.2" src="../whtopic.js"></script>
-<script type="text/javascript" language="javascript1.2">
-<!--
-if (window.gbWhTopic)
-{
-       if (window.setRelStartPage)
-       {
-       addTocInfo("MESH module\nViewing meshes\nVTK 3D Viewer");
-addButton("show",BTN_IMG,"Show","","","","",0,0,"../whd_show0.gif","../whd_show2.gif","../whd_show1.gif");
-addButton("hide",BTN_IMG,"Hide","","","","",0,0,"../whd_hide0.gif","../whd_hide2.gif","../whd_hide1.gif");
-
-       }
-
-
-       if (window.setRelStartPage)
-       {
-       setRelStartPage("../index.htm");
-
-               autoSync(1);
-               sendSyncInfo();
-               sendAveInfoOut();
-       }
-
-}
-else
-       if (window.gbIE4)
-               document.location.reload();
-//-->
-</script>
-</head>
-<body><script type="text/javascript" language="javascript1.2">
-<!--
-if (window.writeIntopicBar)
-       writeIntopicBar(4);
-//-->
-</script>
-<h1>VTK 3D Viewer</h1>
-
-<p class="whs1"><span style="font-weight: bold;"><B>VTK 
- 3D viewer</B></span> is the default viewer for Mesh Module, allowing to visualize 
- meshes. It is also used in Post-Pro module for all 3D presentations except 
- for Gauss Points.</p>
-
-<p class="whs1">&nbsp;</p>
-
-<p class="whs1">The functionalities of 
- VTK viewer are available via its Viewer Toolbar. Buttons marked with small 
- downward triangles have extended functionality which can be accessed by 
- locking on them with left mouse button. &nbsp;</p>
-
-<p class="whs1">&nbsp;</p>
-
-<p class="whs2"><img src="../pics/image157.gif" x-maintain-ratio="TRUE" width="301px" height="26px" border="0" class="img_whs3"></p>
-
-<ul type="disc" class="whs4">
-       
-       <li class=kadov-p><p class="whs1"><img src="../pics/image77.gif" x-maintain-ratio="TRUE" width="26px" height="25px" border="0" class="img_whs5"> <span style="font-weight: bold;"><B>Dump View</B></span> - exports 
- an object from the viewer in bmp, png, jpg or jpeg image format. </p></li>
-       
-       <li class=kadov-p><p class="whs1"><img src="../pics/image78.gif" x-maintain-ratio="TRUE" width="27px" height="25px" border="0" class="img_whs6"> <span style="font-weight: bold;"><B>Show/Hide Trihedron</B></span> 
- - shows or hides coordinate axes. </p></li>
-       
-       <li class=kadov-p><p class="whs1"><img src="../pics/image96.gif" x-maintain-ratio="TRUE" width="24px" height="23px" border="0" class="img_whs7"> &nbsp;<span style="font-weight: bold;"><B>Fit 
- all - </B></span>allows to select a point to be the center of a scene representing 
- all displayed objects in the visible area.<span style="font-weight: bold;"> 
- <B></B></span></p></li>
-       
-       <li class=kadov-p><p class="whs1">&nbsp;<img src="../pics/image97.gif" x-maintain-ratio="TRUE" width="24px" height="24px" border="0" class="img_whs8"> <span style="font-weight: bold;"><B>Fit area</B></span> - resizes 
- the view to place in the visible area only the contents of a frame drawn 
- with pressed left mouse button.</p></li>
-       
-       <li class=kadov-p><p class="whs1"><img src="../pics/image98.gif" x-maintain-ratio="TRUE" width="25px" height="24px" border="0" class="img_whs9"> <span style="font-weight: bold;"><B>Zoom</B></span> - &nbsp;allows 
- to zoom in and out. </p></li>
-       
-       <li class=kadov-p><p class="whs1"><img src="../pics/image99.gif" x-maintain-ratio="TRUE" width="23px" height="23px" border="0" class="img_whs10"> <span style="font-weight: bold;"><B>Panning</B></span> - if the 
- represented objects are greater that the visible area and you don't wish 
- to use <span style="font-weight: bold;"><B>Fit all</B></span> functionality, 
- click on this button and you'll be able to drag the scene to see its remote 
- parts. </p></li>
-       
-       <li class=kadov-p><p class="whs1"><img src="../pics/image100.gif" x-maintain-ratio="TRUE" width="24px" height="24px" border="0" class="img_whs8"> <span style="font-weight: bold;"><B>Global panning</B></span> - 
- represents all displayed objects in the visible area. </p></li>
-       
-       <li class=kadov-p><p class="whs1"><img src="../pics/view_rotation_point.png" x-maintain-ratio="TRUE" width="20px" height="20px" border="0" class="img_whs11"> <span style="font-weight: bold;"><B>Change rotation point</B></span> 
- - allows to to choose the point around which the rotation is performed</p></li>
-</ul>
-
-<p class="whs12"><img src="../pics/set_rotation_point_dialog1.png" x-maintain-ratio="TRUE" width="410px" height="255px" border="0" class="img_whs13"></p>
-
-<p class="whs12">&nbsp;</p>
-
-<p class="whs12">By default the rotation point is located 
- in the Center of the bounding box of an object. </p>
-
-<p class="whs12">&nbsp;</p>
-
-<p class="whs12"><img src="../pics/set_rotation_point_dialog2.png" x-maintain-ratio="TRUE" width="410px" height="255px" border="0" class="img_whs13"></p>
-
-<p class="whs12">&nbsp;</p>
-
-<p class="whs12">Unchecking <span style="font-weight: bold;"><B>Use 
- Bounding Box Center</B></span> box allows you to define the coordinates of 
- the rotation point manually. </p>
-
-<p class="whs12">&nbsp;</p>
-
-<p class="whs12"><span style="font-weight: bold;"><B>Set to 
- Origin</B></span> button restores the default rotation point coordinates.</p>
-
-<p class="whs12"><span style="font-weight: bold;"><B>Select 
- Point from View</B></span> button allows to select the rotation point in the 
- 3D Viewer</p>
-
-<ul type="disc" class="whs4">
-       
-       <li class=kadov-p><p class="whs1"><img src="../pics/image89.gif" x-maintain-ratio="TRUE" width="26px" height="26px" border="0" class="img_whs14"> <span style="font-weight: bold;"><B>Rotation</B></span> - allows 
- to rotate the selected object using the mouse. </p></li>
-       
-       <li class=kadov-p><p class="whs1"><img src="../pics/image102.gif" x-maintain-ratio="TRUE" width="78px" height="147px" border="0" class="img_whs15"> These buttons orientate the scene strictly about coordinate 
- axes.</p></li>
-       
-       <li class=kadov-p><p class="whs1"><img src="../pics/image91.gif" x-maintain-ratio="TRUE" width="26px" height="26px" border="0" class="img_whs14"> <span style="font-weight: bold;"><B>Reset</B></span> - restores 
- the default position (isometric) of objects in the scene.</p></li>
-       
-       <li class=kadov-p><p class="whs1"><img src="../pics/image108.gif" x-maintain-ratio="TRUE" width="28px" height="25px" border="0" class="img_whs16"> <span style="font-weight: bold;"><B>Scaling</B></span> - represents 
- objects deformed (stretched or stuffed) along the axes of coordinates</p></li>
-       
-       <li class=kadov-p><p class="whs1">&nbsp;<span 
- style="font-weight: bold;
-               margin-top: 0pt;
-               margin-bottom: 0pt;"><B><img src="../pics/image109.gif" x-maintain-ratio="TRUE" width="27px" height="27px" border="0" class="img_whs17">Graduated axes - </B></span><span style="margin-top: 0pt;
-                                                                                                       margin-bottom: 0pt;
-                                                                                                       font-weight: normal;">allows 
- to define parameters of axes and graduate them.</span></p></li>
-</ul>
-
-<p class="whs1">&nbsp;</p>
-
-<p class="whs18"><img src="../pics/graduatedaxes1.png" x-maintain-ratio="TRUE" width="350px" height="453px" border="0" class="img_whs19"></p>
-
-<ul type="disc" class="whs4">
-       
-       <li class=kadov-p><p class="whs20">Axis name </p></li>
-       
-       <li class=kadov-p><p class="whs21">Is visible - <span 
- style="font-weight: normal;">if checked the axis name is displayed in 
- the viewer.</span></p></li>
-       
-       <li class=kadov-p><p class="whs21">Name<span style="font-weight: normal;"> 
- - allows to redefine the name of the axis.</span></p></li>
-       
-       <li class=kadov-p><p class="whs21">Font<span style="font-weight: normal;"> 
- - allows to define color and properties of the font of axis name. </span></p></li>
-       
-       <li class=kadov-p><p class="whs22">Labels<span style="font-weight: normal;"> 
- </span></p></li>
-       
-       <li class=kadov-p><p class="whs21">Is visible - <span 
- style="font-weight: normal;">if checked the labels are displayed in the 
- viewer.</span></p></li>
-       
-       <li class=kadov-p><p class="whs21">Number<span style="font-weight: normal;"> 
- - allows to define the number of labels.</span></p></li>
-       
-       <li class=kadov-p><p class="whs21">Offset<span style="font-weight: normal;"> 
- - allows to define the distance between labels.</span></p></li>
-       
-       <li class=kadov-p><p class="whs21">Font<span style="font-weight: normal;"> 
- - allows to define color and properties of the font of labels names.</span></p></li>
-       
-       <li class=kadov-p><p class="whs23">Tick marks </p></li>
-       
-       <li class=kadov-p><p class="whs21">Is visible - <span 
- style="font-weight: normal;">if checked the tick marks are displayed in 
- the viewer.</span></p></li>
-       
-       <li class=kadov-p><p class="whs21">Length<span style="font-weight: normal;"> 
- - allows to define the length of tick marks</span></p></li>
-       
-       <li class=kadov-p><p class="whs23">Is visible <span style="font-weight: normal;">if 
- checked the axis is displayed in the viewer.</span></p></li>
-</ul>
-
-<script type="text/javascript" language="javascript1.2">
-<!--
-if (window.writeIntopicBar)
-       writeIntopicBar(0);
-//-->
-</script>
-</body>
-</html>
diff --git a/doc/salome/gui/SMESH/image159.gif b/doc/salome/gui/SMESH/image159.gif
new file mode 100755 (executable)
index 0000000..45a024e
Binary files /dev/null and b/doc/salome/gui/SMESH/image159.gif differ
diff --git a/doc/salome/gui/SMESH/image160.gif b/doc/salome/gui/SMESH/image160.gif
new file mode 100755 (executable)
index 0000000..6baffdb
Binary files /dev/null and b/doc/salome/gui/SMESH/image160.gif differ
diff --git a/doc/salome/gui/SMESH/image161.gif b/doc/salome/gui/SMESH/image161.gif
new file mode 100755 (executable)
index 0000000..54364d2
Binary files /dev/null and b/doc/salome/gui/SMESH/image161.gif differ
diff --git a/doc/salome/gui/SMESH/mesh_through_point.htm b/doc/salome/gui/SMESH/mesh_through_point.htm
new file mode 100755 (executable)
index 0000000..bf8e6f4
--- /dev/null
@@ -0,0 +1,132 @@
+<!doctype HTML public "-//W3C//DTD HTML 4.0 Frameset//EN">\r
+\r
+<html>\r
+\r
+<head>\r
+<title>Mesh through point</title>\r
+<meta http-equiv="content-type" content="text/html; charset=windows-1252">\r
+<meta name="generator" content="RoboHelp by eHelp Corporation www.ehelp.com"><style type="text/css">\r
+<!--\r
+p.whs1 { font-family:'Arial Black' , sans-serif; font-style:italic; margin-left:0px; }\r
+p.whs2 { margin-left:36px; }\r
+img_whs3 { border:none; width:27px; height:29px; border-style:none; }\r
+img_whs4 { border:none; width:355px; height:366px; float:none; border-style:none; }\r
+p.whs5 { margin-left:40px; font-family:'Times New Roman' , serif; font-style:normal; }\r
+-->\r
+</style><script type="text/javascript" language="JavaScript">\r
+<!--\r
+if ((navigator.appName == "Netscape") && (parseInt(navigator.appVersion) == 4))\r
+{\r
+  var strNSS = "<style type='text/css'>";\r
+  strNSS += "p.whs1 {margin-left:1pt; }";\r
+  strNSS +="</style>";\r
+  document.write(strNSS);\r
+}\r
+//-->\r
+</script>\r
+<script type="text/javascript" language="JavaScript" title="WebHelpInlineScript">\r
+<!--\r
+function reDo() {\r
+  if (innerWidth != origWidth || innerHeight != origHeight)\r
+     location.reload();\r
+}\r
+if ((parseInt(navigator.appVersion) == 4) && (navigator.appName == "Netscape")) {\r
+       origWidth = innerWidth;\r
+       origHeight = innerHeight;\r
+       onresize = reDo;\r
+}\r
+onerror = null; \r
+//-->\r
+</script>\r
+<style type="text/css">\r
+<!--\r
+div.WebHelpPopupMenu { position:absolute; left:0px; top:0px; z-index:4; visibility:hidden; }\r
+p.WebHelpNavBar { text-align:right; }\r
+-->\r
+</style><script type="text/javascript" language="javascript1.2" src="whmsg.js"></script>\r
+<script type="text/javascript" language="javascript" src="whver.js"></script>\r
+<script type="text/javascript" language="javascript1.2" src="whproxy.js"></script>\r
+<script type="text/javascript" language="javascript1.2" src="whutils.js"></script>\r
+<script type="text/javascript" language="javascript1.2" src="whtopic.js"></script>\r
+<script type="text/javascript" language="javascript1.2">\r
+<!--\r
+if (window.gbWhTopic)\r
+{\r
+       if (window.setRelStartPage)\r
+       {\r
+       addTocInfo("MESH module\nModifying meshes\nMesh through point");\r
+addButton("show",BTN_IMG,"Show","","","","",0,0,"whd_show0.gif","whd_show2.gif","whd_show1.gif");\r
+addButton("hide",BTN_IMG,"Hide","","","","",0,0,"whd_hide0.gif","whd_hide2.gif","whd_hide1.gif");\r
+\r
+       }\r
+\r
+\r
+       if (window.setRelStartPage)\r
+       {\r
+       setRelStartPage("index.htm");\r
+\r
+               autoSync(1);\r
+               sendSyncInfo();\r
+               sendAveInfoOut();\r
+       }\r
+\r
+}\r
+else\r
+       if (window.gbIE4)\r
+               document.location.reload();\r
+//-->\r
+</script>\r
+</head>\r
+<body><script type="text/javascript" language="javascript1.2">\r
+<!--\r
+if (window.writeIntopicBar)\r
+       writeIntopicBar(4);\r
+//-->\r
+</script>\r
+<h1>Mesh through point</h1>\r
+\r
+<p>In mesh you can define a node at a certain point either by creation \r
+ of a new node, by movement of the node closest to the point or by movement \r
+ of any node to the point.</p>\r
+\r
+<p class="whs1">To create a mesh passing through a point:</p>\r
+\r
+<p class="whs2">1. From the <span style="font-weight: bold;"><B>Modification \r
+ </B></span>menu choose the <span style="font-weight: bold;"><B>Mesh through point \r
+ </B></span>item or click <img src="image159.gif" width="27px" height="29px" border="0" class="img_whs3"> button in the toolbar. The following \r
+ dialog box shall appear:</p>\r
+\r
+<p class="whs2"><img src="pics/meshtopass.png" x-maintain-ratio="TRUE" width="355px" height="366px" border="0" class="img_whs4"></p>\r
+\r
+<p class="whs2">2. Enter the coordinates of the point</p>\r
+\r
+<p class="whs2">3. Choose one of several methods: you can \r
+ either <span style="font-weight: bold;"><B>Create</B></span> a new node at the \r
+ indicated point or Move the existing node to the point. In the latter \r
+ case you can check in <span style="font-weight: bold;"><B>Automatic search</B></span> \r
+ of the closest node or select the necessary node manually. <span style="font-weight: bold;"><B>Preview</B></span> \r
+ check-box allows to see the results of the operation. </p>\r
+\r
+<p class="whs2">4. Click the <span style="font-weight: bold;"><B>Apply \r
+ </B></span>or <span style="font-weight: bold;"><B>OK </B></span>button.</p>\r
+\r
+<p>&nbsp;<span style="font-weight: bold;"><B>See \r
+ Also</B></span> a sample TUI Script of a <a href="modifying_meshes.htm#bookmark14">Mesh \r
+ through point</a> operation. &nbsp;</p>\r
+\r
+<p>&nbsp;</p>\r
+\r
+<p class="whs2">&nbsp;</p>\r
+\r
+<p>&nbsp;</p>\r
+\r
+<p class="whs5">&nbsp;</p>\r
+\r
+<script type="text/javascript" language="javascript1.2">\r
+<!--\r
+if (window.writeIntopicBar)\r
+       writeIntopicBar(0);\r
+//-->\r
+</script>\r
+</body>\r
+</html>\r
index 7ed7089df751fe972eee3c48acd08c5971bc81f5..e33ea8c4ba0d7966ec5c34d6d02fc8270124bbf7 100755 (executable)
@@ -18,13 +18,14 @@ p.whs3 { margin-top:0pt; margin-bottom:0pt; }
 h4.whs4 { margin-top:0pt; margin-bottom:0pt; }
 p.whs5 { margin-top:0.5pt; margin-bottom:0pt; font-family:'Lucida Console' , monospace; }
 p.whs6 { margin-top:0.5pt; margin-bottom:0pt; }
-p.whs7 { margin-top:0.5pt; margin-bottom:0pt; font-family:'Times New Roman' , serif; }
-p.whs8 { font-family:'Lucida Console' , monospace; }
-p.whs9 { font-family:'Times New Roman' , serif; }
-p.whs10 { margin-left:36px; font-family:'Lucida Console' , monospace; }
-p.whs11 { margin-left:36px; }
-p.whs12 { margin-left:0px; font-family:'Times New Roman' , serif; }
-p.whs13 { font-family:'Lucida Console' , monospace; margin-left:0px; }
+p.whs7 { margin-top:0pt; margin-bottom:0pt; font-family:'Times New Roman' , serif; font-weight:bold; font-size:13.5pt; }
+p.whs8 { margin-top:0.5pt; margin-bottom:0pt; font-family:'Times New Roman' , serif; }
+p.whs9 { font-family:'Lucida Console' , monospace; }
+p.whs10 { font-family:'Times New Roman' , serif; }
+p.whs11 { margin-left:36px; font-family:'Lucida Console' , monospace; }
+p.whs12 { margin-left:36px; }
+p.whs13 { margin-left:0px; font-family:'Times New Roman' , serif; }
+p.whs14 { font-family:'Lucida Console' , monospace; margin-left:0px; }
 -->
 </style><script type="text/javascript" language="JavaScript">
 <!--
@@ -38,8 +39,9 @@ if ((navigator.appName == "Netscape") && (parseInt(navigator.appVersion) == 4))
   strNSS += "p.whs5 {margin-top:1pt;margin-bottom:1pt; }";
   strNSS += "p.whs6 {margin-top:1pt;margin-bottom:1pt; }";
   strNSS += "p.whs7 {margin-top:1pt;margin-bottom:1pt; }";
-  strNSS += "p.whs12 {margin-left:1pt; }";
+  strNSS += "p.whs8 {margin-top:1pt;margin-bottom:1pt; }";
   strNSS += "p.whs13 {margin-left:1pt; }";
+  strNSS += "p.whs14 {margin-left:1pt; }";
   strNSS +="</style>";
   document.write(strNSS);
 }
@@ -652,8 +654,135 @@ if (window.writeIntopicBar)
 <p class="whs1">mesh.MoveNode(38, 
  20., 10., 0.) </p>
 
+<p class="whs1">&nbsp;</p>
+
+<p class="whs2">&nbsp;</p>
+
+<p class="whs7"><a name=bookmark14
+                                                                       style="font-weight: bold; font-size: 13.5pt;">Mesh 
+ through point</a></p>
+
 <p class="whs3">&nbsp;</p>
 
+<p class="whs1">from geompy import 
+ *</p>
+
+<p class="whs1">from smesh import 
+ *</p>
+
+<p class="whs1">&nbsp;</p>
+
+<p class="whs1">box = MakeBoxDXDYDZ(200, 
+ 200, 200)</p>
+
+<p class="whs1">&nbsp;</p>
+
+<p class="whs1">mesh = Mesh( box 
+ )</p>
+
+<p class="whs1">mesh.Segment().AutomaticLength(0.1)</p>
+
+<p class="whs1">mesh.Quadrangle()</p>
+
+<p class="whs1">mesh.Compute()</p>
+
+<p class="whs3">&nbsp;</p>
+
+<p class="whs3"># find node at (0,0,0)</p>
+
+<p class="whs1">node000 = None</p>
+
+<p class="whs1">for vId in SubShapeAllIDs( 
+ box, ShapeType[&quot;VERTEX&quot;]):</p>
+
+<p class="whs1">&nbsp;&nbsp;&nbsp;&nbsp;if 
+ node000: break</p>
+
+<p class="whs1">&nbsp;&nbsp;&nbsp;&nbsp;nodeIds 
+ = mesh.GetSubMeshNodesId( vId, True )</p>
+
+<p class="whs1">&nbsp;&nbsp;&nbsp;&nbsp;for 
+ node in nodeIds:</p>
+
+<p class="whs1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xyz 
+ = mesh.GetNodeXYZ( node )</p>
+
+<p class="whs1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if 
+ xyz[0] == 0 and xyz[1] == 0 and xyz[2] == 0 :</p>
+
+<p class="whs1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;node000 
+ = node</p>
+
+<p class="whs1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pass</p>
+
+<p class="whs1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pass</p>
+
+<p class="whs1">&nbsp;&nbsp;&nbsp;&nbsp;pass</p>
+
+<p class="whs1">if not node000:</p>
+
+<p class="whs1">&nbsp;&nbsp;&nbsp;&nbsp;raise 
+ &quot;node000 not found&quot;</p>
+
+<p class="whs3">&nbsp;</p>
+
+<p class="whs3"># find node000 using the 
+ tested function </p>
+
+<p class="whs1">n = mesh.FindNodeClosestTo( 
+ -1,-1,-1 )</p>
+
+<p class="whs1">if not n == node000:</p>
+
+<p class="whs1">&nbsp;&nbsp;&nbsp;&nbsp;raise 
+ &quot;FindNodeClosestTo() returns &quot; + str( n ) + &quot; != &quot; 
+ + str( node000 )</p>
+
+<p class="whs3">&nbsp;</p>
+
+<p class="whs3"># check if any node will 
+ be found for a point inside a box</p>
+
+<p class="whs1">n = mesh.FindNodeClosestTo( 
+ 100, 100, 100 )</p>
+
+<p class="whs1">if not n &gt; 0:</p>
+
+<p class="whs1">&nbsp;&nbsp;&nbsp;&nbsp;raise 
+ &quot;FindNodeClosestTo( 100, 100, 100 ) fails&quot;</p>
+
+<p class="whs3">&nbsp;</p>
+
+<p class="whs3"># move node000 to a new 
+ location</p>
+
+<p class="whs1">x,y,z = -10, -10, 
+ -10</p>
+
+<p class="whs1">n = mesh.MeshToPassThroughAPoint( 
+ x,y,z )</p>
+
+<p class="whs1">if not n == node000:</p>
+
+<p class="whs1">&nbsp;&nbsp;&nbsp;&nbsp;raise 
+ &quot;FindNodeClosestTo() returns &quot; + str( n ) + &quot; != &quot; 
+ + str( node000 )</p>
+
+<p class="whs3">&nbsp;</p>
+
+<p class="whs3"># check the coordinates 
+ of the node000</p>
+
+<p class="whs1">xyz = mesh.GetNodeXYZ( 
+ node000 )</p>
+
+<p class="whs1">if not ( xyz[0] 
+ == x and xyz[1] == y and xyz[2] == z) :</p>
+
+<p class="whs1">&nbsp;&nbsp;&nbsp;&nbsp;raise 
+ &quot;Wrong coordinates: &quot; + str( xyz ) + &quot; != &quot; + str( 
+ [x,y,z] )</p>
+
 <h3><a name=bookmark4>Diagonal Inversion</a></h3>
 
 <p class="whs5">import salome</p>
@@ -662,7 +791,7 @@ if (window.writeIntopicBar)
 
 <p class="whs5">&nbsp;</p>
 
-<p class="whs7"># create an empty mesh 
+<p class="whs8"># create an empty mesh 
  structure</p>
 
 <p class="whs5">mesh = smesh.Mesh() 
@@ -670,7 +799,7 @@ if (window.writeIntopicBar)
 
 <p class="whs5">&nbsp;</p>
 
-<p class="whs7"># create the following 
+<p class="whs8"># create the following 
  mesh:</p>
 
 <p class="whs5"># .----.----.----.</p>
@@ -751,7 +880,7 @@ if (window.writeIntopicBar)
 
 <p class="whs5">&nbsp;</p>
 
-<p class="whs7"># inverse the diagonal 
+<p class="whs8"># inverse the diagonal 
  bb[1] - tt[2]</p>
 
 <p class="whs5">print &quot;\nDiagonal 
@@ -773,973 +902,973 @@ if (window.writeIntopicBar)
 
 <h3><a name=bookmark5>Uniting two Triangles</a></h3>
 
-<p class="whs8">import salome</p>
+<p class="whs9">import salome</p>
 
-<p class="whs8">import smesh</p>
+<p class="whs9">import smesh</p>
 
 <p>&nbsp;</p>
 
 <p># create an empty mesh structure</p>
 
-<p class="whs8">mesh = smesh.Mesh() 
+<p class="whs9">mesh = smesh.Mesh() 
  </p>
 
 <p>&nbsp;</p>
 
 <p># create the following mesh:</p>
 
-<p class="whs8"># .----.----.----.</p>
+<p class="whs9"># .----.----.----.</p>
 
-<p class="whs8"># | &nbsp;&nbsp;/| 
+<p class="whs9"># | &nbsp;&nbsp;/| 
  &nbsp;&nbsp;/| 
  &nbsp;&nbsp;/|</p>
 
-<p class="whs8"># | &nbsp;/ 
+<p class="whs9"># | &nbsp;/ 
  | &nbsp;/ | &nbsp;/ 
  |</p>
 
-<p class="whs8"># | / &nbsp;| 
+<p class="whs9"># | / &nbsp;| 
  / &nbsp;| / &nbsp;|</p>
 
-<p class="whs8"># |/ &nbsp;&nbsp;|/ 
+<p class="whs9"># |/ &nbsp;&nbsp;|/ 
  &nbsp;&nbsp;|/ 
  &nbsp;&nbsp;|</p>
 
-<p class="whs8"># .----.----.----.</p>
+<p class="whs9"># .----.----.----.</p>
 
 <p>&nbsp;</p>
 
-<p class="whs8">bb = [0, 0, 0, 0]</p>
+<p class="whs9">bb = [0, 0, 0, 0]</p>
 
-<p class="whs8">tt = [0, 0, 0, 0]</p>
+<p class="whs9">tt = [0, 0, 0, 0]</p>
 
-<p class="whs8">ff = [0, 0, 0, 0, 
+<p class="whs9">ff = [0, 0, 0, 0, 
  0, 0]</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8"><span style="font-family: 'Lucida Console', monospace;">bb[0] 
+<p class="whs9"><span style="font-family: 'Lucida Console', monospace;">bb[0] 
  = mesh.AddNode( 0., 0., 0.)</span></p>
 
-<p class="whs8">bb[1] = mesh.AddNode(10., 
+<p class="whs9">bb[1] = mesh.AddNode(10., 
  0., 0.)</p>
 
-<p class="whs8">bb[2] = mesh.AddNode(20., 
+<p class="whs9">bb[2] = mesh.AddNode(20., 
  0., 0.)</p>
 
-<p class="whs8">bb[3] = mesh.AddNode(30., 
+<p class="whs9">bb[3] = mesh.AddNode(30., 
  0., 0.)</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8">tt[0] = mesh.AddNode( 
+<p class="whs9">tt[0] = mesh.AddNode( 
  0., 15., 0.)</p>
 
-<p class="whs8">tt[1] = mesh.AddNode(10., 
+<p class="whs9">tt[1] = mesh.AddNode(10., 
  15., 0.)</p>
 
-<p class="whs8">tt[2] = mesh.AddNode(20., 
+<p class="whs9">tt[2] = mesh.AddNode(20., 
  15., 0.)</p>
 
-<p class="whs8">tt[3] = mesh.AddNode(30., 
+<p class="whs9">tt[3] = mesh.AddNode(30., 
  15., 0.)</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8">ff[0] = mesh.AddFace([bb[0], 
+<p class="whs9">ff[0] = mesh.AddFace([bb[0], 
  bb[1], tt[1]])</p>
 
-<p class="whs8">ff[1] = mesh.AddFace([bb[0], 
+<p class="whs9">ff[1] = mesh.AddFace([bb[0], 
  tt[1], tt[0]])</p>
 
-<p class="whs8">ff[2] = mesh.AddFace([bb[1], 
+<p class="whs9">ff[2] = mesh.AddFace([bb[1], 
  bb[2], tt[2]])</p>
 
-<p class="whs8">ff[3] = mesh.AddFace([bb[1], 
+<p class="whs9">ff[3] = mesh.AddFace([bb[1], 
  tt[2], tt[1]])</p>
 
-<p class="whs8">ff[4] = mesh.AddFace([bb[2], 
+<p class="whs9">ff[4] = mesh.AddFace([bb[2], 
  bb[3], tt[3]])</p>
 
-<p class="whs8">ff[5] = mesh.AddFace([bb[2], 
+<p class="whs9">ff[5] = mesh.AddFace([bb[2], 
  tt[3], tt[2]]) </p>
 
 <p>&nbsp;</p>
 
 <p># delete the diagonal bb[1] - tt[2]</p>
 
-<p class="whs8">print &quot;\nUnite 
+<p class="whs9">print &quot;\nUnite 
  two triangles ... &quot;,</p>
 
-<p class="whs8">res = mesh.DeleteDiag(bb[1], 
+<p class="whs9">res = mesh.DeleteDiag(bb[1], 
  tt[2])</p>
 
-<p class="whs8">if not res: print 
+<p class="whs9">if not res: print 
  &quot;failed!&quot;</p>
 
-<p class="whs8">else: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print 
+<p class="whs9">else: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print 
  &quot;done.&quot;</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
 <p><span style="font-family: 'Lucida Console', monospace;">salome.sg.updateObjBrowser(1)</span> 
  </p>
 
 <h3><a name=bookmark6>Uniting a Set of Triangles</a></h3>
 
-<p class="whs8">import salome</p>
+<p class="whs9">import salome</p>
 
-<p class="whs8">import smesh</p>
+<p class="whs9">import smesh</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs9"># create an empty mesh 
+<p class="whs10"># create an empty mesh 
  structure</p>
 
-<p class="whs8">mesh = smesh.Mesh() 
+<p class="whs9">mesh = smesh.Mesh() 
  </p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs9"># create the following 
+<p class="whs10"># create the following 
  mesh:</p>
 
-<p class="whs8"># .----.----.----.</p>
+<p class="whs9"># .----.----.----.</p>
 
-<p class="whs8"># | &nbsp;&nbsp;/| 
+<p class="whs9"># | &nbsp;&nbsp;/| 
  &nbsp;&nbsp;/| 
  &nbsp;&nbsp;/|</p>
 
-<p class="whs8"># | &nbsp;/ 
+<p class="whs9"># | &nbsp;/ 
  | &nbsp;/ | &nbsp;/ 
  |</p>
 
-<p class="whs8"># | / &nbsp;| 
+<p class="whs9"># | / &nbsp;| 
  / &nbsp;| / &nbsp;|</p>
 
-<p class="whs8"># |/ &nbsp;&nbsp;|/ 
+<p class="whs9"># |/ &nbsp;&nbsp;|/ 
  &nbsp;&nbsp;|/ 
  &nbsp;&nbsp;|</p>
 
-<p class="whs8"># .----.----.----.</p>
+<p class="whs9"># .----.----.----.</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8">bb = [0, 0, 0, 0]</p>
+<p class="whs9">bb = [0, 0, 0, 0]</p>
 
-<p class="whs8">tt = [0, 0, 0, 0]</p>
+<p class="whs9">tt = [0, 0, 0, 0]</p>
 
-<p class="whs8">ff = [0, 0, 0, 0, 
+<p class="whs9">ff = [0, 0, 0, 0, 
  0, 0]</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8"><span style="font-family: 'Lucida Console', monospace;">bb[0] 
+<p class="whs9"><span style="font-family: 'Lucida Console', monospace;">bb[0] 
  = mesh.AddNode( 0., 0., 0.)</span></p>
 
-<p class="whs8">bb[1] = mesh.AddNode(10., 
+<p class="whs9">bb[1] = mesh.AddNode(10., 
  0., 0.)</p>
 
-<p class="whs8">bb[2] = mesh.AddNode(20., 
+<p class="whs9">bb[2] = mesh.AddNode(20., 
  0., 0.)</p>
 
-<p class="whs8">bb[3] = mesh.AddNode(30., 
+<p class="whs9">bb[3] = mesh.AddNode(30., 
  0., 0.)</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8">tt[0] = mesh.AddNode( 
+<p class="whs9">tt[0] = mesh.AddNode( 
  0., 15., 0.)</p>
 
-<p class="whs8">tt[1] = mesh.AddNode(10., 
+<p class="whs9">tt[1] = mesh.AddNode(10., 
  15., 0.)</p>
 
-<p class="whs8">tt[2] = mesh.AddNode(20., 
+<p class="whs9">tt[2] = mesh.AddNode(20., 
  15., 0.)</p>
 
-<p class="whs8">tt[3] = mesh.AddNode(30., 
+<p class="whs9">tt[3] = mesh.AddNode(30., 
  15., 0.)</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8">ff[0] = mesh.AddFace([bb[0], 
+<p class="whs9">ff[0] = mesh.AddFace([bb[0], 
  bb[1], tt[1]])</p>
 
-<p class="whs8">ff[1] = mesh.AddFace([bb[0], 
+<p class="whs9">ff[1] = mesh.AddFace([bb[0], 
  tt[1], tt[0]])</p>
 
-<p class="whs8">ff[2] = mesh.AddFace([bb[1], 
+<p class="whs9">ff[2] = mesh.AddFace([bb[1], 
  bb[2], tt[2]])</p>
 
-<p class="whs8">ff[3] = mesh.AddFace([bb[1], 
+<p class="whs9">ff[3] = mesh.AddFace([bb[1], 
  tt[2], tt[1]])</p>
 
-<p class="whs8">ff[4] = mesh.AddFace([bb[2], 
+<p class="whs9">ff[4] = mesh.AddFace([bb[2], 
  bb[3], tt[3]])</p>
 
-<p class="whs8">ff[5] = mesh.AddFace([bb[2], 
+<p class="whs9">ff[5] = mesh.AddFace([bb[2], 
  tt[3], tt[2]])</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs9"># unite a set of triangles</p>
+<p class="whs10"># unite a set of triangles</p>
 
-<p class="whs8"><span style="font-family: 'Lucida Console', monospace;">print 
+<p class="whs9"><span style="font-family: 'Lucida Console', monospace;">print 
  &quot;\nUnite a set of triangles ... &quot;,</span></p>
 
-<p class="whs8">res = mesh.TriToQuad([ff[2], 
+<p class="whs9">res = mesh.TriToQuad([ff[2], 
  ff[3], ff[4], ff[5]], smesh.FT_MinimumAngle, 60.)</p>
 
-<p class="whs8">if not res: print 
+<p class="whs9">if not res: print 
  &quot;failed!&quot;</p>
 
-<p class="whs8">else: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print 
+<p class="whs9">else: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print 
  &quot;done.&quot;</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8">salome.sg.updateObjBrowser(1) 
+<p class="whs9">salome.sg.updateObjBrowser(1) 
  &nbsp;</p>
 
 <h3><a name=bookmark12>Orientation</a></h3>
 
-<p class="whs8">import salome</p>
+<p class="whs9">import salome</p>
 
-<p class="whs8">import smesh</p>
+<p class="whs9">import smesh</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
 <p># create an empty mesh structure</p>
 
-<p class="whs8">mesh = smesh.Mesh() 
+<p class="whs9">mesh = smesh.Mesh() 
  </p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs9"># build five quadrangles:</p>
+<p class="whs10"># build five quadrangles:</p>
 
-<p class="whs8">dx = 10</p>
+<p class="whs9">dx = 10</p>
 
-<p class="whs8">dy = 20</p>
+<p class="whs9">dy = 20</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8"><span style="font-family: 'Lucida Console', monospace;">n1 
+<p class="whs9"><span style="font-family: 'Lucida Console', monospace;">n1 
  &nbsp;= mesh.AddNode(0.0 
  * dx, 0, 0)</span></p>
 
-<p class="whs8">n2 &nbsp;= 
+<p class="whs9">n2 &nbsp;= 
  mesh.AddNode(1.0 * dx, 0, 0)</p>
 
-<p class="whs8">n3 &nbsp;= 
+<p class="whs9">n3 &nbsp;= 
  mesh.AddNode(2.0 * dx, 0, 0)</p>
 
-<p class="whs8">n4 &nbsp;= 
+<p class="whs9">n4 &nbsp;= 
  mesh.AddNode(3.0 * dx, 0, 0)</p>
 
-<p class="whs8">n5 &nbsp;= 
+<p class="whs9">n5 &nbsp;= 
  mesh.AddNode(4.0 * dx, 0, 0)</p>
 
-<p class="whs8">n6 &nbsp;= 
+<p class="whs9">n6 &nbsp;= 
  mesh.AddNode(5.0 * dx, 0, 0)</p>
 
-<p class="whs8">n7 &nbsp;= 
+<p class="whs9">n7 &nbsp;= 
  mesh.AddNode(0.0 * dx, dy, 0)</p>
 
-<p class="whs8">n8 &nbsp;= 
+<p class="whs9">n8 &nbsp;= 
  mesh.AddNode(1.0 * dx, dy, 0)</p>
 
-<p class="whs8">n9 &nbsp;= 
+<p class="whs9">n9 &nbsp;= 
  mesh.AddNode(2.0 * dx, dy, 0)</p>
 
-<p class="whs8">n10 = mesh.AddNode(3.0 
+<p class="whs9">n10 = mesh.AddNode(3.0 
  * dx, dy, 0)</p>
 
-<p class="whs8">n11 = mesh.AddNode(4.0 
+<p class="whs9">n11 = mesh.AddNode(4.0 
  * dx, dy, 0)</p>
 
-<p class="whs8">n12 = mesh.AddNode(5.0 
+<p class="whs9">n12 = mesh.AddNode(5.0 
  * dx, dy, 0)</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8">f1 = mesh.AddFace([n1, 
+<p class="whs9">f1 = mesh.AddFace([n1, 
  n2, n8 , n7 ])</p>
 
-<p class="whs8">f2 = mesh.AddFace([n2, 
+<p class="whs9">f2 = mesh.AddFace([n2, 
  n3, n9 , n8 ])</p>
 
-<p class="whs8">f3 = mesh.AddFace([n3, 
+<p class="whs9">f3 = mesh.AddFace([n3, 
  n4, n10, n9 ])</p>
 
-<p class="whs8">f4 = mesh.AddFace([n4, 
+<p class="whs9">f4 = mesh.AddFace([n4, 
  n5, n11, n10])</p>
 
-<p class="whs8">f5 = mesh.AddFace([n5, 
+<p class="whs9">f5 = mesh.AddFace([n5, 
  n6, n12, n11]) </p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs9"># Change the orientation 
+<p class="whs10"># Change the orientation 
  of the second and the fourth faces.</p>
 
-<p class="whs8">mesh.Reorient([2, 
+<p class="whs9">mesh.Reorient([2, 
  4])</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8">salome.sg.updateObjBrowser(1) 
+<p class="whs9">salome.sg.updateObjBrowser(1) 
  </p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
 <h3><a name=bookmark7>Cutting Quadrangles</a></h3>
 
-<p class="whs8">import SMESH_mechanic</p>
+<p class="whs9">import SMESH_mechanic</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8">smesh = SMESH_mechanic.smesh</p>
+<p class="whs9">smesh = SMESH_mechanic.smesh</p>
 
-<p class="whs8">mesh &nbsp;= 
+<p class="whs9">mesh &nbsp;= 
  SMESH_mechanic.mesh</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs9"># cut two quadrangles: 
+<p class="whs10"># cut two quadrangles: 
  405 and 406</p>
 
-<p class="whs8">mesh.QuadToTri([405, 
+<p class="whs9">mesh.QuadToTri([405, 
  406], smesh.FT_MinimumAngle) &nbsp;</p>
 
-<p class="whs9">&nbsp;</p>
+<p class="whs10">&nbsp;</p>
 
 <h3><a name=bookmark8>Smoothing</a></h3>
 
-<p class="whs8">import salome</p>
+<p class="whs9">import salome</p>
 
-<p class="whs8">import geompy</p>
+<p class="whs9">import geompy</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8">import SMESH_mechanic</p>
+<p class="whs9">import SMESH_mechanic</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8"><span style="font-family: 'Lucida Console', monospace;">smesh 
+<p class="whs9"><span style="font-family: 'Lucida Console', monospace;">smesh 
  = SMESH_mechanic.smesh</span></p>
 
-<p class="whs8">mesh = SMESH_mechanic.mesh</p>
+<p class="whs9">mesh = SMESH_mechanic.mesh</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs9"># select the top face</p>
+<p class="whs10"># select the top face</p>
 
-<p class="whs8"><span style="font-family: 'Lucida Console', monospace;">faces 
+<p class="whs9"><span style="font-family: 'Lucida Console', monospace;">faces 
  = geompy.SubShapeAllSorted(SMESH_mechanic.shape_mesh, geompy.ShapeType[&quot;FACE&quot;])</span></p>
 
-<p class="whs8">face = faces[3]</p>
+<p class="whs9">face = faces[3]</p>
 
-<p class="whs8">geompy.addToStudyInFather(SMESH_mechanic.shape_mesh, 
+<p class="whs9">geompy.addToStudyInFather(SMESH_mechanic.shape_mesh, 
  face, &quot;face planar with hole&quot;)</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8"># create a group of 
+<p class="whs9"># create a group of 
  faces to be smoothed</p>
 
-<p class="whs8">GroupSmooth = mesh.GroupOnGeom(face, 
+<p class="whs9">GroupSmooth = mesh.GroupOnGeom(face, 
  &quot;Group of faces (smooth)&quot;, smesh.FACE)</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8"># perform smoothing</p>
+<p class="whs9"># perform smoothing</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8"># boolean SmoothObject(Object, 
+<p class="whs9"># boolean SmoothObject(Object, 
  IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method)</p>
 
-<p class="whs8">res = mesh.SmoothObject(GroupSmooth, 
+<p class="whs9">res = mesh.SmoothObject(GroupSmooth, 
  [], 20, 2., smesh.CENTROIDAL_SMOOTH)</p>
 
-<p class="whs8">print &quot;\nSmoothing 
+<p class="whs9">print &quot;\nSmoothing 
  ... &quot;,</p>
 
-<p class="whs8">if not res: print 
+<p class="whs9">if not res: print 
  &quot;failed!&quot;</p>
 
-<p class="whs8">else: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print 
+<p class="whs9">else: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print 
  &quot;done.&quot;</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8">salome.sg.updateObjBrowser(1) 
+<p class="whs9">salome.sg.updateObjBrowser(1) 
  </p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
 <h3><a name=bookmark9>Extrusion</a></h3>
 
-<p class="whs8">import salome</p>
+<p class="whs9">import salome</p>
 
-<p class="whs8">import geompy</p>
+<p class="whs9">import geompy</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8">import SMESH_mechanic</p>
+<p class="whs9">import SMESH_mechanic</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8"><span style="font-family: 'Lucida Console', monospace;">smesh 
+<p class="whs9"><span style="font-family: 'Lucida Console', monospace;">smesh 
  = SMESH_mechanic.smesh</span></p>
 
-<p class="whs8">mesh = SMESH_mechanic.mesh 
+<p class="whs9">mesh = SMESH_mechanic.mesh 
  </p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs9"># select the top face</p>
+<p class="whs10"># select the top face</p>
 
-<p class="whs8">faces = geompy.SubShapeAllSorted(SMESH_mechanic.shape_mesh, 
+<p class="whs9">faces = geompy.SubShapeAllSorted(SMESH_mechanic.shape_mesh, 
  geompy.ShapeType[&quot;FACE&quot;])</p>
 
-<p class="whs8">face = faces[7]</p>
+<p class="whs9">face = faces[7]</p>
 
-<p class="whs8">geompy.addToStudyInFather(SMESH_mechanic.shape_mesh, 
+<p class="whs9">geompy.addToStudyInFather(SMESH_mechanic.shape_mesh, 
  face, &quot;face circular top&quot;)</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8"># create a vector 
+<p class="whs9"># create a vector 
  for extrusion</p>
 
-<p class="whs8">point = smesh.PointStruct(0., 
+<p class="whs9">point = smesh.PointStruct(0., 
  0., 5.)</p>
 
-<p class="whs8">vector = smesh.DirStruct(point)</p>
+<p class="whs9">vector = smesh.DirStruct(point)</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8"># create a group to 
+<p class="whs9"># create a group to 
  be extruded</p>
 
-<p class="whs8">GroupTri = mesh.GroupOnGeom(face, 
+<p class="whs9">GroupTri = mesh.GroupOnGeom(face, 
  &quot;Group of faces (extrusion)&quot;, smesh.FACE)</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8"># perform extrusion 
+<p class="whs9"># perform extrusion 
  of the group</p>
 
-<p class="whs8">mesh.ExtrusionSweepObject(GroupTri, 
+<p class="whs9">mesh.ExtrusionSweepObject(GroupTri, 
  vector, 5)</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs9"><span style="font-family: 'Lucida Console', monospace;">salome.sg.updateObjBrowser(1)</span> 
+<p class="whs10"><span style="font-family: 'Lucida Console', monospace;">salome.sg.updateObjBrowser(1)</span> 
  </p>
 
 <h3><a name=bookmark10>Extrusion along a Path</a></h3>
 
-<p class="whs8">import math</p>
+<p class="whs9">import math</p>
 
-<p class="whs8">import salome</p>
+<p class="whs9">import salome</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs9"># Geometry</p>
+<p class="whs10"># Geometry</p>
 
-<p class="whs8">import geompy</p>
+<p class="whs9">import geompy</p>
 
-<p class="whs9">&nbsp;</p>
+<p class="whs10">&nbsp;</p>
 
-<p class="whs9"># 1. Create points</p>
+<p class="whs10"># 1. Create points</p>
 
-<p class="whs8">points = [[0, 0], 
+<p class="whs9">points = [[0, 0], 
  [50, 30], [50, 110], [0, 150], [-80, 150], [-130, 70], [-130, -20]]</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8">iv = 1</p>
+<p class="whs9">iv = 1</p>
 
-<p class="whs8">vertices = []</p>
+<p class="whs9">vertices = []</p>
 
-<p class="whs8">for point in points:</p>
+<p class="whs9">for point in points:</p>
 
-<p class="whs10">vert 
+<p class="whs11">vert 
  = geompy.MakeVertex(point[0], point[1], 0)</p>
 
-<p class="whs10">geompy.addToStudy(vert, 
+<p class="whs11">geompy.addToStudy(vert, 
  &quot;Vertex_&quot; + `iv`)</p>
 
-<p class="whs10">vertices.append(vert)</p>
+<p class="whs11">vertices.append(vert)</p>
 
-<p class="whs10">iv 
+<p class="whs11">iv 
  += 1</p>
 
-<p class="whs10">pass</p>
+<p class="whs11">pass</p>
 
-<p class="whs9">&nbsp;</p>
+<p class="whs10">&nbsp;</p>
 
-<p class="whs9"># 2. Create edges and 
+<p class="whs10"># 2. Create edges and 
  wires</p>
 
-<p class="whs8">Edge_straight = geompy.MakeEdge(vertices[0], 
+<p class="whs9">Edge_straight = geompy.MakeEdge(vertices[0], 
  vertices[4])</p>
 
-<p class="whs8">Edge_bezierrr = geompy.MakeBezier(vertices)</p>
+<p class="whs9">Edge_bezierrr = geompy.MakeBezier(vertices)</p>
 
-<p class="whs8">Wire_polyline = geompy.MakePolyline(vertices)</p>
+<p class="whs9">Wire_polyline = geompy.MakePolyline(vertices)</p>
 
-<p class="whs8">Edge_Circle &nbsp;&nbsp;= 
+<p class="whs9">Edge_Circle &nbsp;&nbsp;= 
  geompy.MakeCircleThreePnt(vertices[0], vertices[1], vertices[2])</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8">geompy.addToStudy(Edge_straight, 
+<p class="whs9">geompy.addToStudy(Edge_straight, 
  &quot;Edge_straight&quot;)</p>
 
-<p class="whs8">geompy.addToStudy(Edge_bezierrr, 
+<p class="whs9">geompy.addToStudy(Edge_bezierrr, 
  &quot;Edge_bezierrr&quot;)</p>
 
-<p class="whs8">geompy.addToStudy(Wire_polyline, 
+<p class="whs9">geompy.addToStudy(Wire_polyline, 
  &quot;Wire_polyline&quot;)</p>
 
-<p class="whs8">geompy.addToStudy(Edge_Circle 
+<p class="whs9">geompy.addToStudy(Edge_Circle 
  &nbsp;, &quot;Edge_Circle&quot;)</p>
 
-<p class="whs9">&nbsp;</p>
+<p class="whs10">&nbsp;</p>
 
-<p class="whs9"># 3. Explode wire on 
+<p class="whs10"># 3. Explode wire on 
  edges, as they will be used for mesh extrusion</p>
 
-<p class="whs8">Wire_polyline_edges 
+<p class="whs9">Wire_polyline_edges 
  = geompy.SubShapeAll(Wire_polyline, geompy.ShapeType[&quot;EDGE&quot;])</p>
 
-<p class="whs8">for ii in range(len(Wire_polyline_edges)):</p>
+<p class="whs9">for ii in range(len(Wire_polyline_edges)):</p>
 
-<p class="whs10">geompy.addToStudyInFather(Wire_polyline, 
+<p class="whs11">geompy.addToStudyInFather(Wire_polyline, 
  Wire_polyline_edges[ii], &quot;Edge_&quot; + `ii + 1`)</p>
 
-<p class="whs10">pass</p>
+<p class="whs11">pass</p>
 
-<p class="whs11">&nbsp;</p>
+<p class="whs12">&nbsp;</p>
 
-<p class="whs9"># Mesh</p>
+<p class="whs10"># Mesh</p>
 
-<p class="whs8">import smesh</p>
+<p class="whs9">import smesh</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs12"># Mesh 
+<p class="whs13"># Mesh 
  the given shape with the given 1d hypothesis</p>
 
-<p class="whs13">def 
+<p class="whs14">def 
  Mesh1D(shape1d, nbSeg, name):</p>
 
-<p class="whs13">&nbsp;&nbsp;mesh1d_tool 
+<p class="whs14">&nbsp;&nbsp;mesh1d_tool 
  = smesh.Mesh(shape1d, name)</p>
 
-<p class="whs13">&nbsp;&nbsp;algo 
+<p class="whs14">&nbsp;&nbsp;algo 
  = mesh1d_tool.Segment()</p>
 
-<p class="whs13">&nbsp;&nbsp;hyp 
+<p class="whs14">&nbsp;&nbsp;hyp 
  &nbsp;= algo.NumberOfSegments(nbSeg)</p>
 
-<p class="whs13">&nbsp;&nbsp;isDone 
+<p class="whs14">&nbsp;&nbsp;isDone 
  = mesh1d_tool.Compute()</p>
 
-<p class="whs13">&nbsp;&nbsp;if 
+<p class="whs14">&nbsp;&nbsp;if 
  not isDone: print 'Mesh ', name, ': computation failed'</p>
 
-<p class="whs13">&nbsp;&nbsp;return 
+<p class="whs14">&nbsp;&nbsp;return 
  mesh1d_tool</p>
 
-<p class="whs12"># Create 
+<p class="whs13"># Create 
  a mesh with six nodes, seven edges and two quadrangle faces</p>
 
-<p class="whs13">def 
+<p class="whs14">def 
  MakeQuadMesh2(mesh_name):</p>
 
-<p class="whs13">&nbsp;&nbsp;quad_1 
+<p class="whs14">&nbsp;&nbsp;quad_1 
  = smesh.Mesh(name = mesh_name)</p>
 
-<p class="whs13">&nbsp;&nbsp;</p>
+<p class="whs14">&nbsp;&nbsp;</p>
 
-<p class="whs13">&nbsp;&nbsp;<span 
+<p class="whs14">&nbsp;&nbsp;<span 
  style="font-family: 'Times New Roman', serif;"># 
  six nodes</span></p>
 
-<p class="whs13">&nbsp;&nbsp;n1 
+<p class="whs14">&nbsp;&nbsp;n1 
  = quad_1.AddNode(0, 20, 10)</p>
 
-<p class="whs13">&nbsp;&nbsp;n2 
+<p class="whs14">&nbsp;&nbsp;n2 
  = quad_1.AddNode(0, 40, 10)</p>
 
-<p class="whs13">&nbsp;&nbsp;n3 
+<p class="whs14">&nbsp;&nbsp;n3 
  = quad_1.AddNode(0, 40, 30)</p>
 
-<p class="whs13">&nbsp;&nbsp;n4 
+<p class="whs14">&nbsp;&nbsp;n4 
  = quad_1.AddNode(0, 20, 30)</p>
 
-<p class="whs13">&nbsp;&nbsp;n5 
+<p class="whs14">&nbsp;&nbsp;n5 
  = quad_1.AddNode(0, &nbsp;0, 
  30)</p>
 
-<p class="whs13">&nbsp;&nbsp;n6 
+<p class="whs14">&nbsp;&nbsp;n6 
  = quad_1.AddNode(0, &nbsp;0, 
  10)</p>
 
-<p class="whs13">&nbsp;&nbsp;</p>
+<p class="whs14">&nbsp;&nbsp;</p>
 
-<p class="whs13">&nbsp;&nbsp;<span 
+<p class="whs14">&nbsp;&nbsp;<span 
  style="font-family: 'Times New Roman', serif;"># 
  seven edges</span></p>
 
-<p class="whs13">&nbsp;&nbsp;quad_1.AddEdge([n1, 
+<p class="whs14">&nbsp;&nbsp;quad_1.AddEdge([n1, 
  n2]) # 1</p>
 
-<p class="whs13">&nbsp;&nbsp;quad_1.AddEdge([n2, 
+<p class="whs14">&nbsp;&nbsp;quad_1.AddEdge([n2, 
  n3]) # 2</p>
 
-<p class="whs13">&nbsp;&nbsp;quad_1.AddEdge([n3, 
+<p class="whs14">&nbsp;&nbsp;quad_1.AddEdge([n3, 
  n4]) # 3</p>
 
-<p class="whs13">&nbsp;&nbsp;quad_1.AddEdge([n4, 
+<p class="whs14">&nbsp;&nbsp;quad_1.AddEdge([n4, 
  n1]) # 4</p>
 
-<p class="whs13">&nbsp;&nbsp;quad_1.AddEdge([n4, 
+<p class="whs14">&nbsp;&nbsp;quad_1.AddEdge([n4, 
  n5]) # 5</p>
 
-<p class="whs13">&nbsp;&nbsp;quad_1.AddEdge([n5, 
+<p class="whs14">&nbsp;&nbsp;quad_1.AddEdge([n5, 
  n6]) # 6</p>
 
-<p class="whs13">&nbsp;&nbsp;quad_1.AddEdge([n6, 
+<p class="whs14">&nbsp;&nbsp;quad_1.AddEdge([n6, 
  n1]) # 7</p>
 
-<p class="whs13">&nbsp;</p>
+<p class="whs14">&nbsp;</p>
 
-<p class="whs13">&nbsp;&nbsp;<span 
+<p class="whs14">&nbsp;&nbsp;<span 
  style="font-family: 'Times New Roman', serif;"># 
  two quadrangle faces</span></p>
 
-<p class="whs13">&nbsp;&nbsp;quad_1.AddFace([n1, 
+<p class="whs14">&nbsp;&nbsp;quad_1.AddFace([n1, 
  n2, n3, n4]) # 8</p>
 
-<p class="whs13">&nbsp;&nbsp;quad_1.AddFace([n1, 
+<p class="whs14">&nbsp;&nbsp;quad_1.AddFace([n1, 
  n4, n5, n6]) # 9</p>
 
-<p class="whs13">&nbsp;&nbsp;return 
+<p class="whs14">&nbsp;&nbsp;return 
  [quad_1, [1,2,3,4,5,6,7], [8,9]]</p>
 
-<p class="whs13">&nbsp;</p>
+<p class="whs14">&nbsp;</p>
 
-<p class="whs12"># Path 
+<p class="whs13"># Path 
  meshes</p>
 
-<p class="whs13">Edge_straight_mesh 
+<p class="whs14">Edge_straight_mesh 
  = Mesh1D(Edge_straight, 7, &quot;Edge_straight&quot;)</p>
 
-<p class="whs13">Edge_bezierrr_mesh 
+<p class="whs14">Edge_bezierrr_mesh 
  = Mesh1D(Edge_bezierrr, 7, &quot;Edge_bezierrr&quot;)</p>
 
-<p class="whs13">Wire_polyline_mesh 
+<p class="whs14">Wire_polyline_mesh 
  = Mesh1D(Wire_polyline, 3, &quot;Wire_polyline&quot;)</p>
 
-<p class="whs13">Edge_Circle_mesh 
+<p class="whs14">Edge_Circle_mesh 
  &nbsp;&nbsp;= 
  Mesh1D(Edge_Circle &nbsp;, 
  8, &quot;Edge_Circle&quot;)</p>
 
-<p class="whs13">&nbsp;</p>
+<p class="whs14">&nbsp;</p>
 
-<p class="whs12"># Initial 
+<p class="whs13"># Initial 
  meshes (to be extruded)</p>
 
-<p class="whs13">[quad_1, 
+<p class="whs14">[quad_1, 
  ee_1, ff_1] = MakeQuadMesh2(&quot;quad_1&quot;)</p>
 
-<p class="whs13">[quad_2, 
+<p class="whs14">[quad_2, 
  ee_2, ff_2] = MakeQuadMesh2(&quot;quad_2&quot;)</p>
 
-<p class="whs13">[quad_3, 
+<p class="whs14">[quad_3, 
  ee_3, ff_3] = MakeQuadMesh2(&quot;quad_3&quot;)</p>
 
-<p class="whs13">[quad_4, 
+<p class="whs14">[quad_4, 
  ee_4, ff_4] = MakeQuadMesh2(&quot;quad_4&quot;)</p>
 
-<p class="whs13">[quad_5, 
+<p class="whs14">[quad_5, 
  ee_5, ff_5] = MakeQuadMesh2(&quot;quad_5&quot;)</p>
 
-<p class="whs13">[quad_6, 
+<p class="whs14">[quad_6, 
  ee_6, ff_6] = MakeQuadMesh2(&quot;quad_6&quot;)</p>
 
-<p class="whs13">[quad_7, 
+<p class="whs14">[quad_7, 
  ee_7, ff_7] = MakeQuadMesh2(&quot;quad_7&quot;)</p>
 
-<p class="whs13">&nbsp;</p>
+<p class="whs14">&nbsp;</p>
 
-<p class="whs12"># ExtrusionAlongPath</p>
+<p class="whs13"># ExtrusionAlongPath</p>
 
-<p class="whs12"># IDsOfElements, 
+<p class="whs13"># IDsOfElements, 
  PathMesh, PathShape, NodeStart,</p>
 
-<p class="whs12"># HasAngles, 
+<p class="whs13"># HasAngles, 
  Angles, HasRefPoint, RefPoint</p>
 
-<p class="whs13">refPoint 
+<p class="whs14">refPoint 
  = smesh.PointStruct(0, 0, 0)</p>
 
-<p class="whs13">a10 
+<p class="whs14">a10 
  = 10.0*math.pi/180.0</p>
 
-<p class="whs13">a45 
+<p class="whs14">a45 
  = 45.0*math.pi/180.0</p>
 
-<p class="whs13">&nbsp;</p>
+<p class="whs14">&nbsp;</p>
 
-<p class="whs12"># 1. 
+<p class="whs13"># 1. 
  Extrusion of two mesh edges along a straight path</p>
 
-<p class="whs13">error 
+<p class="whs14">error 
  = quad_1.ExtrusionAlongPath([1,2], Edge_straight_mesh, Edge_straight, 
  1,</p>
 
-<p class="whs13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0, 
+<p class="whs14">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0, 
  [], 0, refPoint)</p>
 
-<p class="whs13">&nbsp;</p>
+<p class="whs14">&nbsp;</p>
 
-<p class="whs12"># 2. 
+<p class="whs13"># 2. 
  Extrusion of one mesh edge along a curved path</p>
 
-<p class="whs13">error 
+<p class="whs14">error 
  = quad_2.ExtrusionAlongPath([2], Edge_bezierrr_mesh, Edge_bezierrr, 1,</p>
 
-<p class="whs13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0, 
+<p class="whs14">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0, 
  [], 0, refPoint)</p>
 
-<p class="whs13">&nbsp;</p>
+<p class="whs14">&nbsp;</p>
 
-<p class="whs12"># 3. 
+<p class="whs13"># 3. 
  Extrusion of one mesh edge along a curved path with usage of angles</p>
 
-<p class="whs13">error 
+<p class="whs14">error 
  = quad_3.ExtrusionAlongPath([2], Edge_bezierrr_mesh, Edge_bezierrr, 1,</p>
 
-<p class="whs13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1, 
+<p class="whs14">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1, 
  [a45, a45, a45, 0, -a45, -a45, -a45], 0, refPoint)</p>
 
-<p class="whs13">&nbsp;</p>
+<p class="whs14">&nbsp;</p>
 
-<p class="whs12"># 4. 
+<p class="whs13"># 4. 
  Extrusion of one mesh edge along the path, which is a part of a meshed 
  wire</p>
 
-<p class="whs13">error 
+<p class="whs14">error 
  = quad_4.ExtrusionAlongPath([4], Wire_polyline_mesh, Wire_polyline_edges[0], 
  1,</p>
 
-<p class="whs13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1, 
+<p class="whs14">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1, 
  [a10, a10, a10], 0, refPoint)</p>
 
-<p class="whs13">&nbsp;</p>
+<p class="whs14">&nbsp;</p>
 
-<p class="whs12"># 5. 
+<p class="whs13"># 5. 
  Extrusion of two mesh faces along the path, which is a part of a meshed 
  wire</p>
 
-<p class="whs13">error 
+<p class="whs14">error 
  = quad_5.ExtrusionAlongPath(ff_5 , Wire_polyline_mesh, Wire_polyline_edges[2], 
  4,</p>
 
-<p class="whs13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0, 
+<p class="whs14">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0, 
  [], 0, refPoint)</p>
 
-<p class="whs13">&nbsp;</p>
+<p class="whs14">&nbsp;</p>
 
-<p class="whs12"># 6. 
+<p class="whs13"># 6. 
  Extrusion of two mesh faces along a closed path</p>
 
-<p class="whs13">error 
+<p class="whs14">error 
  = quad_6.ExtrusionAlongPath(ff_6 , Edge_Circle_mesh, Edge_Circle, 1,</p>
 
-<p class="whs13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0, 
+<p class="whs14">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0, 
  [], 0, refPoint)</p>
 
-<p class="whs13">&nbsp;</p>
+<p class="whs14">&nbsp;</p>
 
-<p class="whs12"># 7. 
+<p class="whs13"># 7. 
  Extrusion of two mesh faces along a closed path with usage of angles</p>
 
-<p class="whs13">error 
+<p class="whs14">error 
  = quad_7.ExtrusionAlongPath(ff_7, Edge_Circle_mesh, Edge_Circle, 1,</p>
 
-<p class="whs13">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1, 
+<p class="whs14">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1, 
  [a45, -a45, a45, -a45, a45, -a45, a45, -a45], 0, refPoint)</p>
 
-<p class="whs13">&nbsp;</p>
+<p class="whs14">&nbsp;</p>
 
-<p class="whs13">salome.sg.updateObjBrowser(1) 
+<p class="whs14">salome.sg.updateObjBrowser(1) 
  </p>
 
 <h3><a name=bookmark11>Revolution</a></h3>
 
-<p class="whs8">import math</p>
+<p class="whs9">import math</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8">import SMESH_mechanic</p>
+<p class="whs9">import SMESH_mechanic</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8"><span style="font-family: 'Lucida Console', monospace;">mesh 
+<p class="whs9"><span style="font-family: 'Lucida Console', monospace;">mesh 
  &nbsp;= SMESH_mechanic.mesh</span></p>
 
-<p class="whs8">smesh = SMESH_mechanic.smesh</p>
+<p class="whs9">smesh = SMESH_mechanic.smesh</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs9"># create a group of faces 
+<p class="whs10"># create a group of faces 
  to be revolved</p>
 
-<p class="whs8">FacesRotate = [492, 
+<p class="whs9">FacesRotate = [492, 
  493, 502, 503]</p>
 
-<p class="whs8">GroupRotate = mesh.CreateGroup(SMESH.FACE,&quot;Group 
+<p class="whs9">GroupRotate = mesh.CreateGroup(SMESH.FACE,&quot;Group 
  of faces (rotate)&quot;)</p>
 
-<p class="whs8">GroupRotate.Add(FacesRotate)</p>
+<p class="whs9">GroupRotate.Add(FacesRotate)</p>
 
-<p class="whs9">&nbsp;</p>
+<p class="whs10">&nbsp;</p>
 
-<p class="whs9"># define revolution angle 
+<p class="whs10"># define revolution angle 
  and axis</p>
 
-<p class="whs8">angle45 = 45 * math.pi 
+<p class="whs9">angle45 = 45 * math.pi 
  / 180</p>
 
-<p class="whs8">axisXYZ = SMESH.AxisStruct(-38.3128, 
+<p class="whs9">axisXYZ = SMESH.AxisStruct(-38.3128, 
  -73.3658, -23.321, -13.3402, -13.3265, 6.66632)</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs9"># perform revolution 
+<p class="whs10"># perform revolution 
  of an object</p>
 
-<p class="whs8">mesh.RotationSweepObject(GroupRotate, 
+<p class="whs9">mesh.RotationSweepObject(GroupRotate, 
  axisXYZ, angle45, 4, 1e-5) </p>
 
-<p class="whs9">&nbsp;</p>
+<p class="whs10">&nbsp;</p>
 
 <h3><a name=bookmark13>Pattern Mapping</a></h3>
 
-<p class="whs8">import geompy</p>
+<p class="whs9">import geompy</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8">import smesh</p>
+<p class="whs9">import smesh</p>
 
-<p class="whs8">&nbsp;</p>
+<p class="whs9">&nbsp;</p>
 
-<p class="whs8"># define the geometry</p>
+<p class="whs9"># define the geometry</p>
 
-<p class="whs9">Box_1 = geompy.MakeBoxDXDYDZ(200., 
+<p class="whs10">Box_1 = geompy.MakeBoxDXDYDZ(200., 
  200., 200.)</p>
 
-<p class="whs9">geompy.addToStudy(Box_1, 
+<p class="whs10">geompy.addToStudy(Box_1, 
  &quot;Box_1&quot;)</p>
 
-<p class="whs9">&nbsp;</p>
+<p class="whs10">&nbsp;</p>
 
-<p class="whs9">faces = geompy.SubShapeAll(Box_1, 
+<p class="whs10">faces = geompy.SubShapeAll(Box_1, 
  geompy.ShapeType[&quot;FACE&quot;])</p>
 
-<p class="whs9">Face_1 = faces[0]</p>
+<p class="whs10">Face_1 = faces[0]</p>
 
-<p class="whs9">Face_2 = faces[1]</p>
+<p class="whs10">Face_2 = faces[1]</p>
 
-<p class="whs9">&nbsp;</p>
+<p class="whs10">&nbsp;</p>
 
-<p class="whs9">geompy.addToStudyInFather(Box_1, 
+<p class="whs10">geompy.addToStudyInFather(Box_1, 
  Face_1, &quot;Face_1&quot;)</p>
 
-<p class="whs9">geompy.addToStudyInFather(Box_1, 
+<p class="whs10">geompy.addToStudyInFather(Box_1, 
  Face_2, &quot;Face_2&quot;)</p>
 
-<p class="whs9">&nbsp;</p>
+<p class="whs10">&nbsp;</p>
 
-<p class="whs8"># build a quadrangle 
+<p class="whs9"># build a quadrangle 
  mesh 3x3 on Face_1</p>
 
-<p class="whs9">Mesh_1 = smesh.Mesh(Face_1)</p>
+<p class="whs10">Mesh_1 = smesh.Mesh(Face_1)</p>
 
-<p class="whs9">algo1D = Mesh_1.Segment()</p>
+<p class="whs10">algo1D = Mesh_1.Segment()</p>
 
-<p class="whs9">algo1D.NumberOfSegments(3)</p>
+<p class="whs10">algo1D.NumberOfSegments(3)</p>
 
-<p class="whs9">Mesh_1.Quadrangle()</p>
+<p class="whs10">Mesh_1.Quadrangle()</p>
 
-<p class="whs9">&nbsp;</p>
+<p class="whs10">&nbsp;</p>
 
-<p class="whs9">isDone = Mesh_1.Compute()</p>
+<p class="whs10">isDone = Mesh_1.Compute()</p>
 
-<p class="whs9">if not isDone: print 
+<p class="whs10">if not isDone: print 
  'Mesh Mesh_1 : computation failed'</p>
 
-<p class="whs9">&nbsp;</p>
+<p class="whs10">&nbsp;</p>
 
-<p class="whs8"># build a triangle 
+<p class="whs9"># build a triangle 
  mesh on Face_2</p>
 
-<p class="whs9">Mesh_2 = smesh.Mesh(Face_2)</p>
+<p class="whs10">Mesh_2 = smesh.Mesh(Face_2)</p>
 
-<p class="whs9">&nbsp;</p>
+<p class="whs10">&nbsp;</p>
 
-<p class="whs9">algo1D = Mesh_2.Segment()</p>
+<p class="whs10">algo1D = Mesh_2.Segment()</p>
 
-<p class="whs9">algo1D.NumberOfSegments(1)</p>
+<p class="whs10">algo1D.NumberOfSegments(1)</p>
 
-<p class="whs9">algo2D = Mesh_2.Triangle()</p>
+<p class="whs10">algo2D = Mesh_2.Triangle()</p>
 
-<p class="whs9">algo2D.MaxElementArea(240)</p>
+<p class="whs10">algo2D.MaxElementArea(240)</p>
 
-<p class="whs9">&nbsp;</p>
+<p class="whs10">&nbsp;</p>
 
-<p class="whs9">isDone = Mesh_2.Compute()</p>
+<p class="whs10">isDone = Mesh_2.Compute()</p>
 
-<p class="whs9">if not isDone: print 
+<p class="whs10">if not isDone: print 
  'Mesh Mesh_2 : computation failed'</p>
 
-<p class="whs9">&nbsp;</p>
+<p class="whs10">&nbsp;</p>
 
-<p class="whs8"># create a pattern</p>
+<p class="whs9"># create a pattern</p>
 
-<p class="whs9">pattern = smesh.GetPattern()</p>
+<p class="whs10">pattern = smesh.GetPattern()</p>
 
-<p class="whs9">&nbsp;</p>
+<p class="whs10">&nbsp;</p>
 
-<p class="whs9">isDone = pattern.LoadFromFace(Mesh_2.GetMesh(), 
+<p class="whs10">isDone = pattern.LoadFromFace(Mesh_2.GetMesh(), 
  Face_2, 0)</p>
 
-<p class="whs9">if (isDone != 1): print 
+<p class="whs10">if (isDone != 1): print 
  'LoadFromFace :', pattern.GetErrorCode()</p>
 
-<p class="whs9">&nbsp;</p>
+<p class="whs10">&nbsp;</p>
 
-<p class="whs8"># apply the pattern 
+<p class="whs9"># apply the pattern 
  to a face of the first mesh</p>
 
-<p class="whs9">pattern.ApplyToMeshFaces(Mesh_1.GetMesh(), 
+<p class="whs10">pattern.ApplyToMeshFaces(Mesh_1.GetMesh(), 
  [17], 0, 0)</p>
 
-<p class="whs9">&nbsp;</p>
+<p class="whs10">&nbsp;</p>
 
-<p class="whs9">isDone = pattern.MakeMesh(Mesh_1.GetMesh(), 
+<p class="whs10">isDone = pattern.MakeMesh(Mesh_1.GetMesh(), 
  0, 0)</p>
 
-<p class="whs9">if (isDone != 1): print 
+<p class="whs10">if (isDone != 1): print 
  'MakeMesh :', pattern.GetErrorCode() &nbsp;</p>
 
 <script type="text/javascript" language="javascript1.2">
diff --git a/doc/salome/gui/SMESH/pics/buildcompound.png b/doc/salome/gui/SMESH/pics/buildcompound.png
new file mode 100755 (executable)
index 0000000..79a6073
Binary files /dev/null and b/doc/salome/gui/SMESH/pics/buildcompound.png differ
index 9ed8a62552a80d7245ce6dd4293209cc34d4d75d..8273aac4524a59e52c7f0048d705085fe064fc9d 100755 (executable)
Binary files a/doc/salome/gui/SMESH/pics/createmesh-inv.png and b/doc/salome/gui/SMESH/pics/createmesh-inv.png differ
index f73e1df7d2388c4d722f87a2c77f3cd5023f786e..2bee11b7c7da4d80a9a054f2659390a10f9d7516 100755 (executable)
Binary files a/doc/salome/gui/SMESH/pics/createmesh-inv2.png and b/doc/salome/gui/SMESH/pics/createmesh-inv2.png differ
index 6c9da9c0ac342319f6a8494602b5ae4925c7f721..6dfabaaa8ee77923d2aea52a3f6a16a2c229b5bc 100755 (executable)
Binary files a/doc/salome/gui/SMESH/pics/createmesh-inv3.png and b/doc/salome/gui/SMESH/pics/createmesh-inv3.png differ
diff --git a/doc/salome/gui/SMESH/pics/lengthnearvertex.png b/doc/salome/gui/SMESH/pics/lengthnearvertex.png
new file mode 100755 (executable)
index 0000000..008dcb1
Binary files /dev/null and b/doc/salome/gui/SMESH/pics/lengthnearvertex.png differ
index d994afa28395640ecc39c440f01e7ae57016f5a9..36818438d940faf534ad4823b78b6e8b06390d7b 100755 (executable)
Binary files a/doc/salome/gui/SMESH/pics/mergenodes.png and b/doc/salome/gui/SMESH/pics/mergenodes.png differ
diff --git a/doc/salome/gui/SMESH/pics/meshtopass.png b/doc/salome/gui/SMESH/pics/meshtopass.png
new file mode 100755 (executable)
index 0000000..044c016
Binary files /dev/null and b/doc/salome/gui/SMESH/pics/meshtopass.png differ
index da64656c0791eacbd07cb677bd44587263b7f732..9bdf4a4efe53eccb4308188c8887b58540f3552a 100644 (file)
@@ -3,7 +3,7 @@
 <html>\r
 \r
 <head>\r
-<title>Prism 3D Algorithm</title>\r
+<title>3D extrusion meshing algorithm</title>\r
 <meta http-equiv="content-type" content="text/html; charset=windows-1252">\r
 <meta name="generator" content="RoboHelp by eHelp Corporation www.ehelp.com"><style type="text/css">\r
 <!--\r
@@ -53,7 +53,7 @@ if (window.gbWhTopic)
 {\r
        if (window.setRelStartPage)\r
        {\r
-       addTocInfo("MESH module\nCreating meshes\nDefining Algorithms\nPrism 3D Algorithm");\r
+       addTocInfo("MESH module\nCreating meshes\nDefining Algorithms\n3D extrusion meshing algorithm");\r
 addButton("show",BTN_IMG,"Show","","","","",0,0,"whd_show0.gif","whd_show2.gif","whd_show1.gif");\r
 addButton("hide",BTN_IMG,"Hide","","","","",0,0,"whd_hide0.gif","whd_hide2.gif","whd_hide1.gif");\r
 \r
@@ -82,27 +82,25 @@ if (window.writeIntopicBar)
        writeIntopicBar(4);\r
 //-->\r
 </script>\r
-<h1>Prism 3D Algorithm</h1>\r
+<h1>3D extrusion meshing algorithm</h1>\r
 \r
-<p>Prism 3D algorithm can be used for meshing prisms, i.e. <span style="font-weight: bold;"><B>3D \r
- Shapes</B></span> defined by<span style="margin-left: 24px;\r
-                                                                               margin-top: 0pt;\r
-                                                                               margin-bottom: 0pt;"> two opposing \r
- faces having the same number of vertices and edges and meshed using the \r
+<p>3D extrusion algorithm can be used for meshing prisms, i.e.\r
+<span style="font-weight: bold;"><B>3D Shapes</B></span> defined by\r
+ two opposing faces having the same number of vertices and edges and meshed using the \r
  <a href="projection_algorithms.htm">2D Projection</a> algorithm. These \r
- two faces should be connected by quadrangle &quot;side&quot; faces.</span></p>\r
+ two faces should be connected by quadrangle &quot;side&quot; faces.</p>\r
 \r
 <p><span style="margin-left: 24px;\r
                                margin-top: 0pt;\r
                                margin-bottom: 0pt;">The opposing faces can be meshed with \r
  either quadrangles or triangles, while the side faces should be meshed \r
- with quadranglees only. </span></p>\r
+ with quadrangles only. </span></p>\r
 \r
 <p class="whs1"><img src="image157.gif" width="324px" height="337px" border="0" class="img_whs2"></p>\r
 \r
 <p class="whs1">&nbsp;</p>\r
 \r
-<p class="whs3">As you can see, the <span style="font-weight: bold;"><B>Prism3D</B></span> \r
+<p class="whs3">As you can see, the <span style="font-weight: bold;"><B>3D extrusion</B></span> \r
  algorithm permits to build and to have in the same 3D mesh such elements \r
  as hexahedrons, prisms and polyhedrons.</p>\r
 \r
diff --git a/doc/salome/gui/SMESH/segments_around_vertex_algorithm.htm b/doc/salome/gui/SMESH/segments_around_vertex_algorithm.htm
new file mode 100755 (executable)
index 0000000..7e73af2
--- /dev/null
@@ -0,0 +1,98 @@
+<!doctype HTML public "-//W3C//DTD HTML 4.0 Frameset//EN">\r
+\r
+<html>\r
+\r
+<head>\r
+<title>Segments around Vertex Algorithm</title>\r
+<meta http-equiv="content-type" content="text/html; charset=windows-1252">\r
+<meta name="generator" content="RoboHelp by eHelp Corporation www.ehelp.com"><style type="text/css">\r
+<!--\r
+p.whs1 { margin-left:40px; }\r
+img_whs2 { border:none; width:270px; height:179px; float:none; border-style:none; }\r
+-->\r
+</style><script type="text/javascript" language="JavaScript" title="WebHelpInlineScript">\r
+<!--\r
+function reDo() {\r
+  if (innerWidth != origWidth || innerHeight != origHeight)\r
+     location.reload();\r
+}\r
+if ((parseInt(navigator.appVersion) == 4) && (navigator.appName == "Netscape")) {\r
+       origWidth = innerWidth;\r
+       origHeight = innerHeight;\r
+       onresize = reDo;\r
+}\r
+onerror = null; \r
+//-->\r
+</script>\r
+<style type="text/css">\r
+<!--\r
+div.WebHelpPopupMenu { position:absolute; left:0px; top:0px; z-index:4; visibility:hidden; }\r
+p.WebHelpNavBar { text-align:right; }\r
+-->\r
+</style><script type="text/javascript" language="javascript1.2" src="whmsg.js"></script>\r
+<script type="text/javascript" language="javascript" src="whver.js"></script>\r
+<script type="text/javascript" language="javascript1.2" src="whproxy.js"></script>\r
+<script type="text/javascript" language="javascript1.2" src="whutils.js"></script>\r
+<script type="text/javascript" language="javascript1.2" src="whtopic.js"></script>\r
+<script type="text/javascript" language="javascript1.2">\r
+<!--\r
+if (window.gbWhTopic)\r
+{\r
+       if (window.setRelStartPage)\r
+       {\r
+       addTocInfo("MESH module\nCreating meshes\nDefining Algorithms\nSegments around Vertex Algorithm");\r
+addButton("show",BTN_IMG,"Show","","","","",0,0,"whd_show0.gif","whd_show2.gif","whd_show1.gif");\r
+addButton("hide",BTN_IMG,"Hide","","","","",0,0,"whd_hide0.gif","whd_hide2.gif","whd_hide1.gif");\r
+\r
+       }\r
+\r
+\r
+       if (window.setRelStartPage)\r
+       {\r
+       setRelStartPage("index.htm");\r
+\r
+               autoSync(1);\r
+               sendSyncInfo();\r
+               sendAveInfoOut();\r
+       }\r
+\r
+}\r
+else\r
+       if (window.gbIE4)\r
+               document.location.reload();\r
+//-->\r
+</script>\r
+</head>\r
+<body><script type="text/javascript" language="javascript1.2">\r
+<!--\r
+if (window.writeIntopicBar)\r
+       writeIntopicBar(4);\r
+//-->\r
+</script>\r
+<h1>Segments around Vertex</h1>\r
+\r
+<p><span style="font-weight: bold;"><B>Segments around Vertex</B></span> algorithm \r
+ is considered to be a 0D \r
+ meshing algorithm, but, of course, it doesn't mesh nodes. It allows to \r
+ define the local size of the elements in the neighborhood of a certain \r
+ node. If we choose an object of higher dimension, it applies to all its \r
+ tops, i.e. corners of a box. &nbsp;The \r
+ 0D algorithm combines with the algorithms of higher dimensions, but it \r
+ is not necessarily required for their successful implementation. </p>\r
+\r
+<p>This algorithm allows only one hypothesis. </p>\r
+\r
+<p class="whs1"><img src="pics/lengthnearvertex.png" x-maintain-ratio="TRUE" width="270px" height="179px" border="0" class="img_whs2"></p>\r
+\r
+<p>&nbsp;</p>\r
+\r
+<p>&nbsp;</p>\r
+\r
+<script type="text/javascript" language="javascript1.2">\r
+<!--\r
+if (window.writeIntopicBar)\r
+       writeIntopicBar(0);\r
+//-->\r
+</script>\r
+</body>\r
+</html>\r
index 08ce66a7cc6be41ba7419ebdc4320b8bf0098e37..4222c00a51f6e4ae626a8dfa5cde5abfebac1ae5 100755 (executable)
@@ -120,6 +120,7 @@ adding_quadratic_nodes_and_elements.htm
 aspect_ratio_3d.htm
 borders_at_multi-connection.htm
 borders_at_multiconnection_2d.htm
+building_compounds.htm
 clipping.htm
 constructing_meshes.htm
 convert_to_from_quadratic_mesh.htm
@@ -176,13 +177,18 @@ grouping_elements.htm
 length.htm
 merge_elements.htm
 mesh.htm
+mesh_through_point.htm
 modifying_meshes.htm
 namespacesmesh.html
 netgen_2d_and_3d_hypotheses.htm
 pattern_mapping.htm
 presentation.htm
+prism_3d_algorithm.htm
+projection_algorithms.htm
 quality_controls.htm
+radial_prism.htm
 revolution.htm
+segments_around_vertex_algorithm.htm
 selection_filter_library.htm
 smesh.py_introduction.htm
 transforming_meshes.htm
@@ -193,36 +199,46 @@ ehelp.xml
 texture_horiz_ltbluebubbles.jpg
 index.glo
 default.css
-pics\add_node.png
+pics\curvi_simple_after.png
+pics\image89.gif
+pics\image100.gif
+pics\image78.gif
+pics\image23.gif
+pics\b-mesh_infos.png
 pics\remove_nodes2.png
-pics\merging_nodes2.png
-pics\moving_nodes2.png
+pics\moving_nodes1.png
 pics\smoothing2.png
-pics\b-mberofsegments.png
-pics\b-flection1d.png
-pics\a-cuttingofquadrangles.png
+pics\a-maxelarea.png
+pics\patternmapping1.png
+image94.jpg
+image106.gif
+image91.gif
+image80.gif
+pics\distributionwithtabledensity.png
+pics\moving_nodes2.png
+image7.jpg
+pics\patternmapping2.png
+pics\extrusionalongaline1.png
 pics\addquadrangle.png
-pics\intersectgroups.png
-pics\editgroup.png
 image95.jpg
 pics\sewing1.png
 image92.gif
 image51.jpg
 image70.gif
-pics\netgen2d.png
-pics\circle_simple_after.png
-pics\curvi_simple_after.png
-pics\image138.gif
-pics\create_group.png
-pics\edit_mesh_change_value_hyp.png
+pics\meshtopass.png
+pics\image157.gif
+pics\extrusion1.png
+pics\curvi_angles_after.png
+pics\straight_before.png
+pics\image102.gif
+pics\length2d.png
 pics\free_borders1.png
-pics\add_triangle.png
-pics\b-art_end_length.png
 pics\a-creategroup.png
-pics\a-clipping2.png
-pics\a-transparency.png
-pics\diagonalinversion.png
-pics\translation1.png
+pics\a-startendlength.png
+pics\a-patterntype.png
+pics\extrusionalongaline2.png
+pics\orientaation1.png
+pics\unionoftwotriangles.png
 image96.jpg
 pics\sewing2.png
 image119.gif
@@ -231,15 +247,12 @@ image52.jpg
 image82.gif
 image71.gif
 image30.jpg
-pics\extrusion1.png
-pics\distributionwithanalyticdensity.png
-pics\image139.gif
-pics\rotation1.png
-pics\a-createpolyhedralvolume.png
-pics\a-patterntype.png
-pics\orientaation1.png
-pics\translation2.png
-pics\cutgroups.png
+pics\lengthnearvertex.png
+pics\straight_after.png
+pics\cut_groups1.png
+pics\uniting_a_set_of_triangles1.png
+pics\b-erage_length.png
+pics\removeelements.png
 image97.jpg
 pics\sewing3.png
 image86.jpg
@@ -247,33 +260,38 @@ image50.gif
 image94.gif
 image83.gif
 image31.jpg
-pics\circle_angles_after.png
-pics\circle_simple_before.png
-pics\curvi_angles_after.png
-pics\graduatedaxes1.png
-pics\image107.gif
-pics\automaticlength.png
+pics\aqt.png
+pics\distributionwithanalyticdensity.png
+pics\meshexportmesh.png
 pics\image27.gif
-pics\add_polyhedron.png
-pics\add_edge.png
-pics\rotation2.png
-pics\b-ithmetic1d.png
+pics\cut_groups2.png
+pics\edit_mesh_change_value_hyp.png
+pics\add_node.png
+pics\uniting_a_set_of_triangles2.png
+pics\max_el_area.png
 image10.jpg
-pics\a-maxelarea.png
+pics\a-filteronedges.png
+pics\revolution1.png
 pics\addhexahedron.png
-pics\addtetrahedron.png
-image5.jpg
+pics\addtriangle.png
+pics\editgroup.png
 pics\sewing4.png
 image95.gif
 image76.jpg
 image84.gif
 image32.jpg
 image40.gif
-pics\curvi_simple_before.png
-pics\image108.gif
-pics\aqt.png
-pics\distributionwithtabledensity.png
-pics\smoothing.png
+i_blue.jpg
+image160.gif
+pics\number_of_layers.png
+pics\netgen2d.png
+pics\mesh_for_extr_along_path.png
+pics\meshtrianglemergeelem1.png
+pics\image138.gif
+pics\cut_groups3.png
+pics\revolution2.png
+pics\renumberelements.png
+pics\intersectgroups.png
 image88.jpg
 image30.gif
 image96.gif
@@ -282,18 +300,13 @@ image74.gif
 image63.gif
 image22.jpg
 image41.gif
-pics\edge_wire_3d_before.png
-pics\image109.gif
-pics\meshimportmesh.png
-pics\deletegroups.png
-pics\editing_groups1.png
-pics\uniting_two_triangles1.png
-image7.jpg
-pics\a-averagelength.png
-pics\a-patterntype1.png
-pics\extrusionalongaline1.png
-pics\movenodes.png
-pics\rotation.png
+image161.gif
+pics\createmesh-inv.png
+pics\image139.gif
+pics\b-art_end_length.png
+pics\b-mberofsegments.png
+pics\b-flection1d.png
+pics\a-unionoftriangles.png
 image56.jpg
 image53.gif
 image20.gif
@@ -301,43 +314,54 @@ image97.gif
 image78.jpg
 image64.gif
 image23.jpg
-pics\edge_wire_after.png
-pics\edge_wire_before.png
+pics\buildcompound.png
+pics\projection_3d.png
 image151.gif
-pics\cut_groups1.png
-pics\editing_groups2.png
-pics\uniting_two_triangles2.png
-pics\a-unionoftriangles.png
-pics\a-arithmetic1d.png
-pics\extrusionalongaline2.png
+pics\selectionfilterlibrary.png
+pics\intersect_groups1.png
+pics\create_group.png
+pics\add_triangle.png
+pics\add_edge.png
+pics\rotation1.png
+pics\merging_nodes1.png
+pics\translation1.png
+pics\cutgroups.png
 image79.jpg
 image98.gif
 image32.gif
+pics\projection_2d.png
+pics\advanced_mesh_infos.png
+pics\image108.gif
 pics\image91.gif
 image152.gif
-pics\cut_groups2.png
+pics\automaticlength.png
+pics\intersect_groups2.png
 image130.gif
-pics\max_el_area.png
+pics\rotation2.png
+pics\merging_nodes2.png
+pics\a-cuttingofquadrangles.png
+pics\a-transparency.png
 pics\a-viewgeneral.png
-pics\revolution1.png
-pics\addtriangle.png
+pics\smoothing.png
+pics\translation2.png
 image99.gif
 image55.gif
 image88.gif
 image36.jpg
 image33.gif
 image25.jpg
-i_blue.jpg
+pics\projection_1d.png
+pics\view_rotation_point.png
 image153.gif
+pics\image109.gif
 image15.jpg
 image142.gif
-pics\cut_groups3.png
+pics\intersect_groups3.png
 image131.gif
-pics\add_quadrangle.png
-pics\uniting_a_set_of_triangles1.png
-pics\a-deflection1d.png
-pics\revolution2.png
-pics\unionoftwotriangles.png
+pics\edit_mesh1.png
+pics\b-ithmetic1d.png
+pics\mergenodes.png
+pics\rotation.png
 pics\addnode.png
 image120.gif
 image56.gif
@@ -346,13 +370,18 @@ image67.gif
 image34.gif
 pics\convert.png
 image154.gif
+pics\edge_wire_3d_after.png
+pics\graduatedaxes1.png
+pics\length-crit.png
 image143.gif
+pics\editing_groups1.png
 image132.gif
-pics\edit_mesh1.png
-pics\remove_elements1.png
-pics\uniting_a_set_of_triangles2.png
-pics\mergenodes.png
-pics\symmetry1.png
+pics\a-maxelvolume.png
+pics\a-averagelength.png
+pics\movenodes.png
+pics\removenodes.png
+pics\addtetrahedron.png
+pics\uniongroups.png
 image121.gif
 image79.gif
 image38.jpg
@@ -360,107 +389,99 @@ image46.gif
 image35.gif
 image27.jpg
 image24.gif
+note1.gif
+pics\distribution_of_layers.png
 image155.gif
-pics\mesh_for_extr_along_path.png
-pics\createmesh-inv2.png
+pics\edge_wire_after.png
+pics\edge_wire_before.png
 image144.gif
-pics\intersect_groups1.png
+pics\deletegroups.png
+pics\editing_groups2.png
 image133.gif
-pics\add_polygone.png
-pics\remove_elements2.png
-pics\a-maxelvolume.png
-pics\symmetry2.png
+pics\add_polyhedron.png
+pics\addedge.png
+pics\creategroup.png
 image122.gif
 image58.gif
 image36.gif
 image25.gif
-note1.gif
 image156.gif
-pics\edge_wire_3d_after.png
-pics\createmesh-inv3.png
+pics\circle_simple_after.png
 image145.gif
-pics\intersect_groups2.png
 image134.gif
-pics\b-mesh_infos.png
-pics\symmetry3.png
-pics\addedge.png
+pics\edit_mesh_remove_hyp.png
+pics\a-patterntype1.png
 image123.gif
 image101.gif
 image37.gif
-pics\straight_after.png
+image157.gif
 pics\image96.gif
 image146.gif
-pics\intersect_groups3.png
+pics\meshimportmesh.png
 image135.gif
-pics\b-erage_length.png
-pics\a-standmeshinfo.png
+pics\uniting_two_triangles1.png
 pics\a-nbsegments1.png
-pics\patternmapping1.png
+pics\a-arithmetic1d.png
+pics\symmetry1.png
 image90.jpg
 image124.gif
 image49.gif
+pics\exemple.gif
 image38.gif
-pics\image100.gif
+pics\set_rotation_point_dialog1.png
 pics\image97.gif
-pics\length-crit.png
 image147.gif
+pics\union_groups1.png
 image136.gif
+pics\free_edges.png
+pics\uniting_two_triangles2.png
 pics\a-nbsegments2.png
-pics\a-startendlength.png
-pics\patternmapping2.png
-pics\removeelements.png
-pics\removenodes.png
-pics\uniongroups.png
+pics\symmetry2.png
 image125.gif
 image103.gif
-pics\exemple.gif
 image39.gif
 image28.gif
-pics\advanced_mesh_infos.png
+image159.gif
+pics\set_rotation_point_dialog2.png
+pics\circle_angles_after.png
+pics\createmesh-inv2.png
 pics\image98.gif
+pics\mergeelems.png
 image148.gif
-pics\meshexportmesh.png
 pics\image21.gif
-pics\union_groups1.png
+pics\union_groups2.png
 image137.gif
-pics\free_edges.png
-pics\creategroup.png
+pics\add_quadrangle.png
+pics\remove_elements1.png
+pics\a-createpolyhedralvolume.png
+pics\a-clipping2.png
+pics\a-deflection1d.png
+pics\diagonalinversion.png
+pics\symmetry3.png
+pics\renumbernodes.png
 image92.jpg
 image126.gif
 image18.gif
 image70.jpg
-pics\straight_before.png
-pics\createmesh-inv.png
-pics\image102.gif
+pics\circle_simple_before.png
+pics\edge_wire_3d_before.png
+pics\curvi_simple_before.png
+pics\createmesh-inv3.png
 pics\image99.gif
 pics\image77.gif
-pics\meshtrianglemergeelem1.png
-pics\mergeelems.png
-pics\union_groups2.png
-pics\length2d.png
-pics\renumbernodes.png
+pics\union_groups3.png
+pics\add_polygone.png
+pics\remove_elements2.png
+pics\remove_nodes1.png
+pics\smoothing1.png
+pics\a-standmeshinfo.png
+pics\addpolygon.png
+image5.jpg
 image127.gif
 image93.jpg
 image105.gif
 image19.gif
 image71.jpg
-pics\image89.gif
-pics\image78.gif
-pics\image23.gif
-pics\selectionfilterlibrary.png
-pics\union_groups3.png
-pics\edit_mesh_remove_hyp.png
-pics\remove_nodes1.png
-pics\merging_nodes1.png
-pics\moving_nodes1.png
-pics\smoothing1.png
-pics\a-filteronedges.png
-pics\renumberelements.png
-pics\addpolygon.png
-image94.jpg
-image106.gif
-image91.gif
-image80.gif
 index.ppf
 ehlpdhtm.js
 default_ns.css
@@ -482,6 +503,7 @@ whgdata\whlstt6.htm
 whgdata\whlstt7.htm
 whgdata\whlstt8.htm
 whgdata\whlstt9.htm
+whgdata\whlstt10.htm
 whgdata\whlsti0.htm
 whgdata\whlstfl0.htm
 whgdata\whlstfl1.htm
@@ -509,6 +531,7 @@ whgdata\whlstfl22.htm
 whgdata\whlstfl23.htm
 whgdata\whlstfl24.htm
 whgdata\whlstfl25.htm
+whgdata\whlstfl26.htm
 whgdata\whlstf0.htm
 whgdata\whlstf1.htm
 whgdata\whlstf2.htm
index 78532ffdcf3ae2c8cbbdf8fe3c446509d9bdb02c..d06b4e784265834d8e543c3280342505626ebbab 100755 (executable)
@@ -17,6 +17,7 @@ aTE("Adding Quadratic Nodes and Elements","adding_quadratic_nodes_and_elements.h
 aTE("Aspect ratio 3D","aspect_ratio_3d.htm");
 aTE("Borders at multi-connection","borders_at_multi-connection.htm");
 aTE("Borders at multiconnection 2D","borders_at_multiconnection_2d.htm");
+aTE("Building Compounds","building_compounds.htm");
 aTE("Clipping","clipping.htm");
 aTE("Constructing Meshes","constructing_meshes.htm");
 aTE("Convert to/from Quadratic Mesh","convert_to_from_quadratic_mesh.htm");
@@ -73,6 +74,7 @@ aTE("Grouping Elements","grouping_elements.htm");
 aTE("Length","length.htm");
 aTE("Merge Elements","merge_elements.htm");
 aTE("mesh","mesh.htm");
+aTE("Mesh through point","mesh_through_point.htm");
 aTE("Modifying Meshes","modifying_meshes.htm");
 aTE("SALOME - SMESH - v.version: Package smesh","namespacesmesh.html");
 aTE("Netgen 2D and 3D hypotheses","netgen_2d_and_3d_hypotheses.htm");
@@ -83,6 +85,7 @@ aTE("Projection Algorithms","projection_algorithms.htm");
 aTE("Quality Controls","quality_controls.htm");
 aTE("Radial Prism","radial_prism.htm");
 aTE("Revolution","revolution.htm");
+aTE("Segments around Vertex Algorithm","segments_around_vertex_algorithm.htm");
 aTE("Selection filter library","selection_filter_library.htm");
 aTE("smesh.py_introduction","smesh.py_introduction.htm");
 aTE("Transforming Meshes","transforming_meshes.htm");
index b9fdacc03020c28b242d75e03f89d174aadb5c6c..50ea833ea5bb0d3fcbe5bb1883b0f31bb51e2229 100755 (executable)
 </script>
 <script language="javascript">
 <!--
-aWE("_grp",72);
-aWE("0",14,19,5,6,25,8,12,57,61,63,68,43,72,73,75);
-aWE("000001",68);
-aWE("001",73);
-aWE("0d",14);
-aWE("1",17,1,18,19,20,2,21,23,6,7,26,8,27,28,29,30,11,12,57,31,32,35,36,61,64,68,39,40,70,62,43,44,72,45,47,73,49,50,51,76,54);
-aWE("10",6,8,12,57,31,61,72,73,75);
-aWE("100",6,8,57,68,72,73);
-aWE("109",73);
-aWE("110",61);
-aWE("113",73);
-aWE("12",61,73);
-aWE("13",61);
-aWE("130",61);
-aWE("15",61,68,73);
-aWE("150",8,61,73);
-aWE("17",61);
-aWE("180",61);
-aWE("1d",13,14,15,16,19,23,6,8,11,12,60,61,63,37,67,68,69,70,72);
-aWE("1e",61,68);
-aWE("2",17,1,18,20,2,21,23,6,7,26,8,27,28,29,30,11,12,31,32,36,61,64,68,39,40,70,62,43,44,45,47,73,49,50,51,76,54);
-aWE("20",6,8,57,61,68,72,73,75);
-aWE("200",6,8,61,72);
-aWE("21",61,73);
-aWE("23",61,73);
-aWE("24",73);
-aWE("240",61);
-aWE("245",61);
-aWE("246",61);
-aWE("25",73);
-aWE("255",61);
-aWE("2d",13,14,15,16,18,20,4,23,6,8,11,12,57,33,32,60,36,63,64,66,67,68,69,70,43,72,73,54);
-aWE("3",14,18,20,21,23,6,7,26,8,27,28,11,12,57,31,61,63,64,68,39,40,70,62,43,44,72,45,73,49,50,75,54);
-aWE("30",8,61,63,73);
-aWE("300",6);
-aWE("3128",61);
-aWE("321",61);
-aWE("3265",61);
-aWE("3402",61);
-aWE("35",57,68);
-aWE("3658",61);
-aWE("38",61,68,73);
-aWE("39",61);
-aWE("3d",13,14,15,16,0,17,1,20,2,21,23,6,25,26,8,9,27,28,29,11,12,60,63,34,66,67,68,69,39,40,70,43,72,45,49,50,76,53);
-aWE("3e",68);
-aWE("3rd",14);
-aWE("3x3",61);
-aWE("4",14,18,20,23,6,26,8,28,12,31,61,64,68,62,43,44,47,73,54);
-aWE("40",57,61,72);
-aWE("405",61);
-aWE("406",61);
-aWE("45",12,61,73);
-aWE("47",61);
-aWE("492",61);
-aWE("493",61);
-aWE("5",5,6,8,61,68,73);
-aWE("50",8,61,73);
-aWE("502",61);
-aWE("503",61);
-aWE("58",73);
-aWE("5th",14);
-aWE("6",2,6,8,57,61,73);
-aWE("60",57,61,72);
-aWE("66632",61);
-aWE("69",73);
-aWE("7",6,8,57,61,68);
-aWE("70",8,61,73);
-aWE("71",73);
-aWE("72",73);
-aWE("73",61);
-aWE("8",57,61,68,73);
-aWE("80",61,72);
-aWE("800",6);
-aWE("814",61);
-aWE("850",61);
-aWE("859",61);
-aWE("89",73);
-aWE("9",61,73);
-aWE("90",73);
-aWE("900",6,75);
-aWE("91",73);
-aWE("92",73);
-aWE("95",68);
-aWE("9999",25);
-aWE("a_mesh",61);
-aWE("a10",61);
-aWE("a45",61);
-aWE("aa",61);
-aWE("abl",17,1,53);
-aWE("abord",68);
-aWE("aborder",68);
-aWE("abov",61,45);
-aWE("absent",51);
-aWE("absolute",74);
-aWE("abut",19);
-aWE("acces",0,71,53);
-aWE("accord",16,18,19,20,2,32,36,64,44,45,47,76,54);
-aWE("account",13,64);
-aWE("acomp",73);
-aWE("actual",63,37);
-aWE("ad",17,1,21,7,25,26,57,61,49,51);
-aWE("add",17,1,21,23,25,26,8,30,12,57,61,68,71,72,49);
-aWE("addedg",61);
-aWE("addfac",61);
-aWE("addition",26,60,61);
-aWE("additional",13,14,23,8,37,64,42,71,45);
-aWE("addnod",61);
-aWE("addobject",57);
-aWE("addpolygonalfac",61);
-aWE("addpolyhedralvolum",61);
-aWE("addtostudy",6,8,57,61,68,72,73,75);
-aWE("addtostudyinfath",6,8,57,61);
-aWE("addvolum",61);
-aWE("adjacent",28,36,63,37,39,43,49);
-aWE("adjust",45);
-aWE("adjustabl",37);
-aWE("advanc",0,52);
-aWE("afilt",57,68);
-aWE("afiltermgr",68);
-aWE("ageomgroup",57);
-aWE("agroup",57,68);
-aWE("agroup1",57);
-aWE("agroup2",57);
-aWE("agroup3",57);
-aWE("agroup4",57);
-aWE("agroup5",57);
-aWE("agroupelemid",57);
-aWE("agroupf",68);
-aWE("agroupmain",57);
-aWE("agroupn",68);
-aWE("agroupr",57);
-aWE("agrouptool",57);
-aWE("ai",19);
-aWE("al",61);
-aWE("algeady",67);
-aWE("algo",8,61,68,73);
-aWE("algo_local",6,8,73);
-aWE("algo1d",6,8,57,61,72,73,75);
-aWE("algo2d",6,8,61,72,73,75);
-aWE("algo3d",6,8,72,75);
-aWE("algorithm",13,14,15,16,0,18,23,6,24,8,12,33,60,63,34,64,66,67,69,38,43);
-aWE("allow",13,0,1,19,21,24,7,25,26,31,33,59,35,60,63,37,64,67,41,43,45,46,48,49,51,53);
-aWE("along",11,12,61,64,45,53);
-aWE("already",67);
-aWE("alternativ",23);
+aWE("_grp",75);
+aWE("0",15,20,6,7,26,9,13,58,63,65,70,44,75,76,78);
+aWE("000001",70);
+aWE("001",76);
+aWE("0d",15,73);
+aWE("1",18,1,19,20,21,2,22,24,7,8,27,9,28,29,30,31,12,13,58,32,33,36,62,37,63,66,70,40,41,72,64,44,45,75,46,48,76,50,51,52,79,55);
+aWE("10",7,9,13,58,32,63,75,76,78);
+aWE("100",7,9,58,63,70,75,76);
+aWE("109",76);
+aWE("110",63);
+aWE("113",76);
+aWE("12",63,76);
+aWE("13",63);
+aWE("130",63);
+aWE("15",63,70,76);
+aWE("150",9,63,76);
+aWE("17",63);
+aWE("180",63);
+aWE("1d",14,15,16,17,20,24,7,9,12,13,61,63,65,38,69,70,71,72,75);
+aWE("1e",63,70);
+aWE("2",18,1,19,21,2,22,24,7,8,27,9,28,29,30,31,12,13,32,33,62,37,63,66,70,40,41,72,64,44,45,46,48,76,50,51,52,79,55);
+aWE("20",7,9,58,63,70,75,76,78);
+aWE("200",7,9,63,75);
+aWE("21",63,76);
+aWE("23",63,76);
+aWE("24",76);
+aWE("240",63);
+aWE("245",63);
+aWE("246",63);
+aWE("25",76);
+aWE("255",63);
+aWE("2d",14,15,16,17,19,21,4,24,7,9,12,13,58,34,33,61,37,65,66,68,69,70,71,72,44,75,76,55);
+aWE("3",15,19,21,22,24,7,8,27,9,28,29,12,13,58,32,62,63,65,66,70,40,41,72,64,44,45,75,46,76,50,51,78,55);
+aWE("30",9,63,65,76);
+aWE("300",7);
+aWE("3128",63);
+aWE("321",63);
+aWE("3265",63);
+aWE("3402",63);
+aWE("35",58,70);
+aWE("3658",63);
+aWE("38",63,70,76);
+aWE("39",63);
+aWE("3d",14,15,16,17,0,18,1,21,2,22,24,7,26,27,9,10,28,29,30,12,13,61,65,35,68,69,70,71,40,41,72,44,75,46,50,51,79,54);
+aWE("3e",70);
+aWE("3rd",15);
+aWE("3x3",63);
+aWE("4",15,19,21,24,7,27,9,29,13,32,62,63,66,70,64,44,45,48,76,55);
+aWE("40",58,63,75);
+aWE("405",63);
+aWE("406",63);
+aWE("45",13,63,76);
+aWE("47",63);
+aWE("492",63);
+aWE("493",63);
+aWE("5",6,7,9,63,70,76);
+aWE("50",9,63,76);
+aWE("502",63);
+aWE("503",63);
+aWE("58",76);
+aWE("5th",15);
+aWE("6",2,7,9,58,63,76);
+aWE("60",58,63,75);
+aWE("66632",63);
+aWE("69",76);
+aWE("7",7,9,58,63,70);
+aWE("70",9,63,76);
+aWE("71",76);
+aWE("72",76);
+aWE("73",63);
+aWE("8",58,63,70,76);
+aWE("80",63,75);
+aWE("800",7);
+aWE("814",63);
+aWE("850",63);
+aWE("859",63);
+aWE("89",76);
+aWE("9",63,76);
+aWE("90",76);
+aWE("900",7,78);
+aWE("91",76);
+aWE("92",76);
+aWE("95",70);
+aWE("9999",26);
+aWE("a_mesh",63);
+aWE("a10",63);
+aWE("a45",63);
+aWE("aa",63);
+aWE("abl",18,1,54);
+aWE("abord",70);
+aWE("aborder",70);
+aWE("abov",63,46);
+aWE("absent",52);
+aWE("absolute",77);
+aWE("abut",20);
+aWE("acces",0,74,54);
+aWE("accord",17,19,20,21,2,33,37,66,45,46,48,79,55);
+aWE("account",14,66);
+aWE("acomp",76);
+aWE("actual",65,38);
+aWE("ad",18,1,22,8,26,27,58,63,50,52);
+aWE("add",18,1,22,24,26,27,9,31,13,58,63,70,74,75,50);
+aWE("addedg",63);
+aWE("addfac",63);
+aWE("addition",27,61,63);
+aWE("additional",14,15,24,9,38,66,43,74,46);
+aWE("addnod",63);
+aWE("addobject",58);
+aWE("addpolygonalfac",63);
+aWE("addpolyhedralvolum",63);
+aWE("addtostudy",7,9,58,63,70,75,76,78);
+aWE("addtostudyinfath",7,9,58,63);
+aWE("addvolum",63);
+aWE("adjacent",29,37,65,38,40,44,50);
+aWE("adjust",46);
+aWE("adjustabl",38);
+aWE("advanc",0,53);
+aWE("afilt",58,70);
+aWE("afiltermgr",70);
+aWE("ageomgroup",58);
+aWE("agroup",58,70);
+aWE("agroup1",58);
+aWE("agroup2",58);
+aWE("agroup3",58);
+aWE("agroup4",58);
+aWE("agroup5",58);
+aWE("agroupelemid",58);
+aWE("agroupf",70);
+aWE("agroupmain",58);
+aWE("agroupn",70);
+aWE("agroupr",58);
+aWE("agrouptool",58);
+aWE("ai",20);
+aWE("al",63);
+aWE("algeady",69);
+aWE("algo",9,63,70,76);
+aWE("algo_local",7,9,76);
+aWE("algo1d",7,9,58,63,75,76,78);
+aWE("algo2d",7,9,63,75,76,78);
+aWE("algo3d",7,9,75,78);
+aWE("algorithm",14,15,16,17,0,19,24,7,25,9,13,34,61,65,35,66,68,69,71,39,73,44);
+aWE("allow",14,16,0,1,20,5,22,25,8,26,27,32,34,60,36,61,62,65,38,66,69,42,73,44,46,47,49,50,52,54);
+aWE("along",12,13,63,66,46,54);
+aWE("already",69);
+aWE("alternativ",24);
 aWE("alternative",0,1);
-aWE("alway",45);
-aWE("amesh",6);
+aWE("alway",46);
+aWE("amesh",7);
 aWE("amount",3);
-aWE("analytic",19);
-aWE("angl",16,5,26,12,60,36,61,68,70,41,44,73,49,54);
-aWE("angle270",73);
-aWE("angle45",61);
-aWE("angularity",12);
-aWE("anid",57,68);
-aWE("anoth",15,37,67);
-aWE("any",14,1,23,25,28,12,57,64,69,45);
-aWE("ap",15,17,1,18,20,2,21,5,23,7,25,26,8,9,27,28,30,11,12,32,59,60,36,61,64,67,38,39,40,70,43,44,45,46,47,49,50,51,76,54);
-aWE("api",72);
-aWE("apparent",23);
-aWE("appear",0,17,1,21,23,24,7,26,27,28,30,11,12,35,64,67,39,40,70,41,46,48,49,50,51);
-aWE("append",61);
-aWE("appli",18,19,20,2,23,24,33,32,36,34,37,69,38,71,44,45,47,76,54);
-aWE("applicabl",20,71);
-aWE("application",16,64);
-aWE("apply",13,0,23,24,25);
-aWE("applytomeshfac",61);
-aWE("appropriat",23);
-aWE("approximate",19);
-aWE("ar_margin",68);
-aWE("arc",8,73);
-aWE("arcsin",54);
-aWE("area",13,16,18,8,57,33,60,34,68,45,47,53);
-aWE("area_margin",68);
-aWE("arithmetic",13,19,6,8,60);
-aWE("arithmetic1d",6,8,73);
-aWE("around",5,12,70,53);
-aWE("array_of_nodes_group",73);
-aWE("asmeshgroup1",57);
-aWE("asmeshgroup2",57);
-aWE("aspect",16,20,2,60,68,45);
-aWE("assemb",72);
-aWE("assign",19,23,25,8,38,54);
-aWE("associat",17,29,39);
-aWE("attribut",25);
-aWE("auto",5);
-aWE("automatic",13,19,23,60,64);
-aWE("automatical",0,19,21,23,26,28,49);
-aWE("availabl",43,53);
-aWE("averag",13,19,8,33,60,64,54);
-aWE("ax",53);
-aWE("axi",11,61,70,41,46,73,53,54);
-aWE("axisstruct",61,73);
-aWE("axisxyz",61,73);
+aWE("analytic",20);
+aWE("angl",17,6,27,13,61,37,63,70,72,42,45,76,50,55);
+aWE("angle270",76);
+aWE("angle45",63);
+aWE("angularity",13);
+aWE("anid",58,70);
+aWE("anoth",16,38,69);
+aWE("any",15,16,1,24,26,29,13,58,62,63,66,71,46);
+aWE("ap",16,18,1,19,21,2,22,6,24,8,26,27,9,10,28,29,31,12,13,33,60,61,62,37,63,66,69,39,40,41,72,44,45,46,47,48,50,51,52,79,55);
+aWE("api",75);
+aWE("apparent",24);
+aWE("appear",0,18,1,5,22,24,25,8,27,28,29,31,12,13,36,62,66,69,40,41,72,42,47,49,50,51,52);
+aWE("append",63);
+aWE("appli",19,20,21,2,24,25,34,33,37,35,38,71,39,73,74,45,46,48,79,55);
+aWE("applicabl",21,74);
+aWE("application",17,66);
+aWE("apply",14,0,24,25,26);
+aWE("applytomeshfac",63);
+aWE("appropriat",24);
+aWE("approximate",20);
+aWE("ar_margin",70);
+aWE("arc",9,76);
+aWE("arcsin",55);
+aWE("area",14,17,19,9,58,34,61,35,70,46,48,54);
+aWE("area_margin",70);
+aWE("arithmetic",14,20,7,9,61);
+aWE("arithmetic1d",7,9,76);
+aWE("around",6,13,72,73,54);
+aWE("array_of_nodes_group",76);
+aWE("asmeshgroup1",58);
+aWE("asmeshgroup2",58);
+aWE("aspect",17,21,2,61,70,46);
+aWE("assemb",75);
+aWE("assign",16,20,24,26,9,39,55);
+aWE("associat",18,30,40);
+aWE("attribut",26);
+aWE("auto",6);
+aWE("automatic",14,20,24,61,62,66);
+aWE("automatical",0,20,22,24,27,29,50);
+aWE("automaticlength",63);
+aWE("availabl",44,54);
+aWE("averag",14,20,9,34,61,66,55);
+aWE("ax",54);
+aWE("axi",12,63,72,42,47,76,54,55);
+aWE("axisstruct",63,76);
+aWE("axisxyz",63,76);
 aWE("background",0);
-aWE("bar",16);
-aWE("bas",13,18,8,12,60,54);
-aWE("basi",14,23,24);
-aWE("basic",13,15,0);
-aWE("bb",61);
-aWE("be",67);
-aWE("becom",63,64);
-aWE("befor",71,73);
-aWE("begin",19,43);
-aWE("belong",3,4,25,55,56,67,43,51);
-aWE("below",61,63,72);
-aWE("berder",43);
-aWE("bet",20);
-aWE("binary",71);
-aWE("bisect",54);
-aWE("bisector",54);
-aWE("bit",71);
+aWE("bar",17);
+aWE("bas",14,19,9,13,61,55);
+aWE("basi",15,24,25);
+aWE("basic",14,16,0);
+aWE("bb",63);
+aWE("be",69);
+aWE("becom",5,65,66);
+aWE("befor",74,76);
+aWE("begin",20,44);
+aWE("belong",3,4,26,56,57,69,44,52);
+aWE("below",63,65,75);
+aWE("berder",44);
+aWE("bet",21);
+aWE("binary",74);
+aWE("bisect",55);
+aWE("bisector",55);
+aWE("bit",74);
 aWE("black",0);
 aWE("blu",3);
-aWE("bmp",0,53);
-aWE("bog",19);
-aWE("boolean",61,51);
-aWE("bord",43,73);
-aWE("border",16,3,4,55,56,60,68,43,73);
-aWE("both",0,12,69,45,51);
-aWE("bottom",61,42);
-aWE("bound",14,64,53);
-aWE("boundari",64);
-aWE("boundary",13,25,64,43,45);
-aWE("box",17,1,19,21,23,6,24,7,26,8,27,28,30,11,12,57,31,59,35,63,64,67,68,39,40,70,41,42,71,43,72,45,46,73,48,49,50,51,52,75,53);
-aWE("box_1",61);
-aWE("box_cyl",72);
-aWE("box1",68,73);
-aWE("box2",68,73);
-aWE("broken",1,37);
-aWE("brown",25);
-aWE("brows",0,17,1,22,23,24,25,9,30,65,39,40,71,52);
-aWE("build",8,11,33,61,63,37,64,66,70,72);
-aWE("built",20,24,12,64,45);
-aWE("button",17,1,18,20,2,21,5,23,24,7,25,26,9,27,28,30,11,12,31,32,36,64,67,38,39,40,70,41,71,43,44,45,46,47,48,49,50,51,52,76,53,54);
-aWE("cad",14);
-aWE("cal",64);
-aWE("calculat",16,20,2,33,47);
-aWE("calculation",13,18,32,36);
-aWE("careful",39);
-aWE("cas",17,23,6,8,28,12,64,52);
-aWE("caviti",15);
-aWE("cc",61);
-aWE("cel",25,63,39,50);
-aWE("cent",12,45,53);
-aWE("central",12);
-aWE("centroid",45);
-aWE("centroidal",45);
-aWE("centroidal_smooth",61);
-aWE("certain",25,64);
-aWE("chang",0,19,21,6,28,61,37,38,53);
-aWE("characteristic",16);
-aWE("characteriz",14);
-aWE("check",25,63,43,53);
-aWE("checkbox",17,63,71,48);
-aWE("choic",13,23,64);
-aWE("choos",17,1,18,20,2,21,22,7,25,26,9,27,28,10,29,11,12,31,32,35,36,64,39,40,70,41,42,71,43,44,46,47,48,49,50,76,53,54);
-aWE("chosen",20,26,33,34,49);
-aWE("circl",12,73);
-aWE("circlemesh",73);
-aWE("circular",61);
-aWE("clas",62);
-aWE("clear",62,71);
-aWE("click",0,17,1,18,20,2,21,5,22,23,24,7,25,26,9,27,28,29,30,11,12,31,32,36,64,65,67,38,39,40,70,42,71,43,44,45,47,49,50,51,52,76,53,54);
-aWE("clip",0,5);
-aWE("clos",14,20,9,12,61,43);
-aWE("co",61,43);
-aWE("coars",19,7,63);
-aWE("coincid",59);
-aWE("coincident",12,59,35);
-aWE("color",16,0,18,20,2,25,32,36,44,47,76,53,54);
-aWE("combin",10,32,65,71);
-aWE("common",27,71,50);
-aWE("comp",68);
-aWE("compar",19,43);
-aWE("complete",59);
-aWE("complex",1,12);
-aWE("component",60,42);
-aWE("compos",13,14,15,16,0,19,2,29,33,34,69,44);
-aWE("compound",68);
-aWE("comput",0,19,23,6,8,57,61,64,68,43,72,73,75);
-aWE("computation",23,24,8,61);
-aWE("con",72);
-aWE("concept",37);
-aWE("concern",69);
-aWE("condition",13,25);
-aWE("confirm",21,26,30,39,45,49,51);
-aWE("confirmation",25);
-aWE("conform",13,37,43,73);
-aWE("conformity",20);
-aWE("connect",19,26,66,45);
-aWE("connection",14,16,3,4,60,68);
-aWE("connectivity",64);
-aWE("consid",20,23);
-aWE("consider",14,20,2,43);
-aWE("consist",16,1,18,19,20,3,4,22,23,24,25,12,55,56,57,33,32,36,34,69,47);
-aWE("consol",52);
-aWE("constant",19);
-aWE("construct",15,19,22,23,6,24,38);
-aWE("construction",19,23,6,24);
-aWE("contain",14,15,21,23,24,25,26,12,31,33,64,45,49);
-aWE("content",9,53);
-aWE("continu",45);
-aWE("contour",14,43);
-aWE("contrast",49);
-aWE("control",16,0,18,20,2,3,4,26,55,56,58,32,60,36,68,44,47,49,76,54);
-aWE("converg",45);
-aWE("conversion",19,7);
-aWE("convert",7);
-aWE("coordinat",14,17,28,64,53);
-aWE("copy",41,71,46,73,48);
-aWE("corn",1,54);
-aWE("corner",26,12,45,54);
-aWE("correspond",14,16,31,64,68,71,43,48);
-aWE("cos_bot",61);
-aWE("cos_top",61);
-aWE("cosal",61);
-aWE("cot",72);
-aWE("could",14,17,67);
-aWE("count",43);
-aWE("counterclockwis",64);
-aWE("cours",23);
-aWE("cover",12);
-aWE("creat",14,0,17,1,19,5,23,6,24,25,8,30,57,35,60,61,63,37,64,67,68,38,41,71,72,46,73,48,51,75,54);
-aWE("createemptygroup",57,68);
-aWE("createfiltermanag",68);
-aWE("creategroup",57,61,68,72);
-aWE("createpolyedr",73);
-aWE("createpolygon",73);
-aWE("creation",14,37,64,38,62,72,51);
-aWE("criteria",60,71);
-aWE("criterion",18,20,2,25,26,57,58,32,36,68,71,44,47,49,76,54);
-aWE("cros",0,5,54);
-aWE("cubic",15);
-aWE("current",21,23,26,63,67,38,71,43,49);
-aWE("curv",14,19,12,61);
-aWE("curvilinear",19,12);
-aWE("custom",63);
-aWE("cut",19,6,26,8,57,61,51);
-aWE("cutgroup",57);
-aWE("cyl",8,72);
-aWE("cylind",8,72);
-aWE("d",19);
-aWE("data",62);
-aWE("dd",61);
-aWE("dea",31);
-aWE("deal",14);
-aWE("def",6,61,62);
-aWE("default",0,23,12,57,63,65,71,74,53);
-aWE("defin",14,15,1,19,20,5,23,6,24,25,8,12,61,63,37,64,66,67,62,43,72,73,53);
-aWE("definit",14,16,19,21,22,25,26,60,38,39,49);
-aWE("definition",0,19,6,12,33,63,34);
-aWE("deflection",13,19,8,60);
-aWE("deflection1d",8);
-aWE("deform",53);
-aWE("degre",20,5);
-aWE("delet",9,56,61,39,71);
-aWE("deletediag",61);
-aWE("deletion",39,50);
-aWE("density",19);
-aWE("depend",13,14,23,33,34);
-aWE("describ",14,15,64);
-aWE("description",64);
-aWE("desirabl",35);
-aWE("desktop",42);
-aWE("destin",14,16,60,62);
-aWE("detail",13,15,0);
-aWE("detalization",63);
-aWE("detect",35);
-aWE("dh",61);
-aWE("di1",72);
-aWE("diagonal",26,27,61,47);
-aWE("dialog",17,1,19,21,23,24,7,26,27,28,30,11,12,31,59,35,64,67,39,40,70,41,43,45,46,48,49,50,51);
-aWE("diamet",20);
-aWE("dif",1,63);
-aWE("differ",19);
-aWE("differenc",12,43);
-aWE("different",13,17,25,12,67,38,71,43);
-aWE("digit",12);
-aWE("dimension",14,2,23,11,63,70,52);
-aWE("direct",14,6,43,45);
-aWE("direction",12,64,54);
-aWE("dirstruct",61,73);
-aWE("discretiz",11,70);
-aWE("discretization",14,15);
-aWE("displac",28);
-aWE("display",16,0,1,18,20,2,3,21,23,24,25,26,28,10,29,55,32,36,65,44,45,47,49,52,76,53,54);
-aWE("distanc",19,5,64,53,54);
-aWE("distinguish",25);
-aWE("distortion",45);
-aWE("distribution",19,69);
-aWE("divid",19);
-aWE("do",17);
-aWE("docopy",73);
-aWE("documentation",62);
-aWE("domain",64);
-aWE("don",14,23,12,61,37,67,53);
+aWE("bmp",0,54);
+aWE("bog",20);
+aWE("boolean",63,52);
+aWE("bord",44,76);
+aWE("border",17,3,4,56,57,61,70,44,76);
+aWE("both",0,13,71,46,52);
+aWE("bottom",63,43);
+aWE("bound",15,66,54);
+aWE("boundari",66);
+aWE("boundary",14,26,66,44,46);
+aWE("box",18,1,20,5,22,24,7,25,8,27,9,28,29,31,12,13,58,32,60,36,62,63,65,66,69,70,40,41,72,42,43,73,74,44,75,46,47,76,49,50,51,52,53,78,54);
+aWE("box_1",63);
+aWE("box_cyl",75);
+aWE("box1",70,76);
+aWE("box2",70,76);
+aWE("break",63);
+aWE("broken",1,38);
+aWE("brown",26);
+aWE("brows",0,18,1,5,23,24,25,26,10,31,67,40,41,74,53);
+aWE("build",5,9,12,34,63,65,38,66,68,72,75);
+aWE("built",21,25,13,66,46);
+aWE("button",18,1,19,21,2,5,22,6,24,25,8,26,27,10,28,29,31,12,13,32,33,62,37,66,69,39,40,41,72,42,74,44,45,46,47,48,49,50,51,52,53,79,54,55);
+aWE("c1",16);
+aWE("cad",15);
+aWE("cal",66);
+aWE("calculat",17,21,2,34,48);
+aWE("calculation",14,19,33,37);
+aWE("careful",40);
+aWE("cas",18,5,24,7,9,29,13,62,66,53);
+aWE("caviti",16);
+aWE("cc",63);
+aWE("cel",26,65,40,51);
+aWE("cent",13,46,54);
+aWE("central",13);
+aWE("centroid",46);
+aWE("centroidal",46);
+aWE("centroidal_smooth",63);
+aWE("certain",26,62,66,73);
+aWE("chang",0,20,22,7,29,63,38,39,54);
+aWE("characteristic",17);
+aWE("characteriz",15);
+aWE("check",26,62,63,65,44,54);
+aWE("checkbox",18,65,74,49);
+aWE("choic",14,24,66);
+aWE("choos",18,1,19,21,2,5,22,23,8,26,27,10,28,29,11,30,12,13,32,33,36,62,37,66,40,41,72,42,43,73,74,44,45,47,48,49,50,51,79,54,55);
+aWE("chosen",21,5,27,34,35,50);
+aWE("circl",13,76);
+aWE("circlemesh",76);
+aWE("circular",63);
+aWE("clas",64);
+aWE("clear",64,74);
+aWE("click",0,18,1,19,21,2,5,22,6,23,24,25,8,26,27,10,28,29,30,31,12,13,32,33,62,37,66,67,69,39,40,41,72,43,74,44,45,46,48,50,51,52,53,79,54,55);
+aWE("clip",0,6);
+aWE("clos",15,21,10,13,63,44);
+aWE("closest",62);
+aWE("co",63,44);
+aWE("coars",20,8,65);
+aWE("coincid",60);
+aWE("coincident",5,13,60,36);
+aWE("color",17,0,19,21,2,26,33,37,45,48,79,54,55);
+aWE("combin",11,33,67,73,74);
+aWE("combination",5);
+aWE("common",28,74,51);
+aWE("comp",70);
+aWE("compar",20,44);
+aWE("complete",60);
+aWE("complex",1,13);
+aWE("component",61,43);
+aWE("compos",14,15,16,17,0,20,2,30,34,35,71,45);
+aWE("composit",16);
+aWE("compound",5,70);
+aWE("compound_mesh",5);
+aWE("comput",0,20,24,7,9,58,63,66,70,44,75,76,78);
+aWE("computation",24,25,9,63);
+aWE("con",75);
+aWE("concatenat",5);
+aWE("concept",38);
+aWE("concern",71);
+aWE("condition",14,26);
+aWE("confirm",22,27,31,40,46,50,52);
+aWE("confirmation",26);
+aWE("conform",14,38,44,76);
+aWE("conformity",21);
+aWE("connect",20,27,68,46);
+aWE("connection",15,17,3,4,61,70);
+aWE("connectivity",66);
+aWE("consid",21,24);
+aWE("consider",15,21,2,73,44);
+aWE("consist",17,1,19,20,21,3,4,23,24,25,26,13,56,57,58,34,33,37,35,71,48);
+aWE("consol",53);
+aWE("constant",20);
+aWE("construct",16,20,23,24,7,25,39);
+aWE("construction",20,24,7,25);
+aWE("contain",15,16,22,24,25,26,27,13,32,34,66,46,50);
+aWE("content",10,54);
+aWE("continu",46);
+aWE("contour",15,44);
+aWE("contrast",50);
+aWE("control",17,0,19,21,2,3,4,27,56,57,59,33,61,37,70,45,48,50,79,55);
+aWE("converg",46);
+aWE("conversion",20,8);
+aWE("convert",8);
+aWE("coordinat",15,18,29,62,63,66,54);
+aWE("copy",42,74,47,76,49);
+aWE("corn",1,55);
+aWE("corner",27,13,73,46,55);
+aWE("correspond",15,17,32,66,70,74,44,49);
+aWE("cos_bot",63);
+aWE("cos_top",63);
+aWE("cosal",63);
+aWE("cot",75);
+aWE("could",15,18,69);
+aWE("count",44);
+aWE("counterclockwis",66);
+aWE("cours",24,73);
+aWE("cover",13);
+aWE("creat",15,0,18,1,20,5,6,24,7,25,26,9,31,58,36,61,62,63,65,38,66,69,70,39,42,74,75,47,76,49,52,78,55);
+aWE("createemptygroup",58,70);
+aWE("createfiltermanag",70);
+aWE("creategroup",58,63,70,75);
+aWE("createpolyedr",76);
+aWE("createpolygon",76);
+aWE("creation",15,62,38,66,39,64,75,52);
+aWE("criteria",61,74);
+aWE("criterion",19,21,2,26,27,58,59,33,37,70,74,45,48,50,79,55);
+aWE("cros",0,6,55);
+aWE("ctrl",5);
+aWE("cubic",16);
+aWE("current",22,24,27,65,69,39,74,44,50);
+aWE("curv",15,16,20,13,63);
+aWE("curvilinear",20,13);
+aWE("custom",65);
+aWE("cut",20,7,27,9,58,63,52);
+aWE("cutgroup",58);
+aWE("cyl",9,75);
+aWE("cylind",9,75);
+aWE("d",20);
+aWE("data",64);
+aWE("dd",63);
+aWE("dea",32);
+aWE("deal",15);
+aWE("def",7,63,64);
+aWE("default",0,24,13,58,65,67,74,77,54);
+aWE("defin",15,16,1,20,21,5,6,24,7,25,26,9,13,62,63,65,38,66,68,69,64,73,44,75,76,54);
+aWE("definit",15,17,20,22,23,26,27,61,39,40,50);
+aWE("definition",0,20,7,13,34,65,35);
+aWE("deflection",14,20,9,61);
+aWE("deflection1d",9);
+aWE("deform",54);
+aWE("degre",21,6);
+aWE("delet",10,57,63,40,74);
+aWE("deletediag",63);
+aWE("deletion",40,51);
+aWE("density",20);
+aWE("depend",14,15,24,34,35);
+aWE("describ",15,16,0,66);
+aWE("description",66);
+aWE("desirabl",36);
+aWE("desktop",43);
+aWE("destin",15,17,61,64);
+aWE("detail",14,16,0);
+aWE("detalization",65);
+aWE("detect",36);
+aWE("dh",63);
+aWE("di1",75);
+aWE("diagonal",27,28,63,48);
+aWE("dialog",18,1,20,5,22,24,25,8,27,28,29,31,12,13,32,60,36,62,66,69,40,41,72,42,44,46,47,49,50,51,52);
+aWE("diamet",21);
+aWE("dif",1,65);
+aWE("differ",20);
+aWE("differenc",13,44);
+aWE("different",14,18,26,13,69,39,74,44);
+aWE("digit",13);
+aWE("dimension",15,2,24,12,65,72,73,53);
+aWE("direct",15,7,44,46);
+aWE("direction",13,66,55);
+aWE("dirstruct",63,76);
+aWE("discretisation",16);
+aWE("discretiz",12,72);
+aWE("discretization",15);
+aWE("displac",29);
+aWE("display",17,0,1,19,21,2,3,22,24,25,26,27,29,11,30,56,33,37,67,45,46,48,50,53,79,54,55);
+aWE("distanc",20,6,66,54,55);
+aWE("distinguish",26);
+aWE("distortion",46);
+aWE("distribution",20,71);
+aWE("divid",20);
+aWE("do",18);
+aWE("docopy",76);
+aWE("documentation",0,64);
+aWE("doesn",73);
+aWE("domain",66);
+aWE("don",15,24,13,63,38,69,54);
 aWE("doubl",1);
-aWE("downward",53);
-aWE("dr",61);
-aWE("drag",53);
-aWE("drawn",53);
-aWE("dump",0,53);
-aWE("duplicat",12);
-aWE("dx",61);
-aWE("dy",61);
-aWE("e",20,23,24,26,12,63,64,66,69,43,49);
-aWE("e_arc",8);
-aWE("e_straight",8);
-aWE("e1",61);
-aWE("easi",22);
-aWE("easy",62);
-aWE("edg",13,14,15,16,0,17,1,19,20,3,4,22,23,6,25,26,8,27,28,10,12,55,56,57,58,33,32,60,61,63,37,64,66,67,68,71,43,45,73,49,50,75,54);
-aWE("edge_",61);
-aWE("edge_bezierrr",61);
-aWE("edge_bezierrr_mesh",61);
-aWE("edge_circl",61);
-aWE("edge_circle_mesh",61);
-aWE("edge_straight",61);
-aWE("edge_straight_mesh",61);
-aWE("edge1",73);
-aWE("edgeslist",73);
-aWE("edgex",6,8);
-aWE("edit",6,9,30,57,35,38);
-aWE("edition",62,72);
-aWE("ee_1",61);
-aWE("ee_2",61);
-aWE("ee_3",61);
-aWE("ee_4",61);
-aWE("ee_5",61);
-aWE("ee_6",61);
-aWE("ee_7",61);
-aWE("effect",49);
-aWE("eith",64,66,43);
-aWE("element",13,14,15,16,0,17,1,18,19,20,2,4,21,22,7,25,26,8,9,27,28,29,30,11,12,56,57,33,32,59,60,36,61,63,34,37,64,66,68,39,40,70,41,71,43,44,45,46,47,73,48,49,51,52,76,54);
-aWE("els",6,8,61,64);
-aWE("empty",61);
-aWE("enabl",71);
-aWE("encapsulat",24);
-aWE("encounter",64);
-aWE("end",13,19,8,60,37,71,43,48);
-aWE("enough",43);
-aWE("ent",25,27,28,31,50);
-aWE("entiti",14,15);
-aWE("entity",14,0,10,71);
-aWE("equal",19,33,64,71,43,45);
-aWE("equidistant",19);
-aWE("equilateral",20);
+aWE("downward",54);
+aWE("dr",63);
+aWE("drag",54);
+aWE("drawn",54);
+aWE("dump",0,54);
+aWE("duplicat",13);
+aWE("dx",63);
+aWE("dy",63);
+aWE("e",21,24,25,27,13,65,66,68,71,73,44,50);
+aWE("e_arc",9);
+aWE("e_straight",9);
+aWE("e1",63);
+aWE("easi",23);
+aWE("easy",64);
+aWE("edg",14,15,16,17,0,18,1,20,21,3,4,23,24,7,26,27,9,28,29,11,13,56,57,58,59,34,33,61,63,65,38,66,68,69,70,74,44,46,76,50,51,78,55);
+aWE("edge_",63);
+aWE("edge_bezierrr",63);
+aWE("edge_bezierrr_mesh",63);
+aWE("edge_circl",63);
+aWE("edge_circle_mesh",63);
+aWE("edge_straight",63);
+aWE("edge_straight_mesh",63);
+aWE("edge1",76);
+aWE("edgeslist",76);
+aWE("edgex",7,9);
+aWE("edit",7,10,31,58,36,39);
+aWE("edition",64,75);
+aWE("ee_1",63);
+aWE("ee_2",63);
+aWE("ee_3",63);
+aWE("ee_4",63);
+aWE("ee_5",63);
+aWE("ee_6",63);
+aWE("ee_7",63);
+aWE("effect",50);
+aWE("eith",5,62,66,68,44);
+aWE("element",14,15,16,17,0,18,1,19,20,21,2,4,5,22,23,8,26,27,9,10,28,29,30,31,12,13,57,58,34,33,60,61,37,63,65,35,38,66,68,70,40,41,72,42,73,74,44,45,46,47,48,76,49,50,52,53,79,55);
+aWE("els",7,9,63,66);
+aWE("empty",63);
+aWE("enabl",74);
+aWE("encapsulat",25);
+aWE("encounter",66);
+aWE("end",14,20,9,61,38,74,44,49);
+aWE("enough",44);
+aWE("ent",26,28,29,32,62,51);
+aWE("entiti",15,16);
+aWE("entity",15,0,11,74);
+aWE("equal",20,34,66,74,44,46);
+aWE("equidistant",20);
+aWE("equilateral",21);
 aWE("eras",0);
-aWE("error",61);
-aWE("etc",16,2,26,49);
-aWE("even",23,33,63);
-aWE("eventual",64);
-aWE("every",54);
-aWE("everyth",23);
-aWE("ex21_lamp",72);
-aWE("examin",12);
-aWE("exampl",14,2,23,6,25,12,64,62,72,51);
-aWE("exce",19);
-aWE("exceed",45);
-aWE("except",43,53);
-aWE("exist",13,21,25,26,30,64,71,49);
-aWE("existenc",23);
-aWE("explod",61);
-aWE("exponent",19);
-aWE("export",0,6,31,60,53);
-aWE("exportation",31);
-aWE("exportm",6);
-aWE("extend",53,54);
-aWE("external",12);
-aWE("extreme",19);
-aWE("extremiti",5);
-aWE("extrud",11,12,61,70);
-aWE("extrusion",11,12,61,73);
-aWE("extrusionalongpath",61,73);
-aWE("extrusionsweepobject",61);
-aWE("exy",8);
-aWE("f",19,8);
-aWE("f1",61);
-aWE("f2",61);
-aWE("f3",61);
-aWE("f4",61);
-aWE("f5",61);
-aWE("fac",13,14,15,0,17,19,2,3,22,23,6,24,25,8,10,12,55,57,33,60,61,63,37,64,66,67,68,71,43,72,73,52,75,54);
-aWE("face_1",61);
-aWE("face_2",61);
-aWE("face1",8,73);
-aWE("face2",73);
-aWE("facelist",68);
-aWE("faceslist1",73);
-aWE("faceslist2",73);
-aWE("facesrotat",61);
-aWE("factor",19,26);
-aWE("factoryserv",62);
-aWE("fail",61);
-aWE("far",43);
-aWE("fashion",12);
-aWE("fast",45);
-aWE("featur",25);
-aWE("ff",61);
-aWE("ff_1",61);
-aWE("ff_2",61);
-aWE("ff_3",61);
-aWE("ff_4",61);
-aWE("ff_5",61);
-aWE("ff_6",61);
-aWE("ff_7",61);
-aWE("field",17,1,21,25,27,28,67,40,71,43,45,49,50);
-aWE("fifth",43);
-aWE("fil",6,31,64,71);
-aWE("fill",68,69,40,43);
-aWE("filt",21,25,26,71,49);
-aWE("filter",25,71);
-aWE("fin",19,63);
-aWE("find",31,64,43);
-aWE("findcoincidentnod",73);
-aWE("findorloadcomponent",62);
-aWE("finenes",19,63);
-aWE("first",1,19,23,6,12,57,61,37,64,67,43);
-aWE("firstnodeid1",73);
-aWE("firstnodeid2",73);
-aWE("firstnodeidonfreebord",73);
-aWE("firstnodeidonsid",73);
-aWE("fit",53);
-aWE("fiv",61);
-aWE("fix",14,6,8,45);
-aWE("flag",64);
-aWE("fold",23,24);
-aWE("follow",13,14,17,1,2,21,23,24,7,25,26,27,28,29,30,11,12,35,61,64,67,39,40,70,41,43,45,46,48,49,50,51,52);
-aWE("font",53);
-aWE("form",1,27,30,64,43);
-aWE("format",0,31,60,53);
-aWE("formula",19,20,2);
-aWE("four",14,20,54);
-aWE("fourth",61);
-aWE("fram",53);
-aWE("fre",14,16,55,56,60,68,43,45,73);
-aWE("ft_area",57,68);
-aWE("ft_aspectratio",68);
-aWE("ft_aspectratio3d",68);
-aWE("ft_equalto",57,68);
-aWE("ft_freeborder",68);
-aWE("ft_length",68);
-aWE("ft_length2d",68);
-aWE("ft_lessthan",57,68);
-aWE("ft_minimumangl",61,68);
-aWE("ft_morethan",57,68);
-aWE("ft_multiconnection",68);
-aWE("ft_multiconnection2d",68);
-aWE("ft_skew",68);
-aWE("ft_tap",68);
-aWE("ft_volume3d",68);
-aWE("ft_warp",68);
-aWE("full_netgen",8);
-aWE("function",14,62);
-aWE("functionaliti",53);
-aWE("functionality",23,7,31,59,35,43,53);
-aWE("fus",72);
-aWE("futur",19);
-aWE("g",24);
-aWE("gaus",53);
-aWE("generat",13,14,16,19,23,60,37,64);
-aWE("generation",6,11,64,70,72);
-aWE("geom",14,60);
-aWE("geometric",14,16,8);
-aWE("geometrical",13,14,15,19,23,24,25,33,60,34,64,67,38,41,45,46,48,52);
-aWE("geometry",24,7,25,57,61,67,72,45);
-aWE("geompy",6,8,57,61,68,72,73,75);
-aWE("get",0,5,23,8,12,57,64,52);
-aWE("getedgenearpoint",6,8);
-aWE("geterrorcod",61);
-aWE("getfilt",57,68);
-aWE("getfreeborder",68);
-aWE("getidsfromfilt",57,68);
-aWE("getlistofid",57);
-aWE("getmesh",6,61);
-aWE("getnam",62);
-aWE("getpattern",61);
-aWE("ghs3d",62);
-aWE("giv",71,52);
-aWE("given",19,33,61,43);
-aWE("global",8,53);
-aWE("glu",68);
-aWE("good",6,45);
-aWE("got",64);
-aWE("graduat",53);
+aWE("error",63);
+aWE("etc",17,2,27,50);
+aWE("even",16,24,34,65);
+aWE("eventual",66);
+aWE("every",55);
+aWE("everyth",24);
+aWE("ex21_lamp",75);
+aWE("examin",13);
+aWE("exampl",15,2,5,24,7,26,13,66,64,75,52);
+aWE("exce",20);
+aWE("exceed",46);
+aWE("except",44,54);
+aWE("exist",14,5,22,26,27,31,62,66,74,50);
+aWE("existenc",24);
+aWE("explod",63);
+aWE("exponent",20);
+aWE("export",0,7,32,61,54);
+aWE("exportation",32);
+aWE("exportm",7);
+aWE("extend",54,55);
+aWE("external",13);
+aWE("extreme",20);
+aWE("extremiti",6);
+aWE("extrud",12,13,63,72);
+aWE("extrusion",12,13,63,76);
+aWE("extrusionalongpath",63,76);
+aWE("extrusionsweepobject",63);
+aWE("exy",9);
+aWE("f",20,9);
+aWE("f1",63);
+aWE("f2",63);
+aWE("f3",63);
+aWE("f4",63);
+aWE("f5",63);
+aWE("fac",14,15,16,0,18,20,2,3,23,24,7,25,26,9,11,13,56,58,34,61,63,65,38,66,68,69,70,74,44,75,76,53,78,55);
+aWE("face_1",63);
+aWE("face_2",63);
+aWE("face1",9,76);
+aWE("face2",76);
+aWE("facelist",70);
+aWE("faceslist1",76);
+aWE("faceslist2",76);
+aWE("facesrotat",63);
+aWE("factor",20,27);
+aWE("factoryserv",64);
+aWE("fail",63);
+aWE("far",44);
+aWE("fashion",13);
+aWE("fast",46);
+aWE("featur",26);
+aWE("ff",63);
+aWE("ff_1",63);
+aWE("ff_2",63);
+aWE("ff_3",63);
+aWE("ff_4",63);
+aWE("ff_5",63);
+aWE("ff_6",63);
+aWE("ff_7",63);
+aWE("field",18,1,22,26,28,29,69,41,74,44,46,50,51);
+aWE("fifth",44);
+aWE("fil",7,32,66,74);
+aWE("fill",70,71,41,44);
+aWE("filt",22,26,27,74,50);
+aWE("filter",26,74);
+aWE("fin",20,65);
+aWE("find",32,63,66,44);
+aWE("findcoincidentnod",76);
+aWE("findnodeclosestto",63);
+aWE("findorloadcomponent",64);
+aWE("finenes",20,65);
+aWE("first",1,20,24,7,13,58,63,38,66,69,44);
+aWE("firstnodeid1",76);
+aWE("firstnodeid2",76);
+aWE("firstnodeidonfreebord",76);
+aWE("firstnodeidonsid",76);
+aWE("fit",54);
+aWE("fiv",63);
+aWE("fix",15,7,9,46);
+aWE("flag",66);
+aWE("fold",24,25);
+aWE("follow",14,15,16,18,1,2,5,22,24,25,8,26,27,28,29,30,31,12,13,36,62,63,66,69,40,41,72,42,44,46,47,49,50,51,52,53);
+aWE("font",54);
+aWE("form",1,28,31,66,44);
+aWE("format",0,32,61,54);
+aWE("formula",20,21,2);
+aWE("four",15,21,55);
+aWE("fourth",63);
+aWE("fram",54);
+aWE("fre",15,17,56,57,61,70,44,46,76);
+aWE("ft_area",58,70);
+aWE("ft_aspectratio",70);
+aWE("ft_aspectratio3d",70);
+aWE("ft_equalto",58,70);
+aWE("ft_freeborder",70);
+aWE("ft_length",70);
+aWE("ft_length2d",70);
+aWE("ft_lessthan",58,70);
+aWE("ft_minimumangl",63,70);
+aWE("ft_morethan",58,70);
+aWE("ft_multiconnection",70);
+aWE("ft_multiconnection2d",70);
+aWE("ft_skew",70);
+aWE("ft_tap",70);
+aWE("ft_volume3d",70);
+aWE("ft_warp",70);
+aWE("full_netgen",9);
+aWE("function",15,63,64);
+aWE("functionaliti",54);
+aWE("functionality",24,8,32,60,36,44,54);
+aWE("fus",75);
+aWE("futur",20);
+aWE("g",25);
+aWE("gaus",54);
+aWE("generat",14,15,17,20,24,61,38,66);
+aWE("generation",7,12,66,72,75);
+aWE("geom",15,61);
+aWE("geometric",15,17,9);
+aWE("geometrical",14,15,16,20,24,25,26,34,61,35,66,69,39,42,46,47,49,53);
+aWE("geometry",25,8,26,58,63,69,75,46);
+aWE("geompy",7,9,58,63,70,75,76,78);
+aWE("get",0,6,24,9,13,58,66,53);
+aWE("getedgenearpoint",7,9);
+aWE("geterrorcod",63);
+aWE("getfilt",58,70);
+aWE("getfreeborder",70);
+aWE("getidsfromfilt",58,70);
+aWE("getlistofid",58);
+aWE("getmesh",7,63);
+aWE("getnam",64);
+aWE("getnodexyz",63);
+aWE("getpattern",63);
+aWE("getsubmeshnodesid",63);
+aWE("ghs3d",64);
+aWE("giv",74,53);
+aWE("given",20,34,63,44);
+aWE("global",9,54);
+aWE("glu",70);
+aWE("good",7,46);
+aWE("got",66);
+aWE("graduat",54);
 aWE("graphical",0);
-aWE("great",19,53);
-aWE("greatest",20,2);
-aWE("green",25,12);
-aWE("group",21,22,25,26,9,30,12,57,35,60,61,68,71,72,45,48,49,51,52);
-aWE("group_nam",72);
-aWE("group1",51);
-aWE("group12",51);
-aWE("group12a",51);
-aWE("group12b",51);
-aWE("group2",51);
-aWE("groupongeom",57,61);
-aWE("grouprotat",61);
-aWE("groupsmooth",61);
-aWE("groupsofnod",73);
-aWE("grouptri",61);
-aWE("growth",63);
-aWE("h",54);
-aWE("half",20,54);
-aWE("halv",5);
-aWE("hasangl",61);
-aWE("hasrefpoint",61);
-aWE("hav",20,33,37,64,66);
-aWE("hedron",61);
-aWE("height",72,54);
-aWE("helical",12);
-aWE("help",16);
-aWE("henc",64);
-aWE("her",64);
-aWE("hexa",8);
-aWE("hexahedral",15,6,8);
-aWE("hexahedralization",23);
-aWE("hexahedrical",8);
-aWE("hexahedron",14,15,17,2,8,61,34,66,75);
-aWE("hh",61);
-aWE("hid",0,53);
-aWE("high",14);
-aWE("highlight",3,4,21,25,26,55,56,49);
-aWE("hmax",20);
-aWE("hol",56,61);
-aWE("hold",64);
-aWE("hollow",69);
-aWE("homogeneou",63);
-aWE("how",15,12,63,38);
-aWE("hyp",24,61);
-aWE("hyp1",6);
-aWE("hyp2",6);
-aWE("hyp3",6);
-aWE("hyp4",6);
-aWE("hypothes",13,0,19,23,6,24,8,33,60,63,37,69,38);
-aWE("hypothesi",13,19,23,6,8,33,61,34,37,38,72);
-aWE("i",15,20,23,26,12,57,31,61,63,64,66,68,69,43,49);
-aWE("icon",30,39,42);
-aWE("id",0,19,21,25,26,27,28,29,11,12,57,61,70,43,45,49,50);
-aWE("id_circl",73);
-aWE("id_fac",8);
-aWE("id_face1",73);
-aWE("idbox",6,68);
-aWE("idea",12);
-aWE("idl",6);
-aWE("idsofelement",61);
-aWE("idsoffixednod",61);
-aWE("idsofside1element",73);
-aWE("idsofside2element",73);
-aWE("if",14,17,5,23,6,24,7,8,11,12,57,33,61,63,37,64,67,68,38,39,70,71,43,45,49,53);
-aWE("ii",61);
-aWE("imag",0,12,53);
-aWE("imp",14);
-aWE("import",6,8,57,31,60,61,68,72,73,75);
-aWE("importation",31);
-aWE("in",69);
-aWE("includ",14,52);
-aWE("increas",6,8);
-aWE("index",25,64);
-aWE("indic",64);
-aWE("indicat",67,54);
-aWE("info",0,52,75);
-aWE("information",14,0,6,7,30,69,52,75);
-aWE("initial",12,61,71,46,51);
-aWE("input",1,19);
-aWE("inscrib",20);
-aWE("insert",71,43);
-aWE("instead",6,37,64);
-aWE("int",62);
-aWE("intact",9);
-aWE("integ",25);
-aWE("intend",43);
-aWE("interest",14);
-aWE("interfac",6,72);
-aWE("intermediat",43);
-aWE("internal",64,69);
-aWE("intersect",64,51);
-aWE("intersectgroup",57);
-aWE("intersection",57,64,69,51);
-aWE("introduc",13,25,37);
-aWE("introduction",60,72);
-aWE("invers",14,27,61);
-aWE("inversediag",61);
-aWE("inversion",27,61);
-aWE("invisibl",74);
-aWE("isdon",61);
-aWE("iso",64);
-aWE("isolin",64);
-aWE("isometric",53);
-aWE("isplanarfac",8,73);
-aWE("item",17,1,21,22,7,26,27,28,30,11,12,31,35,64,40,70,41,43,45,46,48,49,50,51);
-aWE("iteration",12,45);
-aWE("iterativ",45);
-aWE("iv",61);
-aWE("j",15,57,68);
-aWE("join",44);
-aWE("jpeg",0,53);
-aWE("jpg",0,53);
-aWE("just",1,64,39);
-aWE("k",15,19,20);
-aWE("keep",12,45,46);
-aWE("key",64);
-aWE("keyboard",26);
-aWE("know",64);
-aWE("ko",61);
-aWE("l",54);
-aWE("label",53);
-aWE("laplacian",45);
-aWE("last",1,19,12,37,43);
-aWE("lastnodeid1",73);
-aWE("lastnodeid2",73);
-aWE("lastnodeidonfreebord",73);
-aWE("lastnodeidonsid",73);
-aWE("lay",11,64,70);
-aWE("layer",69);
-aWE("lcc",62);
-aWE("learn",52);
-aWE("least",64,45);
-aWE("leav",23,9);
-aWE("left",0,12,64,53);
-aWE("len",57,61,68);
-aWE("length",13,16,19,20,6,8,58,33,32,60,68,43,53,54);
-aWE("length_margin",68);
-aWE("lengthfromedg",8,72,73);
-aWE("les",71,43,45);
-aWE("level",13,17,63);
-aWE("library",25,71);
-aWE("lik",17,2,29,43);
-aWE("limit",64,43,45);
-aWE("limitation",67);
-aWE("lin",14,1,19,11,37,64,70,44);
-aWE("linear",12,63);
-aWE("link",43);
-aWE("list",0,17,21,25,26,9,12,67,71,49);
-aWE("lk",19);
-aWE("ll",53);
-aWE("load",64,71);
-aWE("loadfromfac",61);
-aWE("local",6,24,8,60,37);
-aWE("locallength",8,72);
-aWE("locat",64,43,53);
-aWE("location",19,28,31,45);
-aWE("lock",26,45,53);
-aWE("longest",20);
-aWE("look",29,12,64,71);
-aWE("low",14,19,63);
-aWE("ly",64);
-aWE("main",21,26,9,12,37,64,71,49,51);
-aWE("makearc",8,73);
-aWE("makebezi",61);
-aWE("makebox",6,57,68,72,73,75);
-aWE("makeboxdxdydz",6,8,61);
-aWE("makecirclethreepnt",61,73);
-aWE("makecompound",68,73);
-aWE("makecon",72);
-aWE("makecylind",72);
-aWE("makecylinderrh",8);
-aWE("makeedg",8,61);
-aWE("makefac",8,73);
-aWE("makefus",72);
-aWE("makegluefac",68);
-aWE("makegroupbyid",57);
-aWE("makemesh",61);
-aWE("makepolygon",61);
-aWE("makepolylin",61);
-aWE("makequadmesh2",61);
-aWE("makeshell",68);
-aWE("makesketch",8);
-aWE("maketranslation",68);
-aWE("makevector",8,73);
-aWE("makevectordxdydz",72);
-aWE("makevertex",6,8,61,72,73);
-aWE("makewir",8,73);
-aWE("manag",13,17);
-aWE("manual",25,63,64,53);
-aWE("map",15,33,61,64);
-aWE("mark",53);
-aWE("mas",12);
-aWE("math",61,73);
-aWE("max",13,8,33,60,63,34,45);
-aWE("maxaspectratio",61);
-aWE("maxelementarea",6,8,61,68,75);
-aWE("maxelementvolum",6,8,72,75);
-aWE("maximum",19,8,33,63,34,44,45,52);
-aWE("maxnbofiteration",61);
-aWE("mean",14,63);
-aWE("meaningful",14);
-aWE("measur",54);
-aWE("medium",7);
-aWE("meet",26,49);
-aWE("mefisto",15,8);
-aWE("menu",17,1,19,21,5,22,23,24,7,25,26,9,27,28,29,30,11,12,31,35,37,64,67,39,40,70,41,42,71,43,45,46,48,49,50,51,52);
-aWE("merg",59,35,43,73);
-aWE("mergeequalelement",73);
-aWE("mergenod",73);
-aWE("mesh",13,14,15,16,0,17,1,18,19,20,2,3,4,21,5,22,23,6,24,7,25,26,8,9,27,28,29,30,11,12,55,56,57,31,33,32,59,35,60,36,61,63,34,37,64,65,66,67,68,69,38,39,40,70,41,42,62,71,43,44,72,45,46,47,73,48,49,50,51,52,75,76,53,54);
-aWE("mesh_1",23,61);
-aWE("mesh_2",61);
-aWE("mesh_borders_at_multi",68);
-aWE("mesh_free_border",68);
-aWE("mesh_length_1d",68);
-aWE("mesh_length_2d",68);
-aWE("mesh_nam",61);
-aWE("mesh1d",61);
-aWE("mesh1d_tool",61);
-aWE("meshbox",6,75);
-aWE("mesheditor",61);
-aWE("meshm",6);
-aWE("method",61,45);
-aWE("middl",1,12,37);
-aWE("min_angl",68);
-aWE("minimum",16,19,26,60,36,63,68,43,49);
-aWE("mirror",73);
-aWE("mod",0,19,65);
-aWE("model",14,60);
-aWE("modification",14,17,1,21,7,26,27,28,30,11,12,35,60,64,39,40,70,41,43,45,46,48,49,50);
-aWE("modify",21,26,30,61,49);
-aWE("modul",14,15,1,19,6,25,60,42,72,53);
-aWE("mous",0,25,53);
-aWE("mov",28,61);
-aWE("movenod",61);
-aWE("much",63);
-aWE("multi",16,3,4,60,68);
-aWE("multiconnection",68);
-aWE("must",23,12,64,71,43);
-aWE("myelemid",68);
-aWE("mypnt1",68);
-aWE("mypnt2",68);
-aWE("n",64,43);
-aWE("n1",61);
-aWE("n10",61);
-aWE("n11",61);
-aWE("n12",61);
-aWE("n2",61);
-aWE("n23_param",8);
-aWE("n3",61);
-aWE("n4",61);
-aWE("n5",61);
-aWE("n6",61);
-aWE("n7",61);
-aWE("n8",61);
-aWE("n9",61);
-aWE("na",61);
-aWE("nam",23,6,24,25,30,57,31,61,63,67,62,71,72,51,53);
-aWE("nb",57,61,63,68);
-aWE("nb_conn",68);
-aWE("nb_vert",61);
-aWE("nbedg",6,73,75);
-aWE("nbfac",6,75);
-aWE("nbhexa",75);
-aWE("nbnod",6,73,75);
-aWE("nbpolygon",75);
-aWE("nbpolyhedron",75);
-aWE("nbprism",75);
-aWE("nbpyramid",75);
-aWE("nbquadrangl",73,75);
-aWE("nbseg",61);
-aWE("nbtetra",75);
-aWE("nbtriangl",73,75);
-aWE("nbvolum",6,73,75);
-aWE("nc",61);
-aWE("nd",61);
-aWE("ndiagonal",61);
-aWE("ne",23);
-aWE("necessary",17,67);
-aWE("need",69);
-aWE("negativ",19);
-aWE("neighbor",27,50);
-aWE("netgen",15,6,8,63,62,72,75);
-aWE("netgen_2d3d",8);
-aWE("new",0,5,23,24,25,28,61,64,38,71,51);
-aWE("new_id",61);
-aWE("next",19,64);
-aWE("nid",61);
-aWE("nid1",61);
-aWE("nid2",61);
-aWE("nid3",61);
-aWE("nid4",61);
-aWE("no_nam",62);
-aWE("nod",14,0,17,1,18,19,20,21,22,6,7,25,28,29,11,12,33,35,60,61,63,64,65,68,39,40,70,71,43,44,45,47,73,52,75,54);
-aWE("nodal",64,45);
-aWE("node_id",61);
-aWE("nodeid1ofside1tomerg",73);
-aWE("nodeid1ofside2tomerg",73);
-aWE("nodeid2ofside1tomerg",73);
-aWE("nodeid2ofside2tomerg",73);
-aWE("nodestart",61);
-aWE("non",23);
-aWE("nonam",62);
-aWE("normal",46,54);
-aWE("normalisation",20);
-aWE("not",17,20,23,25,9,12);
-aWE("noth",25);
-aWE("notic",14);
-aWE("now",5,23);
-aWE("nsmooth",61);
-aWE("numb",13,14,15,1,19,6,25,8,11,33,60,63,64,66,69,70,43,45,73,52,75,53);
-aWE("number",0,1,29,12);
-aWE("numberofsegment",6,8,57,61,68,73,75);
-aWE("numeric",26);
-aWE("numerical",13);
-aWE("nunit",61);
-aWE("obey",43);
-aWE("obj",62);
-aWE("object",13,15,0,17,1,19,5,22,23,24,7,25,26,9,30,31,33,61,63,34,64,65,67,38,39,40,41,48,49,52,76,53);
-aWE("objet",25);
-aWE("obtain",17,68);
-aWE("offset",53);
-aWE("ok",17,1,21,5,7,26,9,27,28,30,11,12,31,61,39,40,70,43,45,49,50,51);
-aWE("on",14,1,19,23,6,24,26,8,9,27,11,12,55,56,59,61,37,64,68,69,38,39,70,71,43,45,46,48,49,51);
-aWE("onc",49);
-aWE("onto",37,64);
-aWE("oo",20);
-aWE("opaqu",74);
-aWE("open",68);
-aWE("operat",13);
-aWE("operation",15,17,18,19,20,2,3,4,21,24,25,26,9,27,28,30,11,12,55,56,31,58,33,32,59,35,60,36,34,37,64,38,39,40,70,41,43,44,45,46,47,48,49,50,51,76,54);
-aWE("oppos",66);
-aWE("opposit",13,5,6,26,8,33,37,43,44);
-aWE("optimiz",63);
-aWE("option",14,0,19,46,48);
-aWE("optional",23,12,67);
-aWE("ord",14,21,63,64);
-aWE("ordinary",1,37);
-aWE("orientat",53);
-aWE("orientation",21,5,26,61,67,49);
-aWE("origin",53,54);
-aWE("other",49);
-aWE("otherwis",23,33);
-aWE("our",23);
-aWE("out",69,53);
-aWE("outlin",56);
-aWE("outsid",64);
-aWE("own",14);
-aWE("p5",6,8);
-aWE("packag",6,62,72);
-aWE("pag",15,25,30);
-aWE("pair",19);
-aWE("pan",53);
-aWE("paramet",14,19,2,71,43);
-aWE("parameter",13,0,5,8,12,63,41,43,53);
-aWE("parametric",14,64);
-aWE("parent",24);
-aWE("part",61,43,45,53);
-aWE("particularity",14);
-aWE("pas",6,57,61,68);
-aWE("path",12,61,71,73);
-aWE("pathmesh",61);
-aWE("pathshap",61);
-aWE("pattern",61,64);
-aWE("pattern_nam",64);
-aWE("pentagonal",61);
+aWE("great",20,54);
+aWE("greatest",21,2);
+aWE("green",26,13);
+aWE("group",5,22,23,26,27,10,31,13,58,36,61,63,70,74,75,46,49,50,52,53);
+aWE("group_nam",75);
+aWE("group1",5,52);
+aWE("group1_1",5);
+aWE("group1_2",5);
+aWE("group12",52);
+aWE("group12a",52);
+aWE("group12b",52);
+aWE("group2",52);
+aWE("groupongeom",58,63);
+aWE("grouprotat",63);
+aWE("groupsmooth",63);
+aWE("groupsofnod",76);
+aWE("grouptri",63);
+aWE("growth",65);
+aWE("gui",0);
+aWE("h",55);
+aWE("half",21,55);
+aWE("halv",6);
+aWE("hasangl",63);
+aWE("hasrefpoint",63);
+aWE("hav",21,34,38,66,68);
+aWE("hedron",63);
+aWE("height",75,55);
+aWE("helical",13);
+aWE("help",17);
+aWE("henc",66);
+aWE("her",66);
+aWE("hexa",9);
+aWE("hexahedral",16,7,9);
+aWE("hexahedralization",24);
+aWE("hexahedrical",9);
+aWE("hexahedron",15,16,18,2,9,63,35,68,78);
+aWE("hh",63);
+aWE("hid",0,54);
+aWE("high",15,73);
+aWE("highlight",3,4,22,26,27,56,57,50);
+aWE("hmax",21);
+aWE("hol",57,63);
+aWE("hold",5,66);
+aWE("hollow",71);
+aWE("homogeneou",65);
+aWE("how",16,13,65,39);
+aWE("hyp",25,63);
+aWE("hyp1",7);
+aWE("hyp2",7);
+aWE("hyp3",7);
+aWE("hyp4",7);
+aWE("hypothes",14,16,0,20,24,7,25,9,34,61,65,38,71,39);
+aWE("hypothesi",14,16,20,24,7,9,34,63,35,38,39,73,75);
+aWE("i",16,21,24,27,13,58,32,63,65,66,68,70,71,73,44,50);
+aWE("icon",31,40,43);
+aWE("id",0,20,22,26,27,28,29,30,12,13,58,63,72,44,46,50,51);
+aWE("id_circl",76);
+aWE("id_fac",9);
+aWE("id_face1",76);
+aWE("idbox",7,70);
+aWE("idea",13);
+aWE("identical",5);
+aWE("idl",7);
+aWE("idsofelement",63);
+aWE("idsoffixednod",63);
+aWE("idsofside1element",76);
+aWE("idsofside2element",76);
+aWE("if",15,16,18,6,24,7,25,8,9,12,13,58,34,63,65,38,66,69,70,39,40,72,73,74,44,46,50,54);
+aWE("ii",63);
+aWE("imag",0,13,54);
+aWE("imp",15);
+aWE("implementation",73);
+aWE("import",7,9,58,32,61,63,70,75,76,78);
+aWE("importation",32);
+aWE("in",71);
+aWE("includ",15,53);
+aWE("increas",7,9);
+aWE("index",26,66);
+aWE("indic",66);
+aWE("indicat",62,69,55);
+aWE("info",0,53,78);
+aWE("information",15,0,5,7,8,31,71,53,78);
+aWE("initial",13,63,74,47,52);
+aWE("input",1,20);
+aWE("inscrib",21);
+aWE("insert",74,44);
+aWE("insid",63);
+aWE("instead",7,38,66);
+aWE("int",64);
+aWE("intact",10);
+aWE("integ",26);
+aWE("intend",44);
+aWE("interest",15);
+aWE("interfac",7,75);
+aWE("intermediat",44);
+aWE("internal",66,71);
+aWE("intersect",66,52);
+aWE("intersectgroup",58);
+aWE("intersection",58,66,71,52);
+aWE("introduc",14,26,38);
+aWE("introduction",61,75);
+aWE("invers",15,28,63);
+aWE("inversediag",63);
+aWE("inversion",28,63);
+aWE("invisibl",77);
+aWE("isdon",63);
+aWE("iso",66);
+aWE("isolin",66);
+aWE("isometric",54);
+aWE("isplanarfac",9,76);
+aWE("item",18,1,22,23,8,27,28,29,31,12,13,32,36,62,66,41,72,42,44,46,47,49,50,51,52);
+aWE("iteration",13,46);
+aWE("iterativ",46);
+aWE("iv",63);
+aWE("j",16,58,70);
+aWE("join",45);
+aWE("jpeg",0,54);
+aWE("jpg",0,54);
+aWE("just",1,66,40);
+aWE("k",16,20,21);
+aWE("keep",13,46,47);
+aWE("key",66);
+aWE("keyboard",27);
+aWE("know",66);
+aWE("ko",63);
+aWE("l",55);
+aWE("label",54);
+aWE("laplacian",46);
+aWE("last",1,20,13,38,44);
+aWE("lastnodeid1",76);
+aWE("lastnodeid2",76);
+aWE("lastnodeidonfreebord",76);
+aWE("lastnodeidonsid",76);
+aWE("lat",62);
+aWE("lay",12,66,72);
+aWE("layer",71);
+aWE("lcc",64);
+aWE("learn",53);
+aWE("least",66,46);
+aWE("leav",24,10);
+aWE("left",0,13,66,54);
+aWE("len",58,63,70);
+aWE("length",14,17,20,21,7,9,59,34,33,61,70,44,54,55);
+aWE("length_margin",70);
+aWE("lengthfromedg",9,75,76);
+aWE("les",74,44,46);
+aWE("level",14,18,65);
+aWE("library",26,74);
+aWE("lik",18,2,30,44);
+aWE("limit",66,44,46);
+aWE("limitation",69);
+aWE("lin",15,1,20,12,38,66,72,45);
+aWE("linear",13,65);
+aWE("link",44);
+aWE("list",0,18,22,26,27,10,13,69,74,50);
+aWE("lk",20);
+aWE("ll",54);
+aWE("load",66,74);
+aWE("loadfromfac",63);
+aWE("local",7,25,9,61,38,73);
+aWE("locallength",9,75);
+aWE("locat",66,44,54);
+aWE("location",20,29,32,63,46);
+aWE("lock",27,46,54);
+aWE("longest",21);
+aWE("look",30,13,66,74);
+aWE("low",15,20,65);
+aWE("ly",66);
+aWE("main",16,22,27,10,13,38,66,74,50,52);
+aWE("makearc",9,76);
+aWE("makebezi",63);
+aWE("makebox",7,58,70,75,76,78);
+aWE("makeboxdxdydz",7,9,63);
+aWE("makecirclethreepnt",63,76);
+aWE("makecompound",70,76);
+aWE("makecon",75);
+aWE("makecylind",75);
+aWE("makecylinderrh",9);
+aWE("makeedg",9,63);
+aWE("makefac",9,76);
+aWE("makefus",75);
+aWE("makegluefac",70);
+aWE("makegroupbyid",58);
+aWE("makemesh",63);
+aWE("makepolygon",63);
+aWE("makepolylin",63);
+aWE("makequadmesh2",63);
+aWE("makeshell",70);
+aWE("makesketch",9);
+aWE("maketranslation",70);
+aWE("makevector",9,76);
+aWE("makevectordxdydz",75);
+aWE("makevertex",7,9,63,75,76);
+aWE("makewir",9,76);
+aWE("manag",14,18);
+aWE("manual",26,62,65,66,54);
+aWE("map",16,34,63,66);
+aWE("mark",54);
+aWE("mas",13);
+aWE("math",63,76);
+aWE("max",14,9,34,61,65,35,46);
+aWE("maxaspectratio",63);
+aWE("maxelementarea",7,9,63,70,78);
+aWE("maxelementvolum",7,9,75,78);
+aWE("maximum",20,9,34,65,35,45,46,53);
+aWE("maxnbofiteration",63);
+aWE("mean",15,65);
+aWE("meaningful",15);
+aWE("measur",55);
+aWE("medium",8);
+aWE("meet",27,50);
+aWE("mefisto",16,9);
+aWE("menu",18,1,20,5,22,6,23,24,25,8,26,27,10,28,29,30,31,12,13,32,36,62,38,66,69,40,41,72,42,43,74,44,46,47,49,50,51,52,53);
+aWE("merg",5,60,36,44,76);
+aWE("mergeequalelement",76);
+aWE("mergenod",76);
+aWE("mesh",14,15,16,17,0,18,1,19,20,21,2,3,4,5,22,6,23,24,7,25,8,26,27,9,10,28,29,30,31,12,13,56,57,58,32,34,33,60,36,61,62,37,63,65,35,38,66,67,68,69,70,71,39,40,41,72,42,43,64,73,74,44,45,75,46,47,48,76,49,50,51,52,53,78,79,54,55);
+aWE("mesh_1",5,24,63);
+aWE("mesh_2",5,63);
+aWE("mesh_borders_at_multi",70);
+aWE("mesh_free_border",70);
+aWE("mesh_length_1d",70);
+aWE("mesh_length_2d",70);
+aWE("mesh_nam",63);
+aWE("mesh1d",63);
+aWE("mesh1d_tool",63);
+aWE("meshbox",7,78);
+aWE("mesheditor",63);
+aWE("meshm",7);
+aWE("meshtopassthroughapoint",63);
+aWE("method",5,62,63,46);
+aWE("middl",1,13,38);
+aWE("min_angl",70);
+aWE("minimum",17,20,27,61,37,65,70,44,50);
+aWE("mirror",76);
+aWE("mod",0,20,67);
+aWE("model",15,61);
+aWE("modification",15,18,1,22,8,27,28,29,31,12,13,36,61,62,66,40,41,72,42,44,46,47,49,50,51);
+aWE("modify",22,27,31,63,50);
+aWE("modul",15,16,0,1,20,7,26,61,43,75,54);
+aWE("mous",0,26,54);
+aWE("mov",29,62,63);
+aWE("movement",62);
+aWE("movenod",63);
+aWE("much",65);
+aWE("multi",17,3,4,61,70);
+aWE("multiconnection",70);
+aWE("must",24,13,66,74,44);
+aWE("myelemid",70);
+aWE("mypnt1",70);
+aWE("mypnt2",70);
+aWE("n",63,66,44);
+aWE("n1",63);
+aWE("n10",63);
+aWE("n11",63);
+aWE("n12",63);
+aWE("n2",63);
+aWE("n23_param",9);
+aWE("n3",63);
+aWE("n4",63);
+aWE("n5",63);
+aWE("n6",63);
+aWE("n7",63);
+aWE("n8",63);
+aWE("n9",63);
+aWE("na",63);
+aWE("nam",5,24,7,25,26,31,58,32,63,65,69,64,74,75,52,54);
+aWE("namesak",5);
+aWE("nb",58,63,65,70);
+aWE("nb_conn",70);
+aWE("nb_vert",63);
+aWE("nbedg",7,76,78);
+aWE("nbfac",7,78);
+aWE("nbhexa",78);
+aWE("nbnod",7,76,78);
+aWE("nbpolygon",78);
+aWE("nbpolyhedron",78);
+aWE("nbprism",78);
+aWE("nbpyramid",78);
+aWE("nbquadrangl",76,78);
+aWE("nbseg",63);
+aWE("nbtetra",78);
+aWE("nbtriangl",76,78);
+aWE("nbvolum",7,76,78);
+aWE("nc",63);
+aWE("nd",63);
+aWE("ndiagonal",63);
+aWE("ne",24);
+aWE("necessari",73);
+aWE("necessary",18,62,69);
+aWE("need",71);
+aWE("negativ",20);
+aWE("neighbor",28,51);
+aWE("neighborhood",73);
+aWE("netgen",16,7,9,65,64,75,78);
+aWE("netgen_2d3d",9);
+aWE("new",0,6,24,25,26,29,62,63,66,39,74,52);
+aWE("new_id",63);
+aWE("next",20,66);
+aWE("nid",63);
+aWE("nid1",63);
+aWE("nid2",63);
+aWE("nid3",63);
+aWE("nid4",63);
+aWE("no_nam",64);
+aWE("nod",15,0,18,1,19,20,21,5,22,23,7,8,26,29,30,12,13,34,36,61,62,63,65,66,67,70,40,41,72,73,74,44,45,46,48,76,53,78,55);
+aWE("nodal",66,46);
+aWE("node_id",63);
+aWE("node000",63);
+aWE("nodeid",63);
+aWE("nodeid1ofside1tomerg",76);
+aWE("nodeid1ofside2tomerg",76);
+aWE("nodeid2ofside1tomerg",76);
+aWE("nodeid2ofside2tomerg",76);
+aWE("nodestart",63);
+aWE("non",24,63);
+aWE("nonam",64);
+aWE("normal",47,55);
+aWE("normalisation",21);
+aWE("not",18,21,24,26,10,13);
+aWE("noth",26);
+aWE("notic",15);
+aWE("now",6,24);
+aWE("nsmooth",63);
+aWE("numb",14,15,16,1,20,7,26,9,12,34,61,65,66,68,71,72,44,46,76,53,78,54);
+aWE("number",0,1,30,13);
+aWE("numberofsegment",7,9,58,63,70,76,78);
+aWE("numeric",27);
+aWE("numerical",14);
+aWE("nunit",63);
+aWE("obey",44);
+aWE("obj",64);
+aWE("object",14,16,0,18,1,20,5,6,23,24,25,8,26,27,10,31,32,34,63,65,35,66,67,69,39,40,41,42,73,49,50,53,79,54);
+aWE("objet",26);
+aWE("obtain",18,70);
+aWE("offset",54);
+aWE("ok",18,1,22,6,8,27,10,28,29,31,12,13,32,62,63,40,41,72,44,46,50,51,52);
+aWE("on",15,16,1,20,24,7,25,27,9,10,28,12,13,56,57,60,62,63,38,66,70,71,39,40,72,73,74,44,46,47,49,50,52);
+aWE("onc",50);
+aWE("onto",38,66);
+aWE("oo",21);
+aWE("opaqu",77);
+aWE("open",70);
+aWE("operat",14);
+aWE("operation",16,18,19,20,21,2,3,4,5,22,25,26,27,10,28,29,31,12,13,56,57,32,59,34,33,60,36,61,62,37,35,38,66,39,40,41,72,42,44,45,46,47,48,49,50,51,52,79,55);
+aWE("oppos",68);
+aWE("opposit",14,6,7,27,9,34,38,44,45);
+aWE("optimiz",65);
+aWE("option",15,0,20,47,49);
+aWE("optional",24,13,69);
+aWE("ord",15,22,65,66);
+aWE("ordinary",1,38);
+aWE("orientat",54);
+aWE("orientation",22,6,27,63,69,50);
+aWE("origin",54,55);
+aWE("other",50);
+aWE("otherwis",24,34);
+aWE("our",24);
+aWE("out",71,54);
+aWE("outlin",57);
+aWE("outsid",66);
+aWE("own",15);
+aWE("p5",7,9);
+aWE("packag",7,64,75);
+aWE("pag",16,26,31);
+aWE("pair",20);
+aWE("pan",54);
+aWE("paramet",15,20,2,74,44);
+aWE("parameter",14,0,6,9,13,65,42,44,54);
+aWE("parametric",15,66);
+aWE("parent",25);
+aWE("part",63,44,46,54);
+aWE("particularity",15);
+aWE("pas",7,58,62,63,70);
+aWE("path",13,63,74,76);
+aWE("pathmesh",63);
+aWE("pathshap",63);
+aWE("pattern",63,66);
+aWE("pattern_nam",66);
+aWE("pentagonal",63);
 aWE("pentahedron",2);
-aWE("per",63);
-aWE("perform",60,61,40,43,46,51,53);
-aWE("perimet",20);
-aWE("permit",66,67);
-aWE("pi",61,73);
-aWE("pictur",3,25,12,55,56,59);
-aWE("piec",72);
-aWE("plac",7,43,53);
-aWE("plan",5,68,46,54);
-aWE("planar",61,54);
-aWE("platform",25,42);
-aWE("pleas",9,12);
-aWE("plot",19);
-aWE("plu",11,70);
-aWE("png",0,53);
-aWE("point",14,1,19,12,61,37,64,67,70,41,43,46,73,48,53,54);
-aWE("pointstruct",61,73);
-aWE("polygon",17,61,75);
-aWE("polygonal",61);
-aWE("polyhedral",17,61);
-aWE("polyhedron",17,61,66,75);
-aWE("polylin",12);
-aWE("pop",9,29);
-aWE("position",14,64,53);
-aWE("posses",63,37);
-aWE("possibility",71);
-aWE("possibl",13,2,25,63,64);
-aWE("post",53);
-aWE("powerful",71);
-aWE("precision",17);
-aWE("preferenc",13,33,60,65);
-aWE("prefix",71);
-aWE("preproces",25);
-aWE("pres",17,1,12,39,53);
-aWE("present",14,0,63,51);
-aWE("presentation",16,0,53);
-aWE("preserv",64);
-aWE("preset",13);
-aWE("preview",17,5,26,64,71);
-aWE("previou",19,12,49);
-aWE("previous",24,25,60,64);
-aWE("principl",12);
-aWE("print",6,8,57,61,68,73,75);
-aWE("printmeshinfo",6);
-aWE("prism",66,69,75);
-aWE("prism3d",66);
-aWE("prismatic",15);
-aWE("pro",53);
-aWE("problem",6,8);
-aWE("proce",23,9);
-aWE("procedur",45);
-aWE("proceed",12,38);
-aWE("proces",45);
-aWE("produc",14,7,11,70,45);
-aWE("product",54);
-aWE("program",23);
-aWE("progression",19);
-aWE("project",64);
-aWE("projection",15,64,66,67,69,54);
-aWE("prompt",19);
-aWE("propagat",6,8,37);
-aWE("propagation",13,6,8,37,73);
-aWE("properti",53);
-aWE("prov",63);
-aWE("provid",0,17,26,72);
-aWE("pseudo",27);
-aWE("pt1",72);
-aWE("pt2",72);
-aWE("pul",45);
-aWE("put",8);
-aWE("px",8,73);
-aWE("px1",73);
-aWE("py",8,73);
-aWE("py1",73);
-aWE("pyramid",75);
-aWE("pyramidal",15);
-aWE("python",6,62,72,52);
-aWE("pz",8,73);
-aWE("pz1",73);
-aWE("q1",61);
+aWE("per",65);
+aWE("perform",61,63,41,44,47,52,54);
+aWE("perimet",21);
+aWE("permit",68,69);
+aWE("pi",63,76);
+aWE("pictur",3,26,13,56,57,60);
+aWE("piec",75);
+aWE("plac",8,44,54);
+aWE("plan",6,70,47,55);
+aWE("planar",63,55);
+aWE("platform",26,43);
+aWE("pleas",10,13);
+aWE("plot",20);
+aWE("plu",12,72);
+aWE("png",0,54);
+aWE("point",15,1,20,13,62,63,38,66,69,72,42,44,47,76,49,54,55);
+aWE("pointstruct",63,76);
+aWE("polygon",18,63,78);
+aWE("polygonal",63);
+aWE("polyhedral",18,63);
+aWE("polyhedron",18,63,68,78);
+aWE("polylin",13);
+aWE("pop",10,30);
+aWE("position",15,66,54);
+aWE("posses",65,38);
+aWE("possibility",74);
+aWE("possibl",14,2,5,26,65,66);
+aWE("post",54);
+aWE("powerful",74);
+aWE("precision",18);
+aWE("preferenc",14,34,61,67);
+aWE("prefix",74);
+aWE("preproces",26);
+aWE("pres",18,1,13,40,54);
+aWE("present",15,0,65,52);
+aWE("presentation",17,0,54);
+aWE("preserv",66);
+aWE("preset",14);
+aWE("preview",18,6,27,62,66,74);
+aWE("previou",20,13,50);
+aWE("previous",25,26,61,66);
+aWE("principl",13);
+aWE("print",7,9,58,63,70,76,78);
+aWE("printmeshinfo",7);
+aWE("prism",68,71,78);
+aWE("prism3d",68);
+aWE("prismatic",16);
+aWE("pro",54);
+aWE("problem",7,9);
+aWE("proce",24,10);
+aWE("procedur",46);
+aWE("proceed",13,39);
+aWE("proces",5,46);
+aWE("produc",15,8,12,72,46);
+aWE("product",55);
+aWE("program",24);
+aWE("progression",20);
+aWE("project",66);
+aWE("projection",16,66,68,69,71,55);
+aWE("prompt",20);
+aWE("propagat",7,9,38);
+aWE("propagation",14,7,9,38,76);
+aWE("properti",54);
+aWE("prov",65);
+aWE("provid",16,0,18,27,75);
+aWE("pseudo",28);
+aWE("pt1",75);
+aWE("pt2",75);
+aWE("pul",46);
+aWE("put",9);
+aWE("px",9,76);
+aWE("px1",76);
+aWE("py",9,76);
+aWE("py1",76);
+aWE("pyramid",78);
+aWE("pyramidal",16);
+aWE("python",7,64,75,53);
+aWE("pz",9,76);
+aWE("pz1",76);
+aWE("q1",63);
 aWE("qi",2);
-aWE("qk",20,2);
-aWE("quad",54);
-aWE("quad_1",61);
-aWE("quad_2",61);
-aWE("quad_3",61);
-aWE("quad_4",61);
-aWE("quad_5",61);
-aWE("quad_6",61);
-aWE("quad_7",61);
-aWE("quadra",6,57);
-aWE("quadrangl",13,14,15,17,18,20,2,6,26,8,27,11,12,57,33,32,60,36,61,63,66,69,70,44,73,75);
-aWE("quadrangle",66);
-aWE("quadrangular",15,6,8,33,37);
-aWE("quadratic",13,1,7,63,37);
-aWE("quadtotri",61);
-aWE("quality",16,0,18,19,20,2,3,4,26,55,56,58,32,60,36,68,44,47,49,76,54);
-aWE("quantity",13);
-aWE("r1",61);
-aWE("radial",69);
-aWE("radio",21,25,26,41,43,46,49);
-aWE("radiu",20,61,63);
-aWE("radius",63);
-aWE("radius_1",72);
-aWE("radius_2",72);
-aWE("rang",19,25,57,61,63,68);
-aWE("rat",63);
-aWE("ratio",16,20,2,60,68,45,47,54);
-aWE("ready",23);
+aWE("qk",21,2);
+aWE("quad",55);
+aWE("quad_1",63);
+aWE("quad_2",63);
+aWE("quad_3",63);
+aWE("quad_4",63);
+aWE("quad_5",63);
+aWE("quad_6",63);
+aWE("quad_7",63);
+aWE("quadra",7,58);
+aWE("quadrangl",14,15,16,18,19,21,2,7,27,9,28,12,13,58,34,33,61,37,63,65,68,71,72,45,76,78);
+aWE("quadrangle",68);
+aWE("quadrangular",16,7,9,34,38);
+aWE("quadratic",14,1,8,65,38);
+aWE("quadtotri",63);
+aWE("quality",17,0,19,20,21,2,3,4,27,56,57,59,33,61,37,70,45,48,50,79,55);
+aWE("quantity",14);
+aWE("r1",63);
+aWE("radial",71);
+aWE("radio",22,26,27,42,44,47,50);
+aWE("radiu",21,63,65);
+aWE("radius",65);
+aWE("radius_1",75);
+aWE("radius_2",75);
+aWE("rais",63);
+aWE("rang",20,26,58,63,65,70);
+aWE("rat",65);
+aWE("ratio",17,21,2,61,70,46,48,55);
+aWE("ready",24);
 aWE("recent",0);
-aWE("red",56);
-aWE("redefin",0,53);
-aWE("reduc",45);
-aWE("reevaluat",45);
-aWE("refer",64);
-aWE("referenc",14,16,23,24);
-aWE("refin",13);
-aWE("reflect",64,44,76);
-aWE("refpoint",61);
+aWE("red",57);
+aWE("redefin",0,54);
+aWE("reduc",46);
+aWE("reevaluat",46);
+aWE("refer",66);
+aWE("referenc",15,17,24,25);
+aWE("refin",14);
+aWE("reflect",66,45,79);
+aWE("refpoint",63);
 aWE("refresh",0);
-aWE("regular",20,6,8,63,62);
-aWE("relat",42);
-aWE("relation",14);
-aWE("relationship",14);
-aWE("remot",53);
-aWE("remov",21,6,25,26,9,30,12,57,61,68,39,71,49);
-aWE("removal",60);
-aWE("removeelement",61,68);
-aWE("removehypothesi",6);
-aWE("removenod",61);
-aWE("renumb",40);
-aWE("renumber",61,40);
-aWE("renumbernod",61);
-aWE("reorient",21,61);
-aWE("replac",43);
-aWE("represent",13,14,19,2,65,47,53);
-aWE("representation",14);
-aWE("requir",27,28,63,50);
-aWE("res",61);
-aWE("reset",53);
-aWE("resiz",53);
-aWE("respect",12);
+aWE("regular",21,7,9,65,64);
+aWE("relat",43);
+aWE("relation",15);
+aWE("relationship",15);
+aWE("remot",54);
+aWE("remov",22,7,26,27,10,31,13,58,63,70,40,74,50);
+aWE("removal",61);
+aWE("removeelement",63,70);
+aWE("removehypothesi",7);
+aWE("removenod",63);
+aWE("renam",5);
+aWE("renumb",41);
+aWE("renumber",63,41);
+aWE("renumbernod",63);
+aWE("reorient",22,63);
+aWE("replac",44);
+aWE("represent",14,15,20,2,67,48,54);
+aWE("representation",15);
+aWE("requir",28,29,65,73,51);
+aWE("res",63);
+aWE("reset",54);
+aWE("resiz",54);
+aWE("respect",13);
 aWE("respectiv",1);
-aWE("rest",64,43);
-aWE("restor",53);
-aWE("restrict",14);
-aWE("result",13,17,12,57,68,45,51);
-aWE("ret",6,8);
-aWE("retriev",14);
-aWE("return",58,61);
-aWE("reveal",20);
-aWE("revers",1,64);
-aWE("revert",21);
-aWE("revolution",11,61,70);
-aWE("revolv",61,70);
-aWE("right",0,22,9,28,29,12,65);
-aWE("rotat",11,12,61,70,41,73,53);
-aWE("rotation",5,70,41,73,53);
-aWE("rotationsweepobject",61);
-aWE("rough",13);
-aWE("rr",61);
-aWE("rul",19,37,43);
-aWE("run",42);
-aWE("salom",25,8,57,60,61,68,42,62,73);
-aWE("sam",14,0,19,20,2,23,24,8,12,37,66,67,38,71,43,51);
-aWE("sampl",15,17,18,19,20,2,3,4,21,23,24,25,26,27,28,30,11,12,55,56,31,58,33,32,59,35,36,34,37,64,38,39,40,70,41,43,44,45,46,47,48,49,50,51,76,54);
-aWE("sav",71);
-aWE("scal",19,53);
-aWE("scalar",16);
-aWE("scen",53);
-aWE("script",15,17,18,19,20,2,3,4,21,23,6,24,25,26,27,28,30,11,12,55,56,31,58,33,32,59,35,36,34,37,64,38,39,40,70,41,43,44,45,46,47,48,49,50,51,52,76,54);
-aWE("se",15,17,18,19,20,2,3,4,21,5,6,24,7,25,26,27,28,30,11,12,55,56,31,58,33,32,59,35,36,34,37,64,66,38,39,40,70,41,43,44,72,45,46,47,48,49,50,51,76,53,54);
-aWE("seam",64);
-aWE("search",31,71);
-aWE("second",17,61,63,43);
-aWE("secondnodeid1",73);
-aWE("secondnodeid2",73);
-aWE("secondnodeidonfreebord",73);
-aWE("section",0,5,23,64,72);
-aWE("seg",63);
-aWE("segment",13,19,6,8,57,33,60,61,63,68,72,73,75);
-aWE("select",13,0,17,1,19,21,22,23,6,24,7,25,26,9,27,28,30,11,12,31,35,61,63,37,64,65,67,39,40,70,41,42,71,43,45,46,48,49,50,51,52,53);
-aWE("selectabl",59);
-aWE("selection",17,1,21,25,26,9,71,49);
-aWE("sens",14);
-aWE("separat",47);
-aWE("sequenc",43);
-aWE("set",14,15,17,19,21,5,23,25,8,28,12,33,60,61,63,34,64,65,69,71,43,45,74,49,53);
-aWE("setmaxelementarea",6);
-aWE("setnam",62,72);
-aWE("setting",23);
-aWE("seven",12,61);
-aWE("sew",12,43,73);
-aWE("sewbordertosid",73);
-aWE("sewconformfreeborder",73);
-aWE("sewfreeborder",73);
-aWE("sewsideelement",73);
-aWE("sg",57,61,68,73);
-aWE("shad",0,65,74);
-aWE("shall",21,27,28,35,64,70,41,46,48,49,50);
-aWE("shap",13,14,15,12,61,64,66,67,69,45);
-aWE("shape_mesh",61);
-aWE("shape1d",61);
-aWE("shapetyp",6,8,57,61,68,72,73);
-aWE("shel",69);
-aWE("shell",68,69);
-aWE("shift",17,1,26,39,45);
-aWE("shortest",54);
-aWE("should",19,7,25,11,12,64,66,69,70,41,71,43,45,51);
-aWE("show",19,5,12,71,53);
-aWE("shown",16,45);
-aWE("shrink",65);
-aWE("sid",6,8,36,63,66,43,44,73);
-aWE("simp",23,37);
-aWE("simpl",14,17,12,64);
-aWE("simplex",20,2);
-aWE("sin",61);
-aWE("sin_bot",61);
-aWE("sin_top",61);
-aWE("six",12,61);
-aWE("siz",0,63,72,45);
-aWE("sk",20,2);
-aWE("sketch",8);
-aWE("sketcher",8);
-aWE("sketcher1",8);
-aWE("sketcher2",8);
-aWE("skew",16,26,60,68,44,49);
-aWE("skew_margin",68);
-aWE("slid",74);
-aWE("small",53);
-aWE("smesh",6,8,57,61,68,62,43,72,73,75);
-aWE("smesh_mechanic",57,61,68,73);
-aWE("smesh_mechanic_tetra",68);
-aWE("smeshgroup1",57);
-aWE("smooth",61,45);
-aWE("smoothobject",61);
-aWE("smp",64);
-aWE("so",13,19,20,12,64,43,47);
-aWE("solid",8,60,67);
-aWE("somewhat",17);
-aWE("soon",6);
-aWE("sort",21,25,26,49);
-aWE("sourc",67,71);
-aWE("spac",14,64,69,41,48);
-aWE("specifi",19,3,64,39,43,45);
-aWE("specific",15,22,71);
-aWE("specify",17,1,26,11,12,64,39,70,41,71,45,46,48,51);
-aWE("spher",19,20,23);
-aWE("split",15,19,2,5,63,43);
-aWE("sqrt",61);
-aWE("standalon",25,57,71);
-aWE("standard",0,7,31,72,52);
-aWE("start",13,19,5,8,12,60,42,43,48);
-aWE("startendlength",8);
-aWE("static",62);
-aWE("step",11,70);
-aWE("stor",64,71);
-aWE("str",62);
-aWE("straight",1,8,12,61,37);
-aWE("stretch",53);
-aWE("strict",53);
-aWE("structur",23,24,61,62);
-aWE("study",8,57,71,72);
-aWE("stuf",53);
-aWE("styl",6);
-aWE("sub",6,8,12,31,35,64,41,43,46,48);
-aWE("submenu",17,10,39,40);
-aWE("submesh",13,21,22,6,24,25,26,11,12,38,70,45,48,49,52);
-aWE("subshapeall",6,8,57,61,68,73);
-aWE("subshapeallid",72);
-aWE("subshapeallsort",61);
-aWE("subshapelist",6,57);
-aWE("subshapenam",6);
-aWE("succed",8);
+aWE("rest",66,44);
+aWE("restor",54);
+aWE("restrict",15);
+aWE("result",14,18,5,13,58,62,70,46,52);
+aWE("ret",7,9);
+aWE("retriev",15);
+aWE("return",59,63);
+aWE("reveal",21);
+aWE("revers",1,66);
+aWE("revert",22);
+aWE("revolution",12,63,72);
+aWE("revolv",63,72);
+aWE("right",0,23,10,29,30,13,67);
+aWE("rotat",12,13,63,72,42,76,54);
+aWE("rotation",6,72,42,76,54);
+aWE("rotationsweepobject",63);
+aWE("rough",14);
+aWE("rr",63);
+aWE("rul",20,38,44);
+aWE("run",43);
+aWE("salom",26,9,58,61,63,70,43,64,76);
+aWE("sam",15,16,0,20,21,2,24,25,9,13,38,68,69,39,74,44,52);
+aWE("sampl",16,18,19,20,21,2,3,4,22,24,25,26,27,28,29,31,12,13,56,57,32,59,34,33,60,36,62,37,35,38,66,39,40,41,72,42,44,45,46,47,48,49,50,51,52,79,55);
+aWE("sav",74);
+aWE("scal",20,54);
+aWE("scalar",17);
+aWE("scen",54);
+aWE("script",16,18,19,20,21,2,3,4,22,24,7,25,26,27,28,29,31,12,13,56,57,32,59,34,33,60,36,62,37,35,38,66,39,40,41,72,42,44,45,46,47,48,49,50,51,52,53,79,55);
+aWE("se",16,18,19,20,21,2,3,4,5,22,6,7,25,8,26,27,28,29,31,12,13,56,57,32,59,34,33,60,36,62,37,35,38,66,68,39,40,41,72,42,44,45,75,46,47,48,49,50,51,52,79,54,55);
+aWE("seam",66);
+aWE("search",32,62,74);
+aWE("second",18,63,65,44);
+aWE("secondnodeid1",76);
+aWE("secondnodeid2",76);
+aWE("secondnodeidonfreebord",76);
+aWE("section",0,6,24,66,75);
+aWE("seg",65);
+aWE("segment",14,16,20,7,9,58,34,61,63,65,70,73,75,76,78);
+aWE("select",14,0,18,1,20,5,22,23,24,7,25,8,26,27,10,28,29,31,12,13,32,36,62,63,65,38,66,67,69,40,41,72,42,43,74,44,46,47,49,50,51,52,53,54);
+aWE("selectabl",60);
+aWE("selection",18,1,22,26,27,10,74,50);
+aWE("sens",15);
+aWE("separat",48);
+aWE("sequenc",44);
+aWE("set",15,16,18,20,22,6,24,26,9,29,13,34,61,63,65,35,66,67,71,74,44,46,77,50,54);
+aWE("setmaxelementarea",7);
+aWE("setnam",64,75);
+aWE("setting",24);
+aWE("seven",13,63);
+aWE("sew",13,44,76);
+aWE("sewbordertosid",76);
+aWE("sewconformfreeborder",76);
+aWE("sewfreeborder",76);
+aWE("sewsideelement",76);
+aWE("sg",58,63,70,76);
+aWE("shad",0,67,77);
+aWE("shall",22,28,29,36,62,66,72,42,47,49,50,51);
+aWE("shap",14,15,16,13,63,66,68,69,71,46);
+aWE("shape_mesh",63);
+aWE("shape1d",63);
+aWE("shapetyp",7,9,58,63,70,75,76);
+aWE("shel",71);
+aWE("shell",70,71);
+aWE("shift",18,1,27,40,46);
+aWE("shortest",55);
+aWE("should",20,8,26,12,13,66,68,71,72,42,74,44,46,52);
+aWE("show",20,6,13,74,54);
+aWE("shown",17,46);
+aWE("shrink",67);
+aWE("sid",16,7,9,37,65,68,44,45,76);
+aWE("simp",5,24,38);
+aWE("simpl",15,18,13,66);
+aWE("simplex",21,2);
+aWE("sin",63);
+aWE("sin_bot",63);
+aWE("sin_top",63);
+aWE("six",13,63);
+aWE("siz",0,65,73,75,46);
+aWE("sk",21,2);
+aWE("sketch",9);
+aWE("sketcher",9);
+aWE("sketcher1",9);
+aWE("sketcher2",9);
+aWE("skew",17,27,61,70,45,50);
+aWE("skew_margin",70);
+aWE("slid",77);
+aWE("small",54);
+aWE("smesh",7,9,58,63,70,64,44,75,76,78);
+aWE("smesh_mechanic",58,63,70,76);
+aWE("smesh_mechanic_tetra",70);
+aWE("smeshgroup1",58);
+aWE("smooth",63,46);
+aWE("smoothobject",63);
+aWE("smp",66);
+aWE("so",14,20,21,13,66,44,48);
+aWE("solid",9,61,69);
+aWE("somewhat",18);
+aWE("soon",7);
+aWE("sort",22,26,27,50);
+aWE("sourc",69,74);
+aWE("spac",15,66,71,42,49);
+aWE("specifi",20,3,66,40,44,46);
+aWE("specific",16,23,74);
+aWE("specify",18,1,27,12,13,66,40,72,42,74,46,47,49,52);
+aWE("spher",20,21,24);
+aWE("split",16,20,2,6,65,44);
+aWE("sqrt",63);
+aWE("standalon",26,58,74);
+aWE("standard",0,8,32,75,53);
+aWE("start",14,20,6,9,13,61,43,44,49);
+aWE("startendlength",9);
+aWE("static",64);
+aWE("step",12,72);
+aWE("stor",66,74);
+aWE("str",63,64);
+aWE("straight",1,9,13,63,38);
+aWE("stretch",54);
+aWE("strict",54);
+aWE("structur",24,25,63,64);
+aWE("study",9,58,74,75);
+aWE("stuf",54);
+aWE("styl",7);
+aWE("sub",7,9,13,32,36,66,42,44,47,49);
+aWE("submenu",18,11,40,41);
+aWE("submesh",14,22,23,7,25,26,27,12,13,39,72,46,49,50,53);
+aWE("subshapeall",7,9,58,63,70,76);
+aWE("subshapeallid",63,75);
+aWE("subshapeallsort",63);
+aWE("subshapelist",7,58);
+aWE("subshapenam",7);
+aWE("succed",9);
+aWE("successful",73);
 aWE("sum",2);
-aWE("supplement",37);
-aWE("supplementary",26);
-aWE("surfac",14,20,2,11,12,64,70,43);
-aWE("surround",14,45);
-aWE("swept",11,70);
+aWE("supplement",38);
+aWE("supplementary",27);
+aWE("surfac",15,21,2,12,13,66,72,44);
+aWE("surround",15,46);
+aWE("swept",12,72);
 aWE("switch",1);
-aWE("symmetrical",46,73);
-aWE("symmetry",46,73);
-aWE("syntax",71);
-aWE("t",14,19,2,23,37,64,65,53);
-aWE("t1",61);
-aWE("tabl",1,19);
-aWE("tak",20,49);
-aWE("taken",13,22,25,8,64);
-aWE("tap",16,25,60,68,47);
-aWE("taper_margin",68);
-aWE("target",67);
-aWE("techniqu",45);
-aWE("tetra",6,8,72,75);
-aWE("tetrahedral",15,8,63,72);
-aWE("tetrahedralization",23);
-aWE("tetrahedrical",8);
-aWE("tetrahedron",14,15,17,2,6,8,61,34,72,75);
-aWE("tetran",8);
-aWE("th",64,43);
-aWE("them",13,17,1,19,2,25,9,10,11,12,35,63,39,70,43,45,53);
-aWE("themesh",6);
-aWE("third",12);
-aWE("thos",26,49);
-aWE("thre",14,1,20,61,63,37,43,46);
-aWE("threshold",71);
-aWE("tick",53);
+aWE("symmetrical",47,76);
+aWE("symmetry",47,76);
+aWE("syntax",74);
+aWE("t",15,20,2,24,38,66,67,73,54);
+aWE("t1",63);
+aWE("tabl",1,20);
+aWE("tak",21,50);
+aWE("taken",14,23,26,9,66);
+aWE("tap",17,26,61,70,48);
+aWE("taper_margin",70);
+aWE("target",69);
+aWE("techniqu",46);
+aWE("test",63);
+aWE("tetra",7,9,75,78);
+aWE("tetrahedral",16,9,65,75);
+aWE("tetrahedralization",24);
+aWE("tetrahedrical",9);
+aWE("tetrahedron",15,16,18,2,7,9,63,35,75,78);
+aWE("tetran",9);
+aWE("th",66,44);
+aWE("them",14,18,1,20,2,26,10,11,12,13,36,65,40,72,44,46,54);
+aWE("themesh",7);
+aWE("third",13);
+aWE("thos",27,50);
+aWE("thre",15,1,21,63,65,38,44,47);
+aWE("threshold",74);
+aWE("tick",54);
 aWE("tim",0);
-aWE("tmp",6);
-aWE("togeth",33);
-aWE("toggl",17,71,48);
-aWE("toleranc",35,70,71,73);
-aWE("tool",71,51);
-aWE("toolbar",20,2,21,23,24,7,26,27,28,30,11,12,32,64,39,40,70,42,44,45,47,49,50,52,76,53,54);
-aWE("top",61);
-aWE("topological",14,43);
-aWE("topology",14);
-aWE("toru",7);
-aWE("total",52);
-aWE("toward",45);
-aWE("transform",28,73);
-aWE("transformation",35,41,43,46,48);
-aWE("translat",73,48);
-aWE("translation",73,48);
-aWE("transparency",0,74);
-aWE("transparent",74);
-aWE("transtorm",7);
-aWE("tria",6,8,73);
-aWE("tria_mesh",8);
-aWE("triangl",14,15,17,1,18,20,6,8,27,11,33,32,59,36,61,63,66,68,69,70,44,72,47,73,49,50,75,53);
-aWE("triangular",15,33);
-aWE("triangulation",8);
-aWE("trihedron",53);
-aWE("tritoquad",61);
-aWE("truncat",72);
-aWE("try",23,63);
-aWE("tt",8,61);
-aWE("tui",15,17,18,19,20,2,3,4,21,23,24,25,26,27,28,30,11,12,55,56,31,58,33,32,59,35,36,34,37,64,38,39,40,70,41,43,44,45,46,47,48,49,50,51,52,76,54);
-aWE("tupl",62);
-aWE("two",14,17,5,25,26,8,27,12,57,36,61,63,64,66,67,68,69,43,47,73,48,50,51,52);
-aWE("typ",14,17,19,20,2,22,23,25,11,12,39,70,71,43,52);
-aWE("typical",45);
-aWE("u",14,43);
-aWE("unary",71);
-aWE("unassign",38);
-aWE("uncheck",53);
-aWE("uniform",45);
-aWE("union",57,49,50,51);
-aWE("uniongroup",57);
-aWE("unionid",72);
-aWE("unit",61,43,49,50,51);
-aWE("unles",37);
-aWE("unv",31);
-aWE("up",19,9,29);
-aWE("updat",0,6,42,45);
-aWE("updateobjbrows",57,61,68,73);
-aWE("upload",71);
-aWE("us",14,15,19,3,5,23,24,25,11,12,33,35,61,63,64,66,70,71,43,45,74,51,53);
-aWE("usag",16,6,61,72);
-aWE("useful",0,17,25,12,63);
-aWE("usual",43,45);
-aWE("v",14);
-aWE("valu",13,16,19,20,2,23,6,12,58,36,37,38,71,44,72);
-aWE("vari",20);
-aWE("variabl",62);
+aWE("tmp",7);
+aWE("togeth",34);
+aWE("toggl",18,74,49);
+aWE("toleranc",5,36,72,74,76);
+aWE("tool",74,52);
+aWE("toolbar",21,2,5,22,24,25,8,27,28,29,31,12,13,33,62,66,40,41,72,43,45,46,48,50,51,53,79,54,55);
+aWE("top",63,73);
+aWE("topological",15,44);
+aWE("topology",15);
+aWE("toru",8);
+aWE("total",53);
+aWE("toward",46);
+aWE("transform",29,76);
+aWE("transformation",36,42,44,47,49);
+aWE("translat",76,49);
+aWE("translation",76,49);
+aWE("transparency",0,77);
+aWE("transparent",77);
+aWE("transtorm",8);
+aWE("tria",7,9,76);
+aWE("tria_mesh",9);
+aWE("triangl",15,16,18,1,19,21,7,9,28,12,34,33,60,37,63,65,68,70,71,72,45,75,48,76,50,51,78,54);
+aWE("triangular",16,34);
+aWE("triangulation",9);
+aWE("trihedron",54);
+aWE("tritoquad",63);
+aWE("tru",63);
+aWE("truncat",75);
+aWE("try",24,65);
+aWE("tt",9,63);
+aWE("tui",16,18,19,20,21,2,3,4,22,24,25,26,27,28,29,31,12,13,56,57,32,59,34,33,60,36,62,37,35,38,66,39,40,41,72,42,44,45,46,47,48,49,50,51,52,53,79,55);
+aWE("tupl",64);
+aWE("two",15,18,6,26,27,9,28,13,58,37,63,65,66,68,69,70,71,44,48,76,49,51,52,53);
+aWE("typ",15,18,20,21,2,23,24,26,12,13,40,72,74,44,53);
+aWE("typical",46);
+aWE("u",15,44);
+aWE("unary",74);
+aWE("unassign",39);
+aWE("uncheck",54);
+aWE("uniform",46);
+aWE("union",58,50,51,52);
+aWE("uniongroup",58);
+aWE("unionid",75);
+aWE("unit",5,63,44,50,51,52);
+aWE("unles",38);
+aWE("unv",32);
+aWE("up",20,10,30);
+aWE("updat",0,7,43,46);
+aWE("updateobjbrows",58,63,70,76);
+aWE("upload",74);
+aWE("us",15,16,20,3,6,24,25,26,12,13,34,36,63,65,66,68,72,74,44,46,77,52,54);
+aWE("usag",17,7,63,75);
+aWE("useful",0,18,26,13,65);
+aWE("usual",44,46);
+aWE("v",15);
+aWE("valu",14,17,20,21,2,24,7,13,59,37,38,39,74,45,75);
+aWE("vari",21);
+aWE("variabl",64);
 aWE("variou",0);
-aWE("ve",17);
-aWE("vector",11,12,61,70,41,46,73,48,54);
-aWE("versa",7);
-aWE("vert",61);
-aWE("vertex",14,64,67);
-aWE("vertex_",61);
-aWE("vertic",61,64,66,67);
-aWE("very",17,12,63);
-aWE("via",71,52,53);
-aWE("vic",7);
-aWE("vid",61);
-aWE("view",0,17,1,18,20,2,21,5,25,26,9,27,28,29,11,12,32,36,39,40,70,71,43,44,45,47,49,50,52,75,76,53,54);
-aWE("visibl",53);
-aWE("visual",16);
-aWE("visualiz",53);
+aWE("ve",18);
+aWE("vector",12,13,63,72,42,47,76,49,55);
+aWE("versa",8);
+aWE("vert",63);
+aWE("vertex",15,63,66,69,73);
+aWE("vertex_",63);
+aWE("vertic",63,66,68,69);
+aWE("very",18,13,65);
+aWE("via",74,53,54);
+aWE("vic",8);
+aWE("vid",63);
+aWE("view",0,18,1,19,21,2,22,6,26,27,10,28,29,30,12,13,33,37,40,41,72,74,44,45,46,48,50,51,53,78,79,54,55);
+aWE("visibl",54);
+aWE("visual",17);
+aWE("visualiz",54);
 aWE("vk",2);
-aWE("volum",13,14,15,16,17,2,22,6,25,8,10,12,60,61,34,68,71,73,52,75,76);
-aWE("volume_margin",68);
-aWE("vtk",0,53);
-aWE("vxy",8,73);
-aWE("wa_margin",68);
-aWE("walk",64);
-aWE("warp",16,26,60,68,49,54);
-aWE("way",14,17,23,24,25,12,64,38,51);
-aWE("weight",45);
-aWE("well",64);
-aWE("wheth",71);
-aWE("whil",66,39);
-aWE("whit",12,55);
-aWE("whol",2,11,12,70,71,45,48);
-aWE("whos",21,25,26,37,49);
-aWE("will",13,14,0,17,1,18,19,20,2,21,22,23,6,24,7,25,26,9,28,29,30,11,12,31,33,32,59,36,61,63,34,37,64,67,39,40,70,42,71,43,44,45,47,74,49,51,52,76,54);
-aWE("window",5);
-aWE("wir",15,8,12,33,61,63,73);
-aWE("wire_polylin",61);
-aWE("wire_polyline_edg",61);
-aWE("wire_polyline_mesh",61);
-aWE("wirefram",0,65);
-aWE("wish",23,7,9,31,53);
-aWE("within",19,64,43);
-aWE("without",1,12,68,69);
-aWE("word",19);
-aWE("work",1,12,63,67);
-aWE("worst",20);
-aWE("would",17,69,43);
-aWE("ww",8);
-aWE("x",14,5,54);
-aWE("x0",61);
-aWE("y",14,5);
-aWE("y0",61);
-aWE("your",13,14,16,0,17,1,18,19,20,2,21,5,22,23,24,25,28,29,30,31,33,32,35,36,34,64,65,38,39,40,41,71,44,45,46,47,48,52,76,54);
-aWE("z",14,5);
-aWE("z0",61);
-aWE("zero",64);
-aWE("zoom",53);
+aWE("volum",14,15,16,17,18,2,23,7,26,9,11,13,61,63,35,70,74,76,53,78,79);
+aWE("volume_margin",70);
+aWE("vtk",0,54);
+aWE("vxy",9,76);
+aWE("wa_margin",70);
+aWE("walk",66);
+aWE("warp",17,27,61,70,50,55);
+aWE("way",15,18,24,25,26,13,66,39,52);
+aWE("weight",46);
+aWE("well",66);
+aWE("wheth",74);
+aWE("whil",5,68,40);
+aWE("whit",13,56);
+aWE("whol",16,2,12,13,72,74,46,49);
+aWE("whos",22,26,27,38,50);
+aWE("will",14,15,0,18,1,19,20,21,2,5,22,23,24,7,25,8,26,27,10,29,30,31,12,13,32,34,33,60,37,63,65,35,38,66,69,40,41,72,43,74,44,45,46,48,77,50,52,53,79,55);
+aWE("window",6);
+aWE("wir",16,9,13,34,63,65,76);
+aWE("wire_polylin",63);
+aWE("wire_polyline_edg",63);
+aWE("wire_polyline_mesh",63);
+aWE("wirefram",0,67);
+aWE("wish",24,8,10,32,54);
+aWE("within",20,66,44);
+aWE("without",1,13,70,71);
+aWE("word",20);
+aWE("work",1,13,65,69);
+aWE("worst",21);
+aWE("would",18,71,44);
+aWE("wrong",63);
+aWE("ww",9);
+aWE("x",15,6,63,55);
+aWE("x0",63);
+aWE("xyz",63);
+aWE("y",15,6,63);
+aWE("y0",63);
+aWE("your",14,15,17,0,18,1,19,20,21,2,22,6,23,24,25,26,29,30,31,32,34,33,36,37,35,66,67,39,40,41,42,74,45,46,47,48,49,53,79,55);
+aWE("z",15,6,63);
+aWE("z0",63);
+aWE("zero",66);
+aWE("zoom",54);
 
 //-->
 </script>
index 8861e12144ca021d2d6c87f8a65a57328ba09e87..17c79a84c7623a49456847f38a98e7fc922fa53a 100755 (executable)
@@ -8,18 +8,19 @@
 <script language="javascript" src="whtdata.js"></script>
 <script language="javascript">
 <!--
- aTE(1,85,"MESH module");
+ aTE(1,87,"MESH module");
    aTE(2,0,"Introduction to Mesh","mesh.htm");
    aTE(2,0,"Running MESH module","files/running_smesh_module.htm");
    aTE(2,0,"Introduction to MESH module python interface","smesh.py_introduction.htm");
-   aTE(1,17,"Creating meshes");
+   aTE(1,19,"Creating meshes");
      aTE(2,0,"About meshes","files/about_meshes.htm");
      aTE(2,0,"Importing and exporting meshes","files/importing_and_exporting_meshes.htm");
      aTE(2,0,"Constructing meshes","files/constructing_meshes.htm");
-     aTE(1,4,"Defining Algorithms");
+     aTE(1,5,"Defining Algorithms");
        aTE(2,0,"Basic meshing algorithms","files/about_meshing_algorithms.htm");
        aTE(2,0,"Projection Algorithms","projection_algorithms.htm");
        aTE(2,0,"Radial Prism Algorithm","radial_prism.htm");
+       aTE(2,0,"Segments around Vertex Algorithm","segments_around_vertex_algorithm.htm");
        aTE(2,0,"Prism 3D Algorithm","prism_3d_algorithm.htm");
      aTE(1,6,"Defining hypotheses");
        aTE(2,0,"About Hypotheses","files/about_hypotheses.htm");
        aTE(2,0,"Netgen 2D and 3D hypotheses","netgen_2d_and_3d_hypotheses.htm");
        aTE(2,0,"Additional Hypotheses","files/non_conform_mesh_allowed_hypothesis.htm");
      aTE(2,0,"Constructing submeshes","files/constructing_submeshes.htm");
+     aTE(2,0,"Building Compounds","building_compounds.htm");
      aTE(2,0,"Editing Meshes","files/reassigning_hypotheses_and_algorithms.htm");
-   aTE(1,8,"Viewing meshes");
+   aTE(1,7,"Viewing meshes");
      aTE(2,0,"Viewing meshes","about_viewing_meshes.htm");
-     aTE(2,0,"VTK 3D Viewer","files/vtk_3d_viewer.htm");
      aTE(2,0,"Mesh infos","files/viewing_mesh_info.htm");
      aTE(2,0,"Numbering","files/displaying_nodes_numbers.htm");
      aTE(2,0,"Display Mode","presentation.htm");
@@ -62,7 +63,7 @@
      aTE(2,0,"Constructing groups of specific elements","files/constructing_groups_of_specific_elements.htm");
      aTE(2,0,"Deleting Groups","deleting_groups.htm");
      aTE(2,0,"Selection filter library","selection_filter_library.htm");
-   aTE(1,23,"Modifying meshes");
+   aTE(1,24,"Modifying meshes");
      aTE(2,0,"Adding nodes and elements","files/adding_nodes_and_elements.htm");
      aTE(2,0,"Adding quadratic elements","adding_quadratic_nodes_and_elements.htm");
      aTE(2,0,"Removing nodes and elements","files/removing_nodes_and_elements.htm");
@@ -75,6 +76,7 @@
        aTE(2,0,"Merging nodes","files/merging_nodes.htm");
        aTE(2,0,"Merging Elements","merge_elements.htm");
      aTE(2,0,"Moving nodes","files/displacing_nodes.htm");
+     aTE(2,0,"Mesh through point","mesh_through_point.htm");
      aTE(2,0,"Diagonal inversion of elements","files/diagonal_iversion_of_elements.htm");
      aTE(2,0,"Uniting two triangles","files/uniting_two_triangles.htm");
      aTE(2,0,"Uniting a set of triangles","files/uniting_a_set_of_triangles.htm");
@@ -86,8 +88,8 @@
      aTE(2,0,"Revolution","revolution.htm");
      aTE(2,0,"Pattern mapping","pattern_mapping.htm");
      aTE(2,0,"Convert to/from Quadratic Mesh","convert_to_from_quadratic_mesh.htm");
- aTE(2,0,"Python interface smesh.py" ,"smeshpy_doc/namespacesmesh.html");
-     aTE(1,7,"TUI Scripts");
+aTE(2,0,"Python interface smesh.py", "smeshpy_doc/namespacesmesh.html");  
+   aTE(1,7,"TUI Scripts");
      aTE(2,0,"Creating Meshes","constructing_meshes.htm");
      aTE(2,0,"Viewing Meshes","viewing_meshes.htm");
      aTE(2,0,"Defining Hypotheses","defining_hypotheses_tui.htm");
index 22791bb275fb0722c9447e2c765f6c1c6e0cc73f..c3debb8ce61c110af37de2ee912877deeb73e698 100755 (executable)
@@ -5,6 +5,7 @@
 <topic name="Aspect ratio 3D" url="aspect_ratio_3d.htm" />
 <topic name="Borders at multi-connection" url="borders_at_multi-connection.htm" />
 <topic name="Borders at multiconnection 2D" url="borders_at_multiconnection_2d.htm" />
+<topic name="Building Compounds" url="building_compounds.htm" />
 <topic name="Clipping" url="clipping.htm" />
 <topic name="Constructing Meshes" url="constructing_meshes.htm" />
 <topic name="Convert to/from Quadratic Mesh" url="convert_to_from_quadratic_mesh.htm" />
@@ -61,6 +62,7 @@
 <topic name="Length" url="length.htm" />
 <topic name="Merge Elements" url="merge_elements.htm" />
 <topic name="mesh" url="mesh.htm" />
+<topic name="Mesh through point" url="mesh_through_point.htm" />
 <topic name="Modifying Meshes" url="modifying_meshes.htm" />
 <topic name="SALOME - SMESH - v.version: Package smesh" url="namespacesmesh.html" />
 <topic name="Netgen 2D and 3D hypotheses" url="netgen_2d_and_3d_hypotheses.htm" />
@@ -71,6 +73,7 @@
 <topic name="Quality Controls" url="quality_controls.htm" />
 <topic name="Radial Prism" url="radial_prism.htm" />
 <topic name="Revolution" url="revolution.htm" />
+<topic name="Segments around Vertex Algorithm" url="segments_around_vertex_algorithm.htm" />
 <topic name="Selection filter library" url="selection_filter_library.htm" />
 <topic name="smesh.py_introduction" url="smesh.py_introduction.htm" />
 <topic name="Transforming Meshes" url="transforming_meshes.htm" />
index 7d7a59573036cdb08d31d84a4d33aaea0e85b626..1452bb66870c31557b57387c5c8deb5566fa8938 100755 (executable)
 <?xml version='1.0' encoding='windows-1252' ?>
 <ftswdata>
-<key name="_grp"> 72, </key>
-<key name="0"> 14,19,5,6,25,8,12,57,61,63,68,43,72,73,75, </key>
-<key name="000001"> 68, </key>
-<key name="001"> 73, </key>
-<key name="0d"> 14, </key>
-<key name="1"> 17,1,18,19,20,2,21,23,6,7,26,8,27,28,29,30,11,12,57,31,32,35,36,61,64,68,39,40,70,62,43,44,72,45,47,73,49,50,51,76,54, </key>
-<key name="10"> 6,8,12,57,31,61,72,73,75, </key>
-<key name="100"> 6,8,57,68,72,73, </key>
-<key name="109"> 73, </key>
-<key name="110"> 61, </key>
-<key name="113"> 73, </key>
-<key name="12"> 61,73, </key>
-<key name="13"> 61, </key>
-<key name="130"> 61, </key>
-<key name="15"> 61,68,73, </key>
-<key name="150"> 8,61,73, </key>
-<key name="17"> 61, </key>
-<key name="180"> 61, </key>
-<key name="1d"> 13,14,15,16,19,23,6,8,11,12,60,61,63,37,67,68,69,70,72, </key>
-<key name="1e"> 61,68, </key>
-<key name="2"> 17,1,18,20,2,21,23,6,7,26,8,27,28,29,30,11,12,31,32,36,61,64,68,39,40,70,62,43,44,45,47,73,49,50,51,76,54, </key>
-<key name="20"> 6,8,57,61,68,72,73,75, </key>
-<key name="200"> 6,8,61,72, </key>
-<key name="21"> 61,73, </key>
-<key name="23"> 61,73, </key>
-<key name="24"> 73, </key>
-<key name="240"> 61, </key>
-<key name="245"> 61, </key>
-<key name="246"> 61, </key>
-<key name="25"> 73, </key>
-<key name="255"> 61, </key>
-<key name="2d"> 13,14,15,16,18,20,4,23,6,8,11,12,57,33,32,60,36,63,64,66,67,68,69,70,43,72,73,54, </key>
-<key name="3"> 14,18,20,21,23,6,7,26,8,27,28,11,12,57,31,61,63,64,68,39,40,70,62,43,44,72,45,73,49,50,75,54, </key>
-<key name="30"> 8,61,63,73, </key>
-<key name="300"> 6, </key>
-<key name="3128"> 61, </key>
-<key name="321"> 61, </key>
-<key name="3265"> 61, </key>
-<key name="3402"> 61, </key>
-<key name="35"> 57,68, </key>
-<key name="3658"> 61, </key>
-<key name="38"> 61,68,73, </key>
-<key name="39"> 61, </key>
-<key name="3d"> 13,14,15,16,0,17,1,20,2,21,23,6,25,26,8,9,27,28,29,11,12,60,63,34,66,67,68,69,39,40,70,43,72,45,49,50,76,53, </key>
-<key name="3e"> 68, </key>
-<key name="3rd"> 14, </key>
-<key name="3x3"> 61, </key>
-<key name="4"> 14,18,20,23,6,26,8,28,12,31,61,64,68,62,43,44,47,73,54, </key>
-<key name="40"> 57,61,72, </key>
-<key name="405"> 61, </key>
-<key name="406"> 61, </key>
-<key name="45"> 12,61,73, </key>
-<key name="47"> 61, </key>
-<key name="492"> 61, </key>
-<key name="493"> 61, </key>
-<key name="5"> 5,6,8,61,68,73, </key>
-<key name="50"> 8,61,73, </key>
-<key name="502"> 61, </key>
-<key name="503"> 61, </key>
-<key name="58"> 73, </key>
-<key name="5th"> 14, </key>
-<key name="6"> 2,6,8,57,61,73, </key>
-<key name="60"> 57,61,72, </key>
-<key name="66632"> 61, </key>
-<key name="69"> 73, </key>
-<key name="7"> 6,8,57,61,68, </key>
-<key name="70"> 8,61,73, </key>
-<key name="71"> 73, </key>
-<key name="72"> 73, </key>
-<key name="73"> 61, </key>
-<key name="8"> 57,61,68,73, </key>
-<key name="80"> 61,72, </key>
-<key name="800"> 6, </key>
-<key name="814"> 61, </key>
-<key name="850"> 61, </key>
-<key name="859"> 61, </key>
-<key name="89"> 73, </key>
-<key name="9"> 61,73, </key>
-<key name="90"> 73, </key>
-<key name="900"> 6,75, </key>
-<key name="91"> 73, </key>
-<key name="92"> 73, </key>
-<key name="95"> 68, </key>
-<key name="9999"> 25, </key>
-<key name="a_mesh"> 61, </key>
-<key name="a10"> 61, </key>
-<key name="a45"> 61, </key>
-<key name="aa"> 61, </key>
-<key name="abl"> 17,1,53, </key>
-<key name="abord"> 68, </key>
-<key name="aborder"> 68, </key>
-<key name="abov"> 61,45, </key>
-<key name="absent"> 51, </key>
-<key name="absolute"> 74, </key>
-<key name="abut"> 19, </key>
-<key name="acces"> 0,71,53, </key>
-<key name="accord"> 16,18,19,20,2,32,36,64,44,45,47,76,54, </key>
-<key name="account"> 13,64, </key>
-<key name="acomp"> 73, </key>
-<key name="actual"> 63,37, </key>
-<key name="ad"> 17,1,21,7,25,26,57,61,49,51, </key>
-<key name="add"> 17,1,21,23,25,26,8,30,12,57,61,68,71,72,49, </key>
-<key name="addedg"> 61, </key>
-<key name="addfac"> 61, </key>
-<key name="addition"> 26,60,61, </key>
-<key name="additional"> 13,14,23,8,37,64,42,71,45, </key>
-<key name="addnod"> 61, </key>
-<key name="addobject"> 57, </key>
-<key name="addpolygonalfac"> 61, </key>
-<key name="addpolyhedralvolum"> 61, </key>
-<key name="addtostudy"> 6,8,57,61,68,72,73,75, </key>
-<key name="addtostudyinfath"> 6,8,57,61, </key>
-<key name="addvolum"> 61, </key>
-<key name="adjacent"> 28,36,63,37,39,43,49, </key>
-<key name="adjust"> 45, </key>
-<key name="adjustabl"> 37, </key>
-<key name="advanc"> 0,52, </key>
-<key name="afilt"> 57,68, </key>
-<key name="afiltermgr"> 68, </key>
-<key name="ageomgroup"> 57, </key>
-<key name="agroup"> 57,68, </key>
-<key name="agroup1"> 57, </key>
-<key name="agroup2"> 57, </key>
-<key name="agroup3"> 57, </key>
-<key name="agroup4"> 57, </key>
-<key name="agroup5"> 57, </key>
-<key name="agroupelemid"> 57, </key>
-<key name="agroupf"> 68, </key>
-<key name="agroupmain"> 57, </key>
-<key name="agroupn"> 68, </key>
-<key name="agroupr"> 57, </key>
-<key name="agrouptool"> 57, </key>
-<key name="ai"> 19, </key>
-<key name="al"> 61, </key>
-<key name="algeady"> 67, </key>
-<key name="algo"> 8,61,68,73, </key>
-<key name="algo_local"> 6,8,73, </key>
-<key name="algo1d"> 6,8,57,61,72,73,75, </key>
-<key name="algo2d"> 6,8,61,72,73,75, </key>
-<key name="algo3d"> 6,8,72,75, </key>
-<key name="algorithm"> 13,14,15,16,0,18,23,6,24,8,12,33,60,63,34,64,66,67,69,38,43, </key>
-<key name="allow"> 13,0,1,19,21,24,7,25,26,31,33,59,35,60,63,37,64,67,41,43,45,46,48,49,51,53, </key>
-<key name="along"> 11,12,61,64,45,53, </key>
-<key name="already"> 67, </key>
-<key name="alternativ"> 23, </key>
+<key name="_grp"> 75, </key>
+<key name="0"> 15,20,6,7,26,9,13,58,63,65,70,44,75,76,78, </key>
+<key name="000001"> 70, </key>
+<key name="001"> 76, </key>
+<key name="0d"> 15,73, </key>
+<key name="1"> 18,1,19,20,21,2,22,24,7,8,27,9,28,29,30,31,12,13,58,32,33,36,62,37,63,66,70,40,41,72,64,44,45,75,46,48,76,50,51,52,79,55, </key>
+<key name="10"> 7,9,13,58,32,63,75,76,78, </key>
+<key name="100"> 7,9,58,63,70,75,76, </key>
+<key name="109"> 76, </key>
+<key name="110"> 63, </key>
+<key name="113"> 76, </key>
+<key name="12"> 63,76, </key>
+<key name="13"> 63, </key>
+<key name="130"> 63, </key>
+<key name="15"> 63,70,76, </key>
+<key name="150"> 9,63,76, </key>
+<key name="17"> 63, </key>
+<key name="180"> 63, </key>
+<key name="1d"> 14,15,16,17,20,24,7,9,12,13,61,63,65,38,69,70,71,72,75, </key>
+<key name="1e"> 63,70, </key>
+<key name="2"> 18,1,19,21,2,22,24,7,8,27,9,28,29,30,31,12,13,32,33,62,37,63,66,70,40,41,72,64,44,45,46,48,76,50,51,52,79,55, </key>
+<key name="20"> 7,9,58,63,70,75,76,78, </key>
+<key name="200"> 7,9,63,75, </key>
+<key name="21"> 63,76, </key>
+<key name="23"> 63,76, </key>
+<key name="24"> 76, </key>
+<key name="240"> 63, </key>
+<key name="245"> 63, </key>
+<key name="246"> 63, </key>
+<key name="25"> 76, </key>
+<key name="255"> 63, </key>
+<key name="2d"> 14,15,16,17,19,21,4,24,7,9,12,13,58,34,33,61,37,65,66,68,69,70,71,72,44,75,76,55, </key>
+<key name="3"> 15,19,21,22,24,7,8,27,9,28,29,12,13,58,32,62,63,65,66,70,40,41,72,64,44,45,75,46,76,50,51,78,55, </key>
+<key name="30"> 9,63,65,76, </key>
+<key name="300"> 7, </key>
+<key name="3128"> 63, </key>
+<key name="321"> 63, </key>
+<key name="3265"> 63, </key>
+<key name="3402"> 63, </key>
+<key name="35"> 58,70, </key>
+<key name="3658"> 63, </key>
+<key name="38"> 63,70,76, </key>
+<key name="39"> 63, </key>
+<key name="3d"> 14,15,16,17,0,18,1,21,2,22,24,7,26,27,9,10,28,29,30,12,13,61,65,35,68,69,70,71,40,41,72,44,75,46,50,51,79,54, </key>
+<key name="3e"> 70, </key>
+<key name="3rd"> 15, </key>
+<key name="3x3"> 63, </key>
+<key name="4"> 15,19,21,24,7,27,9,29,13,32,62,63,66,70,64,44,45,48,76,55, </key>
+<key name="40"> 58,63,75, </key>
+<key name="405"> 63, </key>
+<key name="406"> 63, </key>
+<key name="45"> 13,63,76, </key>
+<key name="47"> 63, </key>
+<key name="492"> 63, </key>
+<key name="493"> 63, </key>
+<key name="5"> 6,7,9,63,70,76, </key>
+<key name="50"> 9,63,76, </key>
+<key name="502"> 63, </key>
+<key name="503"> 63, </key>
+<key name="58"> 76, </key>
+<key name="5th"> 15, </key>
+<key name="6"> 2,7,9,58,63,76, </key>
+<key name="60"> 58,63,75, </key>
+<key name="66632"> 63, </key>
+<key name="69"> 76, </key>
+<key name="7"> 7,9,58,63,70, </key>
+<key name="70"> 9,63,76, </key>
+<key name="71"> 76, </key>
+<key name="72"> 76, </key>
+<key name="73"> 63, </key>
+<key name="8"> 58,63,70,76, </key>
+<key name="80"> 63,75, </key>
+<key name="800"> 7, </key>
+<key name="814"> 63, </key>
+<key name="850"> 63, </key>
+<key name="859"> 63, </key>
+<key name="89"> 76, </key>
+<key name="9"> 63,76, </key>
+<key name="90"> 76, </key>
+<key name="900"> 7,78, </key>
+<key name="91"> 76, </key>
+<key name="92"> 76, </key>
+<key name="95"> 70, </key>
+<key name="9999"> 26, </key>
+<key name="a_mesh"> 63, </key>
+<key name="a10"> 63, </key>
+<key name="a45"> 63, </key>
+<key name="aa"> 63, </key>
+<key name="abl"> 18,1,54, </key>
+<key name="abord"> 70, </key>
+<key name="aborder"> 70, </key>
+<key name="abov"> 63,46, </key>
+<key name="absent"> 52, </key>
+<key name="absolute"> 77, </key>
+<key name="abut"> 20, </key>
+<key name="acces"> 0,74,54, </key>
+<key name="accord"> 17,19,20,21,2,33,37,66,45,46,48,79,55, </key>
+<key name="account"> 14,66, </key>
+<key name="acomp"> 76, </key>
+<key name="actual"> 65,38, </key>
+<key name="ad"> 18,1,22,8,26,27,58,63,50,52, </key>
+<key name="add"> 18,1,22,24,26,27,9,31,13,58,63,70,74,75,50, </key>
+<key name="addedg"> 63, </key>
+<key name="addfac"> 63, </key>
+<key name="addition"> 27,61,63, </key>
+<key name="additional"> 14,15,24,9,38,66,43,74,46, </key>
+<key name="addnod"> 63, </key>
+<key name="addobject"> 58, </key>
+<key name="addpolygonalfac"> 63, </key>
+<key name="addpolyhedralvolum"> 63, </key>
+<key name="addtostudy"> 7,9,58,63,70,75,76,78, </key>
+<key name="addtostudyinfath"> 7,9,58,63, </key>
+<key name="addvolum"> 63, </key>
+<key name="adjacent"> 29,37,65,38,40,44,50, </key>
+<key name="adjust"> 46, </key>
+<key name="adjustabl"> 38, </key>
+<key name="advanc"> 0,53, </key>
+<key name="afilt"> 58,70, </key>
+<key name="afiltermgr"> 70, </key>
+<key name="ageomgroup"> 58, </key>
+<key name="agroup"> 58,70, </key>
+<key name="agroup1"> 58, </key>
+<key name="agroup2"> 58, </key>
+<key name="agroup3"> 58, </key>
+<key name="agroup4"> 58, </key>
+<key name="agroup5"> 58, </key>
+<key name="agroupelemid"> 58, </key>
+<key name="agroupf"> 70, </key>
+<key name="agroupmain"> 58, </key>
+<key name="agroupn"> 70, </key>
+<key name="agroupr"> 58, </key>
+<key name="agrouptool"> 58, </key>
+<key name="ai"> 20, </key>
+<key name="al"> 63, </key>
+<key name="algeady"> 69, </key>
+<key name="algo"> 9,63,70,76, </key>
+<key name="algo_local"> 7,9,76, </key>
+<key name="algo1d"> 7,9,58,63,75,76,78, </key>
+<key name="algo2d"> 7,9,63,75,76,78, </key>
+<key name="algo3d"> 7,9,75,78, </key>
+<key name="algorithm"> 14,15,16,17,0,19,24,7,25,9,13,34,61,65,35,66,68,69,71,39,73,44, </key>
+<key name="allow"> 14,16,0,1,20,5,22,25,8,26,27,32,34,60,36,61,62,65,38,66,69,42,73,44,46,47,49,50,52,54, </key>
+<key name="along"> 12,13,63,66,46,54, </key>
+<key name="already"> 69, </key>
+<key name="alternativ"> 24, </key>
 <key name="alternative"> 0,1, </key>
-<key name="alway"> 45, </key>
-<key name="amesh"> 6, </key>
+<key name="alway"> 46, </key>
+<key name="amesh"> 7, </key>
 <key name="amount"> 3, </key>
-<key name="analytic"> 19, </key>
-<key name="angl"> 16,5,26,12,60,36,61,68,70,41,44,73,49,54, </key>
-<key name="angle270"> 73, </key>
-<key name="angle45"> 61, </key>
-<key name="angularity"> 12, </key>
-<key name="anid"> 57,68, </key>
-<key name="anoth"> 15,37,67, </key>
-<key name="any"> 14,1,23,25,28,12,57,64,69,45, </key>
-<key name="ap"> 15,17,1,18,20,2,21,5,23,7,25,26,8,9,27,28,30,11,12,32,59,60,36,61,64,67,38,39,40,70,43,44,45,46,47,49,50,51,76,54, </key>
-<key name="api"> 72, </key>
-<key name="apparent"> 23, </key>
-<key name="appear"> 0,17,1,21,23,24,7,26,27,28,30,11,12,35,64,67,39,40,70,41,46,48,49,50,51, </key>
-<key name="append"> 61, </key>
-<key name="appli"> 18,19,20,2,23,24,33,32,36,34,37,69,38,71,44,45,47,76,54, </key>
-<key name="applicabl"> 20,71, </key>
-<key name="application"> 16,64, </key>
-<key name="apply"> 13,0,23,24,25, </key>
-<key name="applytomeshfac"> 61, </key>
-<key name="appropriat"> 23, </key>
-<key name="approximate"> 19, </key>
-<key name="ar_margin"> 68, </key>
-<key name="arc"> 8,73, </key>
-<key name="arcsin"> 54, </key>
-<key name="area"> 13,16,18,8,57,33,60,34,68,45,47,53, </key>
-<key name="area_margin"> 68, </key>
-<key name="arithmetic"> 13,19,6,8,60, </key>
-<key name="arithmetic1d"> 6,8,73, </key>
-<key name="around"> 5,12,70,53, </key>
-<key name="array_of_nodes_group"> 73, </key>
-<key name="asmeshgroup1"> 57, </key>
-<key name="asmeshgroup2"> 57, </key>
-<key name="aspect"> 16,20,2,60,68,45, </key>
-<key name="assemb"> 72, </key>
-<key name="assign"> 19,23,25,8,38,54, </key>
-<key name="associat"> 17,29,39, </key>
-<key name="attribut"> 25, </key>
-<key name="auto"> 5, </key>
-<key name="automatic"> 13,19,23,60,64, </key>
-<key name="automatical"> 0,19,21,23,26,28,49, </key>
-<key name="availabl"> 43,53, </key>
-<key name="averag"> 13,19,8,33,60,64,54, </key>
-<key name="ax"> 53, </key>
-<key name="axi"> 11,61,70,41,46,73,53,54, </key>
-<key name="axisstruct"> 61,73, </key>
-<key name="axisxyz"> 61,73, </key>
+<key name="analytic"> 20, </key>
+<key name="angl"> 17,6,27,13,61,37,63,70,72,42,45,76,50,55, </key>
+<key name="angle270"> 76, </key>
+<key name="angle45"> 63, </key>
+<key name="angularity"> 13, </key>
+<key name="anid"> 58,70, </key>
+<key name="anoth"> 16,38,69, </key>
+<key name="any"> 15,16,1,24,26,29,13,58,62,63,66,71,46, </key>
+<key name="ap"> 16,18,1,19,21,2,22,6,24,8,26,27,9,10,28,29,31,12,13,33,60,61,62,37,63,66,69,39,40,41,72,44,45,46,47,48,50,51,52,79,55, </key>
+<key name="api"> 75, </key>
+<key name="apparent"> 24, </key>
+<key name="appear"> 0,18,1,5,22,24,25,8,27,28,29,31,12,13,36,62,66,69,40,41,72,42,47,49,50,51,52, </key>
+<key name="append"> 63, </key>
+<key name="appli"> 19,20,21,2,24,25,34,33,37,35,38,71,39,73,74,45,46,48,79,55, </key>
+<key name="applicabl"> 21,74, </key>
+<key name="application"> 17,66, </key>
+<key name="apply"> 14,0,24,25,26, </key>
+<key name="applytomeshfac"> 63, </key>
+<key name="appropriat"> 24, </key>
+<key name="approximate"> 20, </key>
+<key name="ar_margin"> 70, </key>
+<key name="arc"> 9,76, </key>
+<key name="arcsin"> 55, </key>
+<key name="area"> 14,17,19,9,58,34,61,35,70,46,48,54, </key>
+<key name="area_margin"> 70, </key>
+<key name="arithmetic"> 14,20,7,9,61, </key>
+<key name="arithmetic1d"> 7,9,76, </key>
+<key name="around"> 6,13,72,73,54, </key>
+<key name="array_of_nodes_group"> 76, </key>
+<key name="asmeshgroup1"> 58, </key>
+<key name="asmeshgroup2"> 58, </key>
+<key name="aspect"> 17,21,2,61,70,46, </key>
+<key name="assemb"> 75, </key>
+<key name="assign"> 16,20,24,26,9,39,55, </key>
+<key name="associat"> 18,30,40, </key>
+<key name="attribut"> 26, </key>
+<key name="auto"> 6, </key>
+<key name="automatic"> 14,20,24,61,62,66, </key>
+<key name="automatical"> 0,20,22,24,27,29,50, </key>
+<key name="automaticlength"> 63, </key>
+<key name="availabl"> 44,54, </key>
+<key name="averag"> 14,20,9,34,61,66,55, </key>
+<key name="ax"> 54, </key>
+<key name="axi"> 12,63,72,42,47,76,54,55, </key>
+<key name="axisstruct"> 63,76, </key>
+<key name="axisxyz"> 63,76, </key>
 <key name="background"> 0, </key>
-<key name="bar"> 16, </key>
-<key name="bas"> 13,18,8,12,60,54, </key>
-<key name="basi"> 14,23,24, </key>
-<key name="basic"> 13,15,0, </key>
-<key name="bb"> 61, </key>
-<key name="be"> 67, </key>
-<key name="becom"> 63,64, </key>
-<key name="befor"> 71,73, </key>
-<key name="begin"> 19,43, </key>
-<key name="belong"> 3,4,25,55,56,67,43,51, </key>
-<key name="below"> 61,63,72, </key>
-<key name="berder"> 43, </key>
-<key name="bet"> 20, </key>
-<key name="binary"> 71, </key>
-<key name="bisect"> 54, </key>
-<key name="bisector"> 54, </key>
-<key name="bit"> 71, </key>
+<key name="bar"> 17, </key>
+<key name="bas"> 14,19,9,13,61,55, </key>
+<key name="basi"> 15,24,25, </key>
+<key name="basic"> 14,16,0, </key>
+<key name="bb"> 63, </key>
+<key name="be"> 69, </key>
+<key name="becom"> 5,65,66, </key>
+<key name="befor"> 74,76, </key>
+<key name="begin"> 20,44, </key>
+<key name="belong"> 3,4,26,56,57,69,44,52, </key>
+<key name="below"> 63,65,75, </key>
+<key name="berder"> 44, </key>
+<key name="bet"> 21, </key>
+<key name="binary"> 74, </key>
+<key name="bisect"> 55, </key>
+<key name="bisector"> 55, </key>
+<key name="bit"> 74, </key>
 <key name="black"> 0, </key>
 <key name="blu"> 3, </key>
-<key name="bmp"> 0,53, </key>
-<key name="bog"> 19, </key>
-<key name="boolean"> 61,51, </key>
-<key name="bord"> 43,73, </key>
-<key name="border"> 16,3,4,55,56,60,68,43,73, </key>
-<key name="both"> 0,12,69,45,51, </key>
-<key name="bottom"> 61,42, </key>
-<key name="bound"> 14,64,53, </key>
-<key name="boundari"> 64, </key>
-<key name="boundary"> 13,25,64,43,45, </key>
-<key name="box"> 17,1,19,21,23,6,24,7,26,8,27,28,30,11,12,57,31,59,35,63,64,67,68,39,40,70,41,42,71,43,72,45,46,73,48,49,50,51,52,75,53, </key>
-<key name="box_1"> 61, </key>
-<key name="box_cyl"> 72, </key>
-<key name="box1"> 68,73, </key>
-<key name="box2"> 68,73, </key>
-<key name="broken"> 1,37, </key>
-<key name="brown"> 25, </key>
-<key name="brows"> 0,17,1,22,23,24,25,9,30,65,39,40,71,52, </key>
-<key name="build"> 8,11,33,61,63,37,64,66,70,72, </key>
-<key name="built"> 20,24,12,64,45, </key>
-<key name="button"> 17,1,18,20,2,21,5,23,24,7,25,26,9,27,28,30,11,12,31,32,36,64,67,38,39,40,70,41,71,43,44,45,46,47,48,49,50,51,52,76,53,54, </key>
-<key name="cad"> 14, </key>
-<key name="cal"> 64, </key>
-<key name="calculat"> 16,20,2,33,47, </key>
-<key name="calculation"> 13,18,32,36, </key>
-<key name="careful"> 39, </key>
-<key name="cas"> 17,23,6,8,28,12,64,52, </key>
-<key name="caviti"> 15, </key>
-<key name="cc"> 61, </key>
-<key name="cel"> 25,63,39,50, </key>
-<key name="cent"> 12,45,53, </key>
-<key name="central"> 12, </key>
-<key name="centroid"> 45, </key>
-<key name="centroidal"> 45, </key>
-<key name="centroidal_smooth"> 61, </key>
-<key name="certain"> 25,64, </key>
-<key name="chang"> 0,19,21,6,28,61,37,38,53, </key>
-<key name="characteristic"> 16, </key>
-<key name="characteriz"> 14, </key>
-<key name="check"> 25,63,43,53, </key>
-<key name="checkbox"> 17,63,71,48, </key>
-<key name="choic"> 13,23,64, </key>
-<key name="choos"> 17,1,18,20,2,21,22,7,25,26,9,27,28,10,29,11,12,31,32,35,36,64,39,40,70,41,42,71,43,44,46,47,48,49,50,76,53,54, </key>
-<key name="chosen"> 20,26,33,34,49, </key>
-<key name="circl"> 12,73, </key>
-<key name="circlemesh"> 73, </key>
-<key name="circular"> 61, </key>
-<key name="clas"> 62, </key>
-<key name="clear"> 62,71, </key>
-<key name="click"> 0,17,1,18,20,2,21,5,22,23,24,7,25,26,9,27,28,29,30,11,12,31,32,36,64,65,67,38,39,40,70,42,71,43,44,45,47,49,50,51,52,76,53,54, </key>
-<key name="clip"> 0,5, </key>
-<key name="clos"> 14,20,9,12,61,43, </key>
-<key name="co"> 61,43, </key>
-<key name="coars"> 19,7,63, </key>
-<key name="coincid"> 59, </key>
-<key name="coincident"> 12,59,35, </key>
-<key name="color"> 16,0,18,20,2,25,32,36,44,47,76,53,54, </key>
-<key name="combin"> 10,32,65,71, </key>
-<key name="common"> 27,71,50, </key>
-<key name="comp"> 68, </key>
-<key name="compar"> 19,43, </key>
-<key name="complete"> 59, </key>
-<key name="complex"> 1,12, </key>
-<key name="component"> 60,42, </key>
-<key name="compos"> 13,14,15,16,0,19,2,29,33,34,69,44, </key>
-<key name="compound"> 68, </key>
-<key name="comput"> 0,19,23,6,8,57,61,64,68,43,72,73,75, </key>
-<key name="computation"> 23,24,8,61, </key>
-<key name="con"> 72, </key>
-<key name="concept"> 37, </key>
-<key name="concern"> 69, </key>
-<key name="condition"> 13,25, </key>
-<key name="confirm"> 21,26,30,39,45,49,51, </key>
-<key name="confirmation"> 25, </key>
-<key name="conform"> 13,37,43,73, </key>
-<key name="conformity"> 20, </key>
-<key name="connect"> 19,26,66,45, </key>
-<key name="connection"> 14,16,3,4,60,68, </key>
-<key name="connectivity"> 64, </key>
-<key name="consid"> 20,23, </key>
-<key name="consider"> 14,20,2,43, </key>
-<key name="consist"> 16,1,18,19,20,3,4,22,23,24,25,12,55,56,57,33,32,36,34,69,47, </key>
-<key name="consol"> 52, </key>
-<key name="constant"> 19, </key>
-<key name="construct"> 15,19,22,23,6,24,38, </key>
-<key name="construction"> 19,23,6,24, </key>
-<key name="contain"> 14,15,21,23,24,25,26,12,31,33,64,45,49, </key>
-<key name="content"> 9,53, </key>
-<key name="continu"> 45, </key>
-<key name="contour"> 14,43, </key>
-<key name="contrast"> 49, </key>
-<key name="control"> 16,0,18,20,2,3,4,26,55,56,58,32,60,36,68,44,47,49,76,54, </key>
-<key name="converg"> 45, </key>
-<key name="conversion"> 19,7, </key>
-<key name="convert"> 7, </key>
-<key name="coordinat"> 14,17,28,64,53, </key>
-<key name="copy"> 41,71,46,73,48, </key>
-<key name="corn"> 1,54, </key>
-<key name="corner"> 26,12,45,54, </key>
-<key name="correspond"> 14,16,31,64,68,71,43,48, </key>
-<key name="cos_bot"> 61, </key>
-<key name="cos_top"> 61, </key>
-<key name="cosal"> 61, </key>
-<key name="cot"> 72, </key>
-<key name="could"> 14,17,67, </key>
-<key name="count"> 43, </key>
-<key name="counterclockwis"> 64, </key>
-<key name="cours"> 23, </key>
-<key name="cover"> 12, </key>
-<key name="creat"> 14,0,17,1,19,5,23,6,24,25,8,30,57,35,60,61,63,37,64,67,68,38,41,71,72,46,73,48,51,75,54, </key>
-<key name="createemptygroup"> 57,68, </key>
-<key name="createfiltermanag"> 68, </key>
-<key name="creategroup"> 57,61,68,72, </key>
-<key name="createpolyedr"> 73, </key>
-<key name="createpolygon"> 73, </key>
-<key name="creation"> 14,37,64,38,62,72,51, </key>
-<key name="criteria"> 60,71, </key>
-<key name="criterion"> 18,20,2,25,26,57,58,32,36,68,71,44,47,49,76,54, </key>
-<key name="cros"> 0,5,54, </key>
-<key name="cubic"> 15, </key>
-<key name="current"> 21,23,26,63,67,38,71,43,49, </key>
-<key name="curv"> 14,19,12,61, </key>
-<key name="curvilinear"> 19,12, </key>
-<key name="custom"> 63, </key>
-<key name="cut"> 19,6,26,8,57,61,51, </key>
-<key name="cutgroup"> 57, </key>
-<key name="cyl"> 8,72, </key>
-<key name="cylind"> 8,72, </key>
-<key name="d"> 19, </key>
-<key name="data"> 62, </key>
-<key name="dd"> 61, </key>
-<key name="dea"> 31, </key>
-<key name="deal"> 14, </key>
-<key name="def"> 6,61,62, </key>
-<key name="default"> 0,23,12,57,63,65,71,74,53, </key>
-<key name="defin"> 14,15,1,19,20,5,23,6,24,25,8,12,61,63,37,64,66,67,62,43,72,73,53, </key>
-<key name="definit"> 14,16,19,21,22,25,26,60,38,39,49, </key>
-<key name="definition"> 0,19,6,12,33,63,34, </key>
-<key name="deflection"> 13,19,8,60, </key>
-<key name="deflection1d"> 8, </key>
-<key name="deform"> 53, </key>
-<key name="degre"> 20,5, </key>
-<key name="delet"> 9,56,61,39,71, </key>
-<key name="deletediag"> 61, </key>
-<key name="deletion"> 39,50, </key>
-<key name="density"> 19, </key>
-<key name="depend"> 13,14,23,33,34, </key>
-<key name="describ"> 14,15,64, </key>
-<key name="description"> 64, </key>
-<key name="desirabl"> 35, </key>
-<key name="desktop"> 42, </key>
-<key name="destin"> 14,16,60,62, </key>
-<key name="detail"> 13,15,0, </key>
-<key name="detalization"> 63, </key>
-<key name="detect"> 35, </key>
-<key name="dh"> 61, </key>
-<key name="di1"> 72, </key>
-<key name="diagonal"> 26,27,61,47, </key>
-<key name="dialog"> 17,1,19,21,23,24,7,26,27,28,30,11,12,31,59,35,64,67,39,40,70,41,43,45,46,48,49,50,51, </key>
-<key name="diamet"> 20, </key>
-<key name="dif"> 1,63, </key>
-<key name="differ"> 19, </key>
-<key name="differenc"> 12,43, </key>
-<key name="different"> 13,17,25,12,67,38,71,43, </key>
-<key name="digit"> 12, </key>
-<key name="dimension"> 14,2,23,11,63,70,52, </key>
-<key name="direct"> 14,6,43,45, </key>
-<key name="direction"> 12,64,54, </key>
-<key name="dirstruct"> 61,73, </key>
-<key name="discretiz"> 11,70, </key>
-<key name="discretization"> 14,15, </key>
-<key name="displac"> 28, </key>
-<key name="display"> 16,0,1,18,20,2,3,21,23,24,25,26,28,10,29,55,32,36,65,44,45,47,49,52,76,53,54, </key>
-<key name="distanc"> 19,5,64,53,54, </key>
-<key name="distinguish"> 25, </key>
-<key name="distortion"> 45, </key>
-<key name="distribution"> 19,69, </key>
-<key name="divid"> 19, </key>
-<key name="do"> 17, </key>
-<key name="docopy"> 73, </key>
-<key name="documentation"> 62, </key>
-<key name="domain"> 64, </key>
-<key name="don"> 14,23,12,61,37,67,53, </key>
+<key name="bmp"> 0,54, </key>
+<key name="bog"> 20, </key>
+<key name="boolean"> 63,52, </key>
+<key name="bord"> 44,76, </key>
+<key name="border"> 17,3,4,56,57,61,70,44,76, </key>
+<key name="both"> 0,13,71,46,52, </key>
+<key name="bottom"> 63,43, </key>
+<key name="bound"> 15,66,54, </key>
+<key name="boundari"> 66, </key>
+<key name="boundary"> 14,26,66,44,46, </key>
+<key name="box"> 18,1,20,5,22,24,7,25,8,27,9,28,29,31,12,13,58,32,60,36,62,63,65,66,69,70,40,41,72,42,43,73,74,44,75,46,47,76,49,50,51,52,53,78,54, </key>
+<key name="box_1"> 63, </key>
+<key name="box_cyl"> 75, </key>
+<key name="box1"> 70,76, </key>
+<key name="box2"> 70,76, </key>
+<key name="break"> 63, </key>
+<key name="broken"> 1,38, </key>
+<key name="brown"> 26, </key>
+<key name="brows"> 0,18,1,5,23,24,25,26,10,31,67,40,41,74,53, </key>
+<key name="build"> 5,9,12,34,63,65,38,66,68,72,75, </key>
+<key name="built"> 21,25,13,66,46, </key>
+<key name="button"> 18,1,19,21,2,5,22,6,24,25,8,26,27,10,28,29,31,12,13,32,33,62,37,66,69,39,40,41,72,42,74,44,45,46,47,48,49,50,51,52,53,79,54,55, </key>
+<key name="c1"> 16, </key>
+<key name="cad"> 15, </key>
+<key name="cal"> 66, </key>
+<key name="calculat"> 17,21,2,34,48, </key>
+<key name="calculation"> 14,19,33,37, </key>
+<key name="careful"> 40, </key>
+<key name="cas"> 18,5,24,7,9,29,13,62,66,53, </key>
+<key name="caviti"> 16, </key>
+<key name="cc"> 63, </key>
+<key name="cel"> 26,65,40,51, </key>
+<key name="cent"> 13,46,54, </key>
+<key name="central"> 13, </key>
+<key name="centroid"> 46, </key>
+<key name="centroidal"> 46, </key>
+<key name="centroidal_smooth"> 63, </key>
+<key name="certain"> 26,62,66,73, </key>
+<key name="chang"> 0,20,22,7,29,63,38,39,54, </key>
+<key name="characteristic"> 17, </key>
+<key name="characteriz"> 15, </key>
+<key name="check"> 26,62,63,65,44,54, </key>
+<key name="checkbox"> 18,65,74,49, </key>
+<key name="choic"> 14,24,66, </key>
+<key name="choos"> 18,1,19,21,2,5,22,23,8,26,27,10,28,29,11,30,12,13,32,33,36,62,37,66,40,41,72,42,43,73,74,44,45,47,48,49,50,51,79,54,55, </key>
+<key name="chosen"> 21,5,27,34,35,50, </key>
+<key name="circl"> 13,76, </key>
+<key name="circlemesh"> 76, </key>
+<key name="circular"> 63, </key>
+<key name="clas"> 64, </key>
+<key name="clear"> 64,74, </key>
+<key name="click"> 0,18,1,19,21,2,5,22,6,23,24,25,8,26,27,10,28,29,30,31,12,13,32,33,62,37,66,67,69,39,40,41,72,43,74,44,45,46,48,50,51,52,53,79,54,55, </key>
+<key name="clip"> 0,6, </key>
+<key name="clos"> 15,21,10,13,63,44, </key>
+<key name="closest"> 62, </key>
+<key name="co"> 63,44, </key>
+<key name="coars"> 20,8,65, </key>
+<key name="coincid"> 60, </key>
+<key name="coincident"> 5,13,60,36, </key>
+<key name="color"> 17,0,19,21,2,26,33,37,45,48,79,54,55, </key>
+<key name="combin"> 11,33,67,73,74, </key>
+<key name="combination"> 5, </key>
+<key name="common"> 28,74,51, </key>
+<key name="comp"> 70, </key>
+<key name="compar"> 20,44, </key>
+<key name="complete"> 60, </key>
+<key name="complex"> 1,13, </key>
+<key name="component"> 61,43, </key>
+<key name="compos"> 14,15,16,17,0,20,2,30,34,35,71,45, </key>
+<key name="composit"> 16, </key>
+<key name="compound"> 5,70, </key>
+<key name="compound_mesh"> 5, </key>
+<key name="comput"> 0,20,24,7,9,58,63,66,70,44,75,76,78, </key>
+<key name="computation"> 24,25,9,63, </key>
+<key name="con"> 75, </key>
+<key name="concatenat"> 5, </key>
+<key name="concept"> 38, </key>
+<key name="concern"> 71, </key>
+<key name="condition"> 14,26, </key>
+<key name="confirm"> 22,27,31,40,46,50,52, </key>
+<key name="confirmation"> 26, </key>
+<key name="conform"> 14,38,44,76, </key>
+<key name="conformity"> 21, </key>
+<key name="connect"> 20,27,68,46, </key>
+<key name="connection"> 15,17,3,4,61,70, </key>
+<key name="connectivity"> 66, </key>
+<key name="consid"> 21,24, </key>
+<key name="consider"> 15,21,2,73,44, </key>
+<key name="consist"> 17,1,19,20,21,3,4,23,24,25,26,13,56,57,58,34,33,37,35,71,48, </key>
+<key name="consol"> 53, </key>
+<key name="constant"> 20, </key>
+<key name="construct"> 16,20,23,24,7,25,39, </key>
+<key name="construction"> 20,24,7,25, </key>
+<key name="contain"> 15,16,22,24,25,26,27,13,32,34,66,46,50, </key>
+<key name="content"> 10,54, </key>
+<key name="continu"> 46, </key>
+<key name="contour"> 15,44, </key>
+<key name="contrast"> 50, </key>
+<key name="control"> 17,0,19,21,2,3,4,27,56,57,59,33,61,37,70,45,48,50,79,55, </key>
+<key name="converg"> 46, </key>
+<key name="conversion"> 20,8, </key>
+<key name="convert"> 8, </key>
+<key name="coordinat"> 15,18,29,62,63,66,54, </key>
+<key name="copy"> 42,74,47,76,49, </key>
+<key name="corn"> 1,55, </key>
+<key name="corner"> 27,13,73,46,55, </key>
+<key name="correspond"> 15,17,32,66,70,74,44,49, </key>
+<key name="cos_bot"> 63, </key>
+<key name="cos_top"> 63, </key>
+<key name="cosal"> 63, </key>
+<key name="cot"> 75, </key>
+<key name="could"> 15,18,69, </key>
+<key name="count"> 44, </key>
+<key name="counterclockwis"> 66, </key>
+<key name="cours"> 24,73, </key>
+<key name="cover"> 13, </key>
+<key name="creat"> 15,0,18,1,20,5,6,24,7,25,26,9,31,58,36,61,62,63,65,38,66,69,70,39,42,74,75,47,76,49,52,78,55, </key>
+<key name="createemptygroup"> 58,70, </key>
+<key name="createfiltermanag"> 70, </key>
+<key name="creategroup"> 58,63,70,75, </key>
+<key name="createpolyedr"> 76, </key>
+<key name="createpolygon"> 76, </key>
+<key name="creation"> 15,62,38,66,39,64,75,52, </key>
+<key name="criteria"> 61,74, </key>
+<key name="criterion"> 19,21,2,26,27,58,59,33,37,70,74,45,48,50,79,55, </key>
+<key name="cros"> 0,6,55, </key>
+<key name="ctrl"> 5, </key>
+<key name="cubic"> 16, </key>
+<key name="current"> 22,24,27,65,69,39,74,44,50, </key>
+<key name="curv"> 15,16,20,13,63, </key>
+<key name="curvilinear"> 20,13, </key>
+<key name="custom"> 65, </key>
+<key name="cut"> 20,7,27,9,58,63,52, </key>
+<key name="cutgroup"> 58, </key>
+<key name="cyl"> 9,75, </key>
+<key name="cylind"> 9,75, </key>
+<key name="d"> 20, </key>
+<key name="data"> 64, </key>
+<key name="dd"> 63, </key>
+<key name="dea"> 32, </key>
+<key name="deal"> 15, </key>
+<key name="def"> 7,63,64, </key>
+<key name="default"> 0,24,13,58,65,67,74,77,54, </key>
+<key name="defin"> 15,16,1,20,21,5,6,24,7,25,26,9,13,62,63,65,38,66,68,69,64,73,44,75,76,54, </key>
+<key name="definit"> 15,17,20,22,23,26,27,61,39,40,50, </key>
+<key name="definition"> 0,20,7,13,34,65,35, </key>
+<key name="deflection"> 14,20,9,61, </key>
+<key name="deflection1d"> 9, </key>
+<key name="deform"> 54, </key>
+<key name="degre"> 21,6, </key>
+<key name="delet"> 10,57,63,40,74, </key>
+<key name="deletediag"> 63, </key>
+<key name="deletion"> 40,51, </key>
+<key name="density"> 20, </key>
+<key name="depend"> 14,15,24,34,35, </key>
+<key name="describ"> 15,16,0,66, </key>
+<key name="description"> 66, </key>
+<key name="desirabl"> 36, </key>
+<key name="desktop"> 43, </key>
+<key name="destin"> 15,17,61,64, </key>
+<key name="detail"> 14,16,0, </key>
+<key name="detalization"> 65, </key>
+<key name="detect"> 36, </key>
+<key name="dh"> 63, </key>
+<key name="di1"> 75, </key>
+<key name="diagonal"> 27,28,63,48, </key>
+<key name="dialog"> 18,1,20,5,22,24,25,8,27,28,29,31,12,13,32,60,36,62,66,69,40,41,72,42,44,46,47,49,50,51,52, </key>
+<key name="diamet"> 21, </key>
+<key name="dif"> 1,65, </key>
+<key name="differ"> 20, </key>
+<key name="differenc"> 13,44, </key>
+<key name="different"> 14,18,26,13,69,39,74,44, </key>
+<key name="digit"> 13, </key>
+<key name="dimension"> 15,2,24,12,65,72,73,53, </key>
+<key name="direct"> 15,7,44,46, </key>
+<key name="direction"> 13,66,55, </key>
+<key name="dirstruct"> 63,76, </key>
+<key name="discretisation"> 16, </key>
+<key name="discretiz"> 12,72, </key>
+<key name="discretization"> 15, </key>
+<key name="displac"> 29, </key>
+<key name="display"> 17,0,1,19,21,2,3,22,24,25,26,27,29,11,30,56,33,37,67,45,46,48,50,53,79,54,55, </key>
+<key name="distanc"> 20,6,66,54,55, </key>
+<key name="distinguish"> 26, </key>
+<key name="distortion"> 46, </key>
+<key name="distribution"> 20,71, </key>
+<key name="divid"> 20, </key>
+<key name="do"> 18, </key>
+<key name="docopy"> 76, </key>
+<key name="documentation"> 0,64, </key>
+<key name="doesn"> 73, </key>
+<key name="domain"> 66, </key>
+<key name="don"> 15,24,13,63,38,69,54, </key>
 <key name="doubl"> 1, </key>
-<key name="downward"> 53, </key>
-<key name="dr"> 61, </key>
-<key name="drag"> 53, </key>
-<key name="drawn"> 53, </key>
-<key name="dump"> 0,53, </key>
-<key name="duplicat"> 12, </key>
-<key name="dx"> 61, </key>
-<key name="dy"> 61, </key>
-<key name="e"> 20,23,24,26,12,63,64,66,69,43,49, </key>
-<key name="e_arc"> 8, </key>
-<key name="e_straight"> 8, </key>
-<key name="e1"> 61, </key>
-<key name="easi"> 22, </key>
-<key name="easy"> 62, </key>
-<key name="edg"> 13,14,15,16,0,17,1,19,20,3,4,22,23,6,25,26,8,27,28,10,12,55,56,57,58,33,32,60,61,63,37,64,66,67,68,71,43,45,73,49,50,75,54, </key>
-<key name="edge_"> 61, </key>
-<key name="edge_bezierrr"> 61, </key>
-<key name="edge_bezierrr_mesh"> 61, </key>
-<key name="edge_circl"> 61, </key>
-<key name="edge_circle_mesh"> 61, </key>
-<key name="edge_straight"> 61, </key>
-<key name="edge_straight_mesh"> 61, </key>
-<key name="edge1"> 73, </key>
-<key name="edgeslist"> 73, </key>
-<key name="edgex"> 6,8, </key>
-<key name="edit"> 6,9,30,57,35,38, </key>
-<key name="edition"> 62,72, </key>
-<key name="ee_1"> 61, </key>
-<key name="ee_2"> 61, </key>
-<key name="ee_3"> 61, </key>
-<key name="ee_4"> 61, </key>
-<key name="ee_5"> 61, </key>
-<key name="ee_6"> 61, </key>
-<key name="ee_7"> 61, </key>
-<key name="effect"> 49, </key>
-<key name="eith"> 64,66,43, </key>
-<key name="element"> 13,14,15,16,0,17,1,18,19,20,2,4,21,22,7,25,26,8,9,27,28,29,30,11,12,56,57,33,32,59,60,36,61,63,34,37,64,66,68,39,40,70,41,71,43,44,45,46,47,73,48,49,51,52,76,54, </key>
-<key name="els"> 6,8,61,64, </key>
-<key name="empty"> 61, </key>
-<key name="enabl"> 71, </key>
-<key name="encapsulat"> 24, </key>
-<key name="encounter"> 64, </key>
-<key name="end"> 13,19,8,60,37,71,43,48, </key>
-<key name="enough"> 43, </key>
-<key name="ent"> 25,27,28,31,50, </key>
-<key name="entiti"> 14,15, </key>
-<key name="entity"> 14,0,10,71, </key>
-<key name="equal"> 19,33,64,71,43,45, </key>
-<key name="equidistant"> 19, </key>
-<key name="equilateral"> 20, </key>
+<key name="downward"> 54, </key>
+<key name="dr"> 63, </key>
+<key name="drag"> 54, </key>
+<key name="drawn"> 54, </key>
+<key name="dump"> 0,54, </key>
+<key name="duplicat"> 13, </key>
+<key name="dx"> 63, </key>
+<key name="dy"> 63, </key>
+<key name="e"> 21,24,25,27,13,65,66,68,71,73,44,50, </key>
+<key name="e_arc"> 9, </key>
+<key name="e_straight"> 9, </key>
+<key name="e1"> 63, </key>
+<key name="easi"> 23, </key>
+<key name="easy"> 64, </key>
+<key name="edg"> 14,15,16,17,0,18,1,20,21,3,4,23,24,7,26,27,9,28,29,11,13,56,57,58,59,34,33,61,63,65,38,66,68,69,70,74,44,46,76,50,51,78,55, </key>
+<key name="edge_"> 63, </key>
+<key name="edge_bezierrr"> 63, </key>
+<key name="edge_bezierrr_mesh"> 63, </key>
+<key name="edge_circl"> 63, </key>
+<key name="edge_circle_mesh"> 63, </key>
+<key name="edge_straight"> 63, </key>
+<key name="edge_straight_mesh"> 63, </key>
+<key name="edge1"> 76, </key>
+<key name="edgeslist"> 76, </key>
+<key name="edgex"> 7,9, </key>
+<key name="edit"> 7,10,31,58,36,39, </key>
+<key name="edition"> 64,75, </key>
+<key name="ee_1"> 63, </key>
+<key name="ee_2"> 63, </key>
+<key name="ee_3"> 63, </key>
+<key name="ee_4"> 63, </key>
+<key name="ee_5"> 63, </key>
+<key name="ee_6"> 63, </key>
+<key name="ee_7"> 63, </key>
+<key name="effect"> 50, </key>
+<key name="eith"> 5,62,66,68,44, </key>
+<key name="element"> 14,15,16,17,0,18,1,19,20,21,2,4,5,22,23,8,26,27,9,10,28,29,30,31,12,13,57,58,34,33,60,61,37,63,65,35,38,66,68,70,40,41,72,42,73,74,44,45,46,47,48,76,49,50,52,53,79,55, </key>
+<key name="els"> 7,9,63,66, </key>
+<key name="empty"> 63, </key>
+<key name="enabl"> 74, </key>
+<key name="encapsulat"> 25, </key>
+<key name="encounter"> 66, </key>
+<key name="end"> 14,20,9,61,38,74,44,49, </key>
+<key name="enough"> 44, </key>
+<key name="ent"> 26,28,29,32,62,51, </key>
+<key name="entiti"> 15,16, </key>
+<key name="entity"> 15,0,11,74, </key>
+<key name="equal"> 20,34,66,74,44,46, </key>
+<key name="equidistant"> 20, </key>
+<key name="equilateral"> 21, </key>
 <key name="eras"> 0, </key>
-<key name="error"> 61, </key>
-<key name="etc"> 16,2,26,49, </key>
-<key name="even"> 23,33,63, </key>
-<key name="eventual"> 64, </key>
-<key name="every"> 54, </key>
-<key name="everyth"> 23, </key>
-<key name="ex21_lamp"> 72, </key>
-<key name="examin"> 12, </key>
-<key name="exampl"> 14,2,23,6,25,12,64,62,72,51, </key>
-<key name="exce"> 19, </key>
-<key name="exceed"> 45, </key>
-<key name="except"> 43,53, </key>
-<key name="exist"> 13,21,25,26,30,64,71,49, </key>
-<key name="existenc"> 23, </key>
-<key name="explod"> 61, </key>
-<key name="exponent"> 19, </key>
-<key name="export"> 0,6,31,60,53, </key>
-<key name="exportation"> 31, </key>
-<key name="exportm"> 6, </key>
-<key name="extend"> 53,54, </key>
-<key name="external"> 12, </key>
-<key name="extreme"> 19, </key>
-<key name="extremiti"> 5, </key>
-<key name="extrud"> 11,12,61,70, </key>
-<key name="extrusion"> 11,12,61,73, </key>
-<key name="extrusionalongpath"> 61,73, </key>
-<key name="extrusionsweepobject"> 61, </key>
-<key name="exy"> 8, </key>
-<key name="f"> 19,8, </key>
-<key name="f1"> 61, </key>
-<key name="f2"> 61, </key>
-<key name="f3"> 61, </key>
-<key name="f4"> 61, </key>
-<key name="f5"> 61, </key>
-<key name="fac"> 13,14,15,0,17,19,2,3,22,23,6,24,25,8,10,12,55,57,33,60,61,63,37,64,66,67,68,71,43,72,73,52,75,54, </key>
-<key name="face_1"> 61, </key>
-<key name="face_2"> 61, </key>
-<key name="face1"> 8,73, </key>
-<key name="face2"> 73, </key>
-<key name="facelist"> 68, </key>
-<key name="faceslist1"> 73, </key>
-<key name="faceslist2"> 73, </key>
-<key name="facesrotat"> 61, </key>
-<key name="factor"> 19,26, </key>
-<key name="factoryserv"> 62, </key>
-<key name="fail"> 61, </key>
-<key name="far"> 43, </key>
-<key name="fashion"> 12, </key>
-<key name="fast"> 45, </key>
-<key name="featur"> 25, </key>
-<key name="ff"> 61, </key>
-<key name="ff_1"> 61, </key>
-<key name="ff_2"> 61, </key>
-<key name="ff_3"> 61, </key>
-<key name="ff_4"> 61, </key>
-<key name="ff_5"> 61, </key>
-<key name="ff_6"> 61, </key>
-<key name="ff_7"> 61, </key>
-<key name="field"> 17,1,21,25,27,28,67,40,71,43,45,49,50, </key>
-<key name="fifth"> 43, </key>
-<key name="fil"> 6,31,64,71, </key>
-<key name="fill"> 68,69,40,43, </key>
-<key name="filt"> 21,25,26,71,49, </key>
-<key name="filter"> 25,71, </key>
-<key name="fin"> 19,63, </key>
-<key name="find"> 31,64,43, </key>
-<key name="findcoincidentnod"> 73, </key>
-<key name="findorloadcomponent"> 62, </key>
-<key name="finenes"> 19,63, </key>
-<key name="first"> 1,19,23,6,12,57,61,37,64,67,43, </key>
-<key name="firstnodeid1"> 73, </key>
-<key name="firstnodeid2"> 73, </key>
-<key name="firstnodeidonfreebord"> 73, </key>
-<key name="firstnodeidonsid"> 73, </key>
-<key name="fit"> 53, </key>
-<key name="fiv"> 61, </key>
-<key name="fix"> 14,6,8,45, </key>
-<key name="flag"> 64, </key>
-<key name="fold"> 23,24, </key>
-<key name="follow"> 13,14,17,1,2,21,23,24,7,25,26,27,28,29,30,11,12,35,61,64,67,39,40,70,41,43,45,46,48,49,50,51,52, </key>
-<key name="font"> 53, </key>
-<key name="form"> 1,27,30,64,43, </key>
-<key name="format"> 0,31,60,53, </key>
-<key name="formula"> 19,20,2, </key>
-<key name="four"> 14,20,54, </key>
-<key name="fourth"> 61, </key>
-<key name="fram"> 53, </key>
-<key name="fre"> 14,16,55,56,60,68,43,45,73, </key>
-<key name="ft_area"> 57,68, </key>
-<key name="ft_aspectratio"> 68, </key>
-<key name="ft_aspectratio3d"> 68, </key>
-<key name="ft_equalto"> 57,68, </key>
-<key name="ft_freeborder"> 68, </key>
-<key name="ft_length"> 68, </key>
-<key name="ft_length2d"> 68, </key>
-<key name="ft_lessthan"> 57,68, </key>
-<key name="ft_minimumangl"> 61,68, </key>
-<key name="ft_morethan"> 57,68, </key>
-<key name="ft_multiconnection"> 68, </key>
-<key name="ft_multiconnection2d"> 68, </key>
-<key name="ft_skew"> 68, </key>
-<key name="ft_tap"> 68, </key>
-<key name="ft_volume3d"> 68, </key>
-<key name="ft_warp"> 68, </key>
-<key name="full_netgen"> 8, </key>
-<key name="function"> 14,62, </key>
-<key name="functionaliti"> 53, </key>
-<key name="functionality"> 23,7,31,59,35,43,53, </key>
-<key name="fus"> 72, </key>
-<key name="futur"> 19, </key>
-<key name="g"> 24, </key>
-<key name="gaus"> 53, </key>
-<key name="generat"> 13,14,16,19,23,60,37,64, </key>
-<key name="generation"> 6,11,64,70,72, </key>
-<key name="geom"> 14,60, </key>
-<key name="geometric"> 14,16,8, </key>
-<key name="geometrical"> 13,14,15,19,23,24,25,33,60,34,64,67,38,41,45,46,48,52, </key>
-<key name="geometry"> 24,7,25,57,61,67,72,45, </key>
-<key name="geompy"> 6,8,57,61,68,72,73,75, </key>
-<key name="get"> 0,5,23,8,12,57,64,52, </key>
-<key name="getedgenearpoint"> 6,8, </key>
-<key name="geterrorcod"> 61, </key>
-<key name="getfilt"> 57,68, </key>
-<key name="getfreeborder"> 68, </key>
-<key name="getidsfromfilt"> 57,68, </key>
-<key name="getlistofid"> 57, </key>
-<key name="getmesh"> 6,61, </key>
-<key name="getnam"> 62, </key>
-<key name="getpattern"> 61, </key>
-<key name="ghs3d"> 62, </key>
-<key name="giv"> 71,52, </key>
-<key name="given"> 19,33,61,43, </key>
-<key name="global"> 8,53, </key>
-<key name="glu"> 68, </key>
-<key name="good"> 6,45, </key>
-<key name="got"> 64, </key>
-<key name="graduat"> 53, </key>
+<key name="error"> 63, </key>
+<key name="etc"> 17,2,27,50, </key>
+<key name="even"> 16,24,34,65, </key>
+<key name="eventual"> 66, </key>
+<key name="every"> 55, </key>
+<key name="everyth"> 24, </key>
+<key name="ex21_lamp"> 75, </key>
+<key name="examin"> 13, </key>
+<key name="exampl"> 15,2,5,24,7,26,13,66,64,75,52, </key>
+<key name="exce"> 20, </key>
+<key name="exceed"> 46, </key>
+<key name="except"> 44,54, </key>
+<key name="exist"> 14,5,22,26,27,31,62,66,74,50, </key>
+<key name="existenc"> 24, </key>
+<key name="explod"> 63, </key>
+<key name="exponent"> 20, </key>
+<key name="export"> 0,7,32,61,54, </key>
+<key name="exportation"> 32, </key>
+<key name="exportm"> 7, </key>
+<key name="extend"> 54,55, </key>
+<key name="external"> 13, </key>
+<key name="extreme"> 20, </key>
+<key name="extremiti"> 6, </key>
+<key name="extrud"> 12,13,63,72, </key>
+<key name="extrusion"> 12,13,63,76, </key>
+<key name="extrusionalongpath"> 63,76, </key>
+<key name="extrusionsweepobject"> 63, </key>
+<key name="exy"> 9, </key>
+<key name="f"> 20,9, </key>
+<key name="f1"> 63, </key>
+<key name="f2"> 63, </key>
+<key name="f3"> 63, </key>
+<key name="f4"> 63, </key>
+<key name="f5"> 63, </key>
+<key name="fac"> 14,15,16,0,18,20,2,3,23,24,7,25,26,9,11,13,56,58,34,61,63,65,38,66,68,69,70,74,44,75,76,53,78,55, </key>
+<key name="face_1"> 63, </key>
+<key name="face_2"> 63, </key>
+<key name="face1"> 9,76, </key>
+<key name="face2"> 76, </key>
+<key name="facelist"> 70, </key>
+<key name="faceslist1"> 76, </key>
+<key name="faceslist2"> 76, </key>
+<key name="facesrotat"> 63, </key>
+<key name="factor"> 20,27, </key>
+<key name="factoryserv"> 64, </key>
+<key name="fail"> 63, </key>
+<key name="far"> 44, </key>
+<key name="fashion"> 13, </key>
+<key name="fast"> 46, </key>
+<key name="featur"> 26, </key>
+<key name="ff"> 63, </key>
+<key name="ff_1"> 63, </key>
+<key name="ff_2"> 63, </key>
+<key name="ff_3"> 63, </key>
+<key name="ff_4"> 63, </key>
+<key name="ff_5"> 63, </key>
+<key name="ff_6"> 63, </key>
+<key name="ff_7"> 63, </key>
+<key name="field"> 18,1,22,26,28,29,69,41,74,44,46,50,51, </key>
+<key name="fifth"> 44, </key>
+<key name="fil"> 7,32,66,74, </key>
+<key name="fill"> 70,71,41,44, </key>
+<key name="filt"> 22,26,27,74,50, </key>
+<key name="filter"> 26,74, </key>
+<key name="fin"> 20,65, </key>
+<key name="find"> 32,63,66,44, </key>
+<key name="findcoincidentnod"> 76, </key>
+<key name="findnodeclosestto"> 63, </key>
+<key name="findorloadcomponent"> 64, </key>
+<key name="finenes"> 20,65, </key>
+<key name="first"> 1,20,24,7,13,58,63,38,66,69,44, </key>
+<key name="firstnodeid1"> 76, </key>
+<key name="firstnodeid2"> 76, </key>
+<key name="firstnodeidonfreebord"> 76, </key>
+<key name="firstnodeidonsid"> 76, </key>
+<key name="fit"> 54, </key>
+<key name="fiv"> 63, </key>
+<key name="fix"> 15,7,9,46, </key>
+<key name="flag"> 66, </key>
+<key name="fold"> 24,25, </key>
+<key name="follow"> 14,15,16,18,1,2,5,22,24,25,8,26,27,28,29,30,31,12,13,36,62,63,66,69,40,41,72,42,44,46,47,49,50,51,52,53, </key>
+<key name="font"> 54, </key>
+<key name="form"> 1,28,31,66,44, </key>
+<key name="format"> 0,32,61,54, </key>
+<key name="formula"> 20,21,2, </key>
+<key name="four"> 15,21,55, </key>
+<key name="fourth"> 63, </key>
+<key name="fram"> 54, </key>
+<key name="fre"> 15,17,56,57,61,70,44,46,76, </key>
+<key name="ft_area"> 58,70, </key>
+<key name="ft_aspectratio"> 70, </key>
+<key name="ft_aspectratio3d"> 70, </key>
+<key name="ft_equalto"> 58,70, </key>
+<key name="ft_freeborder"> 70, </key>
+<key name="ft_length"> 70, </key>
+<key name="ft_length2d"> 70, </key>
+<key name="ft_lessthan"> 58,70, </key>
+<key name="ft_minimumangl"> 63,70, </key>
+<key name="ft_morethan"> 58,70, </key>
+<key name="ft_multiconnection"> 70, </key>
+<key name="ft_multiconnection2d"> 70, </key>
+<key name="ft_skew"> 70, </key>
+<key name="ft_tap"> 70, </key>
+<key name="ft_volume3d"> 70, </key>
+<key name="ft_warp"> 70, </key>
+<key name="full_netgen"> 9, </key>
+<key name="function"> 15,63,64, </key>
+<key name="functionaliti"> 54, </key>
+<key name="functionality"> 24,8,32,60,36,44,54, </key>
+<key name="fus"> 75, </key>
+<key name="futur"> 20, </key>
+<key name="g"> 25, </key>
+<key name="gaus"> 54, </key>
+<key name="generat"> 14,15,17,20,24,61,38,66, </key>
+<key name="generation"> 7,12,66,72,75, </key>
+<key name="geom"> 15,61, </key>
+<key name="geometric"> 15,17,9, </key>
+<key name="geometrical"> 14,15,16,20,24,25,26,34,61,35,66,69,39,42,46,47,49,53, </key>
+<key name="geometry"> 25,8,26,58,63,69,75,46, </key>
+<key name="geompy"> 7,9,58,63,70,75,76,78, </key>
+<key name="get"> 0,6,24,9,13,58,66,53, </key>
+<key name="getedgenearpoint"> 7,9, </key>
+<key name="geterrorcod"> 63, </key>
+<key name="getfilt"> 58,70, </key>
+<key name="getfreeborder"> 70, </key>
+<key name="getidsfromfilt"> 58,70, </key>
+<key name="getlistofid"> 58, </key>
+<key name="getmesh"> 7,63, </key>
+<key name="getnam"> 64, </key>
+<key name="getnodexyz"> 63, </key>
+<key name="getpattern"> 63, </key>
+<key name="getsubmeshnodesid"> 63, </key>
+<key name="ghs3d"> 64, </key>
+<key name="giv"> 74,53, </key>
+<key name="given"> 20,34,63,44, </key>
+<key name="global"> 9,54, </key>
+<key name="glu"> 70, </key>
+<key name="good"> 7,46, </key>
+<key name="got"> 66, </key>
+<key name="graduat"> 54, </key>
 <key name="graphical"> 0, </key>
-<key name="great"> 19,53, </key>
-<key name="greatest"> 20,2, </key>
-<key name="green"> 25,12, </key>
-<key name="group"> 21,22,25,26,9,30,12,57,35,60,61,68,71,72,45,48,49,51,52, </key>
-<key name="group_nam"> 72, </key>
-<key name="group1"> 51, </key>
-<key name="group12"> 51, </key>
-<key name="group12a"> 51, </key>
-<key name="group12b"> 51, </key>
-<key name="group2"> 51, </key>
-<key name="groupongeom"> 57,61, </key>
-<key name="grouprotat"> 61, </key>
-<key name="groupsmooth"> 61, </key>
-<key name="groupsofnod"> 73, </key>
-<key name="grouptri"> 61, </key>
-<key name="growth"> 63, </key>
-<key name="h"> 54, </key>
-<key name="half"> 20,54, </key>
-<key name="halv"> 5, </key>
-<key name="hasangl"> 61, </key>
-<key name="hasrefpoint"> 61, </key>
-<key name="hav"> 20,33,37,64,66, </key>
-<key name="hedron"> 61, </key>
-<key name="height"> 72,54, </key>
-<key name="helical"> 12, </key>
-<key name="help"> 16, </key>
-<key name="henc"> 64, </key>
-<key name="her"> 64, </key>
-<key name="hexa"> 8, </key>
-<key name="hexahedral"> 15,6,8, </key>
-<key name="hexahedralization"> 23, </key>
-<key name="hexahedrical"> 8, </key>
-<key name="hexahedron"> 14,15,17,2,8,61,34,66,75, </key>
-<key name="hh"> 61, </key>
-<key name="hid"> 0,53, </key>
-<key name="high"> 14, </key>
-<key name="highlight"> 3,4,21,25,26,55,56,49, </key>
-<key name="hmax"> 20, </key>
-<key name="hol"> 56,61, </key>
-<key name="hold"> 64, </key>
-<key name="hollow"> 69, </key>
-<key name="homogeneou"> 63, </key>
-<key name="how"> 15,12,63,38, </key>
-<key name="hyp"> 24,61, </key>
-<key name="hyp1"> 6, </key>
-<key name="hyp2"> 6, </key>
-<key name="hyp3"> 6, </key>
-<key name="hyp4"> 6, </key>
-<key name="hypothes"> 13,0,19,23,6,24,8,33,60,63,37,69,38, </key>
-<key name="hypothesi"> 13,19,23,6,8,33,61,34,37,38,72, </key>
-<key name="i"> 15,20,23,26,12,57,31,61,63,64,66,68,69,43,49, </key>
-<key name="icon"> 30,39,42, </key>
-<key name="id"> 0,19,21,25,26,27,28,29,11,12,57,61,70,43,45,49,50, </key>
-<key name="id_circl"> 73, </key>
-<key name="id_fac"> 8, </key>
-<key name="id_face1"> 73, </key>
-<key name="idbox"> 6,68, </key>
-<key name="idea"> 12, </key>
-<key name="idl"> 6, </key>
-<key name="idsofelement"> 61, </key>
-<key name="idsoffixednod"> 61, </key>
-<key name="idsofside1element"> 73, </key>
-<key name="idsofside2element"> 73, </key>
-<key name="if"> 14,17,5,23,6,24,7,8,11,12,57,33,61,63,37,64,67,68,38,39,70,71,43,45,49,53, </key>
-<key name="ii"> 61, </key>
-<key name="imag"> 0,12,53, </key>
-<key name="imp"> 14, </key>
-<key name="import"> 6,8,57,31,60,61,68,72,73,75, </key>
-<key name="importation"> 31, </key>
-<key name="in"> 69, </key>
-<key name="includ"> 14,52, </key>
-<key name="increas"> 6,8, </key>
-<key name="index"> 25,64, </key>
-<key name="indic"> 64, </key>
-<key name="indicat"> 67,54, </key>
-<key name="info"> 0,52,75, </key>
-<key name="information"> 14,0,6,7,30,69,52,75, </key>
-<key name="initial"> 12,61,71,46,51, </key>
-<key name="input"> 1,19, </key>
-<key name="inscrib"> 20, </key>
-<key name="insert"> 71,43, </key>
-<key name="instead"> 6,37,64, </key>
-<key name="int"> 62, </key>
-<key name="intact"> 9, </key>
-<key name="integ"> 25, </key>
-<key name="intend"> 43, </key>
-<key name="interest"> 14, </key>
-<key name="interfac"> 6,72, </key>
-<key name="intermediat"> 43, </key>
-<key name="internal"> 64,69, </key>
-<key name="intersect"> 64,51, </key>
-<key name="intersectgroup"> 57, </key>
-<key name="intersection"> 57,64,69,51, </key>
-<key name="introduc"> 13,25,37, </key>
-<key name="introduction"> 60,72, </key>
-<key name="invers"> 14,27,61, </key>
-<key name="inversediag"> 61, </key>
-<key name="inversion"> 27,61, </key>
-<key name="invisibl"> 74, </key>
-<key name="isdon"> 61, </key>
-<key name="iso"> 64, </key>
-<key name="isolin"> 64, </key>
-<key name="isometric"> 53, </key>
-<key name="isplanarfac"> 8,73, </key>
-<key name="item"> 17,1,21,22,7,26,27,28,30,11,12,31,35,64,40,70,41,43,45,46,48,49,50,51, </key>
-<key name="iteration"> 12,45, </key>
-<key name="iterativ"> 45, </key>
-<key name="iv"> 61, </key>
-<key name="j"> 15,57,68, </key>
-<key name="join"> 44, </key>
-<key name="jpeg"> 0,53, </key>
-<key name="jpg"> 0,53, </key>
-<key name="just"> 1,64,39, </key>
-<key name="k"> 15,19,20, </key>
-<key name="keep"> 12,45,46, </key>
-<key name="key"> 64, </key>
-<key name="keyboard"> 26, </key>
-<key name="know"> 64, </key>
-<key name="ko"> 61, </key>
-<key name="l"> 54, </key>
-<key name="label"> 53, </key>
-<key name="laplacian"> 45, </key>
-<key name="last"> 1,19,12,37,43, </key>
-<key name="lastnodeid1"> 73, </key>
-<key name="lastnodeid2"> 73, </key>
-<key name="lastnodeidonfreebord"> 73, </key>
-<key name="lastnodeidonsid"> 73, </key>
-<key name="lay"> 11,64,70, </key>
-<key name="layer"> 69, </key>
-<key name="lcc"> 62, </key>
-<key name="learn"> 52, </key>
-<key name="least"> 64,45, </key>
-<key name="leav"> 23,9, </key>
-<key name="left"> 0,12,64,53, </key>
-<key name="len"> 57,61,68, </key>
-<key name="length"> 13,16,19,20,6,8,58,33,32,60,68,43,53,54, </key>
-<key name="length_margin"> 68, </key>
-<key name="lengthfromedg"> 8,72,73, </key>
-<key name="les"> 71,43,45, </key>
-<key name="level"> 13,17,63, </key>
-<key name="library"> 25,71, </key>
-<key name="lik"> 17,2,29,43, </key>
-<key name="limit"> 64,43,45, </key>
-<key name="limitation"> 67, </key>
-<key name="lin"> 14,1,19,11,37,64,70,44, </key>
-<key name="linear"> 12,63, </key>
-<key name="link"> 43, </key>
-<key name="list"> 0,17,21,25,26,9,12,67,71,49, </key>
-<key name="lk"> 19, </key>
-<key name="ll"> 53, </key>
-<key name="load"> 64,71, </key>
-<key name="loadfromfac"> 61, </key>
-<key name="local"> 6,24,8,60,37, </key>
-<key name="locallength"> 8,72, </key>
-<key name="locat"> 64,43,53, </key>
-<key name="location"> 19,28,31,45, </key>
-<key name="lock"> 26,45,53, </key>
-<key name="longest"> 20, </key>
-<key name="look"> 29,12,64,71, </key>
-<key name="low"> 14,19,63, </key>
-<key name="ly"> 64, </key>
-<key name="main"> 21,26,9,12,37,64,71,49,51, </key>
-<key name="makearc"> 8,73, </key>
-<key name="makebezi"> 61, </key>
-<key name="makebox"> 6,57,68,72,73,75, </key>
-<key name="makeboxdxdydz"> 6,8,61, </key>
-<key name="makecirclethreepnt"> 61,73, </key>
-<key name="makecompound"> 68,73, </key>
-<key name="makecon"> 72, </key>
-<key name="makecylind"> 72, </key>
-<key name="makecylinderrh"> 8, </key>
-<key name="makeedg"> 8,61, </key>
-<key name="makefac"> 8,73, </key>
-<key name="makefus"> 72, </key>
-<key name="makegluefac"> 68, </key>
-<key name="makegroupbyid"> 57, </key>
-<key name="makemesh"> 61, </key>
-<key name="makepolygon"> 61, </key>
-<key name="makepolylin"> 61, </key>
-<key name="makequadmesh2"> 61, </key>
-<key name="makeshell"> 68, </key>
-<key name="makesketch"> 8, </key>
-<key name="maketranslation"> 68, </key>
-<key name="makevector"> 8,73, </key>
-<key name="makevectordxdydz"> 72, </key>
-<key name="makevertex"> 6,8,61,72,73, </key>
-<key name="makewir"> 8,73, </key>
-<key name="manag"> 13,17, </key>
-<key name="manual"> 25,63,64,53, </key>
-<key name="map"> 15,33,61,64, </key>
-<key name="mark"> 53, </key>
-<key name="mas"> 12, </key>
-<key name="math"> 61,73, </key>
-<key name="max"> 13,8,33,60,63,34,45, </key>
-<key name="maxaspectratio"> 61, </key>
-<key name="maxelementarea"> 6,8,61,68,75, </key>
-<key name="maxelementvolum"> 6,8,72,75, </key>
-<key name="maximum"> 19,8,33,63,34,44,45,52, </key>
-<key name="maxnbofiteration"> 61, </key>
-<key name="mean"> 14,63, </key>
-<key name="meaningful"> 14, </key>
-<key name="measur"> 54, </key>
-<key name="medium"> 7, </key>
-<key name="meet"> 26,49, </key>
-<key name="mefisto"> 15,8, </key>
-<key name="menu"> 17,1,19,21,5,22,23,24,7,25,26,9,27,28,29,30,11,12,31,35,37,64,67,39,40,70,41,42,71,43,45,46,48,49,50,51,52, </key>
-<key name="merg"> 59,35,43,73, </key>
-<key name="mergeequalelement"> 73, </key>
-<key name="mergenod"> 73, </key>
-<key name="mesh"> 13,14,15,16,0,17,1,18,19,20,2,3,4,21,5,22,23,6,24,7,25,26,8,9,27,28,29,30,11,12,55,56,57,31,33,32,59,35,60,36,61,63,34,37,64,65,66,67,68,69,38,39,40,70,41,42,62,71,43,44,72,45,46,47,73,48,49,50,51,52,75,76,53,54, </key>
-<key name="mesh_1"> 23,61, </key>
-<key name="mesh_2"> 61, </key>
-<key name="mesh_borders_at_multi"> 68, </key>
-<key name="mesh_free_border"> 68, </key>
-<key name="mesh_length_1d"> 68, </key>
-<key name="mesh_length_2d"> 68, </key>
-<key name="mesh_nam"> 61, </key>
-<key name="mesh1d"> 61, </key>
-<key name="mesh1d_tool"> 61, </key>
-<key name="meshbox"> 6,75, </key>
-<key name="mesheditor"> 61, </key>
-<key name="meshm"> 6, </key>
-<key name="method"> 61,45, </key>
-<key name="middl"> 1,12,37, </key>
-<key name="min_angl"> 68, </key>
-<key name="minimum"> 16,19,26,60,36,63,68,43,49, </key>
-<key name="mirror"> 73, </key>
-<key name="mod"> 0,19,65, </key>
-<key name="model"> 14,60, </key>
-<key name="modification"> 14,17,1,21,7,26,27,28,30,11,12,35,60,64,39,40,70,41,43,45,46,48,49,50, </key>
-<key name="modify"> 21,26,30,61,49, </key>
-<key name="modul"> 14,15,1,19,6,25,60,42,72,53, </key>
-<key name="mous"> 0,25,53, </key>
-<key name="mov"> 28,61, </key>
-<key name="movenod"> 61, </key>
-<key name="much"> 63, </key>
-<key name="multi"> 16,3,4,60,68, </key>
-<key name="multiconnection"> 68, </key>
-<key name="must"> 23,12,64,71,43, </key>
-<key name="myelemid"> 68, </key>
-<key name="mypnt1"> 68, </key>
-<key name="mypnt2"> 68, </key>
-<key name="n"> 64,43, </key>
-<key name="n1"> 61, </key>
-<key name="n10"> 61, </key>
-<key name="n11"> 61, </key>
-<key name="n12"> 61, </key>
-<key name="n2"> 61, </key>
-<key name="n23_param"> 8, </key>
-<key name="n3"> 61, </key>
-<key name="n4"> 61, </key>
-<key name="n5"> 61, </key>
-<key name="n6"> 61, </key>
-<key name="n7"> 61, </key>
-<key name="n8"> 61, </key>
-<key name="n9"> 61, </key>
-<key name="na"> 61, </key>
-<key name="nam"> 23,6,24,25,30,57,31,61,63,67,62,71,72,51,53, </key>
-<key name="nb"> 57,61,63,68, </key>
-<key name="nb_conn"> 68, </key>
-<key name="nb_vert"> 61, </key>
-<key name="nbedg"> 6,73,75, </key>
-<key name="nbfac"> 6,75, </key>
-<key name="nbhexa"> 75, </key>
-<key name="nbnod"> 6,73,75, </key>
-<key name="nbpolygon"> 75, </key>
-<key name="nbpolyhedron"> 75, </key>
-<key name="nbprism"> 75, </key>
-<key name="nbpyramid"> 75, </key>
-<key name="nbquadrangl"> 73,75, </key>
-<key name="nbseg"> 61, </key>
-<key name="nbtetra"> 75, </key>
-<key name="nbtriangl"> 73,75, </key>
-<key name="nbvolum"> 6,73,75, </key>
-<key name="nc"> 61, </key>
-<key name="nd"> 61, </key>
-<key name="ndiagonal"> 61, </key>
-<key name="ne"> 23, </key>
-<key name="necessary"> 17,67, </key>
-<key name="need"> 69, </key>
-<key name="negativ"> 19, </key>
-<key name="neighbor"> 27,50, </key>
-<key name="netgen"> 15,6,8,63,62,72,75, </key>
-<key name="netgen_2d3d"> 8, </key>
-<key name="new"> 0,5,23,24,25,28,61,64,38,71,51, </key>
-<key name="new_id"> 61, </key>
-<key name="next"> 19,64, </key>
-<key name="nid"> 61, </key>
-<key name="nid1"> 61, </key>
-<key name="nid2"> 61, </key>
-<key name="nid3"> 61, </key>
-<key name="nid4"> 61, </key>
-<key name="no_nam"> 62, </key>
-<key name="nod"> 14,0,17,1,18,19,20,21,22,6,7,25,28,29,11,12,33,35,60,61,63,64,65,68,39,40,70,71,43,44,45,47,73,52,75,54, </key>
-<key name="nodal"> 64,45, </key>
-<key name="node_id"> 61, </key>
-<key name="nodeid1ofside1tomerg"> 73, </key>
-<key name="nodeid1ofside2tomerg"> 73, </key>
-<key name="nodeid2ofside1tomerg"> 73, </key>
-<key name="nodeid2ofside2tomerg"> 73, </key>
-<key name="nodestart"> 61, </key>
-<key name="non"> 23, </key>
-<key name="nonam"> 62, </key>
-<key name="normal"> 46,54, </key>
-<key name="normalisation"> 20, </key>
-<key name="not"> 17,20,23,25,9,12, </key>
-<key name="noth"> 25, </key>
-<key name="notic"> 14, </key>
-<key name="now"> 5,23, </key>
-<key name="nsmooth"> 61, </key>
-<key name="numb"> 13,14,15,1,19,6,25,8,11,33,60,63,64,66,69,70,43,45,73,52,75,53, </key>
-<key name="number"> 0,1,29,12, </key>
-<key name="numberofsegment"> 6,8,57,61,68,73,75, </key>
-<key name="numeric"> 26, </key>
-<key name="numerical"> 13, </key>
-<key name="nunit"> 61, </key>
-<key name="obey"> 43, </key>
-<key name="obj"> 62, </key>
-<key name="object"> 13,15,0,17,1,19,5,22,23,24,7,25,26,9,30,31,33,61,63,34,64,65,67,38,39,40,41,48,49,52,76,53, </key>
-<key name="objet"> 25, </key>
-<key name="obtain"> 17,68, </key>
-<key name="offset"> 53, </key>
-<key name="ok"> 17,1,21,5,7,26,9,27,28,30,11,12,31,61,39,40,70,43,45,49,50,51, </key>
-<key name="on"> 14,1,19,23,6,24,26,8,9,27,11,12,55,56,59,61,37,64,68,69,38,39,70,71,43,45,46,48,49,51, </key>
-<key name="onc"> 49, </key>
-<key name="onto"> 37,64, </key>
-<key name="oo"> 20, </key>
-<key name="opaqu"> 74, </key>
-<key name="open"> 68, </key>
-<key name="operat"> 13, </key>
-<key name="operation"> 15,17,18,19,20,2,3,4,21,24,25,26,9,27,28,30,11,12,55,56,31,58,33,32,59,35,60,36,34,37,64,38,39,40,70,41,43,44,45,46,47,48,49,50,51,76,54, </key>
-<key name="oppos"> 66, </key>
-<key name="opposit"> 13,5,6,26,8,33,37,43,44, </key>
-<key name="optimiz"> 63, </key>
-<key name="option"> 14,0,19,46,48, </key>
-<key name="optional"> 23,12,67, </key>
-<key name="ord"> 14,21,63,64, </key>
-<key name="ordinary"> 1,37, </key>
-<key name="orientat"> 53, </key>
-<key name="orientation"> 21,5,26,61,67,49, </key>
-<key name="origin"> 53,54, </key>
-<key name="other"> 49, </key>
-<key name="otherwis"> 23,33, </key>
-<key name="our"> 23, </key>
-<key name="out"> 69,53, </key>
-<key name="outlin"> 56, </key>
-<key name="outsid"> 64, </key>
-<key name="own"> 14, </key>
-<key name="p5"> 6,8, </key>
-<key name="packag"> 6,62,72, </key>
-<key name="pag"> 15,25,30, </key>
-<key name="pair"> 19, </key>
-<key name="pan"> 53, </key>
-<key name="paramet"> 14,19,2,71,43, </key>
-<key name="parameter"> 13,0,5,8,12,63,41,43,53, </key>
-<key name="parametric"> 14,64, </key>
-<key name="parent"> 24, </key>
-<key name="part"> 61,43,45,53, </key>
-<key name="particularity"> 14, </key>
-<key name="pas"> 6,57,61,68, </key>
-<key name="path"> 12,61,71,73, </key>
-<key name="pathmesh"> 61, </key>
-<key name="pathshap"> 61, </key>
-<key name="pattern"> 61,64, </key>
-<key name="pattern_nam"> 64, </key>
-<key name="pentagonal"> 61, </key>
+<key name="great"> 20,54, </key>
+<key name="greatest"> 21,2, </key>
+<key name="green"> 26,13, </key>
+<key name="group"> 5,22,23,26,27,10,31,13,58,36,61,63,70,74,75,46,49,50,52,53, </key>
+<key name="group_nam"> 75, </key>
+<key name="group1"> 5,52, </key>
+<key name="group1_1"> 5, </key>
+<key name="group1_2"> 5, </key>
+<key name="group12"> 52, </key>
+<key name="group12a"> 52, </key>
+<key name="group12b"> 52, </key>
+<key name="group2"> 52, </key>
+<key name="groupongeom"> 58,63, </key>
+<key name="grouprotat"> 63, </key>
+<key name="groupsmooth"> 63, </key>
+<key name="groupsofnod"> 76, </key>
+<key name="grouptri"> 63, </key>
+<key name="growth"> 65, </key>
+<key name="gui"> 0, </key>
+<key name="h"> 55, </key>
+<key name="half"> 21,55, </key>
+<key name="halv"> 6, </key>
+<key name="hasangl"> 63, </key>
+<key name="hasrefpoint"> 63, </key>
+<key name="hav"> 21,34,38,66,68, </key>
+<key name="hedron"> 63, </key>
+<key name="height"> 75,55, </key>
+<key name="helical"> 13, </key>
+<key name="help"> 17, </key>
+<key name="henc"> 66, </key>
+<key name="her"> 66, </key>
+<key name="hexa"> 9, </key>
+<key name="hexahedral"> 16,7,9, </key>
+<key name="hexahedralization"> 24, </key>
+<key name="hexahedrical"> 9, </key>
+<key name="hexahedron"> 15,16,18,2,9,63,35,68,78, </key>
+<key name="hh"> 63, </key>
+<key name="hid"> 0,54, </key>
+<key name="high"> 15,73, </key>
+<key name="highlight"> 3,4,22,26,27,56,57,50, </key>
+<key name="hmax"> 21, </key>
+<key name="hol"> 57,63, </key>
+<key name="hold"> 5,66, </key>
+<key name="hollow"> 71, </key>
+<key name="homogeneou"> 65, </key>
+<key name="how"> 16,13,65,39, </key>
+<key name="hyp"> 25,63, </key>
+<key name="hyp1"> 7, </key>
+<key name="hyp2"> 7, </key>
+<key name="hyp3"> 7, </key>
+<key name="hyp4"> 7, </key>
+<key name="hypothes"> 14,16,0,20,24,7,25,9,34,61,65,38,71,39, </key>
+<key name="hypothesi"> 14,16,20,24,7,9,34,63,35,38,39,73,75, </key>
+<key name="i"> 16,21,24,27,13,58,32,63,65,66,68,70,71,73,44,50, </key>
+<key name="icon"> 31,40,43, </key>
+<key name="id"> 0,20,22,26,27,28,29,30,12,13,58,63,72,44,46,50,51, </key>
+<key name="id_circl"> 76, </key>
+<key name="id_fac"> 9, </key>
+<key name="id_face1"> 76, </key>
+<key name="idbox"> 7,70, </key>
+<key name="idea"> 13, </key>
+<key name="identical"> 5, </key>
+<key name="idl"> 7, </key>
+<key name="idsofelement"> 63, </key>
+<key name="idsoffixednod"> 63, </key>
+<key name="idsofside1element"> 76, </key>
+<key name="idsofside2element"> 76, </key>
+<key name="if"> 15,16,18,6,24,7,25,8,9,12,13,58,34,63,65,38,66,69,70,39,40,72,73,74,44,46,50,54, </key>
+<key name="ii"> 63, </key>
+<key name="imag"> 0,13,54, </key>
+<key name="imp"> 15, </key>
+<key name="implementation"> 73, </key>
+<key name="import"> 7,9,58,32,61,63,70,75,76,78, </key>
+<key name="importation"> 32, </key>
+<key name="in"> 71, </key>
+<key name="includ"> 15,53, </key>
+<key name="increas"> 7,9, </key>
+<key name="index"> 26,66, </key>
+<key name="indic"> 66, </key>
+<key name="indicat"> 62,69,55, </key>
+<key name="info"> 0,53,78, </key>
+<key name="information"> 15,0,5,7,8,31,71,53,78, </key>
+<key name="initial"> 13,63,74,47,52, </key>
+<key name="input"> 1,20, </key>
+<key name="inscrib"> 21, </key>
+<key name="insert"> 74,44, </key>
+<key name="insid"> 63, </key>
+<key name="instead"> 7,38,66, </key>
+<key name="int"> 64, </key>
+<key name="intact"> 10, </key>
+<key name="integ"> 26, </key>
+<key name="intend"> 44, </key>
+<key name="interest"> 15, </key>
+<key name="interfac"> 7,75, </key>
+<key name="intermediat"> 44, </key>
+<key name="internal"> 66,71, </key>
+<key name="intersect"> 66,52, </key>
+<key name="intersectgroup"> 58, </key>
+<key name="intersection"> 58,66,71,52, </key>
+<key name="introduc"> 14,26,38, </key>
+<key name="introduction"> 61,75, </key>
+<key name="invers"> 15,28,63, </key>
+<key name="inversediag"> 63, </key>
+<key name="inversion"> 28,63, </key>
+<key name="invisibl"> 77, </key>
+<key name="isdon"> 63, </key>
+<key name="iso"> 66, </key>
+<key name="isolin"> 66, </key>
+<key name="isometric"> 54, </key>
+<key name="isplanarfac"> 9,76, </key>
+<key name="item"> 18,1,22,23,8,27,28,29,31,12,13,32,36,62,66,41,72,42,44,46,47,49,50,51,52, </key>
+<key name="iteration"> 13,46, </key>
+<key name="iterativ"> 46, </key>
+<key name="iv"> 63, </key>
+<key name="j"> 16,58,70, </key>
+<key name="join"> 45, </key>
+<key name="jpeg"> 0,54, </key>
+<key name="jpg"> 0,54, </key>
+<key name="just"> 1,66,40, </key>
+<key name="k"> 16,20,21, </key>
+<key name="keep"> 13,46,47, </key>
+<key name="key"> 66, </key>
+<key name="keyboard"> 27, </key>
+<key name="know"> 66, </key>
+<key name="ko"> 63, </key>
+<key name="l"> 55, </key>
+<key name="label"> 54, </key>
+<key name="laplacian"> 46, </key>
+<key name="last"> 1,20,13,38,44, </key>
+<key name="lastnodeid1"> 76, </key>
+<key name="lastnodeid2"> 76, </key>
+<key name="lastnodeidonfreebord"> 76, </key>
+<key name="lastnodeidonsid"> 76, </key>
+<key name="lat"> 62, </key>
+<key name="lay"> 12,66,72, </key>
+<key name="layer"> 71, </key>
+<key name="lcc"> 64, </key>
+<key name="learn"> 53, </key>
+<key name="least"> 66,46, </key>
+<key name="leav"> 24,10, </key>
+<key name="left"> 0,13,66,54, </key>
+<key name="len"> 58,63,70, </key>
+<key name="length"> 14,17,20,21,7,9,59,34,33,61,70,44,54,55, </key>
+<key name="length_margin"> 70, </key>
+<key name="lengthfromedg"> 9,75,76, </key>
+<key name="les"> 74,44,46, </key>
+<key name="level"> 14,18,65, </key>
+<key name="library"> 26,74, </key>
+<key name="lik"> 18,2,30,44, </key>
+<key name="limit"> 66,44,46, </key>
+<key name="limitation"> 69, </key>
+<key name="lin"> 15,1,20,12,38,66,72,45, </key>
+<key name="linear"> 13,65, </key>
+<key name="link"> 44, </key>
+<key name="list"> 0,18,22,26,27,10,13,69,74,50, </key>
+<key name="lk"> 20, </key>
+<key name="ll"> 54, </key>
+<key name="load"> 66,74, </key>
+<key name="loadfromfac"> 63, </key>
+<key name="local"> 7,25,9,61,38,73, </key>
+<key name="locallength"> 9,75, </key>
+<key name="locat"> 66,44,54, </key>
+<key name="location"> 20,29,32,63,46, </key>
+<key name="lock"> 27,46,54, </key>
+<key name="longest"> 21, </key>
+<key name="look"> 30,13,66,74, </key>
+<key name="low"> 15,20,65, </key>
+<key name="ly"> 66, </key>
+<key name="main"> 16,22,27,10,13,38,66,74,50,52, </key>
+<key name="makearc"> 9,76, </key>
+<key name="makebezi"> 63, </key>
+<key name="makebox"> 7,58,70,75,76,78, </key>
+<key name="makeboxdxdydz"> 7,9,63, </key>
+<key name="makecirclethreepnt"> 63,76, </key>
+<key name="makecompound"> 70,76, </key>
+<key name="makecon"> 75, </key>
+<key name="makecylind"> 75, </key>
+<key name="makecylinderrh"> 9, </key>
+<key name="makeedg"> 9,63, </key>
+<key name="makefac"> 9,76, </key>
+<key name="makefus"> 75, </key>
+<key name="makegluefac"> 70, </key>
+<key name="makegroupbyid"> 58, </key>
+<key name="makemesh"> 63, </key>
+<key name="makepolygon"> 63, </key>
+<key name="makepolylin"> 63, </key>
+<key name="makequadmesh2"> 63, </key>
+<key name="makeshell"> 70, </key>
+<key name="makesketch"> 9, </key>
+<key name="maketranslation"> 70, </key>
+<key name="makevector"> 9,76, </key>
+<key name="makevectordxdydz"> 75, </key>
+<key name="makevertex"> 7,9,63,75,76, </key>
+<key name="makewir"> 9,76, </key>
+<key name="manag"> 14,18, </key>
+<key name="manual"> 26,62,65,66,54, </key>
+<key name="map"> 16,34,63,66, </key>
+<key name="mark"> 54, </key>
+<key name="mas"> 13, </key>
+<key name="math"> 63,76, </key>
+<key name="max"> 14,9,34,61,65,35,46, </key>
+<key name="maxaspectratio"> 63, </key>
+<key name="maxelementarea"> 7,9,63,70,78, </key>
+<key name="maxelementvolum"> 7,9,75,78, </key>
+<key name="maximum"> 20,9,34,65,35,45,46,53, </key>
+<key name="maxnbofiteration"> 63, </key>
+<key name="mean"> 15,65, </key>
+<key name="meaningful"> 15, </key>
+<key name="measur"> 55, </key>
+<key name="medium"> 8, </key>
+<key name="meet"> 27,50, </key>
+<key name="mefisto"> 16,9, </key>
+<key name="menu"> 18,1,20,5,22,6,23,24,25,8,26,27,10,28,29,30,31,12,13,32,36,62,38,66,69,40,41,72,42,43,74,44,46,47,49,50,51,52,53, </key>
+<key name="merg"> 5,60,36,44,76, </key>
+<key name="mergeequalelement"> 76, </key>
+<key name="mergenod"> 76, </key>
+<key name="mesh"> 14,15,16,17,0,18,1,19,20,21,2,3,4,5,22,6,23,24,7,25,8,26,27,9,10,28,29,30,31,12,13,56,57,58,32,34,33,60,36,61,62,37,63,65,35,38,66,67,68,69,70,71,39,40,41,72,42,43,64,73,74,44,45,75,46,47,48,76,49,50,51,52,53,78,79,54,55, </key>
+<key name="mesh_1"> 5,24,63, </key>
+<key name="mesh_2"> 5,63, </key>
+<key name="mesh_borders_at_multi"> 70, </key>
+<key name="mesh_free_border"> 70, </key>
+<key name="mesh_length_1d"> 70, </key>
+<key name="mesh_length_2d"> 70, </key>
+<key name="mesh_nam"> 63, </key>
+<key name="mesh1d"> 63, </key>
+<key name="mesh1d_tool"> 63, </key>
+<key name="meshbox"> 7,78, </key>
+<key name="mesheditor"> 63, </key>
+<key name="meshm"> 7, </key>
+<key name="meshtopassthroughapoint"> 63, </key>
+<key name="method"> 5,62,63,46, </key>
+<key name="middl"> 1,13,38, </key>
+<key name="min_angl"> 70, </key>
+<key name="minimum"> 17,20,27,61,37,65,70,44,50, </key>
+<key name="mirror"> 76, </key>
+<key name="mod"> 0,20,67, </key>
+<key name="model"> 15,61, </key>
+<key name="modification"> 15,18,1,22,8,27,28,29,31,12,13,36,61,62,66,40,41,72,42,44,46,47,49,50,51, </key>
+<key name="modify"> 22,27,31,63,50, </key>
+<key name="modul"> 15,16,0,1,20,7,26,61,43,75,54, </key>
+<key name="mous"> 0,26,54, </key>
+<key name="mov"> 29,62,63, </key>
+<key name="movement"> 62, </key>
+<key name="movenod"> 63, </key>
+<key name="much"> 65, </key>
+<key name="multi"> 17,3,4,61,70, </key>
+<key name="multiconnection"> 70, </key>
+<key name="must"> 24,13,66,74,44, </key>
+<key name="myelemid"> 70, </key>
+<key name="mypnt1"> 70, </key>
+<key name="mypnt2"> 70, </key>
+<key name="n"> 63,66,44, </key>
+<key name="n1"> 63, </key>
+<key name="n10"> 63, </key>
+<key name="n11"> 63, </key>
+<key name="n12"> 63, </key>
+<key name="n2"> 63, </key>
+<key name="n23_param"> 9, </key>
+<key name="n3"> 63, </key>
+<key name="n4"> 63, </key>
+<key name="n5"> 63, </key>
+<key name="n6"> 63, </key>
+<key name="n7"> 63, </key>
+<key name="n8"> 63, </key>
+<key name="n9"> 63, </key>
+<key name="na"> 63, </key>
+<key name="nam"> 5,24,7,25,26,31,58,32,63,65,69,64,74,75,52,54, </key>
+<key name="namesak"> 5, </key>
+<key name="nb"> 58,63,65,70, </key>
+<key name="nb_conn"> 70, </key>
+<key name="nb_vert"> 63, </key>
+<key name="nbedg"> 7,76,78, </key>
+<key name="nbfac"> 7,78, </key>
+<key name="nbhexa"> 78, </key>
+<key name="nbnod"> 7,76,78, </key>
+<key name="nbpolygon"> 78, </key>
+<key name="nbpolyhedron"> 78, </key>
+<key name="nbprism"> 78, </key>
+<key name="nbpyramid"> 78, </key>
+<key name="nbquadrangl"> 76,78, </key>
+<key name="nbseg"> 63, </key>
+<key name="nbtetra"> 78, </key>
+<key name="nbtriangl"> 76,78, </key>
+<key name="nbvolum"> 7,76,78, </key>
+<key name="nc"> 63, </key>
+<key name="nd"> 63, </key>
+<key name="ndiagonal"> 63, </key>
+<key name="ne"> 24, </key>
+<key name="necessari"> 73, </key>
+<key name="necessary"> 18,62,69, </key>
+<key name="need"> 71, </key>
+<key name="negativ"> 20, </key>
+<key name="neighbor"> 28,51, </key>
+<key name="neighborhood"> 73, </key>
+<key name="netgen"> 16,7,9,65,64,75,78, </key>
+<key name="netgen_2d3d"> 9, </key>
+<key name="new"> 0,6,24,25,26,29,62,63,66,39,74,52, </key>
+<key name="new_id"> 63, </key>
+<key name="next"> 20,66, </key>
+<key name="nid"> 63, </key>
+<key name="nid1"> 63, </key>
+<key name="nid2"> 63, </key>
+<key name="nid3"> 63, </key>
+<key name="nid4"> 63, </key>
+<key name="no_nam"> 64, </key>
+<key name="nod"> 15,0,18,1,19,20,21,5,22,23,7,8,26,29,30,12,13,34,36,61,62,63,65,66,67,70,40,41,72,73,74,44,45,46,48,76,53,78,55, </key>
+<key name="nodal"> 66,46, </key>
+<key name="node_id"> 63, </key>
+<key name="node000"> 63, </key>
+<key name="nodeid"> 63, </key>
+<key name="nodeid1ofside1tomerg"> 76, </key>
+<key name="nodeid1ofside2tomerg"> 76, </key>
+<key name="nodeid2ofside1tomerg"> 76, </key>
+<key name="nodeid2ofside2tomerg"> 76, </key>
+<key name="nodestart"> 63, </key>
+<key name="non"> 24,63, </key>
+<key name="nonam"> 64, </key>
+<key name="normal"> 47,55, </key>
+<key name="normalisation"> 21, </key>
+<key name="not"> 18,21,24,26,10,13, </key>
+<key name="noth"> 26, </key>
+<key name="notic"> 15, </key>
+<key name="now"> 6,24, </key>
+<key name="nsmooth"> 63, </key>
+<key name="numb"> 14,15,16,1,20,7,26,9,12,34,61,65,66,68,71,72,44,46,76,53,78,54, </key>
+<key name="number"> 0,1,30,13, </key>
+<key name="numberofsegment"> 7,9,58,63,70,76,78, </key>
+<key name="numeric"> 27, </key>
+<key name="numerical"> 14, </key>
+<key name="nunit"> 63, </key>
+<key name="obey"> 44, </key>
+<key name="obj"> 64, </key>
+<key name="object"> 14,16,0,18,1,20,5,6,23,24,25,8,26,27,10,31,32,34,63,65,35,66,67,69,39,40,41,42,73,49,50,53,79,54, </key>
+<key name="objet"> 26, </key>
+<key name="obtain"> 18,70, </key>
+<key name="offset"> 54, </key>
+<key name="ok"> 18,1,22,6,8,27,10,28,29,31,12,13,32,62,63,40,41,72,44,46,50,51,52, </key>
+<key name="on"> 15,16,1,20,24,7,25,27,9,10,28,12,13,56,57,60,62,63,38,66,70,71,39,40,72,73,74,44,46,47,49,50,52, </key>
+<key name="onc"> 50, </key>
+<key name="onto"> 38,66, </key>
+<key name="oo"> 21, </key>
+<key name="opaqu"> 77, </key>
+<key name="open"> 70, </key>
+<key name="operat"> 14, </key>
+<key name="operation"> 16,18,19,20,21,2,3,4,5,22,25,26,27,10,28,29,31,12,13,56,57,32,59,34,33,60,36,61,62,37,35,38,66,39,40,41,72,42,44,45,46,47,48,49,50,51,52,79,55, </key>
+<key name="oppos"> 68, </key>
+<key name="opposit"> 14,6,7,27,9,34,38,44,45, </key>
+<key name="optimiz"> 65, </key>
+<key name="option"> 15,0,20,47,49, </key>
+<key name="optional"> 24,13,69, </key>
+<key name="ord"> 15,22,65,66, </key>
+<key name="ordinary"> 1,38, </key>
+<key name="orientat"> 54, </key>
+<key name="orientation"> 22,6,27,63,69,50, </key>
+<key name="origin"> 54,55, </key>
+<key name="other"> 50, </key>
+<key name="otherwis"> 24,34, </key>
+<key name="our"> 24, </key>
+<key name="out"> 71,54, </key>
+<key name="outlin"> 57, </key>
+<key name="outsid"> 66, </key>
+<key name="own"> 15, </key>
+<key name="p5"> 7,9, </key>
+<key name="packag"> 7,64,75, </key>
+<key name="pag"> 16,26,31, </key>
+<key name="pair"> 20, </key>
+<key name="pan"> 54, </key>
+<key name="paramet"> 15,20,2,74,44, </key>
+<key name="parameter"> 14,0,6,9,13,65,42,44,54, </key>
+<key name="parametric"> 15,66, </key>
+<key name="parent"> 25, </key>
+<key name="part"> 63,44,46,54, </key>
+<key name="particularity"> 15, </key>
+<key name="pas"> 7,58,62,63,70, </key>
+<key name="path"> 13,63,74,76, </key>
+<key name="pathmesh"> 63, </key>
+<key name="pathshap"> 63, </key>
+<key name="pattern"> 63,66, </key>
+<key name="pattern_nam"> 66, </key>
+<key name="pentagonal"> 63, </key>
 <key name="pentahedron"> 2, </key>
-<key name="per"> 63, </key>
-<key name="perform"> 60,61,40,43,46,51,53, </key>
-<key name="perimet"> 20, </key>
-<key name="permit"> 66,67, </key>
-<key name="pi"> 61,73, </key>
-<key name="pictur"> 3,25,12,55,56,59, </key>
-<key name="piec"> 72, </key>
-<key name="plac"> 7,43,53, </key>
-<key name="plan"> 5,68,46,54, </key>
-<key name="planar"> 61,54, </key>
-<key name="platform"> 25,42, </key>
-<key name="pleas"> 9,12, </key>
-<key name="plot"> 19, </key>
-<key name="plu"> 11,70, </key>
-<key name="png"> 0,53, </key>
-<key name="point"> 14,1,19,12,61,37,64,67,70,41,43,46,73,48,53,54, </key>
-<key name="pointstruct"> 61,73, </key>
-<key name="polygon"> 17,61,75, </key>
-<key name="polygonal"> 61, </key>
-<key name="polyhedral"> 17,61, </key>
-<key name="polyhedron"> 17,61,66,75, </key>
-<key name="polylin"> 12, </key>
-<key name="pop"> 9,29, </key>
-<key name="position"> 14,64,53, </key>
-<key name="posses"> 63,37, </key>
-<key name="possibility"> 71, </key>
-<key name="possibl"> 13,2,25,63,64, </key>
-<key name="post"> 53, </key>
-<key name="powerful"> 71, </key>
-<key name="precision"> 17, </key>
-<key name="preferenc"> 13,33,60,65, </key>
-<key name="prefix"> 71, </key>
-<key name="preproces"> 25, </key>
-<key name="pres"> 17,1,12,39,53, </key>
-<key name="present"> 14,0,63,51, </key>
-<key name="presentation"> 16,0,53, </key>
-<key name="preserv"> 64, </key>
-<key name="preset"> 13, </key>
-<key name="preview"> 17,5,26,64,71, </key>
-<key name="previou"> 19,12,49, </key>
-<key name="previous"> 24,25,60,64, </key>
-<key name="principl"> 12, </key>
-<key name="print"> 6,8,57,61,68,73,75, </key>
-<key name="printmeshinfo"> 6, </key>
-<key name="prism"> 66,69,75, </key>
-<key name="prism3d"> 66, </key>
-<key name="prismatic"> 15, </key>
-<key name="pro"> 53, </key>
-<key name="problem"> 6,8, </key>
-<key name="proce"> 23,9, </key>
-<key name="procedur"> 45, </key>
-<key name="proceed"> 12,38, </key>
-<key name="proces"> 45, </key>
-<key name="produc"> 14,7,11,70,45, </key>
-<key name="product"> 54, </key>
-<key name="program"> 23, </key>
-<key name="progression"> 19, </key>
-<key name="project"> 64, </key>
-<key name="projection"> 15,64,66,67,69,54, </key>
-<key name="prompt"> 19, </key>
-<key name="propagat"> 6,8,37, </key>
-<key name="propagation"> 13,6,8,37,73, </key>
-<key name="properti"> 53, </key>
-<key name="prov"> 63, </key>
-<key name="provid"> 0,17,26,72, </key>
-<key name="pseudo"> 27, </key>
-<key name="pt1"> 72, </key>
-<key name="pt2"> 72, </key>
-<key name="pul"> 45, </key>
-<key name="put"> 8, </key>
-<key name="px"> 8,73, </key>
-<key name="px1"> 73, </key>
-<key name="py"> 8,73, </key>
-<key name="py1"> 73, </key>
-<key name="pyramid"> 75, </key>
-<key name="pyramidal"> 15, </key>
-<key name="python"> 6,62,72,52, </key>
-<key name="pz"> 8,73, </key>
-<key name="pz1"> 73, </key>
-<key name="q1"> 61, </key>
+<key name="per"> 65, </key>
+<key name="perform"> 61,63,41,44,47,52,54, </key>
+<key name="perimet"> 21, </key>
+<key name="permit"> 68,69, </key>
+<key name="pi"> 63,76, </key>
+<key name="pictur"> 3,26,13,56,57,60, </key>
+<key name="piec"> 75, </key>
+<key name="plac"> 8,44,54, </key>
+<key name="plan"> 6,70,47,55, </key>
+<key name="planar"> 63,55, </key>
+<key name="platform"> 26,43, </key>
+<key name="pleas"> 10,13, </key>
+<key name="plot"> 20, </key>
+<key name="plu"> 12,72, </key>
+<key name="png"> 0,54, </key>
+<key name="point"> 15,1,20,13,62,63,38,66,69,72,42,44,47,76,49,54,55, </key>
+<key name="pointstruct"> 63,76, </key>
+<key name="polygon"> 18,63,78, </key>
+<key name="polygonal"> 63, </key>
+<key name="polyhedral"> 18,63, </key>
+<key name="polyhedron"> 18,63,68,78, </key>
+<key name="polylin"> 13, </key>
+<key name="pop"> 10,30, </key>
+<key name="position"> 15,66,54, </key>
+<key name="posses"> 65,38, </key>
+<key name="possibility"> 74, </key>
+<key name="possibl"> 14,2,5,26,65,66, </key>
+<key name="post"> 54, </key>
+<key name="powerful"> 74, </key>
+<key name="precision"> 18, </key>
+<key name="preferenc"> 14,34,61,67, </key>
+<key name="prefix"> 74, </key>
+<key name="preproces"> 26, </key>
+<key name="pres"> 18,1,13,40,54, </key>
+<key name="present"> 15,0,65,52, </key>
+<key name="presentation"> 17,0,54, </key>
+<key name="preserv"> 66, </key>
+<key name="preset"> 14, </key>
+<key name="preview"> 18,6,27,62,66,74, </key>
+<key name="previou"> 20,13,50, </key>
+<key name="previous"> 25,26,61,66, </key>
+<key name="principl"> 13, </key>
+<key name="print"> 7,9,58,63,70,76,78, </key>
+<key name="printmeshinfo"> 7, </key>
+<key name="prism"> 68,71,78, </key>
+<key name="prism3d"> 68, </key>
+<key name="prismatic"> 16, </key>
+<key name="pro"> 54, </key>
+<key name="problem"> 7,9, </key>
+<key name="proce"> 24,10, </key>
+<key name="procedur"> 46, </key>
+<key name="proceed"> 13,39, </key>
+<key name="proces"> 5,46, </key>
+<key name="produc"> 15,8,12,72,46, </key>
+<key name="product"> 55, </key>
+<key name="program"> 24, </key>
+<key name="progression"> 20, </key>
+<key name="project"> 66, </key>
+<key name="projection"> 16,66,68,69,71,55, </key>
+<key name="prompt"> 20, </key>
+<key name="propagat"> 7,9,38, </key>
+<key name="propagation"> 14,7,9,38,76, </key>
+<key name="properti"> 54, </key>
+<key name="prov"> 65, </key>
+<key name="provid"> 16,0,18,27,75, </key>
+<key name="pseudo"> 28, </key>
+<key name="pt1"> 75, </key>
+<key name="pt2"> 75, </key>
+<key name="pul"> 46, </key>
+<key name="put"> 9, </key>
+<key name="px"> 9,76, </key>
+<key name="px1"> 76, </key>
+<key name="py"> 9,76, </key>
+<key name="py1"> 76, </key>
+<key name="pyramid"> 78, </key>
+<key name="pyramidal"> 16, </key>
+<key name="python"> 7,64,75,53, </key>
+<key name="pz"> 9,76, </key>
+<key name="pz1"> 76, </key>
+<key name="q1"> 63, </key>
 <key name="qi"> 2, </key>
-<key name="qk"> 20,2, </key>
-<key name="quad"> 54, </key>
-<key name="quad_1"> 61, </key>
-<key name="quad_2"> 61, </key>
-<key name="quad_3"> 61, </key>
-<key name="quad_4"> 61, </key>
-<key name="quad_5"> 61, </key>
-<key name="quad_6"> 61, </key>
-<key name="quad_7"> 61, </key>
-<key name="quadra"> 6,57, </key>
-<key name="quadrangl"> 13,14,15,17,18,20,2,6,26,8,27,11,12,57,33,32,60,36,61,63,66,69,70,44,73,75, </key>
-<key name="quadrangle"> 66, </key>
-<key name="quadrangular"> 15,6,8,33,37, </key>
-<key name="quadratic"> 13,1,7,63,37, </key>
-<key name="quadtotri"> 61, </key>
-<key name="quality"> 16,0,18,19,20,2,3,4,26,55,56,58,32,60,36,68,44,47,49,76,54, </key>
-<key name="quantity"> 13, </key>
-<key name="r1"> 61, </key>
-<key name="radial"> 69, </key>
-<key name="radio"> 21,25,26,41,43,46,49, </key>
-<key name="radiu"> 20,61,63, </key>
-<key name="radius"> 63, </key>
-<key name="radius_1"> 72, </key>
-<key name="radius_2"> 72, </key>
-<key name="rang"> 19,25,57,61,63,68, </key>
-<key name="rat"> 63, </key>
-<key name="ratio"> 16,20,2,60,68,45,47,54, </key>
-<key name="ready"> 23, </key>
+<key name="qk"> 21,2, </key>
+<key name="quad"> 55, </key>
+<key name="quad_1"> 63, </key>
+<key name="quad_2"> 63, </key>
+<key name="quad_3"> 63, </key>
+<key name="quad_4"> 63, </key>
+<key name="quad_5"> 63, </key>
+<key name="quad_6"> 63, </key>
+<key name="quad_7"> 63, </key>
+<key name="quadra"> 7,58, </key>
+<key name="quadrangl"> 14,15,16,18,19,21,2,7,27,9,28,12,13,58,34,33,61,37,63,65,68,71,72,45,76,78, </key>
+<key name="quadrangle"> 68, </key>
+<key name="quadrangular"> 16,7,9,34,38, </key>
+<key name="quadratic"> 14,1,8,65,38, </key>
+<key name="quadtotri"> 63, </key>
+<key name="quality"> 17,0,19,20,21,2,3,4,27,56,57,59,33,61,37,70,45,48,50,79,55, </key>
+<key name="quantity"> 14, </key>
+<key name="r1"> 63, </key>
+<key name="radial"> 71, </key>
+<key name="radio"> 22,26,27,42,44,47,50, </key>
+<key name="radiu"> 21,63,65, </key>
+<key name="radius"> 65, </key>
+<key name="radius_1"> 75, </key>
+<key name="radius_2"> 75, </key>
+<key name="rais"> 63, </key>
+<key name="rang"> 20,26,58,63,65,70, </key>
+<key name="rat"> 65, </key>
+<key name="ratio"> 17,21,2,61,70,46,48,55, </key>
+<key name="ready"> 24, </key>
 <key name="recent"> 0, </key>
-<key name="red"> 56, </key>
-<key name="redefin"> 0,53, </key>
-<key name="reduc"> 45, </key>
-<key name="reevaluat"> 45, </key>
-<key name="refer"> 64, </key>
-<key name="referenc"> 14,16,23,24, </key>
-<key name="refin"> 13, </key>
-<key name="reflect"> 64,44,76, </key>
-<key name="refpoint"> 61, </key>
+<key name="red"> 57, </key>
+<key name="redefin"> 0,54, </key>
+<key name="reduc"> 46, </key>
+<key name="reevaluat"> 46, </key>
+<key name="refer"> 66, </key>
+<key name="referenc"> 15,17,24,25, </key>
+<key name="refin"> 14, </key>
+<key name="reflect"> 66,45,79, </key>
+<key name="refpoint"> 63, </key>
 <key name="refresh"> 0, </key>
-<key name="regular"> 20,6,8,63,62, </key>
-<key name="relat"> 42, </key>
-<key name="relation"> 14, </key>
-<key name="relationship"> 14, </key>
-<key name="remot"> 53, </key>
-<key name="remov"> 21,6,25,26,9,30,12,57,61,68,39,71,49, </key>
-<key name="removal"> 60, </key>
-<key name="removeelement"> 61,68, </key>
-<key name="removehypothesi"> 6, </key>
-<key name="removenod"> 61, </key>
-<key name="renumb"> 40, </key>
-<key name="renumber"> 61,40, </key>
-<key name="renumbernod"> 61, </key>
-<key name="reorient"> 21,61, </key>
-<key name="replac"> 43, </key>
-<key name="represent"> 13,14,19,2,65,47,53, </key>
-<key name="representation"> 14, </key>
-<key name="requir"> 27,28,63,50, </key>
-<key name="res"> 61, </key>
-<key name="reset"> 53, </key>
-<key name="resiz"> 53, </key>
-<key name="respect"> 12, </key>
+<key name="regular"> 21,7,9,65,64, </key>
+<key name="relat"> 43, </key>
+<key name="relation"> 15, </key>
+<key name="relationship"> 15, </key>
+<key name="remot"> 54, </key>
+<key name="remov"> 22,7,26,27,10,31,13,58,63,70,40,74,50, </key>
+<key name="removal"> 61, </key>
+<key name="removeelement"> 63,70, </key>
+<key name="removehypothesi"> 7, </key>
+<key name="removenod"> 63, </key>
+<key name="renam"> 5, </key>
+<key name="renumb"> 41, </key>
+<key name="renumber"> 63,41, </key>
+<key name="renumbernod"> 63, </key>
+<key name="reorient"> 22,63, </key>
+<key name="replac"> 44, </key>
+<key name="represent"> 14,15,20,2,67,48,54, </key>
+<key name="representation"> 15, </key>
+<key name="requir"> 28,29,65,73,51, </key>
+<key name="res"> 63, </key>
+<key name="reset"> 54, </key>
+<key name="resiz"> 54, </key>
+<key name="respect"> 13, </key>
 <key name="respectiv"> 1, </key>
-<key name="rest"> 64,43, </key>
-<key name="restor"> 53, </key>
-<key name="restrict"> 14, </key>
-<key name="result"> 13,17,12,57,68,45,51, </key>
-<key name="ret"> 6,8, </key>
-<key name="retriev"> 14, </key>
-<key name="return"> 58,61, </key>
-<key name="reveal"> 20, </key>
-<key name="revers"> 1,64, </key>
-<key name="revert"> 21, </key>
-<key name="revolution"> 11,61,70, </key>
-<key name="revolv"> 61,70, </key>
-<key name="right"> 0,22,9,28,29,12,65, </key>
-<key name="rotat"> 11,12,61,70,41,73,53, </key>
-<key name="rotation"> 5,70,41,73,53, </key>
-<key name="rotationsweepobject"> 61, </key>
-<key name="rough"> 13, </key>
-<key name="rr"> 61, </key>
-<key name="rul"> 19,37,43, </key>
-<key name="run"> 42, </key>
-<key name="salom"> 25,8,57,60,61,68,42,62,73, </key>
-<key name="sam"> 14,0,19,20,2,23,24,8,12,37,66,67,38,71,43,51, </key>
-<key name="sampl"> 15,17,18,19,20,2,3,4,21,23,24,25,26,27,28,30,11,12,55,56,31,58,33,32,59,35,36,34,37,64,38,39,40,70,41,43,44,45,46,47,48,49,50,51,76,54, </key>
-<key name="sav"> 71, </key>
-<key name="scal"> 19,53, </key>
-<key name="scalar"> 16, </key>
-<key name="scen"> 53, </key>
-<key name="script"> 15,17,18,19,20,2,3,4,21,23,6,24,25,26,27,28,30,11,12,55,56,31,58,33,32,59,35,36,34,37,64,38,39,40,70,41,43,44,45,46,47,48,49,50,51,52,76,54, </key>
-<key name="se"> 15,17,18,19,20,2,3,4,21,5,6,24,7,25,26,27,28,30,11,12,55,56,31,58,33,32,59,35,36,34,37,64,66,38,39,40,70,41,43,44,72,45,46,47,48,49,50,51,76,53,54, </key>
-<key name="seam"> 64, </key>
-<key name="search"> 31,71, </key>
-<key name="second"> 17,61,63,43, </key>
-<key name="secondnodeid1"> 73, </key>
-<key name="secondnodeid2"> 73, </key>
-<key name="secondnodeidonfreebord"> 73, </key>
-<key name="section"> 0,5,23,64,72, </key>
-<key name="seg"> 63, </key>
-<key name="segment"> 13,19,6,8,57,33,60,61,63,68,72,73,75, </key>
-<key name="select"> 13,0,17,1,19,21,22,23,6,24,7,25,26,9,27,28,30,11,12,31,35,61,63,37,64,65,67,39,40,70,41,42,71,43,45,46,48,49,50,51,52,53, </key>
-<key name="selectabl"> 59, </key>
-<key name="selection"> 17,1,21,25,26,9,71,49, </key>
-<key name="sens"> 14, </key>
-<key name="separat"> 47, </key>
-<key name="sequenc"> 43, </key>
-<key name="set"> 14,15,17,19,21,5,23,25,8,28,12,33,60,61,63,34,64,65,69,71,43,45,74,49,53, </key>
-<key name="setmaxelementarea"> 6, </key>
-<key name="setnam"> 62,72, </key>
-<key name="setting"> 23, </key>
-<key name="seven"> 12,61, </key>
-<key name="sew"> 12,43,73, </key>
-<key name="sewbordertosid"> 73, </key>
-<key name="sewconformfreeborder"> 73, </key>
-<key name="sewfreeborder"> 73, </key>
-<key name="sewsideelement"> 73, </key>
-<key name="sg"> 57,61,68,73, </key>
-<key name="shad"> 0,65,74, </key>
-<key name="shall"> 21,27,28,35,64,70,41,46,48,49,50, </key>
-<key name="shap"> 13,14,15,12,61,64,66,67,69,45, </key>
-<key name="shape_mesh"> 61, </key>
-<key name="shape1d"> 61, </key>
-<key name="shapetyp"> 6,8,57,61,68,72,73, </key>
-<key name="shel"> 69, </key>
-<key name="shell"> 68,69, </key>
-<key name="shift"> 17,1,26,39,45, </key>
-<key name="shortest"> 54, </key>
-<key name="should"> 19,7,25,11,12,64,66,69,70,41,71,43,45,51, </key>
-<key name="show"> 19,5,12,71,53, </key>
-<key name="shown"> 16,45, </key>
-<key name="shrink"> 65, </key>
-<key name="sid"> 6,8,36,63,66,43,44,73, </key>
-<key name="simp"> 23,37, </key>
-<key name="simpl"> 14,17,12,64, </key>
-<key name="simplex"> 20,2, </key>
-<key name="sin"> 61, </key>
-<key name="sin_bot"> 61, </key>
-<key name="sin_top"> 61, </key>
-<key name="six"> 12,61, </key>
-<key name="siz"> 0,63,72,45, </key>
-<key name="sk"> 20,2, </key>
-<key name="sketch"> 8, </key>
-<key name="sketcher"> 8, </key>
-<key name="sketcher1"> 8, </key>
-<key name="sketcher2"> 8, </key>
-<key name="skew"> 16,26,60,68,44,49, </key>
-<key name="skew_margin"> 68, </key>
-<key name="slid"> 74, </key>
-<key name="small"> 53, </key>
-<key name="smesh"> 6,8,57,61,68,62,43,72,73,75, </key>
-<key name="smesh_mechanic"> 57,61,68,73, </key>
-<key name="smesh_mechanic_tetra"> 68, </key>
-<key name="smeshgroup1"> 57, </key>
-<key name="smooth"> 61,45, </key>
-<key name="smoothobject"> 61, </key>
-<key name="smp"> 64, </key>
-<key name="so"> 13,19,20,12,64,43,47, </key>
-<key name="solid"> 8,60,67, </key>
-<key name="somewhat"> 17, </key>
-<key name="soon"> 6, </key>
-<key name="sort"> 21,25,26,49, </key>
-<key name="sourc"> 67,71, </key>
-<key name="spac"> 14,64,69,41,48, </key>
-<key name="specifi"> 19,3,64,39,43,45, </key>
-<key name="specific"> 15,22,71, </key>
-<key name="specify"> 17,1,26,11,12,64,39,70,41,71,45,46,48,51, </key>
-<key name="spher"> 19,20,23, </key>
-<key name="split"> 15,19,2,5,63,43, </key>
-<key name="sqrt"> 61, </key>
-<key name="standalon"> 25,57,71, </key>
-<key name="standard"> 0,7,31,72,52, </key>
-<key name="start"> 13,19,5,8,12,60,42,43,48, </key>
-<key name="startendlength"> 8, </key>
-<key name="static"> 62, </key>
-<key name="step"> 11,70, </key>
-<key name="stor"> 64,71, </key>
-<key name="str"> 62, </key>
-<key name="straight"> 1,8,12,61,37, </key>
-<key name="stretch"> 53, </key>
-<key name="strict"> 53, </key>
-<key name="structur"> 23,24,61,62, </key>
-<key name="study"> 8,57,71,72, </key>
-<key name="stuf"> 53, </key>
-<key name="styl"> 6, </key>
-<key name="sub"> 6,8,12,31,35,64,41,43,46,48, </key>
-<key name="submenu"> 17,10,39,40, </key>
-<key name="submesh"> 13,21,22,6,24,25,26,11,12,38,70,45,48,49,52, </key>
-<key name="subshapeall"> 6,8,57,61,68,73, </key>
-<key name="subshapeallid"> 72, </key>
-<key name="subshapeallsort"> 61, </key>
-<key name="subshapelist"> 6,57, </key>
-<key name="subshapenam"> 6, </key>
-<key name="succed"> 8, </key>
+<key name="rest"> 66,44, </key>
+<key name="restor"> 54, </key>
+<key name="restrict"> 15, </key>
+<key name="result"> 14,18,5,13,58,62,70,46,52, </key>
+<key name="ret"> 7,9, </key>
+<key name="retriev"> 15, </key>
+<key name="return"> 59,63, </key>
+<key name="reveal"> 21, </key>
+<key name="revers"> 1,66, </key>
+<key name="revert"> 22, </key>
+<key name="revolution"> 12,63,72, </key>
+<key name="revolv"> 63,72, </key>
+<key name="right"> 0,23,10,29,30,13,67, </key>
+<key name="rotat"> 12,13,63,72,42,76,54, </key>
+<key name="rotation"> 6,72,42,76,54, </key>
+<key name="rotationsweepobject"> 63, </key>
+<key name="rough"> 14, </key>
+<key name="rr"> 63, </key>
+<key name="rul"> 20,38,44, </key>
+<key name="run"> 43, </key>
+<key name="salom"> 26,9,58,61,63,70,43,64,76, </key>
+<key name="sam"> 15,16,0,20,21,2,24,25,9,13,38,68,69,39,74,44,52, </key>
+<key name="sampl"> 16,18,19,20,21,2,3,4,22,24,25,26,27,28,29,31,12,13,56,57,32,59,34,33,60,36,62,37,35,38,66,39,40,41,72,42,44,45,46,47,48,49,50,51,52,79,55, </key>
+<key name="sav"> 74, </key>
+<key name="scal"> 20,54, </key>
+<key name="scalar"> 17, </key>
+<key name="scen"> 54, </key>
+<key name="script"> 16,18,19,20,21,2,3,4,22,24,7,25,26,27,28,29,31,12,13,56,57,32,59,34,33,60,36,62,37,35,38,66,39,40,41,72,42,44,45,46,47,48,49,50,51,52,53,79,55, </key>
+<key name="se"> 16,18,19,20,21,2,3,4,5,22,6,7,25,8,26,27,28,29,31,12,13,56,57,32,59,34,33,60,36,62,37,35,38,66,68,39,40,41,72,42,44,45,75,46,47,48,49,50,51,52,79,54,55, </key>
+<key name="seam"> 66, </key>
+<key name="search"> 32,62,74, </key>
+<key name="second"> 18,63,65,44, </key>
+<key name="secondnodeid1"> 76, </key>
+<key name="secondnodeid2"> 76, </key>
+<key name="secondnodeidonfreebord"> 76, </key>
+<key name="section"> 0,6,24,66,75, </key>
+<key name="seg"> 65, </key>
+<key name="segment"> 14,16,20,7,9,58,34,61,63,65,70,73,75,76,78, </key>
+<key name="select"> 14,0,18,1,20,5,22,23,24,7,25,8,26,27,10,28,29,31,12,13,32,36,62,63,65,38,66,67,69,40,41,72,42,43,74,44,46,47,49,50,51,52,53,54, </key>
+<key name="selectabl"> 60, </key>
+<key name="selection"> 18,1,22,26,27,10,74,50, </key>
+<key name="sens"> 15, </key>
+<key name="separat"> 48, </key>
+<key name="sequenc"> 44, </key>
+<key name="set"> 15,16,18,20,22,6,24,26,9,29,13,34,61,63,65,35,66,67,71,74,44,46,77,50,54, </key>
+<key name="setmaxelementarea"> 7, </key>
+<key name="setnam"> 64,75, </key>
+<key name="setting"> 24, </key>
+<key name="seven"> 13,63, </key>
+<key name="sew"> 13,44,76, </key>
+<key name="sewbordertosid"> 76, </key>
+<key name="sewconformfreeborder"> 76, </key>
+<key name="sewfreeborder"> 76, </key>
+<key name="sewsideelement"> 76, </key>
+<key name="sg"> 58,63,70,76, </key>
+<key name="shad"> 0,67,77, </key>
+<key name="shall"> 22,28,29,36,62,66,72,42,47,49,50,51, </key>
+<key name="shap"> 14,15,16,13,63,66,68,69,71,46, </key>
+<key name="shape_mesh"> 63, </key>
+<key name="shape1d"> 63, </key>
+<key name="shapetyp"> 7,9,58,63,70,75,76, </key>
+<key name="shel"> 71, </key>
+<key name="shell"> 70,71, </key>
+<key name="shift"> 18,1,27,40,46, </key>
+<key name="shortest"> 55, </key>
+<key name="should"> 20,8,26,12,13,66,68,71,72,42,74,44,46,52, </key>
+<key name="show"> 20,6,13,74,54, </key>
+<key name="shown"> 17,46, </key>
+<key name="shrink"> 67, </key>
+<key name="sid"> 16,7,9,37,65,68,44,45,76, </key>
+<key name="simp"> 5,24,38, </key>
+<key name="simpl"> 15,18,13,66, </key>
+<key name="simplex"> 21,2, </key>
+<key name="sin"> 63, </key>
+<key name="sin_bot"> 63, </key>
+<key name="sin_top"> 63, </key>
+<key name="six"> 13,63, </key>
+<key name="siz"> 0,65,73,75,46, </key>
+<key name="sk"> 21,2, </key>
+<key name="sketch"> 9, </key>
+<key name="sketcher"> 9, </key>
+<key name="sketcher1"> 9, </key>
+<key name="sketcher2"> 9, </key>
+<key name="skew"> 17,27,61,70,45,50, </key>
+<key name="skew_margin"> 70, </key>
+<key name="slid"> 77, </key>
+<key name="small"> 54, </key>
+<key name="smesh"> 7,9,58,63,70,64,44,75,76,78, </key>
+<key name="smesh_mechanic"> 58,63,70,76, </key>
+<key name="smesh_mechanic_tetra"> 70, </key>
+<key name="smeshgroup1"> 58, </key>
+<key name="smooth"> 63,46, </key>
+<key name="smoothobject"> 63, </key>
+<key name="smp"> 66, </key>
+<key name="so"> 14,20,21,13,66,44,48, </key>
+<key name="solid"> 9,61,69, </key>
+<key name="somewhat"> 18, </key>
+<key name="soon"> 7, </key>
+<key name="sort"> 22,26,27,50, </key>
+<key name="sourc"> 69,74, </key>
+<key name="spac"> 15,66,71,42,49, </key>
+<key name="specifi"> 20,3,66,40,44,46, </key>
+<key name="specific"> 16,23,74, </key>
+<key name="specify"> 18,1,27,12,13,66,40,72,42,74,46,47,49,52, </key>
+<key name="spher"> 20,21,24, </key>
+<key name="split"> 16,20,2,6,65,44, </key>
+<key name="sqrt"> 63, </key>
+<key name="standalon"> 26,58,74, </key>
+<key name="standard"> 0,8,32,75,53, </key>
+<key name="start"> 14,20,6,9,13,61,43,44,49, </key>
+<key name="startendlength"> 9, </key>
+<key name="static"> 64, </key>
+<key name="step"> 12,72, </key>
+<key name="stor"> 66,74, </key>
+<key name="str"> 63,64, </key>
+<key name="straight"> 1,9,13,63,38, </key>
+<key name="stretch"> 54, </key>
+<key name="strict"> 54, </key>
+<key name="structur"> 24,25,63,64, </key>
+<key name="study"> 9,58,74,75, </key>
+<key name="stuf"> 54, </key>
+<key name="styl"> 7, </key>
+<key name="sub"> 7,9,13,32,36,66,42,44,47,49, </key>
+<key name="submenu"> 18,11,40,41, </key>
+<key name="submesh"> 14,22,23,7,25,26,27,12,13,39,72,46,49,50,53, </key>
+<key name="subshapeall"> 7,9,58,63,70,76, </key>
+<key name="subshapeallid"> 63,75, </key>
+<key name="subshapeallsort"> 63, </key>
+<key name="subshapelist"> 7,58, </key>
+<key name="subshapenam"> 7, </key>
+<key name="succed"> 9, </key>
+<key name="successful"> 73, </key>
 <key name="sum"> 2, </key>
-<key name="supplement"> 37, </key>
-<key name="supplementary"> 26, </key>
-<key name="surfac"> 14,20,2,11,12,64,70,43, </key>
-<key name="surround"> 14,45, </key>
-<key name="swept"> 11,70, </key>
+<key name="supplement"> 38, </key>
+<key name="supplementary"> 27, </key>
+<key name="surfac"> 15,21,2,12,13,66,72,44, </key>
+<key name="surround"> 15,46, </key>
+<key name="swept"> 12,72, </key>
 <key name="switch"> 1, </key>
-<key name="symmetrical"> 46,73, </key>
-<key name="symmetry"> 46,73, </key>
-<key name="syntax"> 71, </key>
-<key name="t"> 14,19,2,23,37,64,65,53, </key>
-<key name="t1"> 61, </key>
-<key name="tabl"> 1,19, </key>
-<key name="tak"> 20,49, </key>
-<key name="taken"> 13,22,25,8,64, </key>
-<key name="tap"> 16,25,60,68,47, </key>
-<key name="taper_margin"> 68, </key>
-<key name="target"> 67, </key>
-<key name="techniqu"> 45, </key>
-<key name="tetra"> 6,8,72,75, </key>
-<key name="tetrahedral"> 15,8,63,72, </key>
-<key name="tetrahedralization"> 23, </key>
-<key name="tetrahedrical"> 8, </key>
-<key name="tetrahedron"> 14,15,17,2,6,8,61,34,72,75, </key>
-<key name="tetran"> 8, </key>
-<key name="th"> 64,43, </key>
-<key name="them"> 13,17,1,19,2,25,9,10,11,12,35,63,39,70,43,45,53, </key>
-<key name="themesh"> 6, </key>
-<key name="third"> 12, </key>
-<key name="thos"> 26,49, </key>
-<key name="thre"> 14,1,20,61,63,37,43,46, </key>
-<key name="threshold"> 71, </key>
-<key name="tick"> 53, </key>
+<key name="symmetrical"> 47,76, </key>
+<key name="symmetry"> 47,76, </key>
+<key name="syntax"> 74, </key>
+<key name="t"> 15,20,2,24,38,66,67,73,54, </key>
+<key name="t1"> 63, </key>
+<key name="tabl"> 1,20, </key>
+<key name="tak"> 21,50, </key>
+<key name="taken"> 14,23,26,9,66, </key>
+<key name="tap"> 17,26,61,70,48, </key>
+<key name="taper_margin"> 70, </key>
+<key name="target"> 69, </key>
+<key name="techniqu"> 46, </key>
+<key name="test"> 63, </key>
+<key name="tetra"> 7,9,75,78, </key>
+<key name="tetrahedral"> 16,9,65,75, </key>
+<key name="tetrahedralization"> 24, </key>
+<key name="tetrahedrical"> 9, </key>
+<key name="tetrahedron"> 15,16,18,2,7,9,63,35,75,78, </key>
+<key name="tetran"> 9, </key>
+<key name="th"> 66,44, </key>
+<key name="them"> 14,18,1,20,2,26,10,11,12,13,36,65,40,72,44,46,54, </key>
+<key name="themesh"> 7, </key>
+<key name="third"> 13, </key>
+<key name="thos"> 27,50, </key>
+<key name="thre"> 15,1,21,63,65,38,44,47, </key>
+<key name="threshold"> 74, </key>
+<key name="tick"> 54, </key>
 <key name="tim"> 0, </key>
-<key name="tmp"> 6, </key>
-<key name="togeth"> 33, </key>
-<key name="toggl"> 17,71,48, </key>
-<key name="toleranc"> 35,70,71,73, </key>
-<key name="tool"> 71,51, </key>
-<key name="toolbar"> 20,2,21,23,24,7,26,27,28,30,11,12,32,64,39,40,70,42,44,45,47,49,50,52,76,53,54, </key>
-<key name="top"> 61, </key>
-<key name="topological"> 14,43, </key>
-<key name="topology"> 14, </key>
-<key name="toru"> 7, </key>
-<key name="total"> 52, </key>
-<key name="toward"> 45, </key>
-<key name="transform"> 28,73, </key>
-<key name="transformation"> 35,41,43,46,48, </key>
-<key name="translat"> 73,48, </key>
-<key name="translation"> 73,48, </key>
-<key name="transparency"> 0,74, </key>
-<key name="transparent"> 74, </key>
-<key name="transtorm"> 7, </key>
-<key name="tria"> 6,8,73, </key>
-<key name="tria_mesh"> 8, </key>
-<key name="triangl"> 14,15,17,1,18,20,6,8,27,11,33,32,59,36,61,63,66,68,69,70,44,72,47,73,49,50,75,53, </key>
-<key name="triangular"> 15,33, </key>
-<key name="triangulation"> 8, </key>
-<key name="trihedron"> 53, </key>
-<key name="tritoquad"> 61, </key>
-<key name="truncat"> 72, </key>
-<key name="try"> 23,63, </key>
-<key name="tt"> 8,61, </key>
-<key name="tui"> 15,17,18,19,20,2,3,4,21,23,24,25,26,27,28,30,11,12,55,56,31,58,33,32,59,35,36,34,37,64,38,39,40,70,41,43,44,45,46,47,48,49,50,51,52,76,54, </key>
-<key name="tupl"> 62, </key>
-<key name="two"> 14,17,5,25,26,8,27,12,57,36,61,63,64,66,67,68,69,43,47,73,48,50,51,52, </key>
-<key name="typ"> 14,17,19,20,2,22,23,25,11,12,39,70,71,43,52, </key>
-<key name="typical"> 45, </key>
-<key name="u"> 14,43, </key>
-<key name="unary"> 71, </key>
-<key name="unassign"> 38, </key>
-<key name="uncheck"> 53, </key>
-<key name="uniform"> 45, </key>
-<key name="union"> 57,49,50,51, </key>
-<key name="uniongroup"> 57, </key>
-<key name="unionid"> 72, </key>
-<key name="unit"> 61,43,49,50,51, </key>
-<key name="unles"> 37, </key>
-<key name="unv"> 31, </key>
-<key name="up"> 19,9,29, </key>
-<key name="updat"> 0,6,42,45, </key>
-<key name="updateobjbrows"> 57,61,68,73, </key>
-<key name="upload"> 71, </key>
-<key name="us"> 14,15,19,3,5,23,24,25,11,12,33,35,61,63,64,66,70,71,43,45,74,51,53, </key>
-<key name="usag"> 16,6,61,72, </key>
-<key name="useful"> 0,17,25,12,63, </key>
-<key name="usual"> 43,45, </key>
-<key name="v"> 14, </key>
-<key name="valu"> 13,16,19,20,2,23,6,12,58,36,37,38,71,44,72, </key>
-<key name="vari"> 20, </key>
-<key name="variabl"> 62, </key>
+<key name="tmp"> 7, </key>
+<key name="togeth"> 34, </key>
+<key name="toggl"> 18,74,49, </key>
+<key name="toleranc"> 5,36,72,74,76, </key>
+<key name="tool"> 74,52, </key>
+<key name="toolbar"> 21,2,5,22,24,25,8,27,28,29,31,12,13,33,62,66,40,41,72,43,45,46,48,50,51,53,79,54,55, </key>
+<key name="top"> 63,73, </key>
+<key name="topological"> 15,44, </key>
+<key name="topology"> 15, </key>
+<key name="toru"> 8, </key>
+<key name="total"> 53, </key>
+<key name="toward"> 46, </key>
+<key name="transform"> 29,76, </key>
+<key name="transformation"> 36,42,44,47,49, </key>
+<key name="translat"> 76,49, </key>
+<key name="translation"> 76,49, </key>
+<key name="transparency"> 0,77, </key>
+<key name="transparent"> 77, </key>
+<key name="transtorm"> 8, </key>
+<key name="tria"> 7,9,76, </key>
+<key name="tria_mesh"> 9, </key>
+<key name="triangl"> 15,16,18,1,19,21,7,9,28,12,34,33,60,37,63,65,68,70,71,72,45,75,48,76,50,51,78,54, </key>
+<key name="triangular"> 16,34, </key>
+<key name="triangulation"> 9, </key>
+<key name="trihedron"> 54, </key>
+<key name="tritoquad"> 63, </key>
+<key name="tru"> 63, </key>
+<key name="truncat"> 75, </key>
+<key name="try"> 24,65, </key>
+<key name="tt"> 9,63, </key>
+<key name="tui"> 16,18,19,20,21,2,3,4,22,24,25,26,27,28,29,31,12,13,56,57,32,59,34,33,60,36,62,37,35,38,66,39,40,41,72,42,44,45,46,47,48,49,50,51,52,53,79,55, </key>
+<key name="tupl"> 64, </key>
+<key name="two"> 15,18,6,26,27,9,28,13,58,37,63,65,66,68,69,70,71,44,48,76,49,51,52,53, </key>
+<key name="typ"> 15,18,20,21,2,23,24,26,12,13,40,72,74,44,53, </key>
+<key name="typical"> 46, </key>
+<key name="u"> 15,44, </key>
+<key name="unary"> 74, </key>
+<key name="unassign"> 39, </key>
+<key name="uncheck"> 54, </key>
+<key name="uniform"> 46, </key>
+<key name="union"> 58,50,51,52, </key>
+<key name="uniongroup"> 58, </key>
+<key name="unionid"> 75, </key>
+<key name="unit"> 5,63,44,50,51,52, </key>
+<key name="unles"> 38, </key>
+<key name="unv"> 32, </key>
+<key name="up"> 20,10,30, </key>
+<key name="updat"> 0,7,43,46, </key>
+<key name="updateobjbrows"> 58,63,70,76, </key>
+<key name="upload"> 74, </key>
+<key name="us"> 15,16,20,3,6,24,25,26,12,13,34,36,63,65,66,68,72,74,44,46,77,52,54, </key>
+<key name="usag"> 17,7,63,75, </key>
+<key name="useful"> 0,18,26,13,65, </key>
+<key name="usual"> 44,46, </key>
+<key name="v"> 15, </key>
+<key name="valu"> 14,17,20,21,2,24,7,13,59,37,38,39,74,45,75, </key>
+<key name="vari"> 21, </key>
+<key name="variabl"> 64, </key>
 <key name="variou"> 0, </key>
-<key name="ve"> 17, </key>
-<key name="vector"> 11,12,61,70,41,46,73,48,54, </key>
-<key name="versa"> 7, </key>
-<key name="vert"> 61, </key>
-<key name="vertex"> 14,64,67, </key>
-<key name="vertex_"> 61, </key>
-<key name="vertic"> 61,64,66,67, </key>
-<key name="very"> 17,12,63, </key>
-<key name="via"> 71,52,53, </key>
-<key name="vic"> 7, </key>
-<key name="vid"> 61, </key>
-<key name="view"> 0,17,1,18,20,2,21,5,25,26,9,27,28,29,11,12,32,36,39,40,70,71,43,44,45,47,49,50,52,75,76,53,54, </key>
-<key name="visibl"> 53, </key>
-<key name="visual"> 16, </key>
-<key name="visualiz"> 53, </key>
+<key name="ve"> 18, </key>
+<key name="vector"> 12,13,63,72,42,47,76,49,55, </key>
+<key name="versa"> 8, </key>
+<key name="vert"> 63, </key>
+<key name="vertex"> 15,63,66,69,73, </key>
+<key name="vertex_"> 63, </key>
+<key name="vertic"> 63,66,68,69, </key>
+<key name="very"> 18,13,65, </key>
+<key name="via"> 74,53,54, </key>
+<key name="vic"> 8, </key>
+<key name="vid"> 63, </key>
+<key name="view"> 0,18,1,19,21,2,22,6,26,27,10,28,29,30,12,13,33,37,40,41,72,74,44,45,46,48,50,51,53,78,79,54,55, </key>
+<key name="visibl"> 54, </key>
+<key name="visual"> 17, </key>
+<key name="visualiz"> 54, </key>
 <key name="vk"> 2, </key>
-<key name="volum"> 13,14,15,16,17,2,22,6,25,8,10,12,60,61,34,68,71,73,52,75,76, </key>
-<key name="volume_margin"> 68, </key>
-<key name="vtk"> 0,53, </key>
-<key name="vxy"> 8,73, </key>
-<key name="wa_margin"> 68, </key>
-<key name="walk"> 64, </key>
-<key name="warp"> 16,26,60,68,49,54, </key>
-<key name="way"> 14,17,23,24,25,12,64,38,51, </key>
-<key name="weight"> 45, </key>
-<key name="well"> 64, </key>
-<key name="wheth"> 71, </key>
-<key name="whil"> 66,39, </key>
-<key name="whit"> 12,55, </key>
-<key name="whol"> 2,11,12,70,71,45,48, </key>
-<key name="whos"> 21,25,26,37,49, </key>
-<key name="will"> 13,14,0,17,1,18,19,20,2,21,22,23,6,24,7,25,26,9,28,29,30,11,12,31,33,32,59,36,61,63,34,37,64,67,39,40,70,42,71,43,44,45,47,74,49,51,52,76,54, </key>
-<key name="window"> 5, </key>
-<key name="wir"> 15,8,12,33,61,63,73, </key>
-<key name="wire_polylin"> 61, </key>
-<key name="wire_polyline_edg"> 61, </key>
-<key name="wire_polyline_mesh"> 61, </key>
-<key name="wirefram"> 0,65, </key>
-<key name="wish"> 23,7,9,31,53, </key>
-<key name="within"> 19,64,43, </key>
-<key name="without"> 1,12,68,69, </key>
-<key name="word"> 19, </key>
-<key name="work"> 1,12,63,67, </key>
-<key name="worst"> 20, </key>
-<key name="would"> 17,69,43, </key>
-<key name="ww"> 8, </key>
-<key name="x"> 14,5,54, </key>
-<key name="x0"> 61, </key>
-<key name="y"> 14,5, </key>
-<key name="y0"> 61, </key>
-<key name="your"> 13,14,16,0,17,1,18,19,20,2,21,5,22,23,24,25,28,29,30,31,33,32,35,36,34,64,65,38,39,40,41,71,44,45,46,47,48,52,76,54, </key>
-<key name="z"> 14,5, </key>
-<key name="z0"> 61, </key>
-<key name="zero"> 64, </key>
-<key name="zoom"> 53, </key>
+<key name="volum"> 14,15,16,17,18,2,23,7,26,9,11,13,61,63,35,70,74,76,53,78,79, </key>
+<key name="volume_margin"> 70, </key>
+<key name="vtk"> 0,54, </key>
+<key name="vxy"> 9,76, </key>
+<key name="wa_margin"> 70, </key>
+<key name="walk"> 66, </key>
+<key name="warp"> 17,27,61,70,50,55, </key>
+<key name="way"> 15,18,24,25,26,13,66,39,52, </key>
+<key name="weight"> 46, </key>
+<key name="well"> 66, </key>
+<key name="wheth"> 74, </key>
+<key name="whil"> 5,68,40, </key>
+<key name="whit"> 13,56, </key>
+<key name="whol"> 16,2,12,13,72,74,46,49, </key>
+<key name="whos"> 22,26,27,38,50, </key>
+<key name="will"> 14,15,0,18,1,19,20,21,2,5,22,23,24,7,25,8,26,27,10,29,30,31,12,13,32,34,33,60,37,63,65,35,38,66,69,40,41,72,43,74,44,45,46,48,77,50,52,53,79,55, </key>
+<key name="window"> 6, </key>
+<key name="wir"> 16,9,13,34,63,65,76, </key>
+<key name="wire_polylin"> 63, </key>
+<key name="wire_polyline_edg"> 63, </key>
+<key name="wire_polyline_mesh"> 63, </key>
+<key name="wirefram"> 0,67, </key>
+<key name="wish"> 24,8,10,32,54, </key>
+<key name="within"> 20,66,44, </key>
+<key name="without"> 1,13,70,71, </key>
+<key name="word"> 20, </key>
+<key name="work"> 1,13,65,69, </key>
+<key name="worst"> 21, </key>
+<key name="would"> 18,71,44, </key>
+<key name="wrong"> 63, </key>
+<key name="ww"> 9, </key>
+<key name="x"> 15,6,63,55, </key>
+<key name="x0"> 63, </key>
+<key name="xyz"> 63, </key>
+<key name="y"> 15,6,63, </key>
+<key name="y0"> 63, </key>
+<key name="your"> 14,15,17,0,18,1,19,20,21,2,22,6,23,24,25,26,29,30,31,32,34,33,36,37,35,66,67,39,40,41,42,74,45,46,47,48,49,53,79,55, </key>
+<key name="z"> 15,6,63, </key>
+<key name="z0"> 63, </key>
+<key name="zero"> 66, </key>
+<key name="zoom"> 54, </key>
 
 </ftswdata>  
index f81db8e9f716e8d9739ad849f65fc237d131b5fd..ae74c4dc1dd4ef6d8e71a483225724208bff078d 100755 (executable)
@@ -12,6 +12,7 @@
       <item name="Basic meshing algorithms" url="files/about_meshing_algorithms.htm" />
       <item name="Projection Algorithms" url="projection_algorithms.htm" />
       <item name="Radial Prism Algorithm" url="radial_prism.htm" />
+      <item name="Segments around Vertex Algorithm" url="segments_around_vertex_algorithm.htm" />
       <item name="Prism 3D Algorithm" url="prism_3d_algorithm.htm" />
     </book>
     <book name="Defining hypotheses" >
       <item name="Additional Hypotheses" url="files/non_conform_mesh_allowed_hypothesis.htm" />
     </book>
     <item name="Constructing submeshes" url="files/constructing_submeshes.htm" />
+    <item name="Building Compounds" url="building_compounds.htm" />
     <item name="Editing Meshes" url="files/reassigning_hypotheses_and_algorithms.htm" />
   </book>
   <book name="Viewing meshes" >
     <item name="Viewing meshes" url="about_viewing_meshes.htm" />
-    <item name="VTK 3D Viewer" url="files/vtk_3d_viewer.htm" />
     <item name="Mesh infos" url="files/viewing_mesh_info.htm" />
     <item name="Numbering" url="files/displaying_nodes_numbers.htm" />
     <item name="Display Mode" url="presentation.htm" />
@@ -74,6 +75,7 @@
       <item name="Merging Elements" url="merge_elements.htm" />
     </book>
     <item name="Moving nodes" url="files/displacing_nodes.htm" />
+    <item name="Mesh through point" url="mesh_through_point.htm" />
     <item name="Diagonal inversion of elements" url="files/diagonal_iversion_of_elements.htm" />
     <item name="Uniting two triangles" url="files/uniting_two_triangles.htm" />
     <item name="Uniting a set of triangles" url="files/uniting_a_set_of_triangles.htm" />
@@ -86,8 +88,8 @@
     <item name="Pattern mapping" url="pattern_mapping.htm" />
     <item name="Convert to/from Quadratic Mesh" url="convert_to_from_quadratic_mesh.htm" />
   </book>
- <item name="Python Interface smesh.py" url="smeshpy_doc/namespacesmesh.html" /> 
 <book name="TUI Scripts" >
+ <item name="Python Interface smesh.py" url="smeshpy_doc/namespacesmesh.html" />
+ <book name="TUI Scripts" >
     <item name="Creating Meshes" url="constructing_meshes.htm" />
     <item name="Viewing Meshes" url="viewing_meshes.htm" />
     <item name="Defining Hypotheses" url="defining_hypotheses_tui.htm" />
index 0e8dc99b8a7f5320d6decdd5d5f8dc69f38dc9fe..84d91680203dbd86ba300b1afd4989330d3e6235 100644 (file)
@@ -33,7 +33,8 @@ BASEIDL_FILES = \
        SMESH_BasicHypothesis.idl \
        SMESH_Filter.idl \
        SMESH_Group.idl \
-       SMESH_Pattern.idl
+       SMESH_Pattern.idl \
+       SMESH_MeshEditor.idl
 
 EXTRA_DIST+= $(BASEIDL_FILES)
 
@@ -51,7 +52,8 @@ nodist_libSalomeIDLSMESH_la_SOURCES = \
        SMESH_BasicHypothesisSK.cc \
        SMESH_FilterSK.cc \
        SMESH_GroupSK.cc \
-       SMESH_PatternSK.cc
+       SMESH_PatternSK.cc \
+       SMESH_MeshEditorSK.cc
 
 # header files must be exported: other modules have to use this library
 nodist_salomeinclude_HEADERS= $(BASEIDL_FILES:%.idl=%.hh)
index 8ae1235e764c461307607bead88f3e3198f132e6..cf2984bb31c3c7bf224d4aa030beedf19249bd1a 100644 (file)
@@ -507,6 +507,32 @@ module StdMeshers
       raises (SALOME::SALOME_Exception);
   };
 
+  /*!
+   * interface of "SegmentLengthAroundVertex" hypothesis.
+   * This hypothesis specifies length of segments adjacent to the vertex the
+   * hypothesis is assigned to
+   */
+  interface StdMeshers_SegmentLengthAroundVertex : SMESH::SMESH_Hypothesis
+  {
+    /*!
+     * Sets <length> parameter value
+     */
+    void SetLength(in double length)
+      raises (SALOME::SALOME_Exception);
+
+    /*!
+     * Returns <length> parameter value
+     */
+    double GetLength();
+  };
+
+  /*!
+   * StdMeshers_SegmentAroundVertex_0D: interface of "SegmentAroundVertex" algorithm
+   */
+  interface StdMeshers_SegmentAroundVertex_0D : SMESH::SMESH_0D_Algo
+  {
+  };
+
   /*!
    * StdMeshers_Regular_1D: interface of "Wire discretisation" algorithm
    */
@@ -514,6 +540,13 @@ module StdMeshers
   {
   };
 
+  /*!
+   * StdMeshers_CompositeSegment_1D: interface of "Composite side discretisation" algorithm
+   */
+  interface StdMeshers_CompositeSegment_1D : SMESH::SMESH_1D_Algo
+  {
+  };
+
   /*!
    * StdMeshers_MEFISTO_2D: interface of "Triangle (Mefisto)" algorithm
    */
@@ -536,7 +569,7 @@ module StdMeshers
   };
 
   /*!
-   * StdMeshers_Prism_3D: interface of "Prism 3D" algorithm
+   * StdMeshers_Prism_3D: interface of "3D extrusion" algorithm
    */
   interface StdMeshers_Prism_3D : SMESH::SMESH_3D_Algo
   {
index 5018b07815759813ab6ef3f6a71973c6f2b9b29f..fcb5a993682e38c48b15730bc2712e031273f84c 100644 (file)
@@ -55,6 +55,7 @@ module SMESH
     FT_BelongToGeom,
     FT_BelongToPlane,
     FT_BelongToCylinder,
+    FT_BelongToGenSurface,
     FT_LyingOnGeom,
     FT_RangeOfIds,
     FT_BadOrientedVolume,
@@ -158,22 +159,28 @@ module SMESH
 
   /*!
   * Logical functor (predicate) "Belong To Surface".
-  * Base interface for "belong to plane" and "belong to cylinder interfaces"
+  * Base interface for "belong to plane" and "belong to cylinder"
+  * and "Belong To Generic Surface" interfaces
   */
   interface BelongToSurface: Predicate
   {
-    void   SetTolerance( in double theToler );
-    double GetTolerance();
-    void   SetShapeName( in string theName, in ElementType theType );
-    void   SetShape( in string theID, in string theName, in ElementType theType );
-    string GetShapeName();
-    string GetShapeID();
+    void    SetTolerance( in double theToler );
+    double  GetTolerance();
+    void    SetShapeName( in string theName, in ElementType theType );
+    void    SetShape( in string theID, in string theName, in ElementType theType );
+    string  GetShapeName();
+    string  GetShapeID();
+    /*!
+    * Limit surface extent to bounding box of boundaries (edges)
+    * in surface parametric space. Boundaries are ignored by default
+    */
+    void    SetUseBoundaries( in boolean theUseBndRestrictions );
+    boolean GetUseBoundaries();
   };
 
-
   /*!
   * Logical functor (predicate) "Belong To Plane".
-  * Verify whether mesh element lie in pointed Geom planar object
+  * Verify whether mesh element lie on pointed Geom planar object
   */
   interface BelongToPlane: BelongToSurface
   {
@@ -181,14 +188,23 @@ module SMESH
   };
 
   /*!
-  * Logical functor (predicate) "Belong To Culinder".
-  * Verify whether mesh element lie in pointed Geom cylindrical object
+  * Logical functor (predicate) "Belong To Cylinder".
+  * Verify whether mesh element lie on pointed Geom cylindrical object
   */
   interface BelongToCylinder: BelongToSurface
   {
     void   SetCylinder( in GEOM::GEOM_Object theGeom, in ElementType theType );
   };
 
+  /*!
+  * Logical functor (predicate) "Belong To Generic Surface".
+  * Verify whether mesh element lie in pointed Geom cylindrical object
+  */
+  interface BelongToGenSurface: BelongToSurface
+  {
+    void   SetSurface( in GEOM::GEOM_Object theGeom, in ElementType theType );
+  };
+
   /*!
   * Logical functor (predicate) "Lying On Geometry".
   * Verify whether mesh element or node lying or partially lying on the pointed Geom Object
@@ -391,6 +407,7 @@ module SMESH
     BelongToGeom      CreateBelongToGeom();
     BelongToPlane     CreateBelongToPlane();
     BelongToCylinder  CreateBelongToCylinder();
+    BelongToGenSurface CreateBelongToGenSurface();
 
     LyingOnGeom       CreateLyingOnGeom();
 
index 475d0253a294bff99fd64ae31f96910a505441f5..92270813be23843781485fae1b96a35d3521ed10 100644 (file)
 module SMESH
 {
   typedef sequence<GEOM::GEOM_Object> object_array;
-  typedef sequence<SMESH_Mesh> mesh_array;
+  typedef sequence<SMESH_Mesh>        mesh_array;
 
   interface FilterManager;
   interface SMESH_Pattern;
 
-  enum AlgoStateErrorName { MISSING_ALGO, MISSING_HYPO, NOT_CONFORM_MESH, BAD_PARAM_VALUE };
-  struct AlgoStateError {
-    AlgoStateErrorName name;
+  /*!
+   * Hypothesis definintion error
+   */
+  struct AlgoStateError 
+  {
+    Hypothesis_Status  state;
     string             algoName;
     long               algoDim;
     boolean            isGlobalAlgo;
   };
   typedef sequence<AlgoStateError> algo_error_array;
-    
+
+  /*!
+   * Mesh computation error
+   */
+  enum ComputeErrorName
+  {
+    COMPERR_OK            ,
+    COMPERR_BAD_INPUT_MESH,  // wrong mesh on lower submesh
+    COMPERR_STD_EXCEPTION ,  // some std exception raised
+    COMPERR_OCC_EXCEPTION ,  // OCC exception raised
+    COMPERR_SLM_EXCEPTION ,  // SALOME exception raised
+    COMPERR_EXCEPTION     ,  // other exception raised
+    COMPERR_MEMORY_PB     ,  // memory allocation problem
+    COMPERR_ALGO_FAILED   ,  // computation failed
+    COMPERR_BAD_SHAPE        // bad geometry
+  };
+  struct ComputeError
+  {
+    short  code;       // ComputeErrorName or, if negative, algo specific code
+    string comment;    // textual problem description
+    string algoName;
+    short  subShapeID; // id of subshape of a shape to mesh
+  };
+  typedef sequence<ComputeError> compute_error_array;
+
+
   interface SMESH_Gen : Engines::Component, SALOMEDS::Driver
   {
 
@@ -169,6 +197,14 @@ module SMESH
                                    in GEOM::GEOM_Object theSubObject )
       raises ( SALOME::SALOME_Exception );
 
+    /*!
+     * Return errors of mesh computation
+     * compute_error_array is empty if everything is OK
+     */
+    compute_error_array GetComputeErrors( in SMESH_Mesh        theMesh, 
+                                          in GEOM::GEOM_Object theSubObject )
+      raises ( SALOME::SALOME_Exception );
+
     /*!
      * Return indeces of faces, edges and vertices of given subshapes
      * within theMainObject
@@ -195,6 +231,19 @@ module SMESH
                                                 in long        theElementID)
       raises ( SALOME::SALOME_Exception );
 
+    /*!
+     * Concatenate the given meshes into one mesh.
+     * Union groups with the same name and type if
+     * theUniteIdenticalGroups flag is true.
+     * Merge coincident nodes and elements if 
+     * theMergeNodesAndElements flag is true.
+     */
+    SMESH_Mesh Concatenate(in mesh_array theMeshesArray, 
+                          in boolean    theUniteIdenticalGroups, 
+                          in boolean    theMergeNodesAndElements, 
+                          in double     theMergeTolerance)
+      raises ( SALOME::SALOME_Exception );
+
   };
 
 };
index b4fdd1c814433d16c3fe9f3765695f9ed58ccb5a..4076e5c8af353bca37fd5549547bb95af62a844f 100644 (file)
@@ -33,6 +33,7 @@ module SMESH
 {
   enum Dimension
   {
+    DIM_0D,
     DIM_1D,
     DIM_2D,
     DIM_3D
@@ -72,6 +73,13 @@ module SMESH
 
   };
 
+  interface SMESH_0D_Algo : SMESH_Algo
+  {
+    /*!
+     * 
+     */
+  };
+
   interface SMESH_1D_Algo : SMESH_Algo
   {
     /*!
index bd524b8005abf68f53c2e7de9c61436f4a944c80..0e9d8ceb8abc167faaafe6448e35b4de92ba3d20 100644 (file)
@@ -38,9 +38,9 @@ module SMESH
   interface SMESH_GroupBase;
   typedef sequence<SMESH_GroupBase> ListOfGroups;
 
-  typedef sequence<double> double_array ;
-  typedef sequence<long> long_array ;
-  typedef sequence<string> string_array ;
+  typedef sequence<double    > double_array ;
+  typedef sequence<long      > long_array ;
+  typedef sequence<string    > string_array ;
   typedef sequence<long_array> array_of_long_array ;
 
   enum log_command
@@ -81,6 +81,9 @@ module SMESH
   struct PointStruct { double x;
                       double y;
                       double z; } ;
+
+  typedef sequence<PointStruct> nodes_array;
+
   struct DirStruct   { PointStruct PS ; } ;          // analog to Occ Direction
 
   struct AxisStruct  { double x;
@@ -121,6 +124,8 @@ module SMESH
     HYP_MISSING,      // algo misses a hypothesis
     HYP_CONCURENT,    // several applicable hypotheses
     HYP_BAD_PARAMETER,// hypothesis has a bad parameter value
+    HYP_HIDDEN_ALGO,  // an algo is hidden by an upper dim algo generating all-dim elements
+    HYP_HIDING_ALGO,  // an algo hides lower dim algos by generating all-dim elements
     HYP_UNKNOWN_FATAL,//  --- all statuses below should be considered as fatal
                       //      for Add/RemoveHypothesis operations
     HYP_INCOMPATIBLE, // hypothesis does not fit algo
@@ -178,31 +183,27 @@ module SMESH
   interface SMESH_MeshEditor;
   interface SMESH_Mesh : SALOME::GenericObj, SMESH_IDSource
   {
-    ///*!
-    // * Associate a Shape to a Mesh created with NewEmpty
-    // */
-    //boolean SetMesh(in GEOM::GEOM_Object anObject)
-    //  raises (SALOME::SALOME_Exception);
+    /*!
+     * Return true if there is a geometry to be meshed
+     */
+    boolean HasShapeToMesh()
+      raises (SALOME::SALOME_Exception);
 
     /*!
-     * Get the subMesh object associated to a subShape. The subMesh object
-     * gives access to nodes and elements IDs.
-     * SubMesh will be used instead of SubShape in a next idl version to
-     * adress a specific subMesh...
+     * Get geom shape to mesh. A result sould not be nil. Use HasShapeToMesh()
+     * to know if a returned shape 
      */
-    SMESH_subMesh GetSubMesh(in GEOM::GEOM_Object aSubObject, in string name)
+    GEOM::GEOM_Object GetShapeToMesh()
       raises (SALOME::SALOME_Exception);
 
-    ///*!
-    // * Create a subMesh without reference to a subShape
-    // */
-    //SMESH_subMesh NewEmpty()
-    //  raises (SALOME::SALOME_Exception);
 
     /*!
-     * Get geom shape to mesh. A result may be nil
+     * Get the subMesh object associated to a subShape. The subMesh object
+     * gives access to nodes and elements IDs.
+     * SubMesh will be used instead of SubShape in a next idl version to
+     * adress a specific subMesh...
      */
-    GEOM::GEOM_Object GetShapeToMesh()
+    SMESH_subMesh GetSubMesh(in GEOM::GEOM_Object aSubObject, in string name)
       raises (SALOME::SALOME_Exception);
 
     /*!
@@ -211,6 +212,7 @@ module SMESH
     void RemoveSubMesh(in SMESH_subMesh aSubMesh)
       raises (SALOME::SALOME_Exception);
 
+
     /*!
      * Create a group
      */
@@ -349,6 +351,13 @@ module SMESH
     SMESH_MeshEditor GetMeshEditor()
       raises (SALOME::SALOME_Exception);
 
+    /*!
+     * Return SMESH_MeshEditor that would not modify the mesh but
+     * fill MeshPreviewStruct
+     */
+    SMESH_MeshEditor GetMeshEditPreviewer()
+      raises (SALOME::SALOME_Exception);
+
     /*! Check group names for duplications.
      *  Consider maximum group name length stored in MED file.
      */
@@ -494,7 +503,7 @@ module SMESH
     /*!
      * Get mesh pointer
      */
-    long GetMeshPtr();
+    long long GetMeshPtr();
 
     /*!
      * Get XYZ coordinates of node as list of double
@@ -642,348 +651,6 @@ module SMESH
       raises (SALOME::SALOME_Exception);
   };
 
-  /*!
-   * This interface makes modifications on the Mesh - removing elements and nodes etc.
-   */
-  interface NumericalFunctor;
-  interface SMESH_MeshEditor
-  {
-    boolean RemoveElements(in long_array IDsOfElements);
-
-    boolean RemoveNodes(in long_array IDsOfNodes);
-
-    long AddNode(in double x, in double y, in double z);
-
-    /*!
-     *  Create edge, either linear and quadratic (this is determed
-     *  by number of given nodes).
-     *  \param IdsOfNodes List of node IDs for creation of element.
-     *  Needed order of nodes in this list corresponds to description
-     *  of MED. This description is located by the following link:
-     *   http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
-     */
-    long AddEdge(in long_array IDsOfNodes);
-
-    /*!
-     *  Create face, either linear and quadratic (this is determed
-     *  by number of given nodes).
-     *  \param IdsOfNodes List of node IDs for creation of element.
-     *  Needed order of nodes in this list corresponds to description
-     *  of MED. This description is located by the following link:
-     *   http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
-     */
-    long AddFace(in long_array IDsOfNodes);
-
-    long AddPolygonalFace(in long_array IdsOfNodes);
-
-    /*!
-     *  Create volume, either linear and quadratic (this is determed
-     *  by number of given nodes).
-     *  \param IdsOfNodes List of node IDs for creation of element.
-     *  Needed order of nodes in this list corresponds to description
-     *  of MED. This description is located by the following link:
-     *   http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
-     */
-    long AddVolume(in long_array IDsOfNodes);
-
-    /*!
-     *  Create volume of many faces, giving nodes for each face.
-     *  \param IdsOfNodes List of node IDs for volume creation face by face.
-     *  \param Quantities List of integer values, Quantities[i]
-     *         gives quantity of nodes in face number i.
-     */
-    long AddPolyhedralVolume (in long_array IdsOfNodes,
-                                in long_array Quantities);
-
-    /*!
-     *  Create volume of many faces, giving IDs of existing faces.
-     *  \param IdsOfFaces List of face IDs for volume creation.
-     *  \note The created volume will refer only to nodes
-     *        of the given faces, not to the faces itself.
-     */
-    long AddPolyhedralVolumeByFaces (in long_array IdsOfFaces);
-
-    boolean MoveNode(in long NodeID, in double x, in double y, in double z);
-
-    boolean InverseDiag(in long NodeID1, in long NodeID2);
-
-    boolean DeleteDiag(in long NodeID1, in long NodeID2);
-
-    boolean Reorient(in long_array IDsOfElements);
-
-    boolean ReorientObject(in SMESH_IDSource theObject);
-
-    /*!
-     * \brief Fuse neighbour triangles into quadrangles.
-     * \param theElems     The triangles to be fused.
-     * \param theCriterion Is used to choose a neighbour to fuse with.
-     * \param theMaxAngle  Is a max angle between element normals at which fusion
-     *                     is still performed; theMaxAngle is mesured in radians.
-     * \return TRUE in case of success, FALSE otherwise.
-     */
-    boolean TriToQuad (in long_array       IDsOfElements,
-                      in NumericalFunctor Criterion,
-                      in double           MaxAngle);
-
-    /*!
-     * \brief Fuse neighbour triangles into quadrangles.
-     *
-     * Behaves like the above method, taking list of elements from \a theObject
-     */
-    boolean TriToQuadObject (in SMESH_IDSource   theObject,
-                            in NumericalFunctor Criterion,
-                            in double           MaxAngle);
-
-    /*!
-     * \brief Split quadrangles into triangles.
-     * \param theElems     The faces to be splitted.
-     * \param theCriterion Is used to choose a diagonal for splitting.
-     * \return TRUE in case of success, FALSE otherwise.
-     */
-    boolean QuadToTri (in long_array       IDsOfElements,
-                      in NumericalFunctor Criterion);
-
-    /*!
-     * \brief Split quadrangles into triangles.
-     *
-     * Behaves like the above method, taking list of elements from \a theObject
-     */
-    boolean QuadToTriObject (in SMESH_IDSource   theObject,
-                            in NumericalFunctor Criterion);
-
-    /*!
-     * \brief Split quadrangles into triangles.
-     * \param theElems  The faces to be splitted.
-     * \param the13Diag Is used to choose a diagonal for splitting.
-     * \return TRUE in case of success, FALSE otherwise.
-     */
-    boolean SplitQuad (in long_array IDsOfElements,
-                      in boolean    Diag13);
-
-    /*!
-     * \brief Split quadrangles into triangles.
-     *
-     * Behaves like the above method, taking list of elements from \a theObject
-     */
-    boolean SplitQuadObject (in SMESH_IDSource theObject,
-                            in boolean        Diag13);
-
-    /*!
-     *  Find better splitting of the given quadrangle.
-     *  \param IDOfQuad  ID of the quadrangle to be splitted.
-     *  \param Criterion A criterion to choose a diagonal for splitting.
-     *  \return 1 if 1-3 diagonal is better, 2 if 2-4
-     *          diagonal is better, 0 if error occurs.
-     */
-    long BestSplit (in long             IDOfQuad,
-                   in NumericalFunctor Criterion);
-
-    enum Smooth_Method { LAPLACIAN_SMOOTH, CENTROIDAL_SMOOTH };
-
-    boolean Smooth(in long_array    IDsOfElements,
-                   in long_array    IDsOfFixedNodes,
-                   in long          MaxNbOfIterations,
-                   in double        MaxAspectRatio,
-                   in Smooth_Method Method);
-
-    boolean SmoothObject(in SMESH_IDSource  theObject,
-                        in long_array      IDsOfFixedNodes,
-                        in long            MaxNbOfIterations,
-                        in double          MaxAspectRatio,
-                        in Smooth_Method   Method);
-
-    boolean SmoothParametric(in long_array    IDsOfElements,
-                             in long_array    IDsOfFixedNodes,
-                             in long          MaxNbOfIterations,
-                             in double        MaxAspectRatio,
-                             in Smooth_Method Method);
-
-    boolean SmoothParametricObject(in SMESH_IDSource  theObject,
-                                   in long_array      IDsOfFixedNodes,
-                                   in long            MaxNbOfIterations,
-                                   in double          MaxAspectRatio,
-                                   in Smooth_Method   Method);
-
-    void ConvertToQuadratic(in boolean theForce3d);
-
-    boolean ConvertFromQuadratic();
-
-    void RenumberNodes();
-
-    void RenumberElements();
-
-    void RotationSweep(in long_array       IDsOfElements,
-                       in AxisStruct       Axix,
-                       in double           AngleInRadians,
-                       in long             NbOfSteps,
-                       in double           Tolerance);
-
-    void RotationSweepObject(in SMESH_IDSource  theObject,
-                            in AxisStruct      Axix,
-                            in double          AngleInRadians,
-                            in long            NbOfSteps,
-                            in double          Tolerance);
-
-    void ExtrusionSweep(in long_array      IDsOfElements,
-                        in DirStruct       StepVector,
-                        in long            NbOfSteps);
-
-   /*!
-    * Generate new elements by extrusion of theElements 
-    * by StepVector by NbOfSteps
-    * param ExtrFlags set flags for performing extrusion
-    * param SewTolerance - uses for comparing locations of nodes if flag
-    *   EXTRUSION_FLAG_SEW is set
-    */
-    void AdvancedExtrusion(in long_array      IDsOfElements,
-                           in DirStruct       StepVector,
-                           in long            NbOfSteps,
-                          in long            ExtrFlags,
-                          in double          SewTolerance);
-
-    void ExtrusionSweepObject(in SMESH_IDSource  theObject,
-                             in DirStruct       StepVector,
-                             in long            NbOfSteps);
-
-    void ExtrusionSweepObject1D(in SMESH_IDSource theObject,
-                               in DirStruct      StepVector,
-                               in long           NbOfSteps);
-
-    void ExtrusionSweepObject2D(in SMESH_IDSource theObject,
-                               in DirStruct      StepVector,
-                               in long           NbOfSteps);
-
-    enum Extrusion_Error {
-      EXTR_OK,
-      EXTR_NO_ELEMENTS,
-      EXTR_PATH_NOT_EDGE,
-      EXTR_BAD_PATH_SHAPE,
-      EXTR_BAD_STARTING_NODE,
-      EXTR_BAD_ANGLES_NUMBER,
-      EXTR_CANT_GET_TANGENT
-      };
-
-    Extrusion_Error ExtrusionAlongPath(in long_array        IDsOfElements,
-                                      in SMESH_Mesh        PathMesh,
-                                      in GEOM::GEOM_Object PathShape,
-                                      in long              NodeStart,
-                                      in boolean           HasAngles,
-                                      in double_array      Angles,
-                                      in boolean           HasRefPoint,
-                                      in PointStruct       RefPoint);
-
-    Extrusion_Error ExtrusionAlongPathObject(in SMESH_IDSource    theObject,
-                                            in SMESH_Mesh        PathMesh,
-                                            in GEOM::GEOM_Object PathShape,
-                                            in long              NodeStart,
-                                            in boolean           HasAngles,
-                                            in double_array      Angles,
-                                            in boolean           HasRefPoint,
-                                            in PointStruct       RefPoint);
-
-    enum MirrorType { POINT, AXIS, PLANE };
-
-    void Mirror (in long_array       IDsOfElements,
-                 in AxisStruct       Mirror,
-                 in MirrorType       theMirrorType,
-                 in boolean          Copy);
-
-    void MirrorObject (in SMESH_IDSource  theObject,
-                      in AxisStruct      Mirror,
-                      in MirrorType      theMirrorType,
-                      in boolean         Copy);
-
-    void Translate (in long_array      IDsOfElements,
-                    in DirStruct       Vector,
-                    in boolean         Copy);
-
-    void TranslateObject (in SMESH_IDSource  theObject,
-                         in DirStruct       Vector,
-                         in boolean         Copy);
-
-    void Rotate (in long_array       IDsOfElements,
-                 in AxisStruct       Axis,
-                 in double           AngleInRadians,
-                 in boolean          Copy);
-
-    void RotateObject (in SMESH_IDSource  theObject,
-                      in AxisStruct      Axis,
-                      in double          AngleInRadians,
-                      in boolean         Copy);
-
-    void FindCoincidentNodes (in  double              Tolerance,
-                              out array_of_long_array GroupsOfNodes);
-
-    void MergeNodes (in array_of_long_array GroupsOfNodes);
-
-    void MergeEqualElements();
-
-    enum Sew_Error {
-      SEW_OK,
-      SEW_BORDER1_NOT_FOUND,
-      SEW_BORDER2_NOT_FOUND,
-      SEW_BOTH_BORDERS_NOT_FOUND,
-      SEW_BAD_SIDE_NODES,
-      SEW_VOLUMES_TO_SPLIT,
-      // for SewSideElements() only:
-      SEW_DIFF_NB_OF_ELEMENTS,
-      SEW_TOPO_DIFF_SETS_OF_ELEMENTS,
-      SEW_BAD_SIDE1_NODES,
-      SEW_BAD_SIDE2_NODES
-      };
-
-    Sew_Error SewFreeBorders (in long FirstNodeID1,
-                              in long SecondNodeID1,
-                              in long LastNodeID1,
-                              in long FirstNodeID2,
-                              in long SecondNodeID2,
-                              in long LastNodeID2,
-                             in boolean CreatePolygons,
-                             in boolean CreatePolyedrs);
-
-    Sew_Error SewConformFreeBorders (in long FirstNodeID1,
-                                     in long SecondNodeID1,
-                                     in long LastNodeID1,
-                                     in long FirstNodeID2,
-                                     in long SecondNodeID2);
-
-    Sew_Error SewBorderToSide (in long FirstNodeIDOnFreeBorder,
-                               in long SecondNodeIDOnFreeBorder,
-                               in long LastNodeIDOnFreeBorder,
-                               in long FirstNodeIDOnSide,
-                               in long LastNodeIDOnSide,
-                              in boolean CreatePolygons,
-                              in boolean CreatePolyedrs);
-
-    Sew_Error SewSideElements (in long_array IDsOfSide1Elements,
-                               in long_array IDsOfSide2Elements,
-                               in long       NodeID1OfSide1ToMerge,
-                               in long       NodeID1OfSide2ToMerge,
-                               in long       NodeID2OfSide1ToMerge,
-                               in long       NodeID2OfSide2ToMerge);
-
-   /*!
-    * Set new nodes for given element.
-    * If number of nodes is not corresponded to type of
-    * element - returns false
-    */
-    boolean ChangeElemNodes(in long ide, in long_array newIDs);
-
-   /*!
-    * If during last operation of MeshEditor some nodes were
-    * created this method returns list of it's IDs, if new nodes
-    * not creared - returns empty list
-    */
-    long_array GetLastCreatedNodes();
-
-   /*!
-    * If during last operation of MeshEditor some elements were
-    * created this method returns list of it's IDs, if new elements
-    * not creared - returns empty list
-    */
-    long_array GetLastCreatedElems();
-
-  };
 };
 
 #endif
diff --git a/idl/SMESH_MeshEditor.idl b/idl/SMESH_MeshEditor.idl
new file mode 100644 (file)
index 0000000..a4dfb1d
--- /dev/null
@@ -0,0 +1,437 @@
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : SMESH_MeshEditor.idl
+//  $Header$
+
+#ifndef _SMESH_MESHEDITOR_IDL_
+#define _SMESH_MESHEDITOR_IDL_
+
+#include "SMESH_Mesh.idl"
+
+module SMESH
+{
+  /*!
+   * Structure used in mesh edit preview data
+   */
+  struct ElementSubType { ElementType SMDS_ElementType;
+                          boolean     isPoly;
+                          long        nbNodesInElement; };
+
+  typedef sequence<ElementSubType> types_array;
+
+  /*!
+   * Structure containing mesh edit preview data
+   */
+  struct MeshPreviewStruct { nodes_array nodesXYZ;
+                             long_array  elementConnectivities;
+                             types_array elementTypes; };
+
+  /*!
+   * This interface makes modifications on the Mesh - removing elements and nodes etc.
+   */
+  interface NumericalFunctor;
+  interface SMESH_MeshEditor
+  {
+    boolean RemoveElements(in long_array IDsOfElements);
+
+    boolean RemoveNodes(in long_array IDsOfNodes);
+
+    long AddNode(in double x, in double y, in double z);
+
+    /*!
+     *  Create edge, either linear and quadratic (this is determed
+     *  by number of given nodes).
+     *  \param IdsOfNodes List of node IDs for creation of element.
+     *  Needed order of nodes in this list corresponds to description
+     *  of MED. This description is located by the following link:
+     *   http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
+     */
+    long AddEdge(in long_array IDsOfNodes);
+
+    /*!
+     *  Create face, either linear and quadratic (this is determed
+     *  by number of given nodes).
+     *  \param IdsOfNodes List of node IDs for creation of element.
+     *  Needed order of nodes in this list corresponds to description
+     *  of MED. This description is located by the following link:
+     *   http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
+     */
+    long AddFace(in long_array IDsOfNodes);
+
+    long AddPolygonalFace(in long_array IdsOfNodes);
+
+    /*!
+     *  Create volume, either linear and quadratic (this is determed
+     *  by number of given nodes).
+     *  \param IdsOfNodes List of node IDs for creation of element.
+     *  Needed order of nodes in this list corresponds to description
+     *  of MED. This description is located by the following link:
+     *   http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3.
+     */
+    long AddVolume(in long_array IDsOfNodes);
+
+    /*!
+     *  Create volume of many faces, giving nodes for each face.
+     *  \param IdsOfNodes List of node IDs for volume creation face by face.
+     *  \param Quantities List of integer values, Quantities[i]
+     *         gives quantity of nodes in face number i.
+     */
+    long AddPolyhedralVolume (in long_array IdsOfNodes,
+                              in long_array Quantities);
+
+    /*!
+     *  Create volume of many faces, giving IDs of existing faces.
+     *  \param IdsOfFaces List of face IDs for volume creation.
+     *  \note The created volume will refer only to nodes
+     *        of the given faces, not to the faces itself.
+     */
+    long AddPolyhedralVolumeByFaces (in long_array IdsOfFaces);
+
+    boolean MoveNode(in long NodeID, in double x, in double y, in double z);
+
+    boolean InverseDiag(in long NodeID1, in long NodeID2);
+
+    boolean DeleteDiag(in long NodeID1, in long NodeID2);
+
+    boolean Reorient(in long_array IDsOfElements);
+
+    boolean ReorientObject(in SMESH_IDSource theObject);
+
+    /*!
+     * \brief Fuse neighbour triangles into quadrangles.
+     * \param theElems     The triangles to be fused.
+     * \param theCriterion Is used to choose a neighbour to fuse with.
+     * \param theMaxAngle  Is a max angle between element normals at which fusion
+     *                     is still performed; theMaxAngle is mesured in radians.
+     * \return TRUE in case of success, FALSE otherwise.
+     */
+    boolean TriToQuad (in long_array       IDsOfElements,
+                      in NumericalFunctor Criterion,
+                      in double           MaxAngle);
+
+    /*!
+     * \brief Fuse neighbour triangles into quadrangles.
+     *
+     * Behaves like the above method, taking list of elements from \a theObject
+     */
+    boolean TriToQuadObject (in SMESH_IDSource   theObject,
+                            in NumericalFunctor Criterion,
+                            in double           MaxAngle);
+
+    /*!
+     * \brief Split quadrangles into triangles.
+     * \param theElems     The faces to be splitted.
+     * \param theCriterion Is used to choose a diagonal for splitting.
+     * \return TRUE in case of success, FALSE otherwise.
+     */
+    boolean QuadToTri (in long_array       IDsOfElements,
+                      in NumericalFunctor Criterion);
+
+    /*!
+     * \brief Split quadrangles into triangles.
+     *
+     * Behaves like the above method, taking list of elements from \a theObject
+     */
+    boolean QuadToTriObject (in SMESH_IDSource   theObject,
+                            in NumericalFunctor Criterion);
+
+    /*!
+     * \brief Split quadrangles into triangles.
+     * \param theElems  The faces to be splitted.
+     * \param the13Diag Is used to choose a diagonal for splitting.
+     * \return TRUE in case of success, FALSE otherwise.
+     */
+    boolean SplitQuad (in long_array IDsOfElements,
+                      in boolean    Diag13);
+
+    /*!
+     * \brief Split quadrangles into triangles.
+     *
+     * Behaves like the above method, taking list of elements from \a theObject
+     */
+    boolean SplitQuadObject (in SMESH_IDSource theObject,
+                            in boolean        Diag13);
+
+    /*!
+     *  Find better splitting of the given quadrangle.
+     *  \param IDOfQuad  ID of the quadrangle to be splitted.
+     *  \param Criterion A criterion to choose a diagonal for splitting.
+     *  \return 1 if 1-3 diagonal is better, 2 if 2-4
+     *          diagonal is better, 0 if error occurs.
+     */
+    long BestSplit (in long             IDOfQuad,
+                   in NumericalFunctor Criterion);
+
+    enum Smooth_Method { LAPLACIAN_SMOOTH, CENTROIDAL_SMOOTH };
+
+    boolean Smooth(in long_array    IDsOfElements,
+                   in long_array    IDsOfFixedNodes,
+                   in long          MaxNbOfIterations,
+                   in double        MaxAspectRatio,
+                   in Smooth_Method Method);
+
+    boolean SmoothObject(in SMESH_IDSource  theObject,
+                        in long_array      IDsOfFixedNodes,
+                        in long            MaxNbOfIterations,
+                        in double          MaxAspectRatio,
+                        in Smooth_Method   Method);
+
+    boolean SmoothParametric(in long_array    IDsOfElements,
+                             in long_array    IDsOfFixedNodes,
+                             in long          MaxNbOfIterations,
+                             in double        MaxAspectRatio,
+                             in Smooth_Method Method);
+
+    boolean SmoothParametricObject(in SMESH_IDSource  theObject,
+                                   in long_array      IDsOfFixedNodes,
+                                   in long            MaxNbOfIterations,
+                                   in double          MaxAspectRatio,
+                                   in Smooth_Method   Method);
+
+    void ConvertToQuadratic(in boolean theForce3d);
+
+    boolean ConvertFromQuadratic();
+
+    void RenumberNodes();
+
+    void RenumberElements();
+
+    void RotationSweep(in long_array       IDsOfElements,
+                       in AxisStruct       Axix,
+                       in double           AngleInRadians,
+                       in long             NbOfSteps,
+                       in double           Tolerance);
+
+    void RotationSweepObject(in SMESH_IDSource  theObject,
+                            in AxisStruct      Axix,
+                            in double          AngleInRadians,
+                            in long            NbOfSteps,
+                            in double          Tolerance);
+
+    void ExtrusionSweep(in long_array      IDsOfElements,
+                        in DirStruct       StepVector,
+                        in long            NbOfSteps);
+
+   /*!
+    * Generate new elements by extrusion of theElements 
+    * by StepVector by NbOfSteps
+    * param ExtrFlags set flags for performing extrusion
+    * param SewTolerance - uses for comparing locations of nodes if flag
+    *   EXTRUSION_FLAG_SEW is set
+    */
+    void AdvancedExtrusion(in long_array      IDsOfElements,
+                           in DirStruct       StepVector,
+                           in long            NbOfSteps,
+                          in long            ExtrFlags,
+                          in double          SewTolerance);
+
+    void ExtrusionSweepObject(in SMESH_IDSource  theObject,
+                             in DirStruct       StepVector,
+                             in long            NbOfSteps);
+
+    void ExtrusionSweepObject1D(in SMESH_IDSource theObject,
+                               in DirStruct      StepVector,
+                               in long           NbOfSteps);
+
+    void ExtrusionSweepObject2D(in SMESH_IDSource theObject,
+                               in DirStruct      StepVector,
+                               in long           NbOfSteps);
+
+    enum Extrusion_Error {
+      EXTR_OK,
+      EXTR_NO_ELEMENTS,
+      EXTR_PATH_NOT_EDGE,
+      EXTR_BAD_PATH_SHAPE,
+      EXTR_BAD_STARTING_NODE,
+      EXTR_BAD_ANGLES_NUMBER,
+      EXTR_CANT_GET_TANGENT
+      };
+
+    Extrusion_Error ExtrusionAlongPath(in long_array        IDsOfElements,
+                                      in SMESH_Mesh        PathMesh,
+                                      in GEOM::GEOM_Object PathShape,
+                                      in long              NodeStart,
+                                      in boolean           HasAngles,
+                                      in double_array      Angles,
+                                      in boolean           HasRefPoint,
+                                      in PointStruct       RefPoint);
+
+    Extrusion_Error ExtrusionAlongPathObject(in SMESH_IDSource    theObject,
+                                            in SMESH_Mesh        PathMesh,
+                                            in GEOM::GEOM_Object PathShape,
+                                            in long              NodeStart,
+                                            in boolean           HasAngles,
+                                            in double_array      Angles,
+                                            in boolean           HasRefPoint,
+                                            in PointStruct       RefPoint);
+
+   /*!
+    * Compute rotation angles for ExtrusionAlongPath as linear variation
+    * of given angles along path steps
+    * param PathMesh mesh containing a 1D sub-mesh on the edge, along 
+    *                which proceeds the extrusion
+    * param PathShape is shape(edge); as the mesh can be complex, the edge 
+    *                 is used to define the sub-mesh for the path
+    */
+    double_array LinearAnglesVariation(in SMESH_Mesh        PathMesh,
+                                       in GEOM::GEOM_Object PathShape,
+                                       in double_array      Angles);
+
+    enum MirrorType { POINT, AXIS, PLANE };
+
+    void Mirror (in long_array       IDsOfElements,
+                 in AxisStruct       Mirror,
+                 in MirrorType       theMirrorType,
+                 in boolean          Copy);
+
+    void MirrorObject (in SMESH_IDSource  theObject,
+                      in AxisStruct      Mirror,
+                      in MirrorType      theMirrorType,
+                      in boolean         Copy);
+
+    void Translate (in long_array      IDsOfElements,
+                    in DirStruct       Vector,
+                    in boolean         Copy);
+
+    void TranslateObject (in SMESH_IDSource  theObject,
+                         in DirStruct       Vector,
+                         in boolean         Copy);
+
+    void Rotate (in long_array       IDsOfElements,
+                 in AxisStruct       Axis,
+                 in double           AngleInRadians,
+                 in boolean          Copy);
+
+    void RotateObject (in SMESH_IDSource  theObject,
+                      in AxisStruct      Axis,
+                      in double          AngleInRadians,
+                      in boolean         Copy);
+
+    void FindCoincidentNodes (in  double              Tolerance,
+                              out array_of_long_array GroupsOfNodes);
+
+    void FindCoincidentNodesOnPart (in  SMESH_IDSource      SubMeshOrGroup,
+                                   in  double              Tolerance,
+                                   out array_of_long_array GroupsOfNodes);
+
+    void MergeNodes (in array_of_long_array GroupsOfNodes);
+
+    /*!
+     * \brief Find elements built on the same nodes.
+     * \param MeshOrSubMeshOrGroup Mesh or SubMesh, or Group of elements for searching.
+     * \return List of groups of equal elements.
+     */
+    void FindEqualElements (in  SMESH_IDSource      MeshOrSubMeshOrGroup,
+                           out array_of_long_array GroupsOfElementsID);
+
+    /*!
+     * \brief Merge elements in each given group.
+     * \param GroupsOfElementsID Groups of elements for merging.
+     */
+    void MergeElements(in array_of_long_array GroupsOfElementsID);
+
+    /*!
+     * \brief Merge equal elements in the whole mesh.
+     */
+    void MergeEqualElements();
+    
+    /*!
+     * If the given ID is a valid node ID (nodeID > 0), just move this node, else
+     * move the node closest to the point to point's location and return ID of the node
+     */
+    long MoveClosestNodeToPoint(in double x, in double y, in double z, in long nodeID);
+
+    enum Sew_Error {
+      SEW_OK,
+      SEW_BORDER1_NOT_FOUND,
+      SEW_BORDER2_NOT_FOUND,
+      SEW_BOTH_BORDERS_NOT_FOUND,
+      SEW_BAD_SIDE_NODES,
+      SEW_VOLUMES_TO_SPLIT,
+      // for SewSideElements() only:
+      SEW_DIFF_NB_OF_ELEMENTS,
+      SEW_TOPO_DIFF_SETS_OF_ELEMENTS,
+      SEW_BAD_SIDE1_NODES,
+      SEW_BAD_SIDE2_NODES
+      };
+
+    Sew_Error SewFreeBorders (in long FirstNodeID1,
+                              in long SecondNodeID1,
+                              in long LastNodeID1,
+                              in long FirstNodeID2,
+                              in long SecondNodeID2,
+                              in long LastNodeID2,
+                             in boolean CreatePolygons,
+                             in boolean CreatePolyedrs);
+
+    Sew_Error SewConformFreeBorders (in long FirstNodeID1,
+                                     in long SecondNodeID1,
+                                     in long LastNodeID1,
+                                     in long FirstNodeID2,
+                                     in long SecondNodeID2);
+
+    Sew_Error SewBorderToSide (in long FirstNodeIDOnFreeBorder,
+                               in long SecondNodeIDOnFreeBorder,
+                               in long LastNodeIDOnFreeBorder,
+                               in long FirstNodeIDOnSide,
+                               in long LastNodeIDOnSide,
+                              in boolean CreatePolygons,
+                              in boolean CreatePolyedrs);
+
+    Sew_Error SewSideElements (in long_array IDsOfSide1Elements,
+                               in long_array IDsOfSide2Elements,
+                               in long       NodeID1OfSide1ToMerge,
+                               in long       NodeID1OfSide2ToMerge,
+                               in long       NodeID2OfSide1ToMerge,
+                               in long       NodeID2OfSide2ToMerge);
+
+   /*!
+    * Set new nodes for given element.
+    * If number of nodes is not corresponded to type of
+    * element - returns false
+    */
+    boolean ChangeElemNodes(in long ide, in long_array newIDs);
+
+   /*!
+    * Return data of mesh edition preview which is computed provided 
+    * that the editor was obtained trough SMESH_Mesh::GetMeshEditPreviewer()
+    */
+    MeshPreviewStruct GetPreviewData();
+
+   /*!
+    * If during last operation of MeshEditor some nodes were
+    * created this method returns list of it's IDs, if new nodes
+    * not creared - returns empty list
+    */
+    long_array GetLastCreatedNodes();
+
+   /*!
+    * If during last operation of MeshEditor some elements were
+    * created this method returns list of it's IDs, if new elements
+    * not creared - returns empty list
+    */
+    long_array GetLastCreatedElems();
+
+  };
+};
+
+#endif
index 2593cf94ca92ae54ba92e2da8b79417b06b3d2d9..f7ea6685ba23c3622514b225de81b81ba0ae2385 100644 (file)
@@ -168,6 +168,9 @@ dist_salomeres_DATA = \
        mesh_tree_hypo_source_edge.png \
        mesh_tree_hypo_source_3d_shape.png \
        mesh_tree_hypo_projection_3d.png \
-       mesh_tree_hypo_projection_2d.png
+       mesh_tree_hypo_projection_2d.png \
+       mesh_build_compound.png \
+       mesh_node_to_point.png \
+       mesh_tree_mesh_partial.png
 
 nodist_salomeres_DATA = SMESHCatalog.xml
index 7d314c75df252290c08ab99d2a2e2f41b0fc227b..6702d3e213e59e0f8008ae3cb298a8f408ff32f0 100644 (file)
@@ -24,6 +24,7 @@
         <popup-item item-id="121" pos-id="" label-id="DAT File" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
         <popup-item item-id="122" pos-id="" label-id="MED File" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
         <popup-item item-id="123" pos-id="" label-id="UNV File" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+        <popup-item item-id="140" pos-id="" label-id="STL File" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
       </submenu>
       <endsubmenu />
       <separator pos-id="10"/>
    <separator pos-id=""/>
    <popup-item item-id="122" pos-id="" label-id="Export to MED" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>   
    <popup-item item-id="123" pos-id="" label-id="Export to UNV" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>   
+   <popup-item item-id="140" pos-id="" label-id="Export to STL" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>   
 </popupmenu>
 
 <popupmenu label-id="Popup for ObjectBrowser" context-id="" parent-id="ObjectBrowser" object-id="SubMesh">
index d5dbf4640e29e36ab9d46671692c1328788c2991..e25d5ef35edcba377db720bbc3a7853d7842b02d 100644 (file)
@@ -24,6 +24,7 @@
         <popup-item item-id="121" pos-id="" label-id="DAT File" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
         <popup-item item-id="122" pos-id="" label-id="MED File" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
         <popup-item item-id="123" pos-id="" label-id="UNV File" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+        <popup-item item-id="140" pos-id="" label-id="STL File" icon-id="" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
       </submenu>
       <endsubmenu />
       <separator pos-id="10"/>
index 3a69b96cf97ce351e1af21664cbcfdcc5936ca74..9b1a1dfaf18c2af0b28cc3aa2a8d174072986b13 100644 (file)
                gui-lib="StdMeshersGUI">
   <hypotheses>
 
+    <hypothesis type="SegmentLengthAroundVertex"
+                label-id="Length Near Vertex"
+                icon-id="mesh_hypo_length.png"
+                dim="0"/>
+
     <hypothesis type="LocalLength"
                 label-id="Average length"
                 icon-id="mesh_hypo_length.png"
 
   <algorithms>
 
+    <algorithm type="SegmentAroundVertex_0D"
+              label-id="Segments around vertex"
+              icon-id="mesh_algo_regular.png"
+               hypos="SegmentLengthAroundVertex"
+               output="VERTEX"
+               dim="0"/>
+
     <algorithm type="Regular_1D"
               label-id="Wire discretisation"
               icon-id="mesh_algo_regular.png"
                output="EDGE"
                dim="1"/>
 
+    <algorithm type="CompositeSegment_1D"
+              label-id="Composite side discretisation"
+              icon-id="mesh_algo_regular.png"
+               hypos="LocalLength,Arithmetic1D,StartEndLength,NumberOfSegments,Deflection1D,AutomaticLength"
+               opt-hypos="Propagation,QuadraticMesh"
+               input="VERTEX"
+               output="EDGE"
+               dim="1"/>
+
     <algorithm type="MEFISTO_2D"
               label-id="Triangle (Mefisto)"
               icon-id="mesh_algo_mefisto.png"
                dim="3"/>
 
     <algorithm type="Prism_3D"
-               label-id="Prism 3D"
+               label-id="3D extrusion"
                icon-id="mesh_algo_hexa.png"
                input="QUAD,TRIA"
                dim="3"/>
diff --git a/resources/mesh_build_compound.png b/resources/mesh_build_compound.png
new file mode 100644 (file)
index 0000000..e9ebe48
Binary files /dev/null and b/resources/mesh_build_compound.png differ
index 3bc292fc4c5d3309d2926054dc834e139ec483e8..4ff27ffdb343fc0d94bc7e33d6568dcc511fbbb5 100644 (file)
Binary files a/resources/mesh_merge_elements.png and b/resources/mesh_merge_elements.png differ
diff --git a/resources/mesh_node_to_point.png b/resources/mesh_node_to_point.png
new file mode 100644 (file)
index 0000000..5d534cb
Binary files /dev/null and b/resources/mesh_node_to_point.png differ
diff --git a/resources/mesh_tree_mesh_partial.png b/resources/mesh_tree_mesh_partial.png
new file mode 100755 (executable)
index 0000000..2ab75b3
Binary files /dev/null and b/resources/mesh_tree_mesh_partial.png differ
index 82eaa6726b0d67ffa07eba30139b8c0e3bca40c1..a8f371a4bc1c859aea8fc52bef5cb677340d4365 100644 (file)
 
 #include <set>
 
+#include <BRepAdaptor_Surface.hxx>
 #include <BRep_Tool.hxx>
-#include <gp_Ax3.hxx>
-#include <gp_Cylinder.hxx>
-#include <gp_Dir.hxx>
-#include <gp_Pnt.hxx>
-#include <gp_Pln.hxx>
-#include <gp_Vec.hxx>
-#include <gp_XYZ.hxx>
-#include <Geom_Plane.hxx>
 #include <Geom_CylindricalSurface.hxx>
+#include <Geom_Plane.hxx>
+#include <Geom_Surface.hxx>
 #include <Precision.hxx>
-#include <TColgp_Array1OfXYZ.hxx>
+#include <TColStd_MapIteratorOfMapOfInteger.hxx>
 #include <TColStd_MapOfInteger.hxx>
 #include <TColStd_SequenceOfAsciiString.hxx>
-#include <TColStd_MapIteratorOfMapOfInteger.hxx>
+#include <TColgp_Array1OfXYZ.hxx>
 #include <TopAbs.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Shape.hxx>
+#include <gp_Ax3.hxx>
+#include <gp_Cylinder.hxx>
+#include <gp_Dir.hxx>
+#include <gp_Pln.hxx>
+#include <gp_Pnt.hxx>
+#include <gp_Vec.hxx>
+#include <gp_XYZ.hxx>
 
 #include "SMDS_Mesh.hxx"
 #include "SMDS_Iterator.hxx"
@@ -2531,6 +2533,7 @@ ElementsOnSurface::ElementsOnSurface()
   myType = SMDSAbs_All;
   mySurf.Nullify();
   myToler = Precision::Confusion();
+  myUseBoundaries = false;
 }
 
 ElementsOnSurface::~ElementsOnSurface()
@@ -2543,7 +2546,6 @@ void ElementsOnSurface::SetMesh( const SMDS_Mesh* theMesh )
   if ( myMesh == theMesh )
     return;
   myMesh = theMesh;
-  myIds.Clear();
   process();
 }
 
@@ -2556,25 +2558,41 @@ SMDSAbs_ElementType ElementsOnSurface::GetType() const
 { return myType; }
 
 void ElementsOnSurface::SetTolerance( const double theToler )
-{ myToler = theToler; }
+{
+  if ( myToler != theToler )
+    myIds.Clear();
+  myToler = theToler;
+}
 
 double ElementsOnSurface::GetTolerance() const
+{ return myToler; }
+
+void ElementsOnSurface::SetUseBoundaries( bool theUse )
 {
-  return myToler;
+  if ( myUseBoundaries != theUse ) {
+    myUseBoundaries = theUse;
+    SetSurface( mySurf, myType );
+  }
 }
 
 void ElementsOnSurface::SetSurface( const TopoDS_Shape& theShape,
                                     const SMDSAbs_ElementType theType )
 {
+  myIds.Clear();
   myType = theType;
   mySurf.Nullify();
   if ( theShape.IsNull() || theShape.ShapeType() != TopAbs_FACE )
-  {
-    mySurf.Nullify();
     return;
-  }
-  TopoDS_Face aFace = TopoDS::Face( theShape );
-  mySurf = BRep_Tool::Surface( aFace );
+  mySurf = TopoDS::Face( theShape );
+  BRepAdaptor_Surface SA( mySurf, myUseBoundaries );
+  Standard_Real
+    u1 = SA.FirstUParameter(),
+    u2 = SA.LastUParameter(),
+    v1 = SA.FirstVParameter(),
+    v2 = SA.LastVParameter();
+  Handle(Geom_Surface) surf = BRep_Tool::Surface( mySurf );
+  myProjector.Init( surf, u1,u2, v1,v2 );
+  process();
 }
 
 void ElementsOnSurface::process()
@@ -2588,6 +2606,7 @@ void ElementsOnSurface::process()
 
   if ( myType == SMDSAbs_Face || myType == SMDSAbs_All )
   {
+    myIds.ReSize( myMesh->NbFaces() );
     SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
     for(; anIter->more(); )
       process( anIter->next() );
@@ -2595,6 +2614,7 @@ void ElementsOnSurface::process()
 
   if ( myType == SMDSAbs_Edge || myType == SMDSAbs_All )
   {
+    myIds.ReSize( myMesh->NbEdges() );
     SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
     for(; anIter->more(); )
       process( anIter->next() );
@@ -2602,6 +2622,7 @@ void ElementsOnSurface::process()
 
   if ( myType == SMDSAbs_Node )
   {
+    myIds.ReSize( myMesh->NbNodes() );
     SMDS_NodeIteratorPtr anIter = myMesh->nodesIterator();
     for(; anIter->more(); )
       process( anIter->next() );
@@ -2625,32 +2646,34 @@ void ElementsOnSurface::process( const SMDS_MeshElement* theElemPtr )
     myIds.Add( theElemPtr->GetID() );
 }
 
-bool ElementsOnSurface::isOnSurface( const SMDS_MeshNode* theNode ) const
+bool ElementsOnSurface::isOnSurface( const SMDS_MeshNode* theNode )
 {
   if ( mySurf.IsNull() )
     return false;
 
   gp_Pnt aPnt( theNode->X(), theNode->Y(), theNode->Z() );
-  double aToler2 = myToler * myToler;
-  if ( mySurf->IsKind(STANDARD_TYPE(Geom_Plane)))
-  {
-    gp_Pln aPln = Handle(Geom_Plane)::DownCast(mySurf)->Pln();
-    if ( aPln.SquareDistance( aPnt ) > aToler2 )
-      return false;
-  }
-  else if ( mySurf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)))
-  {
-    gp_Cylinder aCyl = Handle(Geom_CylindricalSurface)::DownCast(mySurf)->Cylinder();
-    double aRad = aCyl.Radius();
-    gp_Ax3 anAxis = aCyl.Position();
-    gp_XYZ aLoc = aCyl.Location().XYZ();
-    double aXDist = anAxis.XDirection().XYZ() * ( aPnt.XYZ() - aLoc );
-    double aYDist = anAxis.YDirection().XYZ() * ( aPnt.XYZ() - aLoc );
-    if ( fabs(aXDist*aXDist + aYDist*aYDist - aRad*aRad) > aToler2 )
-      return false;
-  }
-  else
-    return false;
-
-  return true;
+  //  double aToler2 = myToler * myToler;
+//   if ( mySurf->IsKind(STANDARD_TYPE(Geom_Plane)))
+//   {
+//     gp_Pln aPln = Handle(Geom_Plane)::DownCast(mySurf)->Pln();
+//     if ( aPln.SquareDistance( aPnt ) > aToler2 )
+//       return false;
+//   }
+//   else if ( mySurf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)))
+//   {
+//     gp_Cylinder aCyl = Handle(Geom_CylindricalSurface)::DownCast(mySurf)->Cylinder();
+//     double aRad = aCyl.Radius();
+//     gp_Ax3 anAxis = aCyl.Position();
+//     gp_XYZ aLoc = aCyl.Location().XYZ();
+//     double aXDist = anAxis.XDirection().XYZ() * ( aPnt.XYZ() - aLoc );
+//     double aYDist = anAxis.YDirection().XYZ() * ( aPnt.XYZ() - aLoc );
+//     if ( fabs(aXDist*aXDist + aYDist*aYDist - aRad*aRad) > aToler2 )
+//       return false;
+//   }
+//   else
+//     return false;
+  myProjector.Perform( aPnt );
+  bool isOn = ( myProjector.IsDone() && myProjector.LowerDistance() <= myToler );
+
+  return isOn;
 }
index c9b4dc0b9de9ab79d3bdb1dbaeeed6bb9fdee34b..84500897a096fcac9ae6f7d7e2d7831f6b079255 100644 (file)
 #include <vector>
 #include <boost/shared_ptr.hpp>
 #include <gp_XYZ.hxx>
-#include <Geom_Surface.hxx>
+//#include <Geom_Surface.hxx>
+#include <GeomAPI_ProjectPointOnSurf.hxx>
 #include <TColStd_SequenceOfInteger.hxx>
 #include <TColStd_MapOfInteger.hxx>
 #include <TCollection_AsciiString.hxx>
+#include <TopoDS_Face.hxx>
 
 #include "SMDSAbs_ElementType.hxx"
 #include "SMDS_MeshNode.hxx"
@@ -54,7 +56,7 @@ class SMESHDS_Mesh;
 class SMESHDS_SubMesh;
 
 class gp_Pnt;
-class TopoDS_Shape;
+//class TopoDS_Shape;
 
 namespace SMESH{
   namespace Controls{
@@ -621,18 +623,23 @@ namespace SMESH{
       double  GetTolerance() const;
       void    SetSurface( const TopoDS_Shape& theShape,
                           const SMDSAbs_ElementType theType );
+      void    SetUseBoundaries( bool theUse );
+      bool    GetUseBoundaries() const { return myUseBoundaries; }
 
     private:
       void    process();
       void    process( const SMDS_MeshElement* theElem  );
-      bool    isOnSurface( const SMDS_MeshNode* theNode ) const;
+      bool    isOnSurface( const SMDS_MeshNode* theNode );
 
     private:
       const SMDS_Mesh*      myMesh;
       TColStd_MapOfInteger  myIds;
       SMDSAbs_ElementType   myType;
-      Handle(Geom_Surface)  mySurf;
+      //Handle(Geom_Surface)  mySurf;
+      TopoDS_Face           mySurf;
       double                myToler;
+      bool                  myUseBoundaries;
+      GeomAPI_ProjectPointOnSurf myProjector;
     };
     
     typedef boost::shared_ptr<ElementsOnSurface> ElementsOnSurfacePtr;
index aa02b402261a3f61a4f9b1c9d431e5d0253fd272..1043e55949fb7047fc7a6860accb0b795ffc1440 100644 (file)
@@ -295,17 +295,21 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
 
     // Storing SMDS groups and sub-meshes
     //-----------------------------------
-    int myNodesDefaultFamilyId = 0;
-    int myEdgesDefaultFamilyId = 0;
-    int myFacesDefaultFamilyId = 0;
+    int myNodesDefaultFamilyId   = 0;
+    int myEdgesDefaultFamilyId   = 0;
+    int myFacesDefaultFamilyId   = 0;
     int myVolumesDefaultFamilyId = 0;
-    if (myDoGroupOfNodes)
+    int nbNodes   = myMesh->NbNodes();
+    int nbEdges   = myMesh->NbEdges();
+    int nbFaces   = myMesh->NbFaces();
+    int nbVolumes = myMesh->NbVolumes();
+    if (myDoGroupOfNodes && nbNodes)
       myNodesDefaultFamilyId = REST_NODES_FAMILY;
-    if (myDoGroupOfEdges)
+    if (myDoGroupOfEdges && nbEdges)
       myEdgesDefaultFamilyId = REST_EDGES_FAMILY;
-    if (myDoGroupOfFaces)
+    if (myDoGroupOfFaces && nbFaces)
       myFacesDefaultFamilyId = REST_FACES_FAMILY;
-    if (myDoGroupOfVolumes)
+    if (myDoGroupOfVolumes && nbVolumes)
       myVolumesDefaultFamilyId = REST_VOLUMES_FAMILY;
 
     MESSAGE("Perform - aFamilyInfo");
@@ -314,11 +318,17 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
     if (myAllSubMeshes) {
       aFamilies = DriverMED_Family::MakeFamilies
         (myMesh->SubMeshes(), myGroups,
-         myDoGroupOfNodes, myDoGroupOfEdges, myDoGroupOfFaces, myDoGroupOfVolumes);
+         myDoGroupOfNodes   && nbNodes,
+         myDoGroupOfEdges   && nbEdges,
+         myDoGroupOfFaces   && nbFaces,
+         myDoGroupOfVolumes && nbVolumes);
     } else {
       aFamilies = DriverMED_Family::MakeFamilies
         (mySubMeshes, myGroups,
-         myDoGroupOfNodes, myDoGroupOfEdges, myDoGroupOfFaces, myDoGroupOfVolumes);
+         myDoGroupOfNodes   && nbNodes,
+         myDoGroupOfEdges   && nbEdges,
+         myDoGroupOfFaces   && nbFaces,
+         myDoGroupOfVolumes && nbVolumes);
     }
     list<DriverMED_FamilyPtr>::iterator aFamsIter = aFamilies.begin();
 
index b9554e306cd250331eda6df1dded300155f2d784..cf05c196216fcd9497462dffe326a04f26b92234 100644 (file)
 #include "DriverUNV_W_SMDS_Mesh.h"
 
 #include "SMDS_Mesh.hxx"
-#include "SMESHDS_GroupBase.hxx"
-//#include "SMESH_Group.hxx"
 #include "SMDS_QuadraticEdge.hxx"
 #include "SMDS_QuadraticFaceOfNodes.hxx"
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+#include "SMESHDS_GroupBase.hxx"
 
 #include "utilities.h"
 
@@ -158,9 +158,16 @@ Driver_Mesh::Status DriverUNV_W_SMDS_Mesh::Perform()
          TElementLab aLabel = anElem->GetID();
 
          int aNbNodes = anElem->NbNodes();
-         aConnect.resize(aNbNodes);
-
          SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
+          if ( anElem->IsPoly() ) {
+            if ( const SMDS_PolyhedralVolumeOfNodes* ph =
+                 dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem))
+            {
+              aNbNodes = ph->NbUniqueNodes();
+              aNodesIter = ph->uniqueNodesIterator();
+            }
+          }
+         aConnect.resize(aNbNodes);
          GetConnect(aNodesIter,aConnect);
 
          int anId = -1;
index aa69c4aaac9888d2df657c8ab0c7e3f40d4d0ed2..63c6ec26640f6493d403fe2a6daac90852c03eb4 100755 (executable)
@@ -1,6 +1,6 @@
 //  MEFISTO :  library to compute 2D triangulation from segmented boundaries
 //
-//  Copyright (C) 2003  Laboratoire J.-L. Lions UPMC Paris
+//  Copyright (C) 2006  Laboratoire J.-L. Lions UPMC Paris
 // 
 //  This library is free software; you can redistribute it and/or 
 //  modify it under the terms of the GNU Lesser General Public 
@@ -23,7 +23,7 @@
 //  File   : Rn.h
 //  Module : SMESH
 //  Authors: Frederic HECHT & Alain PERRONNET
-//
+//  Date   : 13 novembre 2006
 
 #ifndef Rn__h
 #define Rn__h
@@ -62,19 +62,19 @@ typedef char Nom[1+24];
 
 //le type N des nombres entiers positifs
 //=========
+#ifndef PCLINUX64
 typedef unsigned long int N;
+#else 
+typedef unsigned int N;
+#endif
 
 //le type Z des nombres entiers relatifs
 //=========
-// 64-bit porting: "long" replaced with "int". 
-// On 64-bit, C++ long type is 8 byte long. MEFISTO2D C code calls several Fortran subroutines passing
-// arguments of this type, however Fortran knows nothing about changed size of arguments, 
-// therefore stack gets corrupted. With "int" used instead of "long", Fortran calls from C do no harm to the stack
-// After this modification, behavior on 32-bit platforms does not change: on all platforms supported by
-// SALOME 3, "int" and "long" have the same size of 4 bytes. 
-//========
-//typedef long int Z;
+#ifndef PCLINUX64
+typedef long int Z;
+#else
 typedef int Z;
+#endif
 
 //le type R des nombres "reels"
 //=========
index 9f47233228e25340a546a08b4fd49c56389e35b6..26691946aed16d40e404a605b652252f5e17ea2a 100755 (executable)
@@ -1,5 +1,6 @@
 //  MEFISTO2: a library to compute 2D triangulation from segmented boundaries
 //
+//
 //  Copyright (C) 2006  Laboratoire J.-L. Lions UPMC Paris
 //
 //  This library is free software; you can redistribute it and/or
@@ -21,7 +22,7 @@
 //  File   : aptrte.cxx   le C++ de l'appel du trianguleur plan
 //  Module : SMESH
 //  Author : Alain PERRONNET
-//  Date   : 16 mars 2006
+//  Date   : 13 novembre 2006
 
 #include "Rn.h"
 #include "aptrte.h"
@@ -144,15 +145,14 @@ void  aptrte( Z   nutysu, R      aretmx,
 
   R3 comxmi[2];            //coordonnees UV Min et Maximales
   R  aremin, aremax;       //longueur minimale et maximale des aretes
+  R  airemx;               //aire maximale souhaitee d'un triangle
   R  quamoy, quamin;
 
   Z  noar0, noar, na;
   Z  i, l, n, ns, ns0, ns1, ns2, nosotr[3], nt;
   Z  mxsomm, nbsomm, nbarpi, nbarli, ndtri0, mn;
   Z  moins1=-1;
-  R  dist;
-
-  aretemaxface_ = aretmx;
+  Z  nuds = 0;
 
   // initialisation du temps cpu
   deltacpu_( d );
@@ -166,7 +166,8 @@ void  aptrte( Z   nutysu, R      aretmx,
   i = 4*nbarfr/10;
   mxsomm = Max( 20000, 64*nbpti+i*i );
   MESSAGE( "APTRTE: Debut de la triangulation plane avec " );
-  MESSAGE( "nutysu=" << nutysu << "  aretmx=" << aretmx << "  mxsomm=" << mxsomm );
+  MESSAGE( "nutysu=" << nutysu << "  aretmx=" << aretmx
+          << "  mxsomm=" << mxsomm );
   MESSAGE( nbarfr << " sommets sur la frontiere et " << nbpti << " points internes");
 
  NEWDEPART:
@@ -277,6 +278,9 @@ void  aptrte( Z   nutysu, R      aretmx,
       //l'arete precedente est dotee de sa suivante:celle cree ensuite
       //les 2 coordonnees du sommet ns2 de la ligne
       ns = ns1 - 1;
+//debut ajout  5/10/2006  ................................................
+      nuds = Max( nuds, ns );   //le numero du dernier sommet traite
+//fin   ajout  5/10/2006  ................................................
       mnpxyd[ns].x = uvslf[ns].x;
       mnpxyd[ns].y = uvslf[ns].y;
       mnpxyd[ns].z = areteideale();//( mnpxyd[ns], direction );
@@ -289,6 +293,14 @@ void  aptrte( Z   nutysu, R      aretmx,
       aremin = Min( aremin, d );
       aremax = Max( aremax, d );
 
+//debut ajout du 5/10/2006  .............................................
+      //la longueur de l'arete ns1-ns2
+      d = sqrt( d );
+      //longueur arete = Min ( aretmx, aretes incidentes )
+      mnpxyd[ns   ].z = Min( mnpxyd[ns   ].z, d );
+      mnpxyd[ns2-1].z = Min( mnpxyd[ns2-1].z, d );
+//fin ajout du 5/10/2006  ...............................................
+
       //le numero n de la ligne du sommet et son numero ns1 dans la ligne
       mnslig[ns] = 1000000 * n + ns1-nudslf[n-1];
 
@@ -312,9 +324,34 @@ void  aptrte( Z   nutysu, R      aretmx,
   aremin = sqrt( aremin );  //longueur minimale d'une arete des lignes fermees
   aremax = sqrt( aremax );  //longueur maximale d'une arete
 
-  aretmx = Min( aretmx, aremax );  //pour homogeneiser
-  MESSAGE("nutysu=" << nutysu << "  aretmx=" << aretmx 
-       << "  arete min=" << aremin << "  arete max=" << aremax);
+//debut ajout  9/11/2006  ................................................
+  // devenu un commentaire aretmx = Min( aretmx, aremax ); //pour homogeneiser
+
+  // protection contre une arete max desiree trop grande ou trop petite
+  if( aretmx > aremax*2.05 ) aretmx = aremax;
+
+  // protection contre une arete max desiree trop petite
+  if( (aremax-aremin) > (aremin+aremax)*0.05 && aretmx < aremin*0.5 )
+    aretmx =(aremin+aremax*2)/3.0;
+
+  if( aretmx < aremin  && aremin > 0 )
+    aretmx = aremin;
+
+  //sauvegarde pour la fonction areteideale_
+  aretemaxface_ = aretmx;
+
+  //aire maximale souhaitee des triangles
+  airemx = aretmx * aretmx * sqrt(3.0) / 2.0;  //Aire triangle equilateral
+
+  for(i=0; i<=nuds; i++ )
+    mnpxyd[i].z = Min( mnpxyd[i].z, aretmx );
+  //MESSAGE("Numero du dernier sommet frontalier=" << nuds+1);
+//fin  ajout 9/11/2006  .................................................
+
+
+  MESSAGE("Sur  le  bord: arete min=" << aremin << " arete max=" << aremax );
+  MESSAGE("Triangulation: arete mx=" << aretmx
+         << " triangle aire mx=" << airemx );
 
   //chainage des aretes frontalieres : la derniere arete frontaliere
   mnsoar[ mosoar * noar - mosoar + 5 ] = 0;
@@ -438,8 +475,8 @@ void  aptrte( Z   nutysu, R      aretmx,
   if( ierr != 0 ) goto ERREUR;
 
   //qualites de la triangulation actuelle
-  qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
-              nbt, quamoy, quamin );
+  qualitetrte_( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
+               nbt, quamoy, quamin );
 
   // boucle sur les aretes internes (non sur une ligne de la frontiere)
   // avec echange des 2 diagonales afin de rendre la triangulation delaunay
@@ -457,8 +494,8 @@ void  aptrte( Z   nutysu, R      aretmx,
        << d << " secondes");
 
   //qualites de la triangulation actuelle
-  qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
-              nbt, quamoy, quamin );
+  qualitetrte_( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
+               nbt, quamoy, quamin );
 
   // detection des aretes frontalieres initiales perdues
   // triangulation frontale pour les restaurer
@@ -479,11 +516,11 @@ void  aptrte( Z   nutysu, R      aretmx,
 
   terefr( nbarpi, mnpxyd,
           mosoar, mxsoar, n1soar, mnsoar,
-          moartr, n1artr, mnartr, mnarst,
+          moartr, mxartr, n1artr, mnartr, mnarst,
           mxarcf, mn1arcf, mnarcf, mnarcf1, mnarcf2,
           n, ierr );
 
-  MESSAGE( "Restauration de " << n << " aretes perdues de la frontiere" );
+  MESSAGE( "Restauration de " << n << " aretes perdues de la frontiere  ierr=" << ierr );
   deltacpu_( d );
   tcpu += d;
   MESSAGE("Temps de la recuperation des aretes perdues de la frontiere="
@@ -492,8 +529,8 @@ void  aptrte( Z   nutysu, R      aretmx,
   if( ierr != 0 ) goto ERREUR;
 
   //qualites de la triangulation actuelle
-  qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
-              nbt, quamoy, quamin );
+  qualitetrte_( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
+               nbt, quamoy, quamin );
 
   // fin de la triangulation avec respect des aretes initiales frontalieres
 
@@ -529,12 +566,12 @@ void  aptrte( Z   nutysu, R      aretmx,
 
   deltacpu_( d );
   tcpu += d;
-  MESSAGE( "Temps de la suppression des triangles externes=" << d );
+  MESSAGE( "Temps de la suppression des triangles externes=" << d << "ierr=" << ierr );
   if( ierr != 0 ) goto ERREUR;
 
   //qualites de la triangulation actuelle
-  qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
-              nbt, quamoy, quamin );
+  qualitetrte_( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
+               nbt, quamoy, quamin );
 
   // amelioration de la qualite de la triangulation par
   // barycentrage des sommets internes a la triangulation
@@ -548,12 +585,12 @@ void  aptrte( Z   nutysu, R      aretmx,
     cout << "aptrte: MC saturee mnarcf3=" << mnarcf3 << endl;
     goto ERREUR;
   }
-  teamqt( nutysu,
-          mnarst, mosoar, mxsoar, n1soar, mnsoar,
-          moartr, mxartr, n1artr, mnartr,
-          mxarcf, mnarcf2, mnarcf3,
-          mn1arcf, mnarcf, mnarcf1,
-          comxmi, nbarpi, nbsomm, mxsomm, mnpxyd, mnslig,
+  teamqt_( nutysu,  aretmx,  airemx,
+          mnarst,  mosoar,  mxsoar, n1soar, mnsoar,
+          moartr,  mxartr,  n1artr, mnartr,
+          mxarcf,  mnarcf2, mnarcf3,
+          mn1arcf, mnarcf,  mnarcf1,
+          nbarpi,  nbsomm, mxsomm, mnpxyd, mnslig,
           ierr );
   if( mnarcf3 != NULL ) {delete [] mnarcf3; mnarcf3=NULL;}
   if( mn1arcf != NULL ) {delete [] mn1arcf; mn1arcf=NULL;}
@@ -564,11 +601,12 @@ void  aptrte( Z   nutysu, R      aretmx,
   deltacpu_( d );
   tcpu += d;
   MESSAGE( "Temps de l'amelioration de la qualite de la triangulation=" << d );
-  if( ierr != 0 ) goto ERREUR;
+  if( ierr == -13 ) ierr=0; //6/10/2006 arret de l'amelioration apres boucle infinie dans caetoi
+  if( ierr !=   0 ) goto ERREUR;
 
   //qualites de la triangulation finale
-  qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
-              nbt, quamoy, quamin );
+  qualitetrte_( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr,
+               nbt, quamoy, quamin );
 
   // renumerotation des sommets internes: mnarst(i)=numero final du sommet
   // ===================================
@@ -657,7 +695,7 @@ void  aptrte( Z   nutysu, R      aretmx,
   }
   nbt /= nbsttria;  //le nombre final de triangles de la surface
   MESSAGE( "APTRTE: Fin de la triangulation plane avec "<<nbst<<" sommets et "
-          << nbt << " triangles=" << nbt);
+          << nbt << " triangles);
   deltacpu_( d );
   tcpu += d;
   MESSAGE( "APTRTE: Temps total de la triangulation plane=" << tcpu << " secondes" );
@@ -698,10 +736,10 @@ void  aptrte( Z   nutysu, R      aretmx,
 }
 
 
-void qualitetrte( R3 *mnpxyd,
-                 Z & mosoar, Z & mxsoar, Z *mnsoar,
-                 Z & moartr, Z & mxartr, Z *mnartr,
-                 Z & nbtria, R & quamoy, R & quamin )
+void qualitetrte_( R3 *mnpxyd,
+                  Z & mosoar, Z & mxsoar, Z *mnsoar,
+                  Z & moartr, Z & mxartr, Z *mnartr,
+                  Z & nbtria, R & quamoy, R & quamin )
 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 // but :    calculer la qualite moyenne et minimale de la triangulation
 // -----    actuelle definie par les tableaux mnsoar et mnartr
@@ -732,13 +770,14 @@ void qualitetrte( R3 *mnpxyd,
 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 {
   R  d, aire, qualite;
-  Z  nosotr[3], mn, nbtrianeg, nt;
+  Z  nosotr[3], mn, nbtrianeg, nt, ntqmin;
 
   aire   = 0;
   quamoy = 0;
   quamin = 2.0;
   nbtria = 0;
   nbtrianeg = 0;
+  ntqmin = 0;
 
   mn = -moartr;
   for ( nt=1; nt<=mxartr; nt++ )
@@ -760,7 +799,11 @@ void qualitetrte( R3 *mnpxyd,
       quamoy += qualite;
 
       //la qualite minimale
-      quamin = Min( quamin, qualite );
+      if( qualite < quamin )
+      {
+         quamin = qualite;
+         ntqmin = nt;
+      }
 
       //aire signee du triangle nt
       d = surtd2( mnpxyd[nosotr[0]-1], mnpxyd[nosotr[1]-1], mnpxyd[nosotr[2]-1] );
@@ -785,7 +828,20 @@ void qualitetrte( R3 *mnpxyd,
        << " des " << nbtria << " triangles de surface plane totale="
        << aire);
 
+  if( quamin<0.3 )
+  {
+    //le numero des 3 sommets du triangle ntqmin de qualite minimale
+    nusotr_( ntqmin, mosoar, mnsoar, moartr, mnartr,  nosotr );
+    MESSAGE("Triangle de qualite minimale "<<quamin<<" de sommets:"
+            <<nosotr[0]<<" "<<nosotr[1]<<" "<<nosotr[2]<<" ");
+    for (int i=0;i<3;i++)
+      MESSAGE("Sommet "<<nosotr[i]<<": x="<< mnpxyd[nosotr[i]-1].x
+             <<" y="<< mnpxyd[nosotr[i]-1].y);
+  }
+
   if( nbtrianeg>0 )
-    MESSAGE( "ATTENTION: nombre de triangles d'aire negative=" << nbtrianeg );
+    MESSAGE( "ATTENTION: "<< nbtrianeg << " TRIANGLES d'AIRE NEGATIVE" );
+
+  MESSAGE(" ");
   return;
 }
index 87baf0a411aff51dba67e710fc93371d712a4718..cb46a2e2c398bf9a435a5bc908a3fee69a8e105e 100755 (executable)
@@ -1,6 +1,6 @@
 //  SMESH MEFISTO2 : algorithm for meshing
 //
-//  Copyright (C) 2003  Laboratoire J.-L. Lions UPMC Paris
+//  Copyright (C) 2006  Laboratoire J.-L. Lions UPMC Paris
 //
 //  This library is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU Lesser General Public
@@ -21,8 +21,9 @@
 //
 //
 //  File   : aptrte.h
-//  Author: Alain PERRONNET
+//  Author : Alain PERRONNET
 //  Module : SMESH
+//  Date   : 13 novembre 2006
 
 #ifndef aptrte__h
 #define aptrte__h
  #define MEFISTO2D_EXPORT
 #endif
 
-  void qualitetrte( R3 *mnpxyd,
-                 Z & mosoar, Z & mxsoar, Z *mnsoar,
-                 Z & moartr, Z & mxartr, Z *mnartr,
-                 Z & nbtria, R & quamoy, R & quamin );
+extern "C" {
+void qualitetrte_( R3 *mnpxyd,
+                  Z & mosoar, Z & mxsoar, Z *mnsoar,
+                  Z & moartr, Z & mxartr, Z *mnartr,
+                  Z & nbtria, R & quamoy, R & quamin ); }
 // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 // but :    calculer la qualite moyenne et minimale de la triangulation
 // -----    actuelle definie par les tableaux nosoar et noartr
index f0c8744ca31358ed26ee3ae719bfcfda86fccd84..8ee61fadc43a685c62b645303831ec6b0e15c68f 100755 (executable)
@@ -1,6 +1,6 @@
 c  MEFISTO : library to compute 2D triangulation from segmented boundaries
 c
-c  Copyright (C) 2003  Laboratoire J.-L. Lions UPMC Paris
+c  Copyright (C) 2006  Laboratoire J.-L. Lions UPMC Paris
 c
 c  This library is free software; you can redistribute it and/or
 c  modify it under the terms of the GNU Lesser General Public
@@ -21,7 +21,8 @@ c
 c
 c  File   : areteideale.f
 c  Module : SMESH
-c  Author: Alain PERRONNET
+c  Author : Alain PERRONNET
+c  Date   : 13 novembre 2006
 
       double precision function areteideale( xyz, direction )
       double precision xyz(3), direction(3)
index 36fb28d11c7c30d04e7899648deb168a7d573e6c..273569def1c20288d24bbaea4f7f0567688b56b4 100755 (executable)
@@ -21,7 +21,30 @@ c
 c  File   : trte.f    le Fortran du trianguleur plan
 c  Module : SMESH
 c  Author : Alain PERRONNET
-c  Date   : 16 mars 2006
+c  Date   : 13 novembre 2006
+
+      double precision  function diptdr( pt , p1dr , p2dr )
+c++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++012
+c but : calculer la distance entre un point et une droite
+c ----- definie par 2 points p1dr et p2dr
+c
+c entrees :
+c ---------
+c pt        : le point de R ** 2
+c p1dr p2dr : les 2 points de R ** 2  de la droite
+c++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++012
+c programmeur : alain perronnet analyse numrique paris  janvier 1986
+c....................................................................012
+      double precision  pt(2),p1dr(2),p2dr(2), a, b, c
+c
+c     les coefficients de la droite a x + by + c =0
+      a = p2dr(2) - p1dr(2)
+      b = p1dr(1) - p2dr(1)
+      c = - a * p1dr(1) - b * p1dr(2)
+c
+c     la distance = | a * x + b * y + c | / sqrt( a*a + b*b )
+      diptdr = abs( a * pt(1) + b * pt(2) + c ) / sqrt( a*a + b*b )
+      end
 
       subroutine qutr2d( p1, p2, p3, qualite )
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -332,9 +355,12 @@ c             dont le second n'est pas le triangle nt2
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 c auteur : alain perronnet  analyse numerique paris upmc       mars 1997
 c2345x7..............................................................012
+      parameter        (lchain=6)
       common / unites / lecteu, imprim, nunite(30)
       integer           nosoar(mosoar,mxsoar), noarst(*)
       integer           nu2sar(2)
+c
+      ierr = 0
 c
 c     ajout eventuel de l'arete s1 s2 dans nosoar
       nu2sar(1) = ns1
@@ -363,6 +389,8 @@ c        le triangle 1 de l'arete => le triangle nt1
          nosoar(4,noar) = nt1
 c        le triangle 2 de l'arete => le triangle nt2
          nosoar(5,noar) = nt2
+c        le chainage est mis a -1
+         nosoar(lchain,noar) = -1
 c
 c        le sommet appartient a l'arete noar
          noarst( nu2sar(1) ) = noar
@@ -382,25 +410,32 @@ c        alors il y a une erreur
 c                arete appartenant a plus de 2 triangles => erreur
                  if( ierr .ge. 0 ) then
                     write(imprim,*) 'erreur fasoar: arete ',noar,
-     %              ' dans 2 triangles et a creer!'
+     %              ' dans 2 triangles',nosoar(4,noar),nosoar(5,noar),
+     %              ' et ajouter',nt1,nt2
+                write(imprim,*)'arete',noar,(nosoar(i,noar),i=1,mosoar)
                  endif
-                 ierr = 2
-                 return
+c
+c                ERREUR. CORRECTION POUR VOIR ...
+                 nosoar(4,noar) = NT1
+                 nosoar(5,noar) = NT2
+ccc                 ierr = 2
+ccc                 return
              endif
          endif
 c
 c        mise a jour du numero des triangles de l'arete noar
 c        le triangle 2 de l'arete => le triangle nt1
-         if( nosoar(4,noar) .lt. 0 ) then
+         if( nosoar(4,noar) .le. 0 ) then
 c            pas de triangle connu pour cette arete
              n = 4
          else
 c            deja un triangle connu. ce nouveau est le second
              if( nosoar(5,noar) .gt. 0  .and.  nt1 .gt. 0 .and.
-     %          nosoar(5,noar) .ne. nt1 ) then
+     %           nosoar(5,noar) .ne. nt1 ) then
 c               arete appartenant a plus de 2 triangles => erreur
-                write(imprim,*) 'erreur fasoar: arete ',noar,
-     %          ' dans plus de 2 triangles'
+                    write(imprim,*) 'erreur fasoar: arete ',noar,
+     %              ' dans triangles',nosoar(4,noar),nosoar(5,noar),
+     %              ' et ajouter triangle',nt1
                 ierr = 3
                 return
              endif
@@ -415,6 +450,7 @@ c           l'arete appartient a 2 triangles
      %          nosoar(5,noar) .ne. nt2 ) then
 c               arete appartenant a plus de 2 triangles => erreur
                 write(imprim,*) 'erreur fasoar: arete ',noar,
+     %         ' de st',nosoar(1,noar),'-',nosoar(2,noar),
      %         ' dans plus de 2 triangles'
                 ierr = 4
                 return
@@ -432,7 +468,7 @@ c     pas d'erreur
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 c but :   calcul des 2 coordonnees (xc,yc) dans le carre (0,1)
 c -----   image par f:carre unite-->quadrangle appartenant a q1**2
-c         par une resolution directe due a nicolas thenault
+c         par une resolution directe due a Nicolas Thenault
 c
 c entrees:
 c --------
@@ -810,6 +846,7 @@ c     existe t il un point libre
          if( letree(i,ntrp) .eq. 0 ) then
 c           la place i est libre
             letree(i,ntrp) = -ns
+            ierr = 0
             return
          endif
  10   continue
@@ -1125,6 +1162,7 @@ c....................................................................012
       double precision  a(2),s,aretmx,rac3
 c
 c     protection du nombre de sommets avant d'ajouter ceux de tetree
+      ierr   = 0
       nbsofr = nbsomm
       do 1 i = 1, nbsomm 
          comxmi(1,1) = min( comxmi(1,1), pxyd(1,i) )
@@ -1133,8 +1171,8 @@ c     protection du nombre de sommets avant d'ajouter ceux de tetree
          comxmi(2,2) = max( comxmi(2,2), pxyd(2,i) )
  1    continue
 c
-c     creation de l'arbre tee
-c     =======================
+c     creation de l'arbre letree
+c     ==========================
 c     la premiere colonne vide de letree
       letree(0,0) = 2
 c     chainage des te vides
@@ -1218,9 +1256,8 @@ c
 
       subroutine tetaid( nutysu, dx, dy, longai, ierr )
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c but :     calculer la longueur de l'arete ideale en dx,dy
+c but :     calculer la longueur de l'arete ideale longai en dx,dy
 c -----
-c
 c entrees:
 c --------
 c nutysu : numero de traitement de areteideale() selon le type de surface
@@ -1301,8 +1338,8 @@ c aretmx : longueur maximale des aretes des triangles equilateraux
 c permtr : perimetre de la ligne enveloppe dans le plan
 c          avant mise a l'echelle a 2**20
 c
-c modifies :
-c ----------
+c modifies:
+c ---------
 c nbsomm : nombre de sommets apres identification
 c pxyd   : tableau des coordonnees 2d des points
 c          par point : x  y  distance_souhaitee
@@ -1350,6 +1387,8 @@ c                       gestion circulaire
 c
       integer           nuste(3)
       equivalence      (nuste(1),ns1),(nuste(2),ns2),(nuste(3),ns3)
+c
+      ierr = 0
 c
 c     existence ou non de la fonction 'taille_ideale' des aretes
 c     autour du point.  ici la carte est supposee isotrope
@@ -1417,7 +1456,8 @@ c        il est donc decoupe en 4 soustriangles
          if( ierr .ne. 0 ) return
          do 4 i=nbsom0+1,nbsomm
 c           mise a jour de taille_ideale des nouveaux sommets de te
-            call tetaid( nutysu, pxyd(1,i), pxyd(2,i), pxyd(3,i), ierr )
+            call tetaid( nutysu, pxyd(1,i), pxyd(2,i),
+     %                   pxyd(3,i), ierr )
             if( ierr .ne. 0 ) goto 9999
  4       continue
       endif
@@ -2042,7 +2082,7 @@ c
 c
 c        quadrangle convexe : le critere de delaunay intervient
 c        ------------------   ---------------------------------
-c        calcul du centre et rayon de la boule circonscrite a 123
+c        calcul du centre et rayon de la boule circonscrite a ns123
 c        pas d'affichage si le triangle est degenere
          ierr = -1
          call cenced( pxyd(1,ns1), pxyd(1,ns2), pxyd(1,ns3), cetria,
@@ -2060,15 +2100,6 @@ c           protection contre une boucle infinie sur le meme cercle
 c
 c           oui: ns4 est dans le cercle circonscrit a ns1 ns2 ns3
 c           => ns3 est aussi dans le cercle circonscrit de ns1 ns2 ns4
-c
-cccc           les 2 triangles d'arete na sont effaces
-ccc            do 25 j=4,5
-ccc               nt = nosoar(j,na)
-cccc              trace du triangle nt
-ccc               call mttrtr( pxyd, nt, moartr, noartr, mosoar, nosoar,
-ccc     %                      ncnoir, ncjaun )
-ccc 25         continue
-c
 c           echange de la diagonale 12 par 34 des 2 triangles
             call te2t2t( na,     mosoar, n1soar, nosoar, noarst,
      %                   moartr, noartr, na34 )
@@ -2082,9 +2113,6 @@ c
 c           les aretes internes peripheriques des 2 triangles sont enchainees
             do 60 j=4,5
                nt = nosoar(j,na34)
-cccc              trace du triangle nt
-ccc               call mttrtr( pxyd, nt, moartr, noartr, mosoar, nosoar,
-ccc     %                      ncoran, ncgric )
                do 50 i=1,3
                   n = abs( noartr(i,nt) )
                   if( n .ne. na34 ) then
 c        retour en haut de la pile des aretes a traiter
          goto 20
       endif
+c
+      return
       end
 
 
       subroutine terefr( nbarpi, pxyd,
      %                   mosoar, mxsoar, n1soar, nosoar,
-     %                   moartr, n1artr, noartr, noarst,
+     %                   moartr, mxartr, n1artr, noartr, noarst,
      %                   mxarcf, n1arcf, noarcf, larmin, notrcf,
      %                   nbarpe, ierr )
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -2128,6 +2158,7 @@ c          indice dans nosoar de l'arete suivante dans le hachage
 c mxsoar : nombre maximal d'aretes stockables dans le tableau nosoar
 c          attention: mxsoar>3*mxsomm obligatoire!
 c moartr : nombre maximal d'entiers par arete du tableau noartr
+c mxartr : nombre maximal de triangles declarables dans noartr
 c mxarcf : nombre de variables des tableaux n1arcf, noarcf, larmin, notrcf
 c
 c modifies:
@@ -2167,12 +2198,14 @@ c....................................................................012
       common / unites / lecteu,imprim,intera,nunite(29)
       double precision  pxyd(3,*)
       integer           nosoar(mosoar,mxsoar),
-     %                  noartr(moartr,*),
+     %                  noartr(moartr,mxartr),
      %                  noarst(*),
      %                  n1arcf(0:mxarcf),
      %                  noarcf(3,mxarcf),
      %                  larmin(mxarcf),
      %                  notrcf(mxarcf)
+c
+      ierr = 0
 c
 c     le nombre d'aretes de la frontiere non arete de la triangulation
       nbarpe = 0
@@ -2205,7 +2238,7 @@ c
 c              traitement de cette arete perdue ns1-ns2
                call tefoar( narete, nbarpi, pxyd,
      %                      mosoar, mxsoar, n1soar, nosoar,
-     %                      moartr, n1artr, noartr, noarst,
+     %                      moartr, mxartr, n1artr, noartr, noarst,
      %                      mxarcf, n1arcf, noarcf, larmin, notrcf,
      %                      ierr )
                if( ierr .ne. 0 ) return
@@ -2268,6 +2301,7 @@ c ierr   : 0 si pas d'erreur, >0 sinon
 cc++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 c auteur : alain perronnet  analyse numerique paris upmc        mai 1999
 c2345x7..............................................................012
+      common / unites / lecteu,imprim,intera,nunite(29)
       double precision  pxyd(3,*)
       integer           nulftr(nblftr),nslign(nbsomm),
      %                  nosoar(mosoar,mxsoar),
@@ -2360,10 +2394,6 @@ c              triangle deja traite pour une ligne anterieure?
                if(     letrsu(nt)  .ne. 0      .and.
      %             abs(letrsu(nt)) .ne. ligne ) goto 60
 c
-cccc              trace du triangle nt en couleur ligne0
-ccc               call mttrtr( pxyd,   nt, moartr, noartr, mosoar, nosoar,
-ccc     %                      ligne0, ncnoir )
-c
 c              le triangle est marque avec la valeur de ligne
                letrsu(nt) = ligne
 c
@@ -2407,11 +2437,6 @@ c
 c                       temoin de ligne a traiter ensuite dans nulftr
                         nulftr(nl) = -abs( nulftr(nl) )
 c
-cccc                       trace du triangle nt2 en jaune borde de magenta
-ccc                        call mttrtr( pxyd,nt2,
-ccc     %                               moartr,noartr,mosoar,nosoar,
-ccc     %                               ncjaun, ncmage )
-c
 c                       l'arete est traitee
                         nosoar(6,na) = -3
 c
@@ -2602,8 +2627,8 @@ c     remise en etat pour eviter les modifications de ladefi
       end
 
 
-
-      subroutine trp1st( ns,     noarst, mosoar, nosoar, moartr, noartr,
+      subroutine trp1st( ns,     noarst, mosoar, nosoar,
+     %                   moartr, mxartr, noartr,
      %                   mxpile, lhpile, lapile )
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 c but :   recherche des triangles de noartr partageant le sommet ns
@@ -2620,23 +2645,30 @@ c          indice dans nosoar de l'arete suivante dans le hachage
 c nosoar : numero des 2 sommets , no ligne, 2 triangles de l'arete,
 c          chainage des aretes frontalieres, chainage du hachage des aretes
 c moartr : nombre maximal d'entiers par arete du tableau noartr
+c mxartr : nombre de triangles declares dans noartr
 c noartr : les 3 aretes des triangles +-arete1, +-arete2, +-arete3
 c mxpile : nombre maximal de triangles empilables
 c
 c sorties :
-c --------
+c ---------
 c lhpile : >0 nombre de triangles empiles
 c          =0       si impossible de tourner autour du point
+c                   ou zero triangle contenant le sommet ns
 c          =-lhpile si apres butee sur la frontiere il y a a nouveau
 c          butee sur la frontiere . a ce stade on ne peut dire si tous
 c          les triangles ayant ce sommet ont ete recenses
 c          ce cas arrive seulement si le sommet est sur la frontiere
+c          par un balayage de tous les triangles, lhpile donne le
+c          nombre de triangles de sommet ns
+c          remarque: si la pile est saturee recherche de tous les
+c          triangles de sommet ns par balayage de tous les triangles
 c lapile : numero dans noartr des triangles de sommet ns
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c auteur : alain perronnet  analyse numerique paris upmc       mars 1997
+c auteur: alain perronnet analyse numerique paris upmc         mars 1997
+c modifs: alain perronnet Laboratoire J-L. Lions UPMC Paris octobre 2006
 c....................................................................012
       common / unites / lecteu, imprim, nunite(30)
-      integer           noartr(moartr,*),
+      integer           noartr(moartr,mxartr),
      %                  nosoar(mosoar,*),
      %                  noarst(*)
       integer           lapile(1:mxpile)
 c     la premiere arete de sommet ns
       nar = noarst( ns )
       if( nar .le. 0 ) then
-         write(imprim,*) 'trp1st: sommet',ns,' sans arete'
-         goto 9999
+ccc         write(imprim,*) 'trp1st: sommet',ns,' sans arete'
+         goto 100
       endif
 c
 c     l'arete nar est elle active?
       if( nosoar(1,nar) .le. 0 ) then
 ccc         write(imprim,*) 'trp1st: arete vide',nar,
 ccc     %                  ' st1:', nosoar(1,nar),' st2:',nosoar(2,nar)
-         goto 9999
+         goto 100
       endif
 c
 c     le premier triangle de sommet ns
       nt0 = abs( nosoar(4,nar) )
       if( nt0 .le. 0 ) then
          write(imprim,*) 'trp1st: sommet',ns,' dans aucun triangle'
-         goto 9999
+         goto 100
       endif
 c
-c     le triangle est il interne?
-      if( noartr(1,nt0) .eq. 0 ) goto 9999
+c     le triangle est il actif?
+      if( noartr(1,nt0) .eq. 0 ) goto 100
 c
 c     le numero des 3 sommets du triangle nt0 dans le sens direct
       call nusotr( nt0, mosoar, nosoar, moartr, noartr, nosotr )
@@ -2675,10 +2707,10 @@ c     reperage du sommet ns dans le triangle nt0
       do 5 nar=1,3
          if( nosotr(nar) .eq. ns ) goto 10
  5    continue
-      nta = nt0
-      goto 9995
+c     pas de sommet ns dans le triangle nt0
+      goto 100
 c
-c     ns retrouve : le triangle nt0 est empile
+c     ns retrouve : le triangle nt0 de sommet ns est empile
  10   lhpile = 1
       lapile(1) = nt0
       nta = nt0
@@ -2691,8 +2723,11 @@ c     ==========================================================
 c     le triangle nt1 oppose du triangle nt0 par l'arete noar
       if( nosoar(4,noar) .eq. nt0 ) then
          nt1 = nosoar(5,noar)
-      else
+      else if( nosoar(5,noar) .eq. nt0 ) then
          nt1 = nosoar(4,noar)
+      else
+       write(imprim,*)'trp1st: anomalie arete',noar,' sans triangle',nt0
+         goto 100
       endif
 c
 c     la boucle sur les triangles nt1 de sommet ns dans le sens indirect
@@ -2710,11 +2745,11 @@ c        reperage du sommet ns dans nt1
          do 20 nar=1,3
             if( nosotr(nar) .eq. ns ) goto 25
  20      continue
-         nta = nt1
-         goto 9995
+c        pas de sommet ns dans le triangle nt1
+         goto 100
 c
 c        nt1 est empile
- 25      if( lhpile .ge. mxpile ) goto 9990
+ 25      if( lhpile .ge. mxpile ) goto 100
          lhpile = lhpile + 1
          lapile(lhpile) = nt1
 c
@@ -2724,21 +2759,29 @@ c        sauvegarde du precedent triangle dans nta
          noar = abs( noartr(nar,nt1) )
          if( nosoar(4,noar) .eq. nt1 ) then
             nt1 = nosoar(5,noar)
-         else
+         else if( nosoar(5,noar) .eq. nt1 ) then
             nt1 = nosoar(4,noar)
+         else
+            write(imprim,*)'trp1st: Anomalie arete',noar,
+     %                     ' sans triangle',nt1
+            goto 100
          endif
-         if( nt1 .le. 0   ) goto 30
-c        le triangle suivant est a l'exterieur
+c
+c        le triangle suivant est il a l'exterieur?
+         if( nt1 .le. 0 ) goto 30
+c
+c        non: est il le premier triangle de sommet ns?
          if( nt1 .ne. nt0 ) goto 15
 c
-c        recherche terminee par arrivee sur nt0
+c        oui: recherche terminee par arrivee sur nt0
 c        les triangles forment un "cercle" de "centre" ns
+c        lhpile ressort avec le signe +
          return
 c
       endif
 c
-c     pas de triangle voisin a nt1
-c     ============================
+c     pas de triangle voisin a nt1 qui doit etre frontalier
+c     =====================================================
 c     le parcours passe par 1 des triangles exterieurs
 c     le parcours est inverse par l'arete de gauche
 c     le triangle nta est le premier triangle empile
@@ -2750,7 +2793,7 @@ c     le numero des 3 sommets du triangle nta dans le sens direct
       do 32 nar=1,3
          if( nosotr(nar) .eq. ns ) goto 33
  32   continue
-      goto 9995
+      goto 100
 c
 c     l'arete qui precede (rotation / ns dans le sens direct)
  33   if( nar .eq. 1 ) then
@@ -2763,12 +2806,17 @@ c     le triangle voisin de nta dans le sens direct
       noar = abs( noartr(nar,nta) )
       if( nosoar(4,noar) .eq. nta ) then
          nt1 = nosoar(5,noar)
-      else
+      else if( nosoar(5,noar) .eq. nta ) then
          nt1 = nosoar(4,noar)
+      else
+         write(imprim,*)'trp1st: Anomalie arete',noar,
+     %                  ' SANS triangle',nta
+         goto 100
       endif
       if( nt1 .le. 0 ) then
 c        un seul triangle contient ns
-         goto 70
+c        parcours de tous les triangles pour lever le doute
+         goto 100
       endif
 c
 c     boucle sur les triangles de sommet ns dans le sens direct
@@ -2783,11 +2831,10 @@ c     reperage du sommet ns dans nt1
       do 50 nar=1,3
          if( nosotr(nar) .eq. ns ) goto 60
  50   continue
-      nta = nt1
-      goto 9995
+      goto 100
 c
 c     nt1 est empile
- 60   if( lhpile .ge. mxpile ) goto 9990
+ 60   if( lhpile .ge. mxpile ) goto 70
       lhpile = lhpile + 1
       lapile(lhpile) = nt1
 c
@@ -2802,32 +2849,55 @@ c     l'arete de sommet ns dans nosoar
       noar = abs( noartr(nar,nt1) )
 c
 c     le triangle voisin de nta dans le sens direct
-      nta  = nt1
+      nta = nt1
       if( nosoar(4,noar) .eq. nt1 ) then
          nt1 = nosoar(5,noar)
-      else
+      else if( nosoar(5,noar) .eq. nt1 ) then
          nt1 = nosoar(4,noar)
+      else
+         write(imprim,*)'trp1st: anomalie arete',noar,
+     %                  ' SANS triangle',nt1
+         goto 100
       endif
-      nta = nt1
       if( nt1 .gt. 0 ) goto 40
 c
 c     butee sur le trou => fin des triangles de sommet ns
 c     ----------------------------------------------------
- 70   lhpile = -lhpile
-c     impossible ici de trouver les autres triangles de sommet ns
+c     impossible ici de trouver tous les triangles de sommet ns directement
 c     les triangles de sommet ns ne forment pas une boule de centre ns
+c     au moins 1, voire 2 triangles frontaliers de sommet ns
+ 70   lhpile = -lhpile
+      return
+c
+c     Balayage de tous les triangles actifs et de sommet ns
+c     methode lourde et couteuse mais a priori tres fiable
+c     -----------------------------------------------------
+ 100  lhpile = 0
+      do 120 nt1=1,mxartr
+         if( noartr(1,nt1) .ne. 0 ) then
+c           le numero des 3 sommets du triangle i
+            call nusotr( nt1, mosoar, nosoar, moartr, noartr, nosotr )
+            do 110 j=1,3
+               if( nosotr(j) .eq. ns ) then
+c                 le triangle contient le sommet ns
+                  lhpile = lhpile + 1
+                  if( lhpile .gt. mxpile ) goto 9990
+                  lapile( lhpile ) = nt1
+               endif
+ 110        continue
+         endif
+ 120  continue
+c     il n'est pas sur que ces triangles forment une boule de centre ns
+      lhpile = -lhpile
       return
 c
 c     saturation de la pile des triangles
 c     -----------------------------------
- 9990 write(imprim,*)'trp1st: saturation pile des triangles autour ',
-     %'sommet',ns
-      goto 9999
-c
-c     erreur triangle ne contenant pas le sommet ns
-c     ----------------------------------------------
- 9995 write(imprim,*) 'trp1st: triangle ',nta,' st=',
-     %   (nosotr(nar),nar=1,3),' sans le sommet' ,ns
+ 9990 write(imprim,*)'trp1st: saturation pile des triangles autour du so
+     %mmet',ns
+      write(imprim,*) 'Plus de',mxpile,' triangles de sommet',ns
+      write(imprim,19990) (ii,lapile(ii),ii=1,mxpile)
+19990 format(5(' triangle',i9))
 c
  9999 lhpile = 0
       return
@@ -2882,7 +2952,7 @@ c     le sommet nosotr(3 du triangle 123
       end
 
 
-      subroutine tesusp( nbarpi, pxyd,   noarst,
+      subroutine tesusp( quamal, nbarpi, pxyd,   noarst,
      %                   mosoar, mxsoar, n1soar, nosoar,
      %                   moartr, mxartr, n1artr, noartr,
      %                   mxarcf, n1arcf, noarcf, larmin, notrcf, liarcf,
@@ -2890,12 +2960,14 @@ c     le sommet nosotr(3 du triangle 123
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 c but :   supprimer de la triangulation les sommets de te trop proches
 c -----   soit d'un sommet frontalier ou point interne impose
-c         soit d'une arete frontaliere
+c         soit d'une arete frontaliere si la qualite minimale des triangles
+c         est inferieure a quamal
 c
 c         attention: le chainage lchain de nosoar devient celui des cf
 c
 c entrees:
 c --------
+c quamal : qualite des triangles au dessous de laquelle supprimer des sommets
 c nbarpi : numero du dernier point interne impose par l'utilisateur
 c pxyd   : tableau des coordonnees 2d des points
 c          par point : x  y  distance_souhaitee
@@ -2940,15 +3012,11 @@ c          11 algorithme defaillant
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 c auteur : alain perronnet  analyse numerique paris upmc       mars 1997
 c....................................................................012
-c      parameter       ( quamal=0.3 ) => ok
-c      parameter       ( quamal=0.4 ) => pb pour le test ocean
-c      parameter       ( quamal=0.5 ) => pb pour le test ocean
-c
-      parameter       ( quamal=0.333, lchain=6 )
+      parameter       ( lchain=6 )
       common / unites / lecteu,imprim,intera,nunite(29)
-      double precision  pxyd(3,*), qualit
+      double precision  pxyd(3,*), quamal, qualit, quaopt, quamin
       integer           nosoar(mosoar,mxsoar),
-     %                  noartr(moartr,*),
+     %                  noartr(moartr,mxartr),
      %                  noarst(*),
      %                  n1arcf(0:mxarcf),
      %                  noarcf(3,mxarcf),
@@ -2960,8 +3028,9 @@ c
       equivalence      (nosotr(1),ns1), (nosotr(2),ns2),
      %                 (nosotr(3),ns3)
 c
-cccc     le nombre de sommets de te supprimes
-ccc      nbstsu = 0
+c     le nombre de sommets de te supprimes
+      nbstsu = 0
+      ierr   = 0
 c
 c     initialisation du chainage des aretes des cf => 0 arete de cf
       do 10 narete=1,mxsoar
@@ -2972,9 +3041,8 @@ c     boucle sur l'ensemble des sommets frontaliers ou points internes
 c     ================================================================
       do 100 ns = 1, nbarpi
 c
-cccc        le nombre de sommets supprimes pour ce sommet ns
-ccc         nbsuns = 0
-c
+c        le nombre de sommets supprimes pour ce sommet ns
+         nbsuns = 0
 c        la qualite minimale au dessous de laquelle le point proche
 c        interne est supprime
          quaopt = quamal
@@ -2989,26 +3057,25 @@ c           erreur: le point appartient a aucune arete
          endif
 c
 c        recherche des triangles de sommet ns
-c        ils doivent former un contour ferme de type etoile
-         call trp1st( ns, noarst, mosoar, nosoar, moartr, noartr,
+         call trp1st( ns, noarst, mosoar, nosoar,
+     %                moartr, mxartr, noartr,
      %                mxarcf, nbtrcf, notrcf )
          if( nbtrcf .eq. 0 ) goto 100
          if( nbtrcf .lt. 0 ) then
-c           erreur: impossible de trouver tous les triangles de sommet ns
-c           seule une partie est a priori retrouvee
+c           impossible de trouver tous les triangles de sommet ns
+c           seule une partie est a priori retrouvee ce qui est normal
+c           si ns est un sommet frontalier 
             nbtrcf = -nbtrcf
          endif
 c
 c        boucle sur les triangles de l'etoile du sommet ns
-         quamin = 2.0
+c        recherche du triangle de sommet ns ayant la plus basse qualite
+         quamin = 2.0d0
          do 20 i=1,nbtrcf
-c
 c           le numero des 3 sommets du triangle nt
             nt = notrcf(i)
-            call nusotr( nt, mosoar, nosoar, moartr, noartr,
-     %                   nosotr )
+            call nusotr( nt, mosoar, nosoar, moartr, noartr, nosotr )
 c           nosotr(1:3) est en equivalence avec ns1, ns2, ns3
-c
 c           la qualite du triangle ns1 ns2 ns3
             call qutr2d( pxyd(1,ns1), pxyd(1,ns2), pxyd(1,ns3), qualit )
             if( qualit .lt. quamin ) then
@@ -3022,18 +3089,18 @@ c        bilan sur la qualite des triangles de sommet ns
 c
 c           recherche du sommet de ntqmin le plus proche et non frontalier
 c           ==============================================================
-c           le numero des 3 sommets du triangle nt
-            call nusotr( ntqmin, mosoar, nosoar, moartr, noartr,
-     %                   nosotr )
-            nste   = 0
-            quamin = 1e28
+c           le numero des 3 sommets du triangle ntqmin
+            call nusotr(ntqmin, mosoar, nosoar, moartr, noartr, nosotr)
+            nste = 0
+            d0   = 1e28
             do 30 j=1,3
-               if( nosotr(j) .ne. ns .and. nosotr(j) .gt. nbarpi ) then
-                  d = (pxyd(1,nosotr(j))-pxyd(1,ns))**2
-     %              + (pxyd(2,nosotr(j))-pxyd(2,ns))**2
-                  if( d .lt. quamin ) then
-                     quamin = d
-                     nste   = j
+               nst = nosotr(j)
+               if( nst .ne. ns .and. nst .gt. nbarpi ) then
+                  d = (pxyd(1,nst)-pxyd(1,ns))**2
+     %              + (pxyd(2,nst)-pxyd(2,ns))**2
+                  if( d .lt. d0 ) then
+                     d0   = d
+                     nste = j
                   endif
                endif
  30         continue
 c              nste est un sommet de triangle equilateral
 c              => le sommet nste va etre supprime
 c              ==========================================
-               call te1stm( nste,   pxyd,   noarst,
+               call te1stm( nste,   nbarpi, pxyd,   noarst,
      %                      mosoar, mxsoar, n1soar, nosoar,
      %                      moartr, mxartr, n1artr, noartr,
      %                      mxarcf, n1arcf, noarcf,
      %                      larmin, notrcf, liarcf, ierr )
                if( ierr .eq. 0 ) then
-cccc                 un sommet de te supprime de plus
-ccc                  nbstsu = nbstsu + 1
-                  goto 100
-               else if( ierr .lt. 0 ) then
-c                 le sommet nste est externe donc non supprime
-c                 ou bien le sommet nste est le centre d'un cf dont toutes
-c                 les aretes simples sont frontalieres
-c                 dans les 2 cas le sommet n'est pas supprime
-                  ierr = 0
-                  goto 100
+c                 un sommet de te supprime de plus
+                  nbstsu = nbstsu + 1
+c
+c                 boucle jusqu'a obtenir une qualite suffisante
+c                 si triangulation tres irreguliere =>
+c                 destruction de beaucoup de points internes
+c                 les 2 variables suivantes brident ces destructions massives
+                  nbsuns = nbsuns + 1
+                  quaopt = quaopt * 0.8
+                  if( nbsuns .lt. 5 ) goto 15
                else
-c                 erreur motivant un arret de la triangulation
-                  return
+                  if( ierr .lt. 0 ) then
+c                    le sommet nste est externe donc non supprime
+c                    ou bien le sommet nste est le centre d'un cf dont toutes
+c                    les aretes simples sont frontalieres
+c                    dans les 2 cas le sommet n'est pas supprime
+                     ierr = 0
+                     goto 100
+                  else
+c                    erreur motivant un arret de la triangulation
+                     return
+                  endif
                endif
-c
-cccc              boucle jusqu'a obtenir une qualite suffisante
-cccc              si triangulation tres irreguliere =>
-cccc              destruction de beaucoup de points internes
-cccc              les 2 variables suivantes brident ces destructions massives
-ccc               nbsuns = nbsuns + 1
-ccc               quaopt = quaopt * 0.8
-ccc               if( nbsuns .lt. 5 ) goto 15
             endif
          endif
 c
  100  continue
 c
-c      write(imprim,*)'retrait de',nbstsu,
-c     %                ' sommets de te trop proches de la frontiere'
+      write(imprim,*)'tesusp: suppression de',nbstsu,
+     %               ' sommets de te trop proches de la frontiere'
       return
       end
 
 
-      subroutine teamqa( nutysu,
+      subroutine teamqa( nutysu, airemx,
      %                   noarst, mosoar, mxsoar, n1soar, nosoar,
      %                   moartr, mxartr, n1artr, noartr,
      %                   mxtrcf, notrcf, nostbo,
      %                   n1arcf, noarcf, larmin,
-     %                   comxmi, nbarpi, nbsomm, mxsomm, pxyd, nslign,
+     %                   nbarpi, nbsomm, mxsomm, pxyd, nslign,
      %                   ierr )
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c but:    si la taille de l'arete moyenne est >ampli*taille souhaitee
-c ----    alors ajout d'un sommet barycentre du plus grand triangle
+c but:    Boucles sur les aretes actives de la triangulation actuelle
+c ----    si la taille de l'arete moyenne est >ampli*taille souhaitee
+c         alors ajout d'un sommet barycentre du plus grand triangle
 c               de sommet ns
 c         si la taille de l'arete moyenne est <ampli/2*taille souhaitee
 c         alors suppression du sommet ns
@@ -3111,6 +3180,7 @@ c          0 pas d'emploi de la fonction areteideale() => aretmx active
 c          1 il existe une fonction areteideale()
 c            dont seules les 2 premieres composantes de uv sont actives
 c          autres options a definir...
+c airemx : aire maximale d'un triangle
 c noarst : noarst(i) numero d'une arete de sommet i
 c mosoar : nombre maximal d'entiers par arete et
 c          indice dans nosoar de l'arete suivante dans le hachage
@@ -3130,7 +3200,6 @@ c          sommet frontalier
 c          numero du point dans le lexique point si interne impose
 c          0 si le point est interne non impose par l'utilisateur
 c         -1 si le sommet est externe au domaine
-c comxmi : min et max des coordonneees des sommets du maillage
 c
 c modifies :
 c ----------
@@ -3154,13 +3223,12 @@ c....................................................................012
       parameter        (ampli=1.34d0,ampli2=ampli/2d0)
       parameter        (lchain=6)
       common / unites / lecteu, imprim, nunite(30)
-      double precision  pxyd(3,*)
-      double precision  ponder, ponde1, xbar, ybar, x, y, surtd2
-      double precision  d, dmoy
-      double precision  d2d3(3,3)
-      real              origin(3), xyz(3)
-      integer           noartr(moartr,*),
-     %                  nosoar(mosoar,*),
+      double precision  pxyd(3,*), airemx
+      double precision  ponder, ponde1, xbar, ybar, x, y, surtd2,
+     %                  xns, yns, airetm
+      double precision  d, dmoy, dmax, dmin, dns, xyzns(3), s0, s1
+      integer           noartr(moartr,mxartr),
+     %                  nosoar(mosoar,mxsoar),
      %                  noarst(*),
      %                  notrcf(mxtrcf),
      %                  nslign(*),
@@ -3168,11 +3236,16 @@ c....................................................................012
      %                  n1arcf(0:mxtrcf),
      %                  noarcf(3,mxtrcf),
      %                  larmin(mxtrcf)
-      double precision  comxmi(3,2)
       integer           nosotr(3)
 c
+c     initialisation du chainage des aretes des cf => 0 arete de cf
+      do 1 noar=1,mxsoar
+         nosoar( lchain, noar ) = -1
+ 1    continue
+      noar0 = 0
+c
 c     le nombre d'iterations pour ameliorer la qualite
-      nbitaq = 4
+      nbitaq = 5
       ier    = 0
 c
 c     initialisation du parcours
@@ -3182,20 +3255,21 @@ c     initialisation du parcours
 c
       do 5000 iter=1,nbitaq
 c
-c        le nombre de sommets supprimes
-         nbstsu = 0
-         nbbaaj = 0
+cccc        le nombre de barycentres ajoutes
+ccc         nbbaaj = 0
 c
 c        coefficient de ponderation croissant avec les iterations
-         ponder = min( 1d0, ( 50 + (50*iter)/nbitaq ) * 0.01d0 )
+         ponder = 0.1d0 + iter * 0.5d0 / nbitaq
+ccc 9 octobre 2006 ponder = min( 1d0, 0.1d0 + iter * 0.9d0 / nbitaq )
+ccc 9 mars    2006 ponder = min( 1d0, ( 50 + (50*iter)/nbitaq ) * 0.01d0 )
          ponde1 = 1d0 - ponder
 c
 c        l'ordre du parcours dans le sens croissant ou decroissant
+c        alternance du parcours
          nt   = nbs1
          nbs1 = nbs2
          nbs2 = nt
-c        alternance du parcours
-         nbs3 = -nbs3
+         nbs3 =-nbs3
 c
          do 1000 ns = nbs1, nbs2, nbs3
 c
@@ -3203,8 +3277,9 @@ c           le sommet est il interne au domaine?
             if( nslign(ns) .ne. 0 ) goto 1000
 c
 c           existe-t-il une arete de sommet ns ?
10         noar = noarst( ns )
           noar = noarst( ns )
             if( noar .le. 0 ) goto 1000
+            if( nosoar(1,noar) .le. 0 ) goto 1000
 c
 c           le 1-er triangle de l'arete noar
             nt = nosoar( 4, noar )
@@ -3212,32 +3287,60 @@ c           le 1-er triangle de l'arete noar
 c
 c           recherche des triangles de sommet ns
 c           ils doivent former un contour ferme de type etoile
-            call trp1st( ns, noarst, mosoar, nosoar, moartr, noartr,
+            call trp1st( ns, noarst, mosoar, nosoar,
+     %                   moartr, mxartr, noartr,
      %                   mxtrcf, nbtrcf, notrcf )
             if( nbtrcf .le. 0 ) goto 1000
 c
-c           mise a jour de la distance souhaitee
+c           mise a jour de la distance souhaitee autour de ns
+            xns =  pxyd(1,ns)
+            yns =  pxyd(2,ns)
             if( nutysu .gt. 0 ) then
 c              la fonction taille_ideale(x,y,z) existe
-c              calcul de pxyzd(3,ns) dans le repere initial => xyz(1:3)
-               call tetaid( nutysu, pxyd(1,ns), pxyd(2,ns),
+               call tetaid( nutysu, xns, yns,
      %                      pxyd(3,ns), ier )
             endif
 c
-c           boucle sur les triangles qui forment une boule autour du sommet ns
-            nbstbo = 0
-c           chainage des aretes simples de la boule a rendre delaunay
+c           boucle sur les triangles qui forment une etoile autour du sommet ns
+c           chainage des aretes simples de l'etoile formee par ces triangles
+c
+c           remise a zero du lien nosoar des aretes a rendre Delaunay
+ 19         if( noar0 .gt. 0 ) then
+               noar = nosoar(lchain,noar0)
+               nosoar(lchain,noar0) = -1
+               noar0 = noar
+               goto 19
+            endif
+c              
             noar0  = 0
+            nbstbo = 0
+            airetm = 0d0
             do 40 i=1,nbtrcf
-c
-c              le numero de l'arete du triangle nt ne contenant pas le sommet ns
+c              recherche du triangle de plus grande aire
                nt = notrcf(i)
+               call nusotr( nt, mosoar, nosoar,
+     %                      moartr, noartr, nosotr )
+               d = surtd2( pxyd(1,nosotr(1)),
+     %                     pxyd(1,nosotr(2)),
+     %                     pxyd(1,nosotr(3)) )
+               if( d .gt. airetm ) then
+                  airetm = d
+                  imax   = i
+               else if( d .le. 0 ) then
+                  write(imprim,*)'teamqa: triangle notrcf(',i,')=',
+     %            notrcf(i),' st', nosotr,' AIRE=',d,'<=0'
+                  goto 1000
+               endif
+c
+c              le no de l'arete du triangle nt ne contenant pas le sommet ns
                do 20 na=1,3
 c                 le numero de l'arete na dans le tableau nosoar
                   noar = abs( noartr(na,nt) )
                   if( nosoar(1,noar) .ne. ns   .and.
      %                nosoar(2,noar) .ne. ns ) goto 25
  20            continue
+               write(imprim,*)'teamqa: ERREUR triangle',nt,
+     %                        ' SANS sommet',ns
 c
 c              construction de la liste des sommets des aretes simples
 c              de la boule des triangles de sommet ns
@@ -3247,12 +3350,12 @@ c              -------------------------------------------------------
                   do 30 j=nbstbo,1,-1
                      if( ns1 .eq. nostbo(j) ) goto 35
  30               continue
-c                 ns1 est un nouveau sommet a ajouter
+c                 ns1 est un nouveau sommet a ajouter a l'etoile
                   nbstbo = nbstbo + 1
                   nostbo(nbstbo) = ns1
  35            continue
 c
-c              noar est une arete potentielle a rendre delaunay
+c              noar est une arete potentielle a rendre Delaunay
                if( nosoar(3,noar) .eq. 0 ) then
 c                 arete non frontaliere
                   nosoar(lchain,noar) = noar0
@@ -3267,38 +3370,35 @@ c           ---------------------------------------------------------------
             xbar = 0d0
             ybar = 0d0
             dmoy = 0d0
+            dmax = 0d0
+            dmin = 1d124
+            dns  = 0d0
             do 50 i=1,nbstbo
-               x    = pxyd(1,nostbo(i))
-               y    = pxyd(2,nostbo(i))
+               nst  = nostbo(i)
+               x    = pxyd(1,nst)
+               y    = pxyd(2,nst)
                xbar = xbar + x
                ybar = ybar + y
-               dmoy = dmoy + sqrt( (x-pxyd(1,ns))**2+(y-pxyd(2,ns))**2 )
+               d    = sqrt( (x-xns)**2 + (y-yns)**2 )
+               dmoy = dmoy + d
+               dmax = max( dmax, d )
+               dmin = min( dmin, d )
+               dns  = dns + pxyd(3,nst)
  50         continue
+            xbar = xbar / nbstbo
+            ybar = ybar / nbstbo
             dmoy = dmoy / nbstbo
+            dns  = dns  / nbstbo
 c
 c           pas de modification de la topologie lors de la derniere iteration
 c           =================================================================
             if( iter .eq. nbitaq ) goto 200
 c
-c           si la taille de l'arete moyenne est >ampli*taille souhaitee
+c           si la taille de l'arete maximale est >ampli*taille souhaitee
 c           alors ajout d'un sommet barycentre du plus grand triangle
 c                 de sommet ns
-c           ===========================================================
-            if( dmoy .gt. ampli*pxyd(3,ns) ) then
-c
-               dmoy = 0d0
-               do 150 i=1,nbtrcf
-c                 recherche du plus grand triangle en surface
-                  call nusotr( notrcf(i), mosoar, nosoar,
-     %                         moartr, noartr, nosotr )
-                  d  = surtd2( pxyd(1,nosotr(1)),
-     %                         pxyd(1,nosotr(2)),
-     %                         pxyd(1,nosotr(3)) )
-                  if( d .gt. dmoy ) then
-                     dmoy = d
-                     imax = i
-                  endif
- 150           continue
+c           ============================================================
+            if( airetm .gt. airemx .or. dmax .gt. ampli*dns ) then
 c
 c              ajout du barycentre du triangle notrcf(imax)
                nt = notrcf( imax )
@@ -3315,10 +3415,8 @@ c                 abandon de l'amelioration du sommet ns
      %                             + pxyd(i,nosotr(2))
      %                             + pxyd(i,nosotr(3)) ) / 3d0
  160           continue
-c
                if( nutysu .gt. 0 ) then
 c                 la fonction taille_ideale(x,y,z) existe
-c                 calcul de pxyzd(3,nbsomm) dans le repere initial => xyz(1:3)
                   call tetaid( nutysu, pxyd(1,nbsomm), pxyd(2,nbsomm),
      %                         pxyd(3,nbsomm), ier )
                endif
@@ -3344,75 +3442,71 @@ c              protection a ne pas modifier sinon erreur!
                call tr3str( nbsomm, nt,
      %                      mosoar, mxsoar, n1soar, nosoar,
      %                      moartr, mxartr, n1artr, noartr,
-     %                      noarst,
-     %                      nosotr, ierr )
+     %                      noarst, nosotr, ierr )
                if( ierr .ne. 0 ) goto 9999
 c
-c              un barycentre ajoute de plus
-               nbbaaj = nbbaaj + 1
+cccc              un barycentre ajoute de plus
+ccc               nbbaaj = nbbaaj + 1
 c
 c              les aretes chainees de la boule sont rendues delaunay
                goto 900
 c
             endif
 c
-c           si la taille de l'arete moyenne est <ampli/2*taille souhaitee
-c           alors suppression du sommet ns
-c           =============================================================
-            if( dmoy .lt. ampli2*pxyd(3,ns) ) then
-c              remise a -1 du chainage des aretes peripheriques de la boule ns
-               noar = noar0
- 90            if( noar .gt. 0 ) then
-c                 protection du no de l'arete suivante
-                  na = nosoar(lchain,noar)
-c                 l'arete interne est remise a -1
-                  nosoar(lchain,noar) = -1
-c                 l'arete suivante
-                  noar = na
-                  goto 90
-               endif
-               call te1stm( ns,     pxyd,   noarst,
-     %                      mosoar, mxsoar, n1soar, nosoar,
-     %                      moartr, mxartr, n1artr, noartr,
-     %                      mxtrcf, n1arcf, noarcf,
-     %                      larmin, notrcf, nostbo,
-     %                      ierr )
-               if( ierr .eq. -543 ) then
-                  ierr = 0
-                  goto 1000
-               else if( ierr .lt.    0 ) then
-c                 le sommet ns est externe donc non supprime
-c                 ou bien le sommet ns est le centre d'un cf dont toutes
-c                 les aretes simples sont frontalieres
-c                 dans les 2 cas le sommet ns n'est pas supprime
-                  ierr = 0
-                  goto 200
-               else if( ierr .gt. 0 ) then
-c                 erreur irrecuperable
-                  goto 9999
-               endif
-               nbstsu = nbstsu + 1
-               goto 1000
-c
-            endif
-c
 c           les 2 coordonnees du barycentre des sommets des aretes
 c           simples de la boule du sommet ns
 c           ======================================================
- 200        xbar = xbar / nbstbo
-            ybar = ybar / nbstbo
+C DEBUT AJOUT 10 octobre 2006
+C           PONDERATION POUR EVITER LES DEGENERESCENSES AVEC PROTECTION
+C           SI UN TRIANGLE DE SOMMET NS A UNE AIRE NEGATIVE APRES BARYCENTRAGE
+C           ALORS LE SOMMET NS N'EST PAS BOUGE
+c
+c           protection des XY du point initial
+ 200        xyzns(1) = pxyd(1,ns)
+            xyzns(2) = pxyd(2,ns)
+            xyzns(3) = pxyd(3,ns)
 c
 c           ponderation pour eviter les degenerescenses
             pxyd(1,ns) = ponde1 * pxyd(1,ns) + ponder * xbar
             pxyd(2,ns) = ponde1 * pxyd(2,ns) + ponder * ybar
-c
             if( nutysu .gt. 0 ) then
 c              la fonction taille_ideale(x,y,z) existe
-c              calcul de pxyzd(3,ns) dans le repere initial => xyz(1:3)
                call tetaid( nutysu, pxyd(1,ns), pxyd(2,ns),
      %                      pxyd(3,ns), ier )
             endif
 c
+c           calcul des surfaces avant et apres deplacement de ns
+            s0 = 0d0
+            s1 = 0d0
+            do 210 i=1,nbtrcf
+c              le numero de l'arete du triangle nt ne contenant pas le sommet ns
+               nt = notrcf(i)
+               do 204 na=1,3
+c                 le numero de l'arete na dans le tableau nosoar
+                  noar = abs( noartr(na,nt) )
+                  if( nosoar(1,noar) .ne. ns   .and.
+     %                nosoar(2,noar) .ne. ns ) then
+                     ns2 = nosoar(1,noar)
+                     ns3 = nosoar(2,noar)
+                     goto 206
+                  endif
+ 204           continue
+c              aire signee des 2 triangles
+ 206           s0 = s0 + abs(surtd2(xyzns,     pxyd(1,ns2),pxyd(1,ns3)))
+               s1 = s1 + abs(surtd2(pxyd(1,ns),pxyd(1,ns2),pxyd(1,ns3)))
+ 210        continue
+            if( abs(s0-s1) .gt. 1d-10*abs(s0) ) then
+c              retour a la position initiale
+c              car le point est passe au dela d'une arete de son etoile
+               pxyd(1,ns) = xyzns(1)
+               pxyd(2,ns) = xyzns(2)
+               pxyd(3,ns) = xyzns(3)
+c              la ponderation est reduite  10 octobre 2006
+               ponder = max( 0.1d0, ponder*0.5d0 )
+               ponde1 = 1d0 - ponder
+               goto 1000
+            endif
+c
 c           les aretes chainees de la boule sont rendues delaunay
  900        call tedela( pxyd,   noarst,
      %                   mosoar, mxsoar, n1soar, nosoar, noar0,
@@ -3420,9 +3514,8 @@ c           les aretes chainees de la boule sont rendues delaunay
 c
  1000    continue
 c
-ccc         write(imprim,11000) nbstsu, nbbaaj
-ccc11000 format( i6,' sommets supprimes ' ,
-ccc     %        i6,' barycentres ajoutes' )
+ccc         write(imprim,11000) iter, nbbaaj
+ccc11000 format('teamqa: iteration',i3,' =>',i6,' barycentres ajoutes')
 c
 c        mise a jour pour ne pas oublier les nouveaux sommets
          if( nbs1 .gt. nbs2 ) then
       end
 
 
-      subroutine teamsf( nutysu,
+      subroutine teamqt( nutysu, aretmx, airemx,
      %                   noarst, mosoar, mxsoar, n1soar, nosoar,
      %                   moartr, mxartr, n1artr, noartr,
-     %                   mxtrcf, notrcf, nostbo,
+     %                   mxarcf, notrcf, nostbo,
      %                   n1arcf, noarcf, larmin,
-     %                   comxmi, nbarpi, nbsomm, mxsomm, pxyd, nslign,
+     %                   nbarpi, nbsomm, mxsomm, pxyd, nslign,
      %                   ierr )
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c but :    modification de la topologie des triangles autour des
-c -----    sommets frontaliers et mise en triangulation delaunay locale
+c but :    amelioration de la qualite de la triangulation
+c -----
 c
 c entrees:
 c --------
@@ -3455,6 +3548,8 @@ c          0 pas d'emploi de la fonction areteideale() => aretmx active
 c          1 il existe une fonction areteideale()
 c            dont seules les 2 premieres composantes de uv sont actives
 c          autres options a definir...
+c aretmx : longueur maximale des aretes de la future triangulation
+c airemx : aire maximale souhaitee des triangles
 c noarst : noarst(i) numero d'une arete de sommet i
 c mosoar : nombre maximal d'entiers par arete et
 c          indice dans nosoar de l'arete suivante dans le hachage
@@ -3467,15 +3562,13 @@ c mxartr : nombre maximal de triangles declarables dans noartr
 c n1artr : numero du premier triangle vide dans le tableau noartr
 c          le chainage des triangles vides se fait sur noartr(2,.)
 c noartr : les 3 aretes des triangles +-arete1, +-arete2, +-arete3
-c mxtrcf : nombre maximal de triangles empilables
+c mxarcf : nombre maximal de triangles empilables
 c nbarpi : numero du dernier sommet frontalier ou interne impose
-c nslign : >0 => ns numero du point dans le lexique point si interne impose
-c          ou => 1 000 000 * n + ns1
-c              ou n   est le numero (1 a nblftr) de la ligne de ce point
-c                 ns1 est le numero du point dans sa ligne
-c          = 0 si le point est interne non impose par l'utilisateur
-c          =-1 si le sommet est externe au domaine
-c comxmi : min et max des coordonneees des sommets du maillage
+c nslign : tableau du numero de sommet dans sa ligne pour chaque
+c          sommet frontalier
+c          numero du point dans le lexique point si interne impose
+c          0 si le point est interne non impose par l'utilisateur
+c         -1 si le sommet est externe au domaine
 c
 c modifies :
 c ----------
@@ -3485,831 +3578,118 @@ c pxyd   : tableau des coordonnees 2d des points
 c
 c auxiliaires:
 c ------------
-c notrcf : tableau ( mxtrcf ) auxiliaire d'entiers
+c notrcf : tableau ( mxarcf ) auxiliaire d'entiers
 c          numero dans noartr des triangles de sommet ns
-c nostbo : tableau ( mxtrcf ) auxiliaire d'entiers
+c nostbo : tableau ( mxarcf ) auxiliaire d'entiers
 c          numero dans pxyd des sommets des aretes simples de la boule
-c n1arcf : tableau (0:mxtrcf) auxiliaire d'entiers
-c noarcf : tableau (3,mxtrcf) auxiliaire d'entiers
-c larmin : tableau ( mxtrcf ) auxiliaire d'entiers
+c n1arcf : tableau (0:mxarcf) auxiliaire d'entiers
+c noarcf : tableau (3,mxarcf) auxiliaire d'entiers
+c larmin : tableau ( mxarcf ) auxiliaire d'entiers
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c auteur : alain perronnet  analyse numerique paris upmc    janvier 1998
+c auteur : alain perronnet  analyse numerique paris upmc       juin 1997
 c....................................................................012
-      parameter        (lchain=6)
+      double precision  quamal
+c     parameter       ( quamal=0.3d0 ) => ok
+c     parameter       ( quamal=0.4d0 ) => pb pour le test ocean
+c     parameter       ( quamal=0.5d0 ) => pb pour le test ocean
+      parameter       ( quamal=0.1d0 )
+c     quamal=0.1d0 est choisi pour ne pas trop detruire de sommets
+c
       common / unites / lecteu, imprim, nunite(30)
       double precision  pxyd(3,*)
-      double precision  a, angle, angled, pi, deuxpi, pis3
-      double precision  d2d3(3,3)
-      real              origin(3), xyz(3)
       integer           noartr(moartr,*),
      %                  nosoar(mosoar,*),
      %                  noarst(*),
-     %                  notrcf(mxtrcf),
+     %                  notrcf(mxarcf),
      %                  nslign(*),
-     %                  nostbo(*),
-     %                  n1arcf(0:mxtrcf),
-     %                  noarcf(3,mxtrcf),
-     %                  larmin(mxtrcf),
-     %                  nosotr(3)
-      double precision  comxmi(3,2)
-c
-c     le nombre d'iterations pour ameliorer la qualite
-      nbitaq = 2
-      ier    = 0
-c
-c     pi / 3
-      pi     = atan(1d0) * 4d0
-      pis3   = pi / 3d0
-      deuxpi = 2d0 * pi
-c
-c     initialisation du parcours
-      modifs = 0
-      nbs1   = nbarpi
-      nbs2   =  1
-c     => pas de traitement sur les points des lignes de la frontiere
-      nbs3   = -1
-c
-      do 5000 iter=1,nbitaq
-c
-c        le nombre de sommets supprimes
-         nbstsu = 0
-c
-c        l'ordre du parcours dans le sens croissant ou decroissant
-         nt   = nbs1
-         nbs1 = nbs2
-         nbs2 = nt
-c        alternance du parcours
-         nbs3 = -nbs3
+     %                  nostbo(mxarcf),
+     %                  n1arcf(0:mxarcf),
+     %                  noarcf(3,mxarcf),
+     %                  larmin(mxarcf)
+      double precision  aretmx, airemx
+      double precision  quamoy, quamin
 c
-         do 1000 ns = nbs1, nbs2, nbs3
+      ierr = 0
 c
-c           le sommet est il sur une ligne de la frontiere?
-c           if( nslign(ns) .lt. 1 000 000 ) goto 1000
+c     supprimer de la triangulation les triangles de qualite
+c     inferieure a quamal
+c     ======================================================
+      call tesuqm( quamal, nbarpi, pxyd,   noarst,
+     %             mosoar, mxsoar, n1soar, nosoar,
+     %             moartr, mxartr, n1artr, noartr,
+     %             mxarcf, n1arcf, noarcf,
+     %             larmin, notrcf, nostbo,
+     %             quamin )
+      call qualitetrte( pxyd,   mosoar, mxsoar, nosoar,
+     %                  moartr, mxartr, noartr,
+     %                  nbtria, quamoy, quamin )
 c
-c           traitement d'un sommet d'une ligne de la frontiere
-c           ==================================================
-c           existe-t-il une arete de sommet ns ?
-            noar = noarst( ns )
-            if( noar .le. 0 ) goto 1000
+c     suppression des sommets de triangles equilateraux trop proches
+c     d'un sommet frontalier ou d'un point interne impose par
+c     triangulation frontale de l'etoile et mise en delaunay
+c     ==============================================================
+      if( quamin .le. quamal ) then
+         call tesusp( quamal, nbarpi, pxyd,   noarst,
+     %                mosoar, mxsoar, n1soar, nosoar,
+     %                moartr, mxartr, n1artr, noartr,
+     %                mxarcf, n1arcf, noarcf,
+     %                larmin, notrcf, nostbo,
+     %                ierr )
+         if( ierr .ne. 0 ) goto 9999
+      endif
 c
-c           le 1-er triangle de l'arete noar
-            nt = nosoar( 4, noar )
-            if( nt .le. 0 ) goto 1000
+c     ajustage des tailles moyennes des aretes avec ampli=1.34d0 entre
+c     ampli/2 x taille_souhaitee et ampli x taille_souhaitee 
+c     + barycentrage des sommets et mise en triangulation delaunay
+c     ================================================================
+      call teamqa( nutysu, airemx,
+     %             noarst, mosoar, mxsoar, n1soar, nosoar,
+     %             moartr, mxartr, n1artr, noartr,
+     %             mxarcf, notrcf, nostbo,
+     %             n1arcf, noarcf, larmin,
+     %             nbarpi, nbsomm, mxsomm, pxyd, nslign,
+     %             ierr )
+      call qualitetrte( pxyd,   mosoar, mxsoar, nosoar,
+     %                  moartr, mxartr, noartr,
+     %                  nbtria, quamoy, quamin )
+      if( ierr .ne. 0 ) goto 9999
 c
-c           recherche des triangles de sommet ns
-c           ils doivent former un contour ferme de type camembert
-            call trp1st( ns, noarst, mosoar, nosoar, moartr, noartr,
-     %                   mxtrcf, nbtrcf, notrcf )
-            if( nbtrcf .ge. -1 ) goto 1000
+ 9999 return
+      end
+
+      subroutine trfrcf( nscent, mosoar, nosoar, moartr, noartr,
+     %                   nbtrcf, notrcf, nbarfr )
+c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+c but :    calculer le nombre d'aretes simples du contour ferme des
+c -----    nbtrcf triangles de numeros stockes dans le tableau notrcf
+c          ayant tous le sommet nscent
 c
-c           boucle sur les triangles qui forment un camembert autour du sommet n
-            nbtrcf = -nbtrcf
+c entrees:
+c --------
+c nscent : numero du sommet appartenant a tous les triangles notrcf
+c mosoar : nombre maximal d'entiers par arete et
+c          indice dans nosoar de l'arete suivante dans le hachage
+c nosoar : numero des 2 sommets , no ligne, 2 triangles de l'arete,
+c          chainage des aretes frontalieres, chainage du hachage des aretes
+c moartr : nombre maximal d'entiers par arete du tableau noartr
+c noartr : les 3 aretes des triangles +-arete1, +-arete2, +-arete3
+c nbtrcf : >0 nombre de triangles empiles
+c          =0       si impossible de tourner autour du point
+c          =-nbtrcf si apres butee sur la frontiere il y a a nouveau
+c          butee sur la frontiere . a ce stade on ne peut dire si tous
+c          les triangles ayant ce sommet ont ete recenses
+c          ce cas arrive seulement si le sommet est sur la frontiere
+c notrcf : numero dans noartr des triangles de sommet ns
 c
-c           angle interne au camembert autour du sommet ns
-            angle = 0d0
-            do 540 i=1,nbtrcf
-c
-c              le numero de l'arete du triangle nt ne contenant pas le sommet ns
-               nt = notrcf(i)
-               do 520 na=1,3
-c                 le numero de l'arete na dans le tableau nosoar
-                  noar = abs( noartr(na,nt) )
-                  if( nosoar(1,noar) .ne. ns   .and.
-     %                nosoar(2,noar) .ne. ns ) goto 525
- 520           continue
-c
-c              calcul de l'angle (ns-st1 arete, ns-st2 arete)
- 525           ns1 = nosoar(1,noar)
-               ns2 = nosoar(2,noar)
-               a   = angled( pxyd(1,ns), pxyd(1,ns1), pxyd(1,ns2) )
-               if( a .gt. pi ) a = deuxpi - a
-               angle = angle + a
-c
- 540        continue
-c
-c           nombre ideal de triangles autour du sommet ns
-            n = nint( angle / pis3 )
-            if( n .le. 1 ) goto 1000
-            i = 1
-            if( nbtrcf .gt. n ) then
-c
-c              ajout du barycentre du triangle "milieu"
-               nt = notrcf( (n+1)/2 )
-               call nusotr( nt, mosoar, nosoar,
-     %                      moartr, noartr, nosotr )
-               if( nbsomm .ge. mxsomm ) then
-                  write(imprim,*) 'saturation du tableau pxyd'
-c                 abandon de l'amelioration du sommet ns
-                  goto 1000
-               endif
-               nbsomm = nbsomm + 1
-               do 560 i=1,3
-                  pxyd(i,nbsomm) = ( pxyd(i,nosotr(1))
-     %                             + pxyd(i,nosotr(2))
-     %                             + pxyd(i,nosotr(3)) ) / 3d0
- 560           continue
-c
-               if( nutysu .gt. 0 ) then
-c                 la fonction taille_ideale(x,y,z) existe
-c                 calcul de pxyzd(3,nbsomm) dans le repere initial => xyz(1:3)
-                  call tetaid( nutysu, pxyd(1,nbsomm), pxyd(2,nbsomm),
-     %                         pxyd(3,nbsomm), ier )
-               endif
-c
-c              sommet interne a la triangulation
-               nslign(nbsomm) = 0
-c
-c              les 3 aretes du triangle nt sont a rendre delaunay
-               noar0 = 0
-               do 570 i=1,3
-                  noar = abs( noartr(i,nt) )
-                  if( nosoar(3,noar) .eq. 0 ) then
-c                    arete non frontaliere
-                     if( nosoar(lchain,noar) .lt. 0 ) then
-c                       arete non encore chainee
-                        nosoar(lchain,noar) = noar0
-                        noar0 = noar
-                     endif
-                  endif
- 570           continue
-c
-c              triangulation du triangle de barycentre nbsomm
-c              protection a ne pas modifier sinon erreur!
-               call tr3str( nbsomm, nt,
-     %                      mosoar, mxsoar, n1soar, nosoar,
-     %                      moartr, mxartr, n1artr, noartr,
-     %                      noarst,
-     %                      nosotr, ierr )
-               if( ierr .ne. 0 ) goto 9999
-c
-c              les aretes chainees de la boule sont rendues delaunay
-               call tedela( pxyd,   noarst,
-     %                      mosoar, mxsoar, n1soar, nosoar, noar0,
-     %                      moartr, mxartr, n1artr, noartr, modifs )
-            endif
-c
- 1000    continue
-c
- 5000 continue
-c
- 9999 return
-      end
-
-
-      subroutine teamqs( nutysu,
-     %                   noarst, mosoar, mxsoar, n1soar, nosoar,
-     %                   moartr, mxartr, n1artr, noartr,
-     %                   mxtrcf, notrcf, nostbo,
-     %                   n1arcf, noarcf, larmin,
-     %                   comxmi, nbarpi, nbsomm, mxsomm, pxyd, nslign,
-     %                   ierr )
-c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c but :    une iteration de barycentrage des points internes
-c -----    modification de la topologie pour avoir 4 ou 5 ou 6 triangles
-c          pour chaque sommet de la triangulation
-c          mise en triangulation delaunay
-c
-c entrees:
-c --------
-c nutysu : numero de traitement de areteideale() selon le type de surface
-c          0 pas d'emploi de la fonction areteideale() => aretmx active
-c          1 il existe une fonction areteideale()
-c            dont seules les 2 premieres composantes de uv sont actives
-c          autres options a definir...
-c noarst : noarst(i) numero d'une arete de sommet i
-c mosoar : nombre maximal d'entiers par arete et
-c          indice dans nosoar de l'arete suivante dans le hachage
-c mxsoar : nombre maximal d'aretes frontalieres declarables
-c n1soar : numero de la premiere arete vide dans le tableau nosoar
-c nosoar : numero des 2 sommets , no ligne, 2 triangles de l'arete,
-c          chainage des aretes frontalieres, chainage du hachage des aretes
-c moartr : nombre maximal d'entiers par arete du tableau noartr
-c mxartr : nombre maximal de triangles declarables dans noartr
-c n1artr : numero du premier triangle vide dans le tableau noartr
-c          le chainage des triangles vides se fait sur noartr(2,.)
-c noartr : les 3 aretes des triangles +-arete1, +-arete2, +-arete3
-c mxtrcf : nombre maximal de triangles empilables
-c nbarpi : numero du dernier sommet frontalier ou interne impose
-c nslign : >0 => ns numero du point dans le lexique point si interne impose
-c          ou => 1 000 000 * n + ns1
-c              ou n   est le numero (1 a nblftr) de la ligne de ce point
-c                 ns1 est le numero du point dans sa ligne
-c          = 0 si le point est interne non impose par l'utilisateur
-c          =-1 si le sommet est externe au domaine
-c comxmi : min et max des coordonneees des sommets du maillage
-c
-c modifies :
-c ----------
-c nbsomm : nombre actuel de sommets de la triangulation
-c          (certains sommets internes ont ete desactives ou ajoutes)
-c pxyd   : tableau des coordonnees 2d des points
-c
-c auxiliaires:
-c ------------
-c notrcf : tableau ( mxtrcf ) auxiliaire d'entiers
-c          numero dans noartr des triangles de sommet ns
-c nostbo : tableau ( mxtrcf ) auxiliaire d'entiers
-c          numero dans pxyd des sommets des aretes simples de la boule
-c n1arcf : tableau (0:mxtrcf) auxiliaire d'entiers
-c noarcf : tableau (3,mxtrcf) auxiliaire d'entiers
-c larmin : tableau ( mxtrcf ) auxiliaire d'entiers
-c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c auteur : Alain Perronnet  Laboratoire J.-L. LIONS Paris UPMC mars 2006
-c....................................................................012
-      parameter        (lchain=6)
-      common / unites / lecteu, imprim, nunite(30)
-      double precision  pxyd(3,*)
-      double precision  ponder, ponde1, xbar, ybar, x, y, d, dmin, dmax
-      double precision  surtd2
-      double precision  d2d3(3,3)
-      real              origin(3), xyz(3)
-      integer           noartr(moartr,*),
-     %                  nosoar(mosoar,*),
-     %                  noarst(*),
-     %                  notrcf(mxtrcf),
-     %                  nslign(*),
-     %                  nostbo(*),
-     %                  n1arcf(0:mxtrcf),
-     %                  noarcf(3,mxtrcf),
-     %                  larmin(mxtrcf)
-      integer           nosotr(3,2)
-      double precision  comxmi(3,2)
-c
-c     le nombre d'iterations pour ameliorer la qualite
-      nbitaq = 6
-      ier    = 0
-c
-c     initialisation du parcours
-      nbs1 = nbsomm
-      nbs2 = nbarpi + 1
-c     => pas de traitement sur les points des lignes de la frontiere
-      nbs3 = -1
-c
-      do 5000 iter=1,nbitaq
-c
-c        le nombre de sommets supprimes
-         nbstsu = 0
-c
-c        les compteurs de passage sur les differents cas
-         nbst4 = 0
-         nbst5 = 0
-         nbst8 = 0
-c
-c        coefficient de ponderation croissant avec les iterations
-         ponder = min( 1d0, 0.1d0 + iter * 0.9d0 / nbitaq )
-ccc 9 mars 2006 ponder = min( 1d0, ( 50 + (50*iter)/nbitaq ) * 0.01d0 )
-         ponde1 = 1d0 - ponder
-c
-c        l'ordre du parcours dans le sens croissant ou decroissant
-         nt   = nbs1
-         nbs1 = nbs2
-         nbs2 = nt
-c        alternance du parcours
-         nbs3 = -nbs3
-c
-         do 1000 ns = nbs1, nbs2, nbs3
-c
-c           le sommet est il interne au domaine?
-            if( nslign(ns) .ne. 0 ) goto 1000
-c
-c           traitement d'un sommet interne non impose par l'utilisateur
-c           ===========================================================
-c           existe-t-il une arete de sommet ns ?
- 10         noar = noarst( ns )
-            if( noar .le. 0 ) goto 1000
-c
-c           le 1-er triangle de l'arete noar
-            nt = nosoar( 4, noar )
-            if( nt .le. 0 ) goto 1000
-c
-c           recherche des triangles de sommet ns
-c           ils doivent former un contour ferme de type etoile
-            call trp1st( ns, noarst, mosoar, nosoar, moartr, noartr,
-     %                   mxtrcf, nbtrcf, notrcf )
-            if( nbtrcf .le. 2 ) goto 1000
-c
-c           boucle sur les triangles qui forment une boule autour du sommet ns
-            nbstbo = 0
-c           chainage des aretes simples de la boule a rendre delaunay
-            noar0  = 0
-            do 40 i=1,nbtrcf
-c
-c              le numero de l'arete du triangle nt ne contenant pas le sommet ns
-               nt = notrcf(i)
-               do 20 na=1,3
-c                 le numero de l'arete na dans le tableau nosoar
-                  noar = abs( noartr(na,nt) )
-                  if( nosoar(1,noar) .ne. ns   .and.
-     %                nosoar(2,noar) .ne. ns ) goto 25
- 20            continue
-c
-c              construction de la liste des sommets des aretes simples
-c              de la boule des triangles de sommet ns
-c              -------------------------------------------------------
- 25            do 35 na=1,2
-                  ns1 = nosoar(na,noar)
-                  do 30 j=nbstbo,1,-1
-                     if( ns1 .eq. nostbo(j) ) goto 35
- 30               continue
-c                 ns1 est un nouveau sommet a ajouter
-                  nbstbo = nbstbo + 1
-                  nostbo(nbstbo) = ns1
- 35            continue
-c
-c              noar est une arete potentielle a rendre delaunay
-               if( nosoar(3,noar) .eq. 0 ) then
-c                 arete non frontaliere
-                  nosoar(lchain,noar) = noar0
-                  noar0 = noar
-               endif
-c
- 40         continue
-c
-c           calcul des 2 coordonnees du barycentre de la boule du sommet ns
-c           calcul de l'arete de taille maximale et minimale issue de ns
-c           ---------------------------------------------------------------
-            xbar = 0d0
-            ybar = 0d0
-            dmin = 1d28
-            dmax = 0d0
-            do 50 i=1,nbstbo
-               x    = pxyd(1,nostbo(i))
-               y    = pxyd(2,nostbo(i))
-               xbar = xbar + x
-               ybar = ybar + y
-               d    = (x-pxyd(1,ns)) ** 2 + (y-pxyd(2,ns)) ** 2
-               if( d .gt. dmax ) then
-                  dmax = d
-                  imax = i
-               endif
-               if( d .lt. dmin ) then
-                  dmin = d
-                  imin = i
-               endif
- 50         continue
-c
-c           pas de modification de la topologie lors de la derniere iteration
-c           =================================================================
-            if( iter .ge. nbitaq ) goto 200
-c
-c           si la boule de ns contient au plus 3 triangles
-c            =>  pas de changement de topologie
-c           ==============================================
-            if( nbtrcf .le. 3 ) goto 200
-c
-c           si la boule de ns contient 4 triangles le sommet ns est detruit
-c           ===============================================================
-            if( nbtrcf .eq. 4 ) then
-c
-c              remise a -1 du chainage des aretes peripheriques de la boule ns
-               noar = noar0
- 60            if( noar .gt. 0 ) then
-c                 protection du no de l'arete suivante
-                  na = nosoar(lchain,noar)
-c                 l'arete interne est remise a -1
-                  nosoar(lchain,noar) = -1
-c                 l'arete suivante
-                  noar = na
-                  goto 60
-               endif
-               call te1stm( ns,     pxyd,   noarst,
-     %                      mosoar, mxsoar, n1soar, nosoar,
-     %                      moartr, mxartr, n1artr, noartr,
-     %                      mxtrcf, n1arcf, noarcf,
-     %                      larmin, notrcf, nostbo,
-     %                      ierr )
-               if( ierr .eq. -543 ) then
-                  ierr = 0
-                  goto 1000
-               else if( ierr .lt.    0 ) then
-c                 le sommet ns est externe donc non supprime
-c                 ou bien le sommet ns est le centre d'un cf dont toutes
-c                 les aretes simples sont frontalieres
-c                 dans les 2 cas le sommet ns n'est pas supprime
-                  ierr = 0
-                  goto 200
-               else if( ierr .eq. 0 ) then
-                  nbst4  = nbst4 + 1
-                  nbstsu = nbstsu + 1
-               else
-c                 erreur irrecuperable
-                  write(imprim,*)
-     %           'teamqs: erreur1 irrecuperable en sortie te1stm'
-                  goto 9999
-               endif
-               goto 1000
-c
-            endif
-c
-c           si la boule de ns contient 5 triangles et a un sommet voisin
-c           sommet de 5 triangles alors l'arete joignant ces 2 sommets
-c           est transformee en un seul sommet de 6 triangles
-c           ============================================================
-            if( nbtrcf .eq. 5 ) then
-c
-               do 80 i=1,5
-c                 le numero du sommet de l'arete i et different de ns
-                  ns1 = nostbo(i)
-c                 la liste des triangles de sommet ns1
-                  call trp1st( ns1, noarst,
-     %                         mosoar, nosoar, moartr, noartr,
-     %                         mxtrcf-5, nbtrc1, notrcf(6) )
-                  if( nbtrc1 .eq. 5 ) then
-c
-c                    l'arete de sommets ns-ns1 devient un point
-c                    par suppression du sommet ns
-c
-c                    remise a -1 du chainage des aretes peripheriques de la boul
-                     noar = noar0
- 70                  if( noar .gt. 0 ) then
-c                       protection du no de l'arete suivante
-                        na = nosoar(lchain,noar)
-c                       l'arete interne est remise a -1
-                        nosoar(lchain,noar) = -1
-c                       l'arete suivante
-                        noar = na
-                        goto 70
-                     endif
-c
-c                    le point ns1 devient le milieu de l'arete ns-ns1
-                     x = pxyd(1,ns1)
-                     y = pxyd(2,ns1)
-                     d = pxyd(3,ns1)
-                     do 75 j=1,3
-                        pxyd(j,ns1) = (pxyd(j,ns) + pxyd(j,ns1)) * 0.5d0
- 75                  continue
-c
-                     if( nutysu .gt. 0 ) then
-c                       la fonction taille_ideale(x,y,z) existe
-c                       calcul de pxyzd(3,ns1) dans le repere initial => xyz(1:3
-                        call tetaid( nutysu,pxyd(1,ns1),pxyd(2,ns1),
-     %                               pxyd(3,ns1), ier )
-                     endif
-c
-c                    suppression du point ns et mise en delaunay
-                     call te1stm( ns,     pxyd,   noarst,
-     %                            mosoar, mxsoar, n1soar, nosoar,
-     %                            moartr, mxartr, n1artr, noartr,
-     %                            mxtrcf, n1arcf, noarcf,
-     %                            larmin, notrcf, nostbo,
-     %                            ierr )
-                     if( ierr .lt. 0 ) then
-c                       le sommet ns est externe donc non supprime
-c                       ou bien le sommet ns est le centre d'un cf dont toutes
-c                       les aretes simples sont frontalieres ou erreur
-c                       dans les 3 cas le sommet ns n'est pas supprime
-c                       restauration du sommet ns1 a son ancienne place
-                        pxyd(1,ns1) = x
-                        pxyd(2,ns1) = y
-                        pxyd(3,ns1) = d
-                        ierr = 0
-                        goto 1000
-                     else if( ierr .eq. 0 ) then
-                        nbstsu = nbstsu + 1
-                        nbst5  = nbst5 + 1
-                        goto 1000
-                     else
-c                       erreur irrecuperable
-                        write(imprim,*)
-     %                 'teamqs: erreur2 irrecuperable en sortie te1stm'
-                        goto 9999
-                     endif
-                  endif
- 80            continue
-            endif
-c
-c           si la boule de ns contient au moins 8 triangles
-c           alors un triangle interne est ajoute + 3 triangles (1 par arete)
-c           ================================================================
-            if( nbtrcf .ge. 8 ) then
-c
-c              modification des coordonnees du sommet ns
-c              il devient le barycentre du triangle notrcf(1)
-               call nusotr( notrcf(1), mosoar, nosoar,
-     %                      moartr, noartr, nosotr )
-               do 110 i=1,3
-                  pxyd(i,ns) = ( pxyd(i,nosotr(1,1))
-     %                         + pxyd(i,nosotr(2,1))
-     %                         + pxyd(i,nosotr(3,1)) ) / 3d0
- 110           continue
-c
-               if( nutysu .gt. 0 ) then
-c                 la fonction taille_ideale(x,y,z) existe
-c                 calcul de pxyzd(3,nbsomm) dans le repere initial => xyz(1:3)
-                  call tetaid( nutysu, pxyd(1,ns), pxyd(2,ns),
-     %                         pxyd(3,ns), ier )
-               endif
-c
-c              ajout des 2 autres sommets comme barycentres des triangles
-c              notrcf(1+nbtrcf/3) et notrcf(1+2*nbtrcf/3)
-               nbt1 = ( nbtrcf + 1 ) / 3
-               do 140 n=1,2
-c
-c                 le triangle traite
-                  nt = notrcf(1 + n * nbt1 )
-c
-c                 le numero pxyd de ses 3 sommets
-                  call nusotr( nt, mosoar, nosoar,
-     %                         moartr, noartr, nosotr )
-c
-c                 ajout du nouveau barycentre
-                  if( nbsomm .ge. mxsomm ) then
-                   write(imprim,*) 'teamqs: saturation du tableau pxyd'
-c                    abandon de l'amelioration
-                     goto 9999
-                  endif
-                  nbsomm = nbsomm + 1
-                  do 120 i=1,3
-                     pxyd(i,nbsomm) = ( pxyd(i,nosotr(1,1))
-     %                                + pxyd(i,nosotr(2,1))
-     %                                + pxyd(i,nosotr(3,1)) ) / 3d0
- 120              continue
-c
-                  if( nutysu .gt. 0 ) then
-c                    la fonction taille_ideale(x,y,z) existe
-c                    calcul de pxyzd(3,nbsomm) dans le repere initial => xyz(1:3
-                     call tetaid( nutysu, pxyd(1,nbsomm),pxyd(2,nbsomm),
-     %                            pxyd(3,nbsomm), ier )
-                  endif
-c
-c                 sommet interne a la triangulation
-                  nslign(nbsomm) = 0
-c
-c                 les 3 aretes du triangle nt sont a rendre delaunay
-                  do 130 i=1,3
-                     noar = abs( noartr(i,nt) )
-                     if( nosoar(3,noar) .eq. 0 ) then
-c                       arete non frontaliere
-                        if( nosoar(lchain,noar) .lt. 0 ) then
-c                          arete non encore chainee
-                           nosoar(lchain,noar) = noar0
-                           noar0 = noar
-                        endif
-                     endif
- 130              continue
-c
-c                 triangulation du triangle de barycentre nbsomm
-c                 protection a ne pas modifier sinon erreur!
-                  call tr3str( nbsomm, nt,
-     %                         mosoar, mxsoar, n1soar, nosoar,
-     %                         moartr, mxartr, n1artr, noartr,
-     %                         noarst,
-     %                         nosotr, ierr )
-                  if( ierr .ne. 0 ) then
-                     write(imprim,*)
-     %              'teamqs: erreur irrecuperable en sortie tr3str'
-                     goto 9999
-                  endif
- 140           continue
-c
-               nbst8  = nbst8 + 1
-c
-c              les aretes chainees de la boule sont rendues delaunay
-               goto 300
-c
-            endif
-c
-c           nbtrcf est compris entre 5 et 7 => barycentrage simple
-c           ======================================================
-c           les 2 coordonnees du barycentre des sommets des aretes
-c           simples de la boule du sommet ns
- 200        xbar = xbar / nbstbo
-            ybar = ybar / nbstbo
-c
-C DEBUT AJOUT 21/MAI/2005
-C           PONDERATION POUR EVITER LES DEGENERESCENSES AVEC PROTECTION
-C           SI UN TRIANGLE DE SOMMET NS A UNE AIRE NEGATIVE APRES BARYCENTRAGE
-C           ALORS LE SOMMET NS N'EST PAS BOUGE
-c
-c           protection des XY du point initial
-            xxx = pxyd(1,ns)
-            yyy = pxyd(2,ns)
-c
-            pxyd(1,ns) = ponde1 * pxyd(1,ns) + ponder * xbar
-            pxyd(2,ns) = ponde1 * pxyd(2,ns) + ponder * ybar
-c
-ccc         write(imprim,*)'teamqs 200: ns=',ns,' ancien =',xxx,yyy
-ccc         write(imprim,*)'teamqs 200: ns=',ns,' nouveau=',pxyd(1,ns),pxyd(2,ns)
-c
-            do 240 i=1,nbtrcf
-c              le numero de l'arete du triangle nt ne contenant pas le sommet ns
-               nt = notrcf(i)
-               do 220 na=1,3
-c                 le numero de l'arete na dans le tableau nosoar
-                  noar = abs( noartr(na,nt) )
-                  if( nosoar(1,noar) .ne. ns   .and.
-     %                nosoar(2,noar) .ne. ns ) then
-                     if( noartr(na,nt) .ge. 0 ) then
-                        ns2 = nosoar(1,noar)
-                        ns3 = nosoar(2,noar)
-                     else
-                        ns3 = nosoar(1,noar)
-                        ns2 = nosoar(2,noar)
-                     endif
-                     goto 225
-                  endif
- 220           continue
-
-c              aire signee du triangle nt
- 225           d = surtd2( pxyd(1,ns), pxyd(1,ns2), pxyd(1,ns3) )
-               if( d .le. 0d0 ) then
-ccc                  write(imprim,*),'iter=',iter,
-ccc     %            ' Barycentrage au point ns=',ns,
-ccc     %            '   XB=',pxyd(1,ns),' YB=',pxyd(2,ns),
-ccc     %            ' => triangle avec AIRE<0 => Pt REMIS en X =',xxx,
-ccc     %            ' Y =',yyy
-                  pxyd(1,ns) = xxx
-                  pxyd(2,ns) = yyy
-                  goto 1000
-               endif
- 240        continue
-C
-C FIN AJOUT 21/MAI/2005
-c
-c           les aretes chainees de la boule sont rendues delaunay
- 300        call tedela( pxyd,   noarst,
-     %                   mosoar, mxsoar, n1soar, nosoar, noar0,
-     %                   moartr, mxartr, n1artr, noartr, modifs )
-c
- 1000    continue
-c
-ccc         write(imprim,11000) iter, nbitaq, nbst4, nbst5, nbst8
-ccc11000 format( 'teamqs iter=',i2,' max iter=',i2,':',
-ccc     %        i7,' sommets de 4t',
-ccc     %        i7,' sommets 5t+5t',
-ccc     %        i7,' sommets >7t' )
-c
-c        mise a jour pour ne pas oublier les nouveaux sommets
-         if( nbs1 .gt. nbs2 ) then
-            nbs1 = nbsomm
-            nbs2 = nbarpi + 1
-         else
-            nbs1 = nbarpi + 1
-            nbs2 = nbsomm
-         endif
-c
- 5000 continue
-c
- 9999 return
-      end
-
-
-      subroutine teamqt( nutysu,
-     %                   noarst, mosoar, mxsoar, n1soar, nosoar,
-     %                   moartr, mxartr, n1artr, noartr,
-     %                   mxarcf, notrcf, nostbo,
-     %                   n1arcf, noarcf, larmin,
-     %                   comxmi, nbarpi, nbsomm, mxsomm, pxyd, nslign,
-     %                   ierr )
-c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c but :    amelioration de la qualite de la triangulation
-c -----
-c
-c entrees:
-c --------
-c nutysu : numero de traitement de areteideale() selon le type de surface
-c          0 pas d'emploi de la fonction areteideale() => aretmx active
-c          1 il existe une fonction areteideale()
-c            dont seules les 2 premieres composantes de uv sont actives
-c          autres options a definir...
-c noarst : noarst(i) numero d'une arete de sommet i
-c mosoar : nombre maximal d'entiers par arete et
-c          indice dans nosoar de l'arete suivante dans le hachage
-c mxsoar : nombre maximal d'aretes frontalieres declarables
-c n1soar : numero de la premiere arete vide dans le tableau nosoar
-c nosoar : numero des 2 sommets , no ligne, 2 triangles de l'arete,
-c          chainage des aretes frontalieres, chainage du hachage des aretes
-c moartr : nombre maximal d'entiers par arete du tableau noartr
-c mxartr : nombre maximal de triangles declarables dans noartr
-c n1artr : numero du premier triangle vide dans le tableau noartr
-c          le chainage des triangles vides se fait sur noartr(2,.)
-c noartr : les 3 aretes des triangles +-arete1, +-arete2, +-arete3
-c mxarcf : nombre maximal de triangles empilables
-c nbarpi : numero du dernier sommet frontalier ou interne impose
-c nslign : tableau du numero de sommet dans sa ligne pour chaque
-c          sommet frontalier
-c          numero du point dans le lexique point si interne impose
-c          0 si le point est interne non impose par l'utilisateur
-c         -1 si le sommet est externe au domaine
-c comxmi : min et max des coordonneees des sommets du maillage
-c
-c modifies :
-c ----------
-c nbsomm : nombre actuel de sommets de la triangulation
-c          (certains sommets internes ont ete desactives ou ajoutes)
-c pxyd   : tableau des coordonnees 2d des points
-c
-c auxiliaires:
-c ------------
-c notrcf : tableau ( mxarcf ) auxiliaire d'entiers
-c          numero dans noartr des triangles de sommet ns
-c nostbo : tableau ( mxarcf ) auxiliaire d'entiers
-c          numero dans pxyd des sommets des aretes simples de la boule
-c n1arcf : tableau (0:mxarcf) auxiliaire d'entiers
-c noarcf : tableau (3,mxarcf) auxiliaire d'entiers
-c larmin : tableau ( mxarcf ) auxiliaire d'entiers
-c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c auteur : alain perronnet  analyse numerique paris upmc       juin 1997
-c....................................................................012
-      common / unites / lecteu, imprim, nunite(30)
-      double precision  pxyd(3,*), d2d3(3,3)
-      integer           noartr(moartr,*),
-     %                  nosoar(mosoar,*),
-     %                  noarst(*),
-     %                  notrcf(mxarcf),
-     %                  nslign(*),
-     %                  nostbo(mxarcf),
-     %                  n1arcf(0:mxarcf),
-     %                  noarcf(3,mxarcf),
-     %                  larmin(mxarcf)
-      double precision  comxmi(3,2)
-c
-c     suppression des sommets de triangles equilateraux trop proches
-c     d'un sommet frontalier ou d'un point interne impose par
-c     triangulation frontale de l'etoile et mise en delaunay
-c     ==============================================================
-      call tesusp( nbarpi, pxyd,   noarst,
-     %             mosoar, mxsoar, n1soar, nosoar,
-     %             moartr, mxartr, n1artr, noartr,
-     %             mxarcf, n1arcf, noarcf, larmin, notrcf, nostbo,
-     %             ierr )
-      if( ierr .ne. 0 ) goto 9999
-c
-c     ajustage des tailles moyennes des aretes avec ampli=1.34d0 entre
-c     ampli/2 x taille_souhaitee et ampli x taille_souhaitee 
-c     + barycentrage des sommets et mise en triangulation delaunay
-c     ================================================================
-      call teamqa( nutysu,
-     %             noarst, mosoar, mxsoar, n1soar, nosoar,
-     %             moartr, mxartr, n1artr, noartr,
-     %             mxarcf, notrcf, nostbo,
-     %             n1arcf, noarcf, larmin,
-     %             comxmi, nbarpi, nbsomm, mxsomm, pxyd, nslign,
-     %             ierr )
-      if( ierr .ne. 0 ) goto 9999
-c
-cccc     modification de la topologie autour des sommets frontaliers
-cccc     pour avoir un nombre de triangles egal a l'angle/60 degres
-cccc     et mise en triangulation delaunay locale
-cccc     ===========================================================
-ccc      call teamsf( nutysu,
-ccc     %             noarst, mosoar, mxsoar, n1soar, nosoar,
-ccc     %             moartr, mxartr, n1artr, noartr,
-ccc     %             mxarcf, notrcf, nostbo,
-ccc     %             n1arcf, noarcf, larmin,
-ccc     %             comxmi, nbarpi, nbsomm, mxsomm, pxyd, nslign,
-ccc     %             ierr )
-ccc      if( ierr .ne. 0 ) goto 9999
-c
-c     quelques iterations de barycentrage des points internes
-c     modification de la topologie pour avoir 4 ou 5 ou 6 triangles
-c     pour chaque sommet de la triangulation
-c     et mise en triangulation delaunay
-c     =============================================================
-      call teamqs( nutysu,
-     %             noarst, mosoar, mxsoar, n1soar, nosoar,
-     %             moartr, mxartr, n1artr, noartr,
-     %             mxarcf, notrcf, nostbo,
-     %             n1arcf, noarcf, larmin,
-     %             comxmi, nbarpi, nbsomm, mxsomm, pxyd, nslign,
-     %             ierr )
-c
- 9999 return
-      end
-
-      subroutine trfrcf( nscent, mosoar, nosoar, moartr, noartr,
-     %                   nbtrcf, notrcf, nbarfr )
-c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c but :    calculer le nombre d'aretes simples du contour ferme des
-c -----    nbtrcf triangles de numeros stockes dans le tableau notrcf
-c          ayant tous le sommet nscent
-c
-c entrees:
-c --------
-c nscent : numero du sommet appartenant a tous les triangles notrcf
-c mosoar : nombre maximal d'entiers par arete et
-c          indice dans nosoar de l'arete suivante dans le hachage
-c nosoar : numero des 2 sommets , no ligne, 2 triangles de l'arete,
-c          chainage des aretes frontalieres, chainage du hachage des aretes
-c moartr : nombre maximal d'entiers par arete du tableau noartr
-c noartr : les 3 aretes des triangles +-arete1, +-arete2, +-arete3
-c nbtrcf : >0 nombre de triangles empiles
-c          =0       si impossible de tourner autour du point
-c          =-nbtrcf si apres butee sur la frontiere il y a a nouveau
-c          butee sur la frontiere . a ce stade on ne peut dire si tous
-c          les triangles ayant ce sommet ont ete recenses
-c          ce cas arrive seulement si le sommet est sur la frontiere
-c notrcf : numero dans noartr des triangles de sommet ns
-c
-c sortie :
-c --------
-c nbarfr : nombre d'aretes simples frontalieres
-c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c auteur : alain perronnet  analyse numerique paris upmc       juin 1997
-c....................................................................012
-      integer           noartr(moartr,*),
-     %                  nosoar(mosoar,*),
-     %                  notrcf(1:nbtrcf)
+c sortie :
+c --------
+c nbarfr : nombre d'aretes simples frontalieres
+c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+c auteur : alain perronnet  analyse numerique paris upmc       juin 1997
+c....................................................................012
+      integer           noartr(moartr,*),
+     %                  nosoar(mosoar,*),
+     %                  notrcf(1:nbtrcf)
 c
       nbarfr = 0
       do 50 n=1,nbtrcf
@@ -5372,7 +4752,7 @@ c        de 2 nouveaux contours fermes
       end
 
 
-      subroutine tridcf( nbcf0,  pxyd,   noarst,
+      subroutine tridcf( nbcf0,  nbstpe, nostpe, pxyd,   noarst,
      %                   mosoar, mxsoar, n1soar, nosoar,
      %                   moartr, n1artr, noartr,
      %                   mxarcf, n1arcf, noarcf, larmin,
@@ -5380,10 +4760,14 @@ c        de 2 nouveaux contours fermes
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 c but :    triangulation directe de nbcf0 contours fermes (cf)
 c -----    definis par la liste circulaire de leurs aretes peripheriques
+c          avec integration de nbstpe sommets isoles a l'un des cf initiaux
 c
 c entrees:
 c --------
 c nbcf0  : nombre initial de cf a trianguler
+c nbstpe : nombre de sommets isoles a l'interieur des cf et
+c          a devenir sommets de la triangulation
+c nostpe : numero dans pxyd des nbstpe sommets isoles
 c pxyd   : tableau des coordonnees 2d des points
 c          par point : x  y  distance_souhaitee
 c mosoar : nombre maximal d'entiers par arete et
@@ -5433,11 +4817,13 @@ c          2 saturation de l'un des des tableaux nosoar, noartr, ...
 c          3 si contour ferme reduit a moins de 3 aretes
 c          4 saturation du tableau notrcf
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c auteur : alain perronnet  analyse numerique paris upmc       mars 1997
+c auteur : alain perronnet  analyse numerique paris upmc    mars    1997
+c modifs : alain perronnet laboratoire jl lions upmc paris  octobre 2006
 c....................................................................012
       common / unites / lecteu, imprim, nunite(30)
       double precision  pxyd(3,*)
-      integer           noartr(moartr,*),
+      integer           nostpe(nbstpe),
+     %                  noartr(moartr,*),
      %                  nosoar(mosoar,mxsoar),
      %                  noarst(*),
      %                  n1arcf(0:mxarcf),
@@ -5445,14 +4831,136 @@ c....................................................................012
      %                  larmin(mxarcf),
      %                  notrcf(mxarcf)
 c
-ccc      integer           nosotr(3)
-ccc      double precision  d, surtd2
+      integer           nosotr(3)
+      double precision  d, diptdr, surtd2, dmin, s
+c
+c     depart avec nbcf0 cf a trianguler
+      nbcf   = nbcf0
+c
+c     le nombre de triangles formes dans l'ensemble des cf
+      nbtrcf = 0
+c
+c     le nombre restant de sommets isoles a integrer au cf
+      nbstp = nbstpe
+c
+ 1    if( nbstp .le. 0 ) goto 10
+c
+c     il existe au moins un sommet isole
+c     recherche d'un cf dont la premiere arete forme un triangle
+c     d'aire>0 avec un sommet isole et recherche du sommet isole
+c     le plus proche de cette arete
+c     ==========================================================
+      imin = 0
+      dmin = 1d123
+      do 6 ncf=1,nbcf
+c        le cf en haut de pile a pour arete avant la premiere arete
+         na1 = n1arcf( ncf )
+         na2 = na1
+c        recherche de l'arete qui precede la premiere arete
+ 2       if( noarcf( 2, na2 ) .ne. na1 ) then
+            na2 = noarcf( 2, na2 )
+            goto 2
+         endif
+c        l'arete na0 dans noarcf qui precede n1arcf( ncf )
+         na0 = na2
+c        la premiere arete du cf
+         na1   = noarcf( 2, na0 )
+c        son numero dans nosoar
+         noar1 = noarcf( 3, na1 )
+c        l'arete suivante
+         na2   = noarcf( 2, na1 )
+c        le no pxyd des 2 sommets de l'arete na1
+         ns1   = noarcf( 1, na1 )
+         ns2   = noarcf( 1, na2  )
+         do 3 i=1,nbstpe
+c           le sommet isole ns3
+            ns3 = nostpe( i )
+            if( ns3 .le. 0 ) goto 3
+c           aire du triangle arete na1 et sommet ns3
+            d = surtd2( pxyd(1,ns1), pxyd(1,ns2), pxyd(1,ns3) )
+            if( d .gt. 0d0 ) then
+c              distance de ce sommet ns3 a l'arete na1
+               d = diptdr( pxyd(1,ns3),  pxyd(1,ns1), pxyd(1,ns2) )
+               if( d .lt. dmin ) then
+                  dmin = d
+                  imin = i
+               endif
+            endif
+ 3       continue
+         if( imin .gt. 0 ) then
+c           le sommet imin de nostpe est a distance minimale de
+c           la premiere arete du cf de numero ncf
+c           la formation de l'arete ns2-ns3 dans le tableau nosoar
+            call fasoar( ns2, ns3, -1, -1,  0,
+     %                   mosoar, mxsoar, n1soar, nosoar, noarst,
+     %                   noar2,  ierr )
+            if( ierr .ne. 0 ) goto 9900
+c           la formation de l'arete ns3-ns1 dans le tableau nosoar
+            call fasoar( ns3, ns1, -1, -1,  0,
+     %                   mosoar, mxsoar, n1soar, nosoar, noarst,
+     %                   noar3,  ierr )
+            if( ierr .ne. 0 ) goto 9900
+c
+c           ajout dans noartr du triangle de sommets ns1 ns2 ns3
+c           et d'aretes na1, noar2, noar3 dans nosoar
+            call trcf3a( ns1,   ns2,   ns3,
+     %                   noar1, noar2, noar3,
+     %                   mosoar, nosoar,
+     %                   moartr, n1artr, noartr,
+     %                   nt )
+            s = surtd2( pxyd(1,ns1), pxyd(1,ns2), pxyd(1,ns3) )
+            if( s .le. 0 ) then
+               write(imprim,*)'tridcf: trcf3a produit tr',nt,' st',
+     %                         ns1,ns2,ns3
+               write(imprim,*)'tridcf: triangle AIRE<0'
+            endif
+            if( nt .le. 0 ) then
+               ierr = 7
+               return
+            endif
+            if( nbtrcf .ge. mxarcf ) then
+               write(imprim,*) 'saturation du tableau notrcf'
+               ierr = 8
+               return
+            endif
+            nbtrcf = nbtrcf + 1
+            notrcf( nbtrcf ) = nt
+c
+c           modification du cf. creation d'une arete dans noarcf
+            na12 = n1arcf(0)
+            if( na12 .le. 0 ) then
+               write(imprim,*) 'saturation du tableau noarcf'
+               ierr = 10
+               return
+            endif
+c           la 1-ere arete vide de noarcf est mise a jour
+            n1arcf(0) = noarcf( 2, na12 )
+c
+c           l'arete suivante de na0
+            noarcf( 1, na1 ) = ns1
+            noarcf( 2, na1 ) = na12
+            noarcf( 3, na1 ) = noar3
+c           l'arete suivante de na1
+            noarcf( 1, na12 ) = ns3
+            noarcf( 2, na12 ) = na2
+            noarcf( 3, na12 ) = noar2
+c
+c           un sommet isole traite
+            nbstp = nbstp - 1
+            nostpe( imin ) = - nostpe( imin )
+            goto 1
+         endif
 c
-c     depart avec nbcf0 cf a trianguler
-      nbcf   = nbcf0
+ 6    continue
 c
-c     le nombre de triangles formes dans l'ensemble des cf
-      nbtrcf = 0
+      if( imin .eq. 0 ) then
+         write(imprim,*) 'tridcf: il reste',nbstp,
+     %                   ' sommets isoles non triangules'
+         write(imprim,*) 'ameliorer l''algorithme'
+ccc         pause
+         ierr = 9
+         return
+      endif
 c
 c     tant qu'il existe un cf a trianguler faire
 c     la triangulation directe du cf
@@ -5487,6 +4995,14 @@ c           saturation du tableau noartr ou noarcf ou n1arcf
             ierr = 2
             return
          endif
+         call nusotr( nt, mosoar, nosoar, moartr, noartr, nosotr)
+         s = surtd2( pxyd(1,nosotr(1)),
+     %               pxyd(1,nosotr(2)),
+     %               pxyd(1,nosotr(3)) )
+         if( s .le. 0 ) then
+            write(imprim,*)'tridcf: trcf3s produit tr',nt,' st',nosotr
+            write(imprim,*)'tridcf: triangle AIRE<0'
+         endif
 c
 c        ajout du triangle cree a sa pile
          if( nbtrcf .ge. mxarcf ) then
@@ -5506,25 +5022,7 @@ c
 c        le numero du triangle ajoute dans le tableau noartr
          nt0 = notrcf( ntp0 )
 c
-cccc        aire signee du triangle nt0
-cccc        le numero des 3 sommets du triangle nt
-ccc         call nusotr( nt0, mosoar, nosoar, moartr, noartr,
-ccc     %                nosotr )
-ccc         d = surtd2( pxyd(1,nosotr(1)), pxyd(1,nosotr(2)),
-ccc     %               pxyd(1,nosotr(3)) )
-ccc         if( d .le. 0 ) then
-cccc
-cccc           un triangle d'aire negative de plus
-ccc            write(imprim,*) 'triangle ',nt0,' st:',nosotr,
-ccc     %                      ' d aire ',d,'<=0'
-ccc            pause
-ccc         endif
-c
-cccc        trace du triangle nt0
-ccc         call mttrtr( pxyd, nt0, moartr, noartr, mosoar, nosoar,
-ccc     %                ncturq, ncblan )
-c
-c        boucle sur les 3 aretes du triangle
+c        boucle sur les 3 aretes du triangle nt0
          do 20 i=1,3
 c
 c           le numero de l'arete i du triangle dans le tableau nosoar
@@ -5546,7 +5044,19 @@ c               le triangle est ajoute a l'arete
 c              l'arete appartient a 2 triangles differents de nt0
 c              anomalie. chainage des triangles des aretes defectueux
 c              a corriger
-               write(imprim,*) 'pause dans tridcf'
+               write(imprim,*) 'tridcf: erreur 1 arete dans 3 triangles'
+               write(imprim,*) 'tridcf: arete nosoar(',noar,')=',
+     %                          (nosoar(k,noar),k=1,mosoar)
+               call nusotr( nt0, mosoar, nosoar, moartr, noartr, nosotr)
+               write(imprim,*) 'tridcf: triangle nt0=',nt0,' st:',
+     %                          (nosotr(k),k=1,3)
+               call nusotr( nt1, mosoar, nosoar, moartr, noartr, nosotr)
+               write(imprim,*) 'tridcf: triangle nt1=',nt1,' st:',
+     %                          (nosotr(k),k=1,3)
+               call nusotr( nt2, mosoar, nosoar, moartr, noartr, nosotr)
+               write(imprim,*) 'tridcf: triangle nt2=',nt2,' st:',
+     %                          (nosotr(k),k=1,3)
+ccc               pause
                ierr = 5
                return
             endif
  20      continue
 c
  30   continue
+      return
+c
+c     erreur tableau nosoar sature
+ 9900 write(imprim,*) 'saturation du tableau nosoar'
+      ierr = 6
+      return
       end
 
-
-      subroutine te1stm( nsasup, pxyd,   noarst,
+      subroutine te1stm( nsasup, nbarpi, pxyd,   noarst,
      %                   mosoar, mxsoar, n1soar, nosoar,
      %                   moartr, mxartr, n1artr, noartr,
      %                   mxarcf, n1arcf, noarcf, larmin, notrcf, liarcf,
@@ -5571,6 +5086,7 @@ c
 c entrees:
 c --------
 c nsasup : numero dans le tableau pxyd du sommet a supprimer
+c nbarpi : numero du dernier sommet frontalier ou interne impose
 c pxyd   : tableau des coordonnees 2d des points
 c          par point : x  y  distance_souhaitee
 c mosoar : nombre maximal d'entiers par arete et
@@ -5617,53 +5133,56 @@ c             dans les 2 cas => retour sans modifs
 c          >0 si une erreur est survenue
 c          =11 algorithme defaillant
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c auteur : alain perronnet  analyse numerique paris upmc       mars 2006
+c auteur : alain perronnet  analyse numerique paris upmc       mars 1997
 c....................................................................012
-      parameter       ( lchain=6, quamal=0.3)
+      parameter       ( lchain=6, mxstpe=512)
       common / unites / lecteu,imprim,intera,nunite(29)
-      double precision  pxyd(3,*)
+      double precision  pxyd(3,*), s0, s1, surtd2, s
       integer           nosoar(mosoar,mxsoar),
-     %                  noartr(moartr,*),
+     %                  noartr(moartr,mxartr),
      %                  noarst(*),
      %                  n1arcf(0:mxarcf),
      %                  noarcf(3,mxarcf),
      %                  larmin(mxarcf),
      %                  notrcf(mxarcf),
-     %                  liarcf(mxarcf)
+     %                  liarcf(mxarcf),
+     %                  nostpe(mxstpe),
+     %                  nosotr(3)
+c
+      if( nsasup .le. nbarpi ) then
+c        sommet frontalier non destructible
+         ierr = -1
+         return
+      endif
+      ierr = 0
 c
 c     nsasup est il un sommet interne, "centre" d'une boule de triangles?
 c     => le sommet nsasup peut etre supprime
 c     ===================================================================
 c     formation du cf de ''centre'' le sommet nsasup
       call trp1st( nsasup, noarst, mosoar, nosoar,
-     %             moartr, noartr,
+     %             moartr, mxartr, noartr,
      %             mxarcf, nbtrcf, notrcf )
-      if( nbtrcf .le. 0 ) then
+c
+      if( nbtrcf .le. 2 ) then
 c        erreur: impossible de trouver tous les triangles de sommet nsasup
+c        ou pas assez de triangles de sommet nsasup
 c        le sommet nsasup n'est pas supprime de la triangulation
          ierr = -1
          return
-      else if( nbtrcf .le. 2 ) then
-c        le sommet nsasup n'est pas supprime
-         ierr = -1
-         return
       endif
+c
       if( nbtrcf*3 .gt. mxarcf ) then
          write(imprim,*) 'saturation du tableau noarcf'
          ierr = 10
          return
       endif
 c
-ccc      trace des triangles de l'etoile du sommet nsasup
-ccc      call trpltr( nbtrcf, notrcf, pxyd,
-ccc     %             moartr, noartr, mosoar, nosoar,
-ccc     %             ncroug, ncblan )
-c
 c     si toutes les aretes du cf sont frontalieres, alors il est
 c     interdit de detruire le sommet "centre" du cf
 c     calcul du nombre nbarfr des aretes simples des nbtrcf triangles
       call trfrcf( nsasup, mosoar, nosoar, moartr, noartr,
-     %             nbtrcf, notrcf, nbarfr  )
+     %             nbtrcf, notrcf, nbarfr )
       if( nbarfr .ge. nbtrcf ) then
 c        toutes les aretes simples sont frontalieres
 c        le sommet nsasup ("centre" de la cavite) n'est pas supprime
@@ -5671,12 +5190,26 @@ c        le sommet nsasup ("centre" de la cavite) n'est pas supprime
          return
       endif
 c
+c     calcul des surfaces avant suppression du point
+      s0 = 0d0
+      do 10 i=1,nbtrcf
+         nt = notrcf(i)
+c        les numeros des 3 sommets du triangle nt
+         call nusotr( nt, mosoar, nosoar, moartr, noartr, nosotr )
+         s = surtd2( pxyd(1,nosotr(1)),
+     %               pxyd(1,nosotr(2)),
+     %               pxyd(1,nosotr(3)) )
+         s0 = s0 + abs( s )
+ 10   continue
+c
 c     formation du contour ferme (liste chainee des aretes simples)
 c     forme a partir des aretes des triangles de l'etoile du sommet nsasup
-      call focftr( nbtrcf, notrcf, pxyd,   noarst,
+c     les aretes doubles sont detruites
+c     les triangles du cf sont detruits
+      call focftr( nbtrcf, notrcf, nbarpi, pxyd,   noarst,
      %             mosoar, mxsoar, n1soar, nosoar,
      %             moartr, n1artr, noartr,
-     %             nbarcf, n1arcf, noarcf,
+     %             nbarcf, n1arcf, noarcf, nbstpe, nostpe,
      %             ierr )
       if( ierr .ne. 0 ) then
 c        modification de ierr pour continuer le calcul
@@ -5684,7 +5217,7 @@ c        modification de ierr pour continuer le calcul
          return
       endif
 c
-c     ici le sommet nsasup appartient a aucune arete
+c     ici le sommet nsasup n'appartient plus a aucune arete
       noarst( nsasup ) = 0
 c
 c     chainage des aretes vides dans le tableau noarcf
 c     triangulation directe du contour ferme sans le sommet nsasup
 c     ============================================================
       nbcf = 1
-      call tridcf( nbcf,   pxyd,   noarst,
+      call tridcf( nbcf,   nbstpe, nostpe, pxyd,   noarst,
      %             mosoar, mxsoar, n1soar, nosoar,
      %             moartr, n1artr, noartr,
      %             mxarcf, n1arcf, noarcf, larmin,
      %             nbtrcf, notrcf, ierr )
       if( ierr .ne. 0 ) return
+c     calcul des surfaces apres suppression du point
+      s1 = 0d0
+      do 55 i=1,nbtrcf
+         nt = notrcf(i)
+c        les numeros des 3 sommets du triangle nt
+         call nusotr( nt, mosoar, nosoar, moartr, noartr, nosotr )
+         s = surtd2( pxyd(1,nosotr(1)),
+     %               pxyd(1,nosotr(2)),
+     %               pxyd(1,nosotr(3)) )
+         if( s .le. 0 ) then
+            write(imprim,*)'te1stm: apres tridcf le triangle',nt,
+     %                     ' st',nosotr,' AIRE<0'
+         endif
+         s1 = s1 + abs( s )
+ 55   continue
+c
+      if( abs(s0-s1) .gt. 1d-10*s0 ) then
+      write(imprim,*)
+      write(imprim,*)'te1stm: difference des aires lors suppression st',
+     %   nsasup
+      write(imprim,10055) s0, s1
+10055 format('aire0=',d25.16,' aire1=',d25.16)
+      endif
 c
 c     transformation des triangles du cf en triangles delaunay
 c     ========================================================
@@ -5736,7 +5292,6 @@ c     mise en delaunay des aretes chainees
       call tedela( pxyd,   noarst,
      %             mosoar, mxsoar, n1soar, nosoar, liarcf(1),
      %             moartr, mxartr, n1artr, noartr, modifs )
-ccc      write(imprim,*) 'nombre echanges diagonales =',modifs
       return
       end
 
@@ -5744,8 +5299,7 @@ ccc      write(imprim,*) 'nombre echanges diagonales =',modifs
       subroutine tr3str( np,     nt,
      %                   mosoar, mxsoar, n1soar, nosoar,
      %                   moartr, mxartr, n1artr, noartr,
-     %                   noarst,
-     %                   nutr,   ierr )
+     %                   noarst, nutr,   ierr )
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 c but :    former les 3 sous-triangles du triangle nt a partir
 c -----    du point interne np
@@ -6065,6 +5619,7 @@ c          0 si pas d'echange des aretes diagonales
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 c auteur : alain perronnet  analyse numerique paris upmc      avril 1997
 c....................................................................012
+      common / unites / lecteu,imprim,intera,nunite(29)
       integer     nosoar(mosoar,*),
      %            noartr(moartr,*),
      %            noarst(*)
@@ -6085,7 +5640,7 @@ c     recherche du numero de l'arete noaret dans le triangle nt1
          if( abs(noartr(n1,nt1)) .eq. noaret ) goto 15
  10   continue
 c     impossible d'arriver ici sans bogue!
-      write(imprim,*) 'pause dans te2t2t 1'
+      write(imprim,*) 'anomalie dans te2t2t 1'
 c
 c     l'arete de sommets 2 et 3
  15   if( n1 .lt. 3 ) then
@@ -6109,7 +5664,7 @@ c     recherche du numero de l'arete noaret dans le triangle nt2
          if( abs(noartr(n1,nt2)) .eq. noaret ) goto 25
  20   continue
 c     impossible d'arriver ici sans bogue!
-      write(imprim,*) 'pause dans te2t2t 2'
+      write(imprim,*) 'Anomalie dans te2t2t 2'
 c
 c     l'arete de sommets 1 et 4
  25   if( n1 .lt. 3 ) then
@@ -6149,7 +5704,7 @@ c        => pas d'echange
       endif
 c
 c     suppression de l'arete noaret
-      call sasoar( noaret, mosoar, mxsoar, n1soar, nosoar )
+      call sasoar( noaret, mosoar, mxsoar, n1soar, nosoar, noarst )
 c
 c     nt1 = triangle 143
       noartr(1,nt1) =  na14
@@ -6193,7 +5748,6 @@ c     numero d'une arete de chacun des 4 sommets
       end
 
 
-
       subroutine f0trte( letree, pxyd,
      %                   mosoar, mxsoar, n1soar, nosoar,
      %                   moartr, mxartr, n1artr, noartr,
@@ -6756,7 +6310,6 @@ c          =3 si aucun des triangles ne contient l'un des points internes au te
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 c auteur : alain perronnet  analyse numerique paris upmc       mars 1997
 c....................................................................012
-      common / unites / lecteu, imprim, nunite(30)
       double precision  pxyd(3,*)
       integer           letree(0:8),
      %                  milieu(3),
@@ -7035,6 +6588,7 @@ c si erreur rencontree => ns1 = 0
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 c auteur : alain perronnet  analyse numerique paris upmc    juillet 1995
 c2345x7..............................................................012
+      common / unites / lecteu, imprim, nunite(30)
       integer    noartr(moartr,*), nosoar(mosoar,*)
 c
 c     le numero de triangle est il correct  ?
@@ -7070,6 +6624,7 @@ c        arete dans le sens indirect => ns3 est le premier sommet de l'arete
          ns3 = nosoar(1,-na)
       endif
       end
+
       subroutine trpite( letree, pxyd,
      %                   mosoar, mxsoar, n1soar, nosoar,
      %                   moartr, mxartr, n1artr, noartr,
@@ -7121,9 +6676,6 @@ c          =3 si aucun des triangles ne contient l'un des points internes au te
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 c auteur : alain perronnet  analyse numerique paris upmc       mars 1997
 c....................................................................012
-      logical           tratri
-      common / dv2dco / tratri
-c     trace ou non des triangles generes dans la triangulation
       common / unites / lecteu, imprim, nunite(30)
       double precision  pxyd(3,*)
       integer           letree(0:8),
@@ -7134,7 +6686,9 @@ c     trace ou non des triangles generes dans la triangulation
 c
       integer           nosotr(3)
 c
-c     si pas de point interne alors trace eventuel puis retour
+      ierr = 0
+c
+c     si pas de point interne alors retour
       if( letree(0) .eq. 0 ) goto 150
 c
 c     il existe au moins un point interne a trianguler
 10010 format(' erreur trpite: pas de triangle contenant le point',i7)
 c
  150  continue
-
-ccc 150  if( tratri ) then
-cccc       les traces sont demandes
-ccc        call efface
-cccc       le cadre objet global en unites utilisateur
-ccc        xx1 = min(pxyd(1,nosotr(1)),pxyd(1,nosotr(2)),pxyd(1,nosotr(3)))
-ccc        xx2 = max(pxyd(1,nosotr(1)),pxyd(1,nosotr(2)),pxyd(1,nosotr(3)))
-ccc        yy1 = min(pxyd(2,nosotr(1)),pxyd(2,nosotr(2)),pxyd(2,nosotr(3)))
-ccc        yy2 = max(pxyd(2,nosotr(1)),pxyd(2,nosotr(2)),pxyd(2,nosotr(3)))
-ccc        if( xx1 .ge. xx2 ) xx2 = xx1 + (yy2-yy1)
-ccc        if( yy1 .ge. yy2 ) yy2 = yy1 + (xx2-xx1)*0.5
-ccc        call isofenetre( xx1-(xx2-xx1), xx2+(xx2-xx1),
-ccc     %                   yy1-(yy2-yy1), yy2+(yy2-yy1) )
-ccc         do 200 i=1,nbtr
-cccc           trace du triangle nutr(i)
-ccc            call mttrtr( pxyd, nutr(i), moartr, noartr, mosoar, nosoar,
-ccc     %                   i, ncblan )
-ccc 200     continue
-ccc      endif
-
       end
 
 
-      subroutine sasoar( noar, mosoar, mxsoar, n1soar, nosoar )
+      subroutine sasoar( noar, mosoar, mxsoar, n1soar, nosoar, noarst )
 c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 c but :    supprimer l'arete noar du tableau nosoar
-c -----    si celle ci n'est pas une arete des lignes de la frontiere
+c -----    si celle ci n'est pas une arete des lignes de la fontiere
 c
 c          la methode employee ici est celle du hachage
 c          avec pour fonction d'adressage h = min( nu2sar(1), nu2sar(2) )
@@ -7237,11 +6771,43 @@ c          chainage des aretes frontalieres, chainage du hachage des aretes
 c          une arete i de nosoar est vide <=> nosoar(1,i)=0 et
 c          nosoar(4,arete vide)=l'arete vide qui precede
 c          nosoar(5,arete vide)=l'arete vide qui suit
+c noarst : numero d'une arete de nosoar pour chaque sommet
 c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c auteur : alain perronnet  analyse numerique upmc paris       mars 1997
+c auteur : alain perronnet analyse numerique    upmc paris  mars    1997
+c modifs : alain perronnet laboratoire jl lions upmc paris  octobre 2006
 c ...................................................................012
       common / unites / lecteu, imprim, nunite(30)
-      integer           nosoar(mosoar,mxsoar)
+      integer           nosoar(mosoar,mxsoar), noarst(*), ns(2)
+c
+c     13/10/2006
+c     mise a jour de noarst pour les 2 sommets de l'arete a supprimer
+c     necessaire uniquement pour les sommets frontaliers et internes imposes
+c     le numero des 2 sommets de l'arete noar a supprimer
+      ns(1) = nosoar(1,noar)
+      ns(2) = nosoar(2,noar)
+      do 8 k=1,2
+         if( noarst(ns(k)) .eq. noar ) then
+c           il faut remettre a jour le pointeur sur une arete
+            if(nosoar(1,ns(k)).eq.ns(k) .and. nosoar(2,ns(k)).gt.0
+     %         .and. nosoar(4,ns(k)) .gt. 0 ) then
+c              arete active de sommet ns(k)
+               noarst( ns(k) ) = ns(k)
+            else
+               do 5 i=1,mxsoar
+                  if( nosoar(1,i).gt.0 .and. nosoar(4,i).gt.0 ) then
+c                    arete non vide
+                     if( nosoar(2,i).eq.ns(k) .or.
+     %                  (nosoar(1,i).eq.ns(k).and.nosoar(2,i).gt.0))then
+c                       arete active de sommet ns(k)
+                        noarst( ns(k) ) = i
+                        goto 8
+                     endif
+                  endif
+ 5             continue
+            endif
+         endif
+ 8    continue
+c     13/10/2006
 c
       if( nosoar(3,noar) .le. 0 ) then
 c
@@ -7265,6 +6831,7 @@ c           l'arete noar n'a pas ete retrouvee dans le chainage => erreur
      %      ' st2=',nosoar(2,noar),' ligne=',nosoar(3,noar),
      %      ' tr1=',nosoar(4,noar),' tr2=',nosoar(5,noar)
             write(imprim,*) 'chainages=',(nosoar(i,noar),i=6,mosoar)
+ccc            pause
 c           l'arete n'est pas detruite
             return
 c
@@ -7301,7 +6868,7 @@ c        le temoin d'arete vide
       end
 
 
-      subroutine caetoi( noar,   mosoar, mxsoar, n1soar, nosoar,
+      subroutine caetoi( noar,   mosoar, mxsoar, n1soar, nosoar, noarst,
      %                   n1aeoc, nbtrar  )
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 c but :    ajouter (ou retirer) l'arete noar de nosoar de l'etoile
@@ -7334,7 +6901,7 @@ c auteur : alain perronnet  analyse numerique paris upmc       mars 1997
 c2345x7..............................................................012
       parameter        (lchain=6)
       common / unites / lecteu, imprim, nunite(30)
-      integer           nosoar(mosoar,mxsoar)
+      integer           nosoar(mosoar,mxsoar), noarst(*)
 c
 c     si    l'arete n'appartient pas aux aretes de l'etoile naetoi
 c     alors elle est ajoutee a l'etoile dans naetoi
@@ -7367,7 +6934,7 @@ c           passage a la suivante
                return
             endif
             nbpass = nbpass + 1
-            if( nbpass .gt. 128 ) then
+            if( nbpass .gt. 512 ) then
                write(imprim,*)'Pb dans caetoi: boucle infinie evitee'
                nbtrar = 0
                return
@@ -7387,7 +6954,7 @@ c        noar n'est plus une arete simple de l'etoile
          nosoar( lchain, noar ) = -1
 c
 c        destruction du tableau nosoar de l'arete double noar
-         call sasoar( noar, mosoar, mxsoar, n1soar, nosoar )
+         call sasoar( noar, mosoar, mxsoar, n1soar, nosoar, noarst )
 c
 c        arete double
          nbtrar = 2
@@ -7395,10 +6962,10 @@ c        arete double
       end
 
 
-      subroutine focftr( nbtrcf, notrcf, pxyd,   noarst,
+      subroutine focftr( nbtrcf, notrcf, nbarpi, pxyd,   noarst,
      %                   mosoar, mxsoar, n1soar, nosoar,
      %                   moartr, n1artr, noartr,
-     %                   nbarcf, n1arcf, noarcf,
+     %                   nbarcf, n1arcf, noarcf, nbstpe, nostpe,
      %                   ierr )
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 c but :    former un contour ferme (cf) avec les aretes simples des
@@ -7412,6 +6979,7 @@ c entrees:
 c --------
 c nbtrcf : nombre de  triangles du cf a former
 c notrcf : numero des triangles dans le tableau noartr
+c nbarpi : numero du dernier sommet frontalier ou interne impose
 c pxyd   : tableau des coordonnees 2d des points
 c          par point : x  y  distance_souhaitee
 c
@@ -7441,6 +7009,8 @@ c n1arcf : numero d'une arete de chaque contour
 c noarcf : numero des aretes de la ligne du contour ferme
 c attention: chainage circulaire des aretes
 c            les aretes vides pointes par n1arcf(0) ne sont pas chainees
+c nbstpe : nombre de  sommets perdus dans la suppression des triangles
+c nostpe : numero des sommets perdus dans la suppression des triangles 
 c ierr   :  0 si pas d'erreur
 c          14 si les lignes fermees se coupent => donnees a revoir
 c          15 si une seule arete simple frontaliere
@@ -7448,9 +7018,10 @@ c          16 si boucle infinie car toutes les aretes simples
 c                de la boule sont frontalieres!
 c          17 si boucle infinie dans caetoi
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c auteur : alain perronnet  analyse numerique paris upmc       mars 1997
+c auteur : alain perronnet analyse numerique    upmc paris  mars    1997
+c modifs : alain perronnet laboratoire jl lions upmc paris  octobre 2006
 c....................................................................012
-      parameter        (lchain=6)
+      parameter        (lchain=6, mxstpe=512)
       common / unites / lecteu, imprim, nunite(30)
       double precision  pxyd(3,*)
       integer           notrcf(1:nbtrcf)
@@ -7458,7 +7029,9 @@ c....................................................................012
      %                  noartr(moartr,*),
      %                  n1arcf(0:*),
      %                  noarcf(3,*),
-     %                  noarst(*)
+     %                  noarst(*),
+     %                  nostpe(mxstpe),
+     %                  nosotr(3)
 c
 c     formation des aretes simples du cf autour de l'arete ns1-ns2
 c     attention: le chainage lchain du tableau nosoar devient actif
@@ -7467,18 +7040,41 @@ c     ici toutes les aretes du tableau nosoar verifient nosoar(lchain,i) = -1
 c     ce qui equivaut a dire que l'etoile des aretes simples est vide
 c     (initialisation dans le sp insoar puis remise a -1 dans la suite!)
       n1aeoc = 0
+      ierr   = 0
+c
+c     13/10/2006
+c     nombre de sommets des triangles a supprimer sans repetition
+      nbst = 0
+c     13/10/2006
 c
 c     ajout a l'etoile des aretes simples des 3 aretes des triangles a supprimer
 c     suppression des triangles de l'etoile pour les aretes simples de l'etoile
       do 10 i=1,nbtrcf
+c
 c        ajout ou retrait des 3 aretes du triangle notrcf(i) de l'etoile
          nt = notrcf( i )
+c
+c        13/10/2006  ...............................................
+         call nusotr( nt, mosoar, nosoar, moartr, noartr, nosotr )
+c
+c        ajout des numeros de sommets non encore vus dans l'etoile
+         do 3 k=1,3
+            do 2 j=1,nbst
+               if( nosotr(k) .eq. nostpe(j) ) goto 3
+ 2          continue
+c           ajout du sommet
+            nbst = nbst + 1
+            nostpe( nbst ) = nosotr(k)
+ 3       continue
+c        13/10/2006 ................................................
+c
          do 5 j=1,3
 c           l'arete de nosoar a traiter
             noar = abs( noartr(j,nt) )
-            call caetoi( noar,   mosoar, mxsoar, n1soar, nosoar,
+            call caetoi( noar,   mosoar, mxsoar, n1soar, nosoar, noarst,
      %                   n1aeoc, nbtrar  )
             if( nbtrar .le. 0 ) then
+               write(imprim,*)'focftr: erreur dans caetoi noar=',noar
                ierr = 17
                return
             endif
@@ -7487,8 +7083,15 @@ c           pour cette arete
             if( nbtrar .eq. 1 ) then
                if( nosoar(4,noar) .eq. nt ) then
                   nosoar(4,noar) = nosoar(5,noar)
+               else if( nosoar(5,noar) .eq. nt ) then
+                  nosoar(5,noar) = -1
+               else
+                  write(imprim,*)'focftr: anomalie arete',noar,
+     %                           ' sans triangle',nt
+                  write(imprim,*)'focftr: nosoar(',noar,')=',
+     %                            (nosoar(kk,noar),kk=1,mosoar)
+                  nosoar(5,noar) = -1
                endif
-               nosoar(5,noar) = -1
 c           else
 c              l'arete appartient a aucun triangle => elle est vide
 c              les positions 4 et 5 servent maintenant aux chainages des vides
@@ -7520,6 +7123,7 @@ c        la 2=>1, la 3=>2, ... , la derniere=>l'avant derniere, 1=>derniere
 c           attention: boucle infinie si toutes les aretes simples
 c           de la boule sont frontalieres!... arretee par ce test
             ierr = 16
+            write(imprim,*)'focftr: boucle dans les aretes de l etoile'
             return
          endif
          noar = n1aeoc
@@ -7533,6 +7137,7 @@ c           la sauvegarde de l'arete et l'arete suivante
          if( na0 .le. 0 ) then
 c           une seule arete simple frontaliere
             ierr = 15
+            write(imprim,*)'focftr: 1 arete seule pour l etoile'
             return
          endif
 c        le suivant de l'ancien dernier est l'ancien premier
@@ -7569,9 +7174,6 @@ c     le numero de cette arete dans le tableau nosoar
 c     mise a jour du numero d'arete du sommet ns0
       noarst(ns0) = na1
 c
-cccc     trace de l'arete
-ccc      call dvtrar( pxyd, ns0, ns1, ncvert, ncblan )
-c
 c     l'arete suivante a chainer
       n1aeoc = nosoar( lchain, na1 )
 c     l'arete na1 n'est plus dans l'etoile
@@ -7613,9 +7215,6 @@ c           le numero de cette arete dans le tableau nosoar
 c           mise a jour du numero d'arete du sommet ns1
             noarst(ns1) = na1
 c
-cccc           trace de l'arete
-ccc            call dvtrar( pxyd, ns1, ns2, ncvert, ncblan )
-c
 c           suppression de l'arete des aretes simples de l'etoile
             if( n1aeoc .eq. na1 ) then
                 n1aeoc = nosoar( lchain, na1 )
@@ -7634,14 +7233,9 @@ c
 c     verification
       if( ns1 .ne. ns0 ) then
 c        arete non retrouvee : l'etoile ne se referme pas
-c         nblgrc(nrerr) = 3
-c         kerr(1) = 'focftr: revoyez vos donnees'
-c         kerr(2) = 'les lignes fermees doivent etre disjointes'
-c         kerr(3) = 'verifiez si elles ne se coupent pas'
-c         call lereur
-          write(imprim,*) 'focftr: revoyez vos donnees'
-          write(imprim,*)'les lignes fermees doivent etre disjointes'
-          write(imprim,*)'verifiez si elles ne se coupent pas'
+         write(imprim,*)'focftr: revoyez vos donnees du bord'
+         write(imprim,*)'les lignes fermees doivent etre disjointes'
+         write(imprim,*)'verifiez si elles ne se coupent pas'
          ierr = 14
          return
       endif
@@ -7650,17 +7244,61 @@ c     l'arete suivant la derniere arete du cf est la premiere du cf
 c     => realisation d'un chainage circulaire des aretes du cf
       noarcf( 2, nbarcf ) = 1
 c
+c     13/10/2006
+c     existe t il des sommets perdus?
+c     -------------------------------
+      if( nbst .gt. mxstpe ) then
+         write(imprim,*)'focftr: tableau nostfe(',mxstpe,') a augmenter'
+         ierr = 15
+         return
+      endif
+c     le nombre de sommets perdus
+      nbstpe = nbst - nbarcf
+      if( nbstpe .gt. 0 ) then
+c        oui: stockage dans nostpe des sommets perdus
+c        tout sommet des aretes de l'etoile est supprime
+c        de la liste des sommets
+         do 40 i=1,nbarcf
+c           le numero du sommet de l'arete du cf
+            ns1 = noarcf( 1, i )
+            do 30 j=1,nbst
+               if( ns1 .eq. nostpe(j) ) then
+c                 le sommet peripherique est supprime
+c                 de la liste des sommets perdus
+                  nostpe(j) = 0
+                  goto 40
+               endif
+ 30         continue
+ 40      continue
+c
+c        compression
+         n = 0
+         do 45 i=1,nbst
+            if( nostpe(i) .eq. 0 .or. nostpe(i) .gt. nbarpi ) then
+c              un sommet de l'etoile ou perdu mais supprimable
+c              ce qui apporte plus de qualites aux triangles a former
+               n = n + 1
+            else
+c              un sommet perdu
+               nostpe(i-n) = nostpe(i)
+            endif
+ 45      continue
+         nbstpe = nbst - n
+ccc      write(imprim,*)'focftr:',nbstpe,' sommets isoles:',(nostpe(k),k=1,nbstpe)
+      endif
+c     13/10/2006
+c
 c     destruction des triangles de l'etoile du tableau noartr
 c     -------------------------------------------------------
-      do 50 i=1,nbtrcf
+      do 60 n=1,nbtrcf
 c        le numero du triangle dans noartr
-         nt0 = notrcf( i )
+         nt0 = notrcf( n )
 c        l'arete 1 de nt0 devient nulle
          noartr( 1, nt0 ) = 0
 c        chainage de nt0 en tete du chainage des triangles vides de noartr
          noartr( 2, nt0 ) = n1artr
          n1artr = nt0
50   continue
60   continue
       end
 
 
@@ -7754,10 +7392,9 @@ c     pas d'intersection a l'interieur des aretes
       linter = 0
       end
 
-
       subroutine tefoar( narete, nbarpi, pxyd,
      %                   mosoar, mxsoar, n1soar, nosoar,
-     %                   moartr, n1artr, noartr, noarst,
+     %                   moartr, mxartr, n1artr, noartr, noarst,
      %                   mxarcf, n1arcf, noarcf, larmin, notrcf,
      %                   ierr )
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -7779,6 +7416,7 @@ c          indice dans nosoar de l'arete suivante dans le hachage
 c mxsoar : nombre maximal d'aretes stockables dans le tableau nosoar
 c          attention: mxsoar>3*mxsomm obligatoire!
 c moartr : nombre maximal d'entiers par arete du tableau noartr
+c mxartr : nombre maximal de triangles stockables dans le tableau noartr
 c
 c modifies:
 c ---------
@@ -7815,66 +7453,56 @@ c          9 tableau nosoar de taille insuffisante car trop d'aretes
 c            a probleme
 c          10 un des tableaux n1arcf, noarcf notrcf est sature
 c             augmenter a l'appel mxarcf
-c          11 algorithme defaillant
+c         >11 algorithme defaillant
 c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-c auteur : alain perronnet  analyse numerique paris upmc       mars 1997
+c auteur : alain perronnet analyse numerique paris upmc     mars    1997
+c modifs : alain perronnet laboratoire jl lions upmc paris  octobre 2006
 c....................................................................012
-      parameter        (mxpitr=32)
+      parameter        (mxpitr=32, mxstpe=512)
       common / unites / lecteu,imprim,intera,nunite(29)
-      logical           tratri
-      common / dv2dco / tratri
       double precision  pxyd(3,*)
-      integer           noartr(moartr,*),
+      integer           noartr(moartr,mxartr),
      %                  nosoar(mosoar,mxsoar),
      %                  noarst(*),
      %                  n1arcf(0:mxarcf),
      %                  noarcf(3,mxarcf),
      %                  larmin(mxarcf),
-     %                  notrcf(mxarcf)
+     %                  notrcf(mxarcf),
+     %                  nostpe(mxstpe)
 c
       integer           lapitr(mxpitr)
       double precision  x1,y1,x2,y2,d12,d3,d4,x,y,d,dmin
       integer           nosotr(3), ns(2)
       integer           nacf(1:2), nacf1, nacf2
       equivalence      (nacf(1),nacf1), (nacf(2),nacf2)
+c
+      ierr = 0
 c
 c     traitement de cette arete perdue
       ns1 = nosoar( 1, narete )
       ns2 = nosoar( 2, narete )
 c
-      if( tratri ) then
-c        les traces sont demandes
-c         call efface
-c        le cadre objet global en unites utilisateur
-         xx1 = min( pxyd(1,ns1), pxyd(1,ns2) )
-         xx2 = max( pxyd(1,ns1), pxyd(1,ns2) )
-         yy1 = min( pxyd(2,ns1), pxyd(2,ns2) )
-         yy2 = max( pxyd(2,ns1), pxyd(2,ns2) )
-         if( xx1 .ge. xx2 ) xx2 = xx1 + (yy2-yy1)
-         if( yy1 .ge. yy2 ) yy2 = yy1 + (xx2-xx1)*0.5
-c         call isofenetre( xx1-(xx2-xx1), xx2+(xx2-xx1),
-c     %                    yy1-(yy2-yy1), yy2+(yy2-yy1) )
-      endif
-c
-cccc     trace de l'arete perdue
-ccc      call dvtrar( pxyd, ns1, ns2, ncroug, ncblan )
+ccc      write(imprim,*)
+ccc      write(imprim,*) 'tefoar reconstruction de l''arete ',ns1,' ', ns2
+ccc      write(imprim,*) 'sommet',ns1,' x=',pxyd(1,ns1),' y=',pxyd(2,ns1)
+ccc      write(imprim,*) 'sommet',ns2,' x=',pxyd(1,ns2),' y=',pxyd(2,ns2)
 c
 c     le sommet ns2 est il correct?
       na = noarst( ns2 )
       if( na .le. 0 ) then
          write(imprim,*) 'tefoar: erreur sommet ',ns2,' sans arete'
          ierr = 8
+ccc         pause
          return
       endif
       if( nosoar(4,na) .le. 0 ) then
          write(imprim,*) 'tefoar: erreur sommet ',ns2,
      %                   ' dans aucun triangle'
          ierr = 8
+ccc         pause
          return
       endif
 c
-c     recherche du triangle voisin dans le sens indirect de rotation
-      nsens = -1
 c     le premier passage: recherche dans le sens ns1->ns2
       ipas = 0
 c
@@ -7886,17 +7514,22 @@ c     ==========================================================
       y2  = pxyd(2,ns2)
       d12 = (x2-x1)**2 + (y2-y1)**2
 c
+c     recherche du triangle voisin dans le sens indirect de rotation
+      nsens = -1
+c
 c     recherche du no local du sommet ns1 dans l'un de ses triangles
     na01 = noarst( ns1 )
10   na01 = noarst( ns1 )
       if( na01 .le. 0 ) then
          write(imprim,*) 'tefoar: sommet ',ns1,' sans arete'
          ierr = 8
+ccc         pause
          return
       endif
       nt0 = nosoar(4,na01)
       if( nt0 .le. 0 ) then
          write(imprim,*) 'tefoar: sommet ',ns1,' dans aucun triangle'
          ierr = 8
+ccc         pause
          return
       endif
 c
@@ -7920,6 +7553,7 @@ c        les sens ns1->ns2 et ns2->ns1 ne donne pas de solution!
          write(imprim,*)'tefoar:anomalie sommet ',ns1,
      %   'non dans le triangle de sommets ',(nosotr(i),i=1,3)
          ierr = 11
+ccc         pause
          return
       endif
 c
@@ -7929,12 +7563,6 @@ c     le numero des aretes suivante et precedente
       ns3 = nosotr( na0 )
       ns4 = nosotr( na1 )
 c
-cccc     trace du triangle nt0 et de l'arete perdue
-ccc      call mttrtr( pxyd, nt0, moartr, noartr, mosoar, nosoar,
-ccc     %             ncblan, ncjaun )
-ccc      call dvtrar( pxyd, ns1, ns2, ncroug, ncblan )
-ccc      call dvtrar( pxyd, ns3, ns4, ncbleu, nccyan )
-c
 c     point d'intersection du segment ns1-ns2 avec l'arete ns3-ns4
 c     ------------------------------------------------------------
       call int1sd( ns1, ns2, ns3, ns4, pxyd, linter, x1, y1 )
@@ -7961,8 +7589,7 @@ c        le parcours sort du domaine
 c        il faut tourner dans l'autre sens autour de ns1
          if( nsens .lt. 0 ) then
             nsens = 1
-            nt0   = noarst( ns1 )
-            goto 20
+            goto 10
          endif
 c
 c        dans les 2 sens, pas d'intersection => impossible
@@ -7971,7 +7598,8 @@ c        essai avec l'arete inversee ns1 <-> ns2
          write(imprim,*) 'tefoar: arete ',ns1,' ',ns2,
      %  ' sans intersection avec les triangles actuels'
          write(imprim,*) 'revoyez les lignes du contour'
-         ierr = 11
+         ierr = 12
+ccc         pause
          return
       endif
 c
@@ -7988,11 +7616,10 @@ c     le triangle oppose a l'arete na0 de nt0
       else
          nt1 = nosoar(4,noar)
       endif
-c
-cccc     trace du triangle nt1 et de l'arete perdue
-ccc      call mttrtr( pxyd, nt1, moartr, noartr, mosoar, nosoar,
-ccc     %             ncjaun, ncmage )
-ccc      call dvtrar( pxyd, ns1, ns2, ncroug, ncblan )
+      if( nt1 .le. 0 ) then
+         write(imprim,*) 'erreur dans tefoar nt1=',nt1
+         read(lecteu,*) j
+      endif
 c
 c     le numero des 3 sommets du triangle nt1 dans le sens direct
       call nusotr( nt1, mosoar, nosoar, moartr, noartr, nosotr )
@@ -8007,15 +7634,9 @@ c     recherche de l'arete noar, na1 dans nt1 qui est l'arete na0 de nt0
          if( abs( noartr(na1,nt1) ) .eq. noar ) goto 35
  34   continue
 c
-c     trace du triangle nt1 et de l'arete perdue
- 35   continue
-ccc 35   call mttrtr( pxyd, nt1, moartr, noartr, mosoar, nosoar,
-ccc     %             ncjaun, ncmage )
-ccc      call dvtrar( pxyd, ns1, ns2, ncroug, ncblan )
-c
 c     recherche de l'intersection de ns1-ns2 avec les 2 autres aretes de nt1
 c     ======================================================================
     na2 = na1
35   na2 = na1
       do 50 i1 = 1,2
 c        l'arete suivante
          na2 = nosui3(na2)
@@ -8024,7 +7645,6 @@ c        les 2 sommets de l'arete na2 de nt1
          noar = abs( noartr(na2,nt1) )
          ns3  = nosoar( 1, noar )
          ns4  = nosoar( 2, noar )
-ccc         call dvtrar( pxyd, ns3, ns4, ncbleu, nccyan )
 c
 c        point d'intersection du segment ns1-ns2 avec l'arete ns3-ns4
 c        ------------------------------------------------------------
@@ -8047,9 +7667,22 @@ c           nsp est le point le plus proche de (x,y)
 c
 c           ici le sommet nsp est trop proche de l'arete perdue ns1-ns2
             if( nsp .le. nbarpi ) then
-c              point utilisateur ou frontalier non supprimable
-               ierr = 11
-               write(imprim,*) 'pause dans tefoar 1', d, d3, d4, d12
+c              point utilisateur ou frontalier donc non supprimable
+               write(imprim,*) 'tefoar: sommet nsp=',nsp,
+     %' frontalier trop proche de l''arete perdue ns1=',ns1,'-ns2=',ns2
+           write(imprim,*)'s',nsp,': x=', pxyd(1,nsp),' y=', pxyd(2,nsp)
+           write(imprim,*)'s',ns1,': x=', pxyd(1,ns1),' y=', pxyd(2,ns1)
+           write(imprim,*)'s',ns2,': x=', pxyd(1,ns2),' y=', pxyd(2,ns2)
+           write(imprim,*)'arete s',ns1,'-s',ns2,
+     %                    ' coupe arete s',ns3,'-s',ns4,' en (x,y)'
+          write(imprim,*) 's',ns3,': x=', pxyd(1,ns3),' y=', pxyd(2,ns3)
+          write(imprim,*) 's',ns4,': x=', pxyd(1,ns4),' y=', pxyd(2,ns4)
+          write(imprim,*) 'intersection en: x=', x, ' y=', y
+          write(imprim,*) 'distance ns1-ns2=', sqrt(d12)
+          write(imprim,*) 'distance (x,y) au plus proche',ns3,ns4,'=',
+     %                     sqrt(d)
+               ierr = 13
+ccc               pause
                return
             endif
 c
@@ -8058,25 +7691,19 @@ c           l'ayant comme sommet dans la pile notrcf des triangles a supprimer
 c           ------------------------------------------------------------------
 ccc            write(imprim,*) 'tefoar: le sommet ',nsp,' est supprime'
 c           construction de la liste des triangles de sommet nsp
-            call trp1st( nsp, noarst, mosoar, nosoar, moartr, noartr,
+            call trp1st( nsp,    noarst, mosoar, nosoar,
+     %                   moartr, mxartr, noartr,
      %                   mxpitr, nbt, lapitr )
             if( nbt .le. 0 ) then
 c              les triangles de sommet nsp ne forme pas une "boule"
 c              avec ce sommet nsp pour "centre"
                write(imprim,*)
-     %        'tefoar: pas d''etoile de triangles autour du sommet',nsp
-cccc              trace des triangles de l'etoile du sommet nsp
-ccc               tratri = .true.
-ccc               call trpltr( nbt,    lapitr, pxyd,
-ccc     %                      moartr, noartr, mosoar, nosoar,
-ccc     %                      ncroug, ncblan )
-ccc               tratri = .false.
-               ierr = 11
-               write(imprim,*) 'pause dans tefoar 2'
-               return
+     %        'tefoar: les triangles autour du sommet ',nsp,
+     %        ' ne forme pas une etoile'
+               nbt = -nbt
             endif
 c
-c           ajout des triangles de sommet ns1 a notrcf
+c           ajout des triangles de sommet nsp a notrcf
             nbtrc0 = nbtrcf
             do 38 j=1,nbt
                nt = lapitr(j)
@@ -8086,9 +7713,6 @@ c           ajout des triangles de sommet ns1 a notrcf
 c              triangle ajoute
                nbtrcf = nbtrcf + 1
                notrcf( nbtrcf ) = nt
-ccc               call mttrtr( pxyd, nt, moartr, noartr, mosoar, nosoar,
-ccc     %                      ncjaun, ncmage )
-ccc               call dvtrar( pxyd, ns1, ns2, ncroug, ncblan )
  38         continue
 c
 c           ce sommet supprime n'appartient plus a aucun triangle
@@ -8127,7 +7751,7 @@ c                 point d'intersection du segment ns1-ns2 avec l'arete ns3-ns4
 c                 ------------------------------------------------------------
                   call int1sd( ns1, ns2, ns3, ns4, pxyd,
      %                         linter, x , y )
-                  if( linter .gt. 0 ) then
+                   if( linter .gt. 0 ) then
 c                    les 2 aretes s'intersectent en (x,y)
                      d = (x-x2)**2+(y-y2)**2
                      if( d .lt. dmin ) then
@@ -8143,18 +7767,21 @@ c           redemarrage avec le triangle nt0 et l'arete na0
             if( nt0 .gt. 0 ) goto 30
 c
             write(imprim,*) 'tefoar: algorithme defaillant'
-            ierr = 11
+            ierr = 14
+ccc            pause
             return
          endif
  50   continue
 c
 c     pas d'intersection differente de l'initiale => sommet sur ns1-ns2
-c     rotation autour du sommet par l'arete suivant na1
+c     tentative d'inversion des sommets de l'arete ns1-ns2
+      if( ipas .eq. 0 ) goto 25
       write(imprim,*)
       write(imprim,*) 'tefoar 50: revoyez vos donnees'
       write(imprim,*) 'les lignes fermees doivent etre disjointes'
       write(imprim,*) 'verifiez si elles ne se coupent pas'
-      ierr = 13
+      ierr = 15
+ccc      pause
       return
 c
 c     cas sans probleme : intersection differente de celle initiale
@@ -8181,13 +7808,14 @@ c     =============================================================
  80   if( nbtrcf*3 .gt. mxarcf ) then
          write(imprim,*) 'saturation du tableau noarcf'
          ierr = 10
+ccc         pause
          return
       endif
 c
-      call focftr( nbtrcf, notrcf, pxyd,   noarst,
+      call focftr( nbtrcf, notrcf, nbarpi, pxyd,   noarst,
      %             mosoar, mxsoar, n1soar, nosoar,
      %             moartr, n1artr, noartr,
-     %             nbarcf, n1arcf, noarcf,
+     %             nbarcf, n1arcf, noarcf, nbstpe, nostpe,
      %             ierr )
       if( ierr .ne. 0 ) return
 c
@@ -8262,16 +7890,18 @@ c     na0 precede nacf2 => il precede n1
       noarcf( 2, na0 ) = n1
 c
 c     depart avec 2 cf
-      nbcf   = 2
+      nbcf = 2
 c
 c     triangulation directe des 2 contours fermes
 c     l'arete ns1-ns2 devient une arete de la triangulation des 2 cf
 c     ==============================================================
-      call tridcf( nbcf,   pxyd,   noarst,
+      call tridcf( nbcf,   nbstpe, nostpe, pxyd,   noarst,
      %             mosoar, mxsoar, n1soar, nosoar,
      %             moartr, n1artr, noartr,
      %             mxarcf, n1arcf, noarcf, larmin,
      %             nbtrcf, notrcf, ierr )
+c
+      return
       end
 
 
@@ -8318,6 +7948,7 @@ c2345x7..............................................................012
       integer           np(0:3),milieu(3)
 c
 c     debut par l'arete 2 du triangle ntrp
+      ierr = 0
       i1 = 2
       i2 = 3
       do 30 i=1,3
@@ -8429,3 +8060,367 @@ c                 place libre a occuper
          endif
  110  continue
       end
+
+
+      subroutine tesuqm( quamal, nbarpi, pxyd,   noarst,
+     %                   mosoar, mxsoar, n1soar, nosoar,
+     %                   moartr, mxartr, n1artr, noartr,
+     %                   mxarcf, n1arcf, noarcf,
+     %                   larmin, notrcf, liarcf,
+     %                   quamin )
+c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+c but :    supprimer de la triangulation les triangles de qualite
+c -----    inferieure a quamal
+c
+c entrees:
+c --------
+c quamal : qualite des triangles au dessous de laquelle supprimer des sommets
+c nbarpi : numero du dernier point interne impose par l'utilisateur
+c pxyd   : tableau des coordonnees 2d des points
+c          par point : x  y  distance_souhaitee
+c mosoar : nombre maximal d'entiers par arete et
+c          indice dans nosoar de l'arete suivante dans le hachage
+c mxsoar : nombre maximal d'aretes stockables dans le tableau nosoar
+c          attention: mxsoar>3*mxsomm obligatoire!
+c moartr : nombre maximal d'entiers par arete du tableau noartr
+c
+c modifies:
+c ---------
+c noarst : noarst(i) numero d'une arete de sommet i
+c n1soar : no de l'eventuelle premiere arete libre dans le tableau nosoar
+c          chainage des vides suivant en 3 et precedant en 2 de nosoar
+c nosoar : numero des 2 sommets , no ligne, 2 triangles de l'arete,
+c          chainage des aretes frontalieres, chainage du hachage des aretes
+c          hachage des aretes = nosoar(1)+nosoar(2)*2
+c          avec mxsoar>=3*mxsomm
+c          une arete i de nosoar est vide <=> nosoar(1,i)=0 et
+c          nosoar(2,arete vide)=l'arete vide qui precede
+c          nosoar(3,arete vide)=l'arete vide qui suit
+c n1artr : numero du premier triangle vide dans le tableau noartr
+c          le chainage des triangles vides se fait sur noartr(2,.)
+c noartr : les 3 aretes des triangles +-arete1, +-arete2, +-arete3
+c          arete1 = 0 si triangle vide => arete2 = triangle vide suivant
+c
+c auxiliaires :
+c -------------
+c n1arcf : tableau (0:mxarcf) auxiliaire d'entiers
+c noarcf : tableau (3,mxarcf) auxiliaire d'entiers
+c larmin : tableau (mxarcf)   auxiliaire d'entiers
+c notrcf : tableau (mxarcf)   auxiliaire d'entiers
+c liarcf : tableau (mxarcf)   auxiliaire d'entiers
+c
+c sortie :
+c --------
+c quamin : qualite minimale des triangles
+c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+c auteur : alain perronnet Laboratoire JL Lions UPMC Paris  Octobre 2006
+c....................................................................012
+      parameter       ( lchain=6, mxtrqm=1024 )
+      common / unites / lecteu,imprim,intera,nunite(29)
+      double precision  pxyd(3,*), quamal, qualit, quamin
+      integer           nosoar(mosoar,mxsoar),
+     %                  noartr(moartr,mxartr),
+     %                  noarst(*)
+      integer           nosotr(3), notraj(3)
+      double precision  surtd2, s123, s142, s143, s234,
+     %                  s12, s34, a12
+      integer           notrqm(mxtrqm)
+      double precision  qutrqm(mxtrqm)
+      integer           n1arcf(0:mxarcf),
+     %                  noarcf(3,mxarcf),
+     %                  larmin(mxarcf),
+     %                  notrcf(mxarcf),
+     %                  liarcf(mxarcf)
+c
+      ierr = 0
+c
+c     initialisation du chainage des aretes des cf => 0 arete de cf
+      do 5 narete=1,mxsoar
+         nosoar( lchain, narete ) = -1
+ 5    continue
+c
+c     recherche des triangles de plus basse qualite
+      quamin = 2.0
+      nbtrqm = 0
+      do 10 nt=1,mxartr
+         if( noartr(1,nt) .eq. 0 ) goto 10
+c        le numero des 3 sommets du triangle nt
+         call nusotr( nt, mosoar, nosoar, moartr, noartr, nosotr )
+c        la qualite du triangle ns1 ns2 ns3
+         call qutr2d( pxyd(1,nosotr(1)), pxyd(1,nosotr(2)),
+     %                pxyd(1,nosotr(3)), qualit )
+         if( qualit .lt. quamal ) then
+            if( nbtrqm .ge. mxtrqm ) goto 10
+            nbtrqm = nbtrqm + 1
+            notrqm(nbtrqm) = nt
+            qutrqm(nbtrqm) = qualit
+         endif
+ 10   continue
+c
+c     tri croissant des qualites minimales des triangles
+      call tritas( nbtrqm, qutrqm, notrqm )
+c
+c     le plus mauvais triangle
+      ntqmin = notrqm(1)
+      quamin = qutrqm(1)
+c
+      do 100 n=1,nbtrqm
+c
+c        no du triangle de mauvaise qualite
+         ntqmin = notrqm( n )
+c
+c        le triangle a t il ete traite?
+         if( noartr(1,ntqmin) .eq. 0 ) goto 100
+c
+ccc         print *
+ccc         print *,'tesuqm: triangle',ntqmin,' qualite=',qutrqm(n)
+ccc         print *,'tesuqm: noartr(',ntqmin,')=',
+ccc     %           (noartr(j,ntqmin),j=1,moartr)
+cccc
+ccc         do 12 j=1,3
+ccc            noar = noartr(j,ntqmin)
+ccc         print*,'arete',noar,' nosoar=',(nosoar(i,abs(noar)),i=1,mosoar)
+ccc 12      continue
+c
+c        le numero des 3 sommets du triangle ntqmin
+         call nusotr( ntqmin, mosoar, nosoar, moartr, noartr, nosotr )
+c
+ccc         do 15 j=1,3
+ccc            nbt = nosotr(j)
+ccc            print *,'sommet',nbt,':  x=',pxyd(1,nbt),'  y=',pxyd(2,nbt)
+ccc 15      continue
+c
+c        recherche des triangles adjacents par les aretes de ntqmin
+         nbt = 0
+         do 20 j=1,3
+c           le no de l'arete j dans nosoar
+            noar = abs( noartr(j,ntqmin) )
+c           le triangle adjacent a l'arete j de ntqmin
+            if( nosoar(4,noar) .eq. ntqmin ) then
+               notraj(j) = nosoar(5,noar)
+            else
+               notraj(j) = nosoar(4,noar)
+            endif
+            if( notraj(j) .gt. 0 ) then
+c              1 triangle adjacent de plus
+               naop = j
+               nbt  = nbt + 1
+            else
+c              pas de triangle adjacent
+               notraj(j) = 0
+            endif
+ 20      continue
+c
+         if( nbt .eq. 1 ) then
+c
+c           ntqmin a un seul triangle oppose par l'arete naop
+c           le triangle a 2 aretes frontalieres est plat
+c           l'arete commune aux 2 triangles est rendue Delaunay
+c           ---------------------------------------------------
+            noar = abs( noartr(naop,ntqmin) )
+            if( nosoar(3,noar) .ne. 0 ) then
+c              arete frontaliere
+               goto 100
+            endif
+c
+c           l'arete appartient a deux triangles actifs
+c           le numero des 4 sommets du quadrangle des 2 triangles
+            call mt4sqa( noar, moartr, noartr, mosoar, nosoar,
+     %                   ns1, ns2, ns3, ns4 )
+            if( ns4 .eq. 0 ) goto 100
+c
+c           carre de la longueur de l'arete ns1 ns2
+           a12=(pxyd(1,ns2)-pxyd(1,ns1))**2+(pxyd(2,ns2)-pxyd(2,ns1))**2
+c
+c           comparaison de la somme des aires des 2 triangles
+c           -------------------------------------------------
+c           calcul des surfaces des triangles 123 et 142 de cette arete
+            s123=surtd2( pxyd(1,ns1), pxyd(1,ns2), pxyd(1,ns3) )
+            s142=surtd2( pxyd(1,ns1), pxyd(1,ns4), pxyd(1,ns2) )
+ccc            print *,'tesuqm: ns4=',ns4,' x=',pxyd(1,ns4),
+ccc     %                                 ' y=',pxyd(2,ns4)
+ccc            print *,'tesuqm: s123=',s123,'  s142=',s142
+            s12 = abs( s123 ) + abs( s142 )
+            if( s12 .le. 0.001*a12 ) goto 100
+c
+c           calcul des surfaces des triangles 143 et 234 de cette arete
+            s143=surtd2( pxyd(1,ns1), pxyd(1,ns4), pxyd(1,ns3) )
+            s234=surtd2( pxyd(1,ns2), pxyd(1,ns3), pxyd(1,ns4) )
+ccc            print *,'tesuqm: s143=',s143,'  s234=',s234
+            s34 = abs( s234 ) + abs( s143 )
+ccc            print *,'tesuqm: s12=',s12,'  s34=',s34
+c
+            if( abs(s34-s12) .gt. 1d-14*s34 ) goto 100
+c
+c           quadrangle convexe 
+c           echange de la diagonale 12 par 34 des 2 triangles
+c           -------------------------------------------------
+            call te2t2t( noar,   mosoar, n1soar, nosoar, noarst,
+     %                   moartr, noartr, noar34 )
+ccc            print *,'tesuqm: sortie te2t2t avec noar34=',noar34
+c
+c
+         else if( nbt .eq. 2 ) then
+c
+c           ntqmin a 2 triangles opposes par l'arete naop
+c           essai de supprimer le sommet non frontalier
+c           ---------------------------------------------
+            do 30 j=1,3
+               if( notraj(j) .eq. 0 ) goto 33
+ 30         continue
+c
+c           arete sans triangle adjacent
+ 33         noar = abs( noartr(j,ntqmin) )
+ccc            print *,'tesuqm: nosoar(',noar,')=',
+ccc     %              (nosoar(j,noar),j=1,mosoar)
+            if( noar .le. 0 ) goto 100
+c
+c           ses 2 sommets
+            ns1 = nosoar(1,noar)
+            ns2 = nosoar(2,noar)
+c
+c           ns3 l'autre sommet non frontalier
+            do 36 j=1,3
+               ns3 = nosotr(j)
+               if( ns3 .ne. ns1 .and. ns3 .ne. ns2 ) goto 40
+ 36         continue
+c
+ 40         if( ns3 .gt. nbarpi ) then
+c
+c              le sommet ns3 non frontalier va etre supprime
+ccc               print*,'tesuqm: ntqmin=',ntqmin,
+ccc     %                ' demande la suppression ns3=',ns3
+               call te1stm( ns3,    nbarpi, pxyd,   noarst,
+     %                      mosoar, mxsoar, n1soar, nosoar,
+     %                      moartr, mxartr, n1artr, noartr,
+     %                      mxarcf, n1arcf, noarcf,
+     %                      larmin, notrcf, liarcf, ierr )
+ccc               if( ierr .eq. 0 ) then
+ccc                  print *,'tesuqm: st supprime ns3=',ns3
+ccc               else
+ccc                print *,'tesuqm: ST NON SUPPRIME ns3=',ns3,' ierr=',ierr
+ccc               endif
+            endif
+c
+         endif
+c
+ 100  continue
+c
+      return
+      end
+
+
+      subroutine tritas( nb, a, noanc )
+c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+c but :    tri croissant du tableau a de nb reels par la methode du tas
+c -----    methode due a williams et floyd     o(n log n )
+c          version avec un pointeur sur un tableau dont est extrait a
+c entrees:
+c --------
+c nb     : nombre de termes du tableau a
+c a      : les nb reels double precision a trier dans a
+c noanc  : numero ancien position de l'information (souvent noanc(i)=i)
+c
+c sorties:
+c --------
+c a      : les nb reels croissants dans a
+c noanc  : numero ancien position de l'information
+c          noanc(1)=no position pointeur sur a(1), ...
+c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+c auteur : perronnet alain analyse numerique upmc paris     fevrier 1991
+c ...................................................................012
+      integer           noanc(1:nb)
+      integer           pere,per,fil,fils1,fils2,fin
+      double precision  a(1:nb),aux
+c
+c     formation du tas sous forme d'un arbre binaire
+      fin = nb + 1
+c
+      do 20 pere = nb/2,1,-1
+c
+c        descendre pere jusqu'a n dans a  de facon  a respecter
+c        a(pere)>a(j) pour j fils ou petit fils de pere
+c        c-a-d pour tout j tel que pere <= e(j/2)<j<nb+1
+c                                          a(j/2) >= a(j)
+c                                                 >= a(j+1)
+c
+c        protection du pere
+         per = pere
+c
+c        le fils 1 du pere
+ 10      fils1 = 2 * per
+         if( fils1 .lt. fin ) then
+c           il existe un fils1
+            fil   = fils1
+            fils2 = fils1 + 1
+            if( fils2 .lt. fin ) then
+c              il existe 2 fils . selection du plus grand
+               if( a(fils2) .gt. a(fils1) ) fil = fils2
+            endif
+c
+c           ici fil est le plus grand des fils
+            if( a(per) .lt. a(fil) ) then
+c              permutation de per et fil
+               aux    = a(per)
+               a(per) = a(fil)
+               a(fil) = aux
+c              le pointeur est aussi permute
+               naux       = noanc(per)
+               noanc(per) = noanc(fil)
+               noanc(fil) = naux
+c              le nouveau pere est le fils permute
+               per = fil
+               goto 10
+            endif
+         endif
+ 20   continue
+c
+c     a chaque iteration la racine (plus grande valeur actuelle de a)
+c     est mise a sa place (fin actuelle du tableau) et permutee avec
+c     la valeur qui occupe cette place, puis descente de cette nouvelle
+c     racine pour respecter le fait que tout pere est plus grand que tous
+c     ses fils
+c     c-a-d pour tout j tel que pere <= e(j/2)<j<nb+1
+c                                          a(j/2) >= a(j)
+c                                                 >= a(j+1)
+      do 50 fin=nb,2,-1
+c        la permutation premier dernier
+         aux    = a(fin)
+         a(fin) = a(1)
+         a(1)   = aux
+c        le pointeur est aussi permute
+         naux       = noanc(fin)
+         noanc(fin) = noanc(1)
+         noanc(1)   = naux
+c
+c        descendre a(1) entre 1 et fin
+         per = 1
+c
+c        le fils 1 du pere
+ 30      fils1 = 2 * per
+         if( fils1 .lt. fin ) then
+c           il existe un fils1
+            fil   = fils1
+            fils2 = fils1 + 1
+            if( fils2 .lt. fin ) then
+c              il existe 2 fils . selection du plus grand
+               if( a(fils2) .gt. a(fils1) ) fil = fils2
+            endif
+c
+c           ici fil est le plus grand des fils
+            if( a(per) .lt. a(fil) ) then
+c              permutation de per et fil
+               aux    = a(per)
+               a(per) = a(fil)
+               a(fil) = aux
+c              le pointeur est aussi permute
+               naux       = noanc(per)
+               noanc(per) = noanc(fil)
+               noanc(fil) = naux
+c              le nouveau pere est le fils permute
+               per = fil
+               goto 30
+            endif
+         endif
+ 50   continue
+      end
index 4fdbcf0e6348c45895821f20eedf6a1fec85d2bb..aa06545eed0c0b943e384c4f38c2402f8ebdac5a 100644 (file)
@@ -29,6 +29,7 @@
 #include "SMESH_ActorUtils.h"
 
 #include "SMDS_Mesh.hxx"
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
 #include "SMESH_Actor.h"
 #include "SMESH_ControlsDef.hxx"
 #include "SalomeApp_Application.h"
@@ -345,15 +346,21 @@ void SMESH_VisualObjDef::buildElemPrs()
         SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
        switch(aType){
        case SMDSAbs_Volume:{
+          aConnect.clear();
          std::vector<int> aConnectivities;
-         GetConnect(aNodesIter,aConnect);
          // Convertions connectivities from SMDS to VTK
          if (anElem->IsPoly() && aNbNodes > 3) { // POLYEDRE
-           for (int k = 0; k < aNbNodes; k++) {
+
+            if ( const SMDS_PolyhedralVolumeOfNodes* ph =
+                 dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem))
+            {
+              aNbNodes = GetConnect(ph->uniqueNodesIterator(),aConnect);
+              anIdList->SetNumberOfIds( aNbNodes );
+            }
+           for (int k = 0; k < aNbNodes; k++)
              aConnectivities.push_back(k);
-           }
 
-         } else if (aNbNodes == 4) {
+          } else if (aNbNodes == 4) {
            static int anIds[] = {0,2,1,3};
            for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
 
@@ -395,6 +402,9 @@ void SMESH_VisualObjDef::buildElemPrs()
           else {
           }
 
+          if ( aConnect.empty() )
+            GetConnect(aNodesIter,aConnect);
+
          if (aConnectivities.size() > 0) {
            for (vtkIdType aNodeId = 0; aNodeId < aNbNodes; aNodeId++)
              SetId(anIdList,mySMDS2VTKNodes,aConnect,aNodeId,aConnectivities[aNodeId]);
index 0ad564ef79012272ce087a206b007b63e3473c28..45ee55ba9e4a467d93a7a26b64097ca94d7e3f50 100644 (file)
@@ -27,6 +27,8 @@
 #include "SMDS_FaceOfNodes.hxx"
 #include "SMDS_IteratorOfElements.hxx"
 #include "SMDS_MeshNode.hxx"
+#include "SMDS_Mesh.hxx"
+
 #include "utilities.h"
 
 using namespace std;
@@ -76,6 +78,33 @@ class SMDS_FaceOfNodes_MyIterator:public SMDS_NodeArrayElemIterator
     SMDS_NodeArrayElemIterator( s, & s[ l ] ) {}
 };
 
+/// ===================================================================
+/*!
+ * \brief Iterator on edges of face
+ */
+/// ===================================================================
+
+class _MyEdgeIterator : public SMDS_ElemIterator
+{
+  vector< const SMDS_MeshElement* > myElems;
+  int myIndex;
+public:
+  _MyEdgeIterator(const SMDS_FaceOfNodes* face):myIndex(0) {
+    myElems.reserve( face->NbNodes() );
+    for ( int i = 0; i < face->NbNodes(); ++i ) {
+      const SMDS_MeshElement* edge =
+        SMDS_Mesh::FindEdge( face->GetNode( i ), face->GetNode( i + 1 ));
+      if ( edge )
+        myElems.push_back( edge );
+    }
+  }
+  /// Return true if and only if there are other object in this iterator
+  virtual bool more() { return myIndex < myElems.size(); }
+
+  /// Return the current object and step to the next one
+  virtual const SMDS_MeshElement* next() { return myElems[ myIndex++ ]; }
+};
+
 SMDS_ElemIteratorPtr SMDS_FaceOfNodes::elementsIterator
                          (SMDSAbs_ElementType type) const
 {
@@ -86,7 +115,7 @@ SMDS_ElemIteratorPtr SMDS_FaceOfNodes::elementsIterator
   case SMDSAbs_Node:
     return SMDS_ElemIteratorPtr(new SMDS_FaceOfNodes_MyIterator(myNodes,myNbNodes));
   case SMDSAbs_Edge:
-    MESSAGE("Error : edge iterator for SMDS_FaceOfNodes not implemented");
+    return SMDS_ElemIteratorPtr(new _MyEdgeIterator( this ));
     break;
   default:
     return SMDS_ElemIteratorPtr
index 26a998117dc5fda2cd2acc490f44fbd73cb62ca5..bf40922dd0fc76ef91285861799738bfe32e81e5 100644 (file)
@@ -1259,20 +1259,18 @@ const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
 const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
                                          const SMDS_MeshNode * node2)
 {
+  if ( !node1 ) return 0;
   const SMDS_MeshEdge * toReturn=NULL;
   //PROFILER_Init();
   //PROFILER_Set();
-  SMDS_ElemIteratorPtr it1=node1->edgesIterator();
+  SMDS_ElemIteratorPtr it1=node1->GetInverseElementIterator(SMDSAbs_Edge);
   //PROFILER_Get(0);
   //PROFILER_Set();
   while(it1->more()) {
-    const SMDS_MeshEdge * e=static_cast<const SMDS_MeshEdge *> (it1->next());
-    SMDS_ElemIteratorPtr it2=e->nodesIterator();
-    while(it2->more()) {
-      if(it2->next()->GetID()==node2->GetID()) {
-        toReturn = e;
-        break;
-      }
+    const SMDS_MeshElement * e = it1->next();
+    if ( e->NbNodes() == 2 && e->GetNodeIndex( node2 ) >= 0 ) {
+      toReturn = static_cast<const SMDS_MeshEdge*>( e );
+      break;
     }
   }
   //PROFILER_Get(1);
@@ -1317,25 +1315,27 @@ const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
                                          const SMDS_MeshNode * node2,
                                          const SMDS_MeshNode * node3)
 {
-  if ( !node1 || !node2 || !node3 ) return 0;
-  const SMDS_MeshEdge * toReturn = NULL;
-  SMDS_ElemIteratorPtr it1 = node1->edgesIterator();
+  if ( !node1 ) return 0;
+  SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Edge);
   while(it1->more()) {
-    const SMDS_MeshEdge * e = static_cast<const SMDS_MeshEdge *> (it1->next());
-    SMDS_ElemIteratorPtr it2 = e->nodesIterator();
-    int tmp = 0;
-    while(it2->more()) {
-      int nID = it2->next()->GetID();
-      if( nID==node2->GetID() || nID==node3->GetID() ) {
-        tmp++;
-        if(tmp==2) {
-          toReturn = e;
+    const SMDS_MeshElement * e = it1->next();
+    if ( e->NbNodes() == 3 ) {
+      SMDS_ElemIteratorPtr it2 = e->nodesIterator();
+      while(it2->more()) {
+        const SMDS_MeshElement* n = it2->next();
+        if( n!=node1 &&
+            n!=node2 &&
+            n!=node3 )
+        {
+          e = 0;
           break;
         }
       }
+      if ( e )
+        return static_cast<const SMDS_MeshEdge *> (e);
     }
   }
-  return toReturn;
+  return 0;
 }
 
 
@@ -1357,27 +1357,27 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
                                          const SMDS_MeshNode *node2,
                                          const SMDS_MeshNode *node3)
 {
-  if ( !node1 || !node2 || !node3 ) return 0;
-  const SMDS_MeshFace * face;
-  const SMDS_MeshElement * node;
-  bool node2found, node3found;
-
-  SMDS_ElemIteratorPtr it1 = node1->facesIterator();
+  if ( !node1 ) return 0;
+  SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
   while(it1->more()) {
-    face = static_cast<const SMDS_MeshFace*>(it1->next());
-    if(face->NbNodes()!=3) continue;
-    SMDS_ElemIteratorPtr it2 = face->nodesIterator();
-    node2found = false;
-    node3found = false;
-    while(it2->more()) {
-      node = it2->next();
-      if(node->GetID()==node2->GetID()) node2found = true;
-      if(node->GetID()==node3->GetID()) node3found = true;
+    const SMDS_MeshElement * e = it1->next();
+    if ( e->NbNodes() == 3 ) {
+      SMDS_ElemIteratorPtr it2 = e->nodesIterator();
+      while(it2->more()) {
+        const SMDS_MeshElement* n = it2->next();
+        if( n!=node1 &&
+            n!=node2 &&
+            n!=node3 )
+        {
+          e = 0;
+          break;
+        }
+      }
+      if ( e )
+        return static_cast<const SMDS_MeshFace *> (e);
     }
-    if( node2found && node3found )
-      return face;
   }
-  return NULL;
+  return 0;
 }
 
 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
@@ -1413,29 +1413,28 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
                                          const SMDS_MeshNode *node3,
                                          const SMDS_MeshNode *node4)
 {
-  if( (node1==NULL) || (node2==NULL) || (node3==NULL) || (node4==NULL) )
-    return NULL;
-  const SMDS_MeshFace * face;
-  const SMDS_MeshElement * node;
-  bool node2found, node3found, node4found;
-  SMDS_ElemIteratorPtr it1 = node1->facesIterator();
+  if ( !node1 ) return 0;
+  SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
   while(it1->more()) {
-    face = static_cast<const SMDS_MeshFace *>(it1->next());
-    if(face->NbNodes()!=4) continue;
-    SMDS_ElemIteratorPtr it2 = face->nodesIterator();
-    node2found = false;
-    node3found = false;
-    node4found = false;
-    while(it2->more()) {
-      node=it2->next();
-      if(node->GetID()==node2->GetID()) node2found = true;
-      if(node->GetID()==node3->GetID()) node3found = true;
-      if(node->GetID()==node4->GetID()) node4found = true;
+    const SMDS_MeshElement * e = it1->next();
+    if ( e->NbNodes() == 4 ) {
+      SMDS_ElemIteratorPtr it2 = e->nodesIterator();
+      while(it2->more()) {
+        const SMDS_MeshElement* n = it2->next();
+        if( n!=node1 &&
+            n!=node2 &&
+            n!=node3 &&
+            n!=node4 )
+        {
+          e = 0;
+          break;
+        }
+      }
+      if ( e )
+        return static_cast<const SMDS_MeshFace *> (e);
     }
-    if( node2found && node3found && node4found )
-      return face;
   }
-  return NULL;
+  return 0;
 }
 
 SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
@@ -1477,28 +1476,30 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
                                          const SMDS_MeshNode *node5,
                                          const SMDS_MeshNode *node6)
 {
-  if( (node1==NULL) || (node2==NULL) || (node3==NULL) ||
-      (node4==NULL) || (node5==NULL) || (node6==NULL) ) return NULL;
-  const SMDS_MeshFace * face;
-  const SMDS_MeshElement * node;
-  SMDS_ElemIteratorPtr it1 = node1->facesIterator();
+  if ( !node1 ) return 0;
+  SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
   while(it1->more()) {
-    face = static_cast<const SMDS_MeshFace*>(it1->next());
-    if(face->NbNodes()!=6) continue;
-    SMDS_ElemIteratorPtr it2 = face->nodesIterator();
-    int tmp = 0;
-    while(it2->more()) {
-      node = it2->next();
-      if(node->GetID()==node2->GetID()) tmp++;
-      if(node->GetID()==node3->GetID()) tmp++;
-      if(node->GetID()==node4->GetID()) tmp++;
-      if(node->GetID()==node5->GetID()) tmp++;
-      if(node->GetID()==node6->GetID()) tmp++;
+    const SMDS_MeshElement * e = it1->next();
+    if ( e->NbNodes() == 6 ) {
+      SMDS_ElemIteratorPtr it2 = e->nodesIterator();
+      while(it2->more()) {
+        const SMDS_MeshElement* n = it2->next();
+        if( n!=node1 &&
+            n!=node2 &&
+            n!=node3 &&
+            n!=node4 &&
+            n!=node5 &&
+            n!=node6 )
+        {
+          e = 0;
+          break;
+        }
+      }
+      if ( e )
+        return static_cast<const SMDS_MeshFace *> (e);
     }
-    if( tmp==5 )
-      return static_cast<const SMDS_MeshFace*>(face);
   }
-  return NULL;
+  return 0;
 }
 
 
@@ -1532,31 +1533,32 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
                                          const SMDS_MeshNode *node7,
                                          const SMDS_MeshNode *node8)
 {
-  if( (node1==NULL) || (node2==NULL) || (node3==NULL) || (node4==NULL) ||
-      (node5==NULL) || (node6==NULL) || (node7==NULL) || (node8==NULL) )
-    return NULL;
-  const SMDS_MeshFace * face;
-  const SMDS_MeshElement * node;
-  SMDS_ElemIteratorPtr it1 = node1->facesIterator();
+  if ( !node1 ) return 0;
+  SMDS_ElemIteratorPtr it1 = node1->GetInverseElementIterator(SMDSAbs_Face);
   while(it1->more()) {
-    face = static_cast<const SMDS_MeshFace *>(it1->next());
-    if(face->NbNodes()!=8) continue;
-    SMDS_ElemIteratorPtr it2 = face->nodesIterator();
-    int tmp = 0;
-    while(it2->more()) {
-      node = it2->next();
-      if(node->GetID()==node2->GetID()) tmp++;
-      if(node->GetID()==node3->GetID()) tmp++;
-      if(node->GetID()==node4->GetID()) tmp++;
-      if(node->GetID()==node5->GetID()) tmp++;
-      if(node->GetID()==node6->GetID()) tmp++;
-      if(node->GetID()==node7->GetID()) tmp++;
-      if(node->GetID()==node8->GetID()) tmp++;
+    const SMDS_MeshElement * e = it1->next();
+    if ( e->NbNodes() == 8 ) {
+      SMDS_ElemIteratorPtr it2 = e->nodesIterator();
+      while(it2->more()) {
+        const SMDS_MeshElement* n = it2->next();
+        if( n!=node1 &&
+            n!=node2 &&
+            n!=node3 &&
+            n!=node4 &&
+            n!=node5 &&
+            n!=node6 &&
+            n!=node7 &&
+            n!=node8 )
+        {
+          e = 0;
+          break;
+        }
+      }
+      if ( e )
+        return static_cast<const SMDS_MeshFace *> (e);
     }
-    if( tmp==7 )
-      return face;
   }
-  return NULL;
+  return 0;
 }
 
 
@@ -1588,36 +1590,23 @@ const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<int> nodes_ids) const
 
 const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<const SMDS_MeshNode *> nodes)
 {
-  int nbNodes = nodes.size();
-  if (nbNodes < 1) return NULL;
-
-  bool isFound = true;
-  const SMDS_MeshFace * face;
-  set<const SMDS_MeshFace *> faces;
-
-  for (int inode = 0; inode < nbNodes && isFound; inode++) {
-    if ( !nodes[ inode ]) return 0;
-    
-    set<const SMDS_MeshFace *> new_faces;
-
-    SMDS_ElemIteratorPtr itF = nodes[inode]->facesIterator();
+  if ( nodes.size() > 2 && nodes[0] ) {
+    SMDS_ElemIteratorPtr itF = nodes[0]->GetInverseElementIterator(SMDSAbs_Face);
     while (itF->more()) {
-      face = static_cast<const SMDS_MeshFace *>(itF->next());
-      if (face->NbNodes() == nbNodes) {
-        if (inode == 0 || faces.find(face) != faces.end()) {
-          new_faces.insert(face);
+      const SMDS_MeshElement* f = itF->next();
+      if ( f->NbNodes() == nodes.size() ) {
+        SMDS_ElemIteratorPtr it2 = f->nodesIterator();
+        while(it2->more()) {
+          if ( find( nodes.begin(), nodes.end(), it2->next() ) == nodes.end() ) {
+            f = 0;
+            break;
+          }
         }
+        if ( f )
+          return static_cast<const SMDS_MeshFace *> (f);
       }
     }
-    faces = new_faces;
-    if (new_faces.size() == 0) {
-      isFound = false;
-    }
   }
-
-  if (isFound)
-    return face;
-
   return NULL;
 }
 
index 1d968dcbbf710571ec9f267f81970322d5182e39..b7a1cb117ed5544bdc711316938ccecb25327bc5 100644 (file)
@@ -88,16 +88,28 @@ const SMDS_PositionPtr& SMDS_MeshNode::GetPosition() const
        return myPosition;
 }
 
+//=======================================================================
+/*!
+ * \brief Iterator on list of elements
+ */
+//=======================================================================
+
 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):
-    myIterator(s)
+  SMDS_MeshNode_MyInvIterator(const NCollection_List<const SMDS_MeshElement*>& s,
+                              SMDSAbs_ElementType type):
+    myIterator(s), myType(type)
   {}
 
   bool more()
   {
+    if ( myType != SMDSAbs_All ) {
+      while ( myIterator.More() && myIterator.Value()->GetType() != myType)
+        myIterator.Next();
+    }
     return myIterator.More() != Standard_False;
   }
 
@@ -110,9 +122,9 @@ class SMDS_MeshNode_MyInvIterator:public SMDS_ElemIterator
 };
 
 SMDS_ElemIteratorPtr SMDS_MeshNode::
-       GetInverseElementIterator() const
+       GetInverseElementIterator(SMDSAbs_ElementType type) const
 {
-  return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(myInverseElements));
+  return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(myInverseElements,type));
 }
 
 // Same as GetInverseElementIterator but the create iterator only return
@@ -228,6 +240,24 @@ bool SMDS_MeshNode::emptyInverseElements()
   return myInverseElements.IsEmpty() != Standard_False;
 }
 
+//================================================================================
+/*!
+ * \brief Count inverse elements of given type
+ */
+//================================================================================
+
+int SMDS_MeshNode::NbInverseNodes(SMDSAbs_ElementType type) const
+{
+  if ( type == SMDSAbs_All )
+    return myInverseElements.Extent();
+  int nb = 0;
+  NCollection_List<const SMDS_MeshElement*>::Iterator it( myInverseElements );
+  for ( ; it.More(); it.Next() )
+    if ( it.Value()->GetType() == type )
+      nb++;
+  return nb;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 /// To be used with STL set
 ///////////////////////////////////////////////////////////////////////////////
index 86a032efdc3d5bbf33e8302b8b0ef4d8159ce74a..d195fbdfdef8b91326cda458ad31f764c8a9d508 100644 (file)
@@ -46,7 +46,8 @@ class SMDS_EXPORT SMDS_MeshNode:public SMDS_MeshElement
        void RemoveInverseElement(const SMDS_MeshElement * parent);
        void ClearInverseElements();
        bool emptyInverseElements();
-       SMDS_ElemIteratorPtr GetInverseElementIterator() const; 
+       SMDS_ElemIteratorPtr GetInverseElementIterator(SMDSAbs_ElementType type=SMDSAbs_All) const;
+        int NbInverseNodes(SMDSAbs_ElementType type=SMDSAbs_All) const;
        void SetPosition(const SMDS_PositionPtr& aPos);
        const SMDS_PositionPtr& GetPosition() const;
        SMDSAbs_ElementType GetType() const;
index 897cd69934d94a4bbf916b0c1b3fbaa4229de7bb..67d6160ce842ca5ff0e6aa161eab8b09df1e4b9f 100644 (file)
@@ -27,6 +27,8 @@
 
 #include "SMDS_IteratorOfElements.hxx"
 #include "SMDS_SetIterator.hxx"
+#include "SMDS_Mesh.hxx"
+
 #include "utilities.h"
 
 using namespace std;
@@ -135,6 +137,33 @@ class SMDS_PolygonalFaceOfNodes_MyIterator:public SMDS_NodeVectorElemIterator
     SMDS_NodeVectorElemIterator( s.begin(), s.end() ) {}
 };
 
+/// ===================================================================
+/*!
+ * \brief Iterator on edges of face
+ */
+/// ===================================================================
+
+class _MyEdgeIterator : public SMDS_ElemIterator
+{
+  vector< const SMDS_MeshElement* > myElems;
+  int myIndex;
+public:
+  _MyEdgeIterator(const SMDS_MeshFace* face):myIndex(0) {
+    myElems.reserve( face->NbNodes() );
+    for ( int i = 0; i < face->NbNodes(); ++i ) {
+      const SMDS_MeshElement* edge =
+        SMDS_Mesh::FindEdge( face->GetNode( i ), face->GetNode( i + 1 ));
+      if ( edge )
+        myElems.push_back( edge );
+    }
+  }
+  /// Return true if and only if there are other object in this iterator
+  virtual bool more() { return myIndex < myElems.size(); }
+
+  /// Return the current object and step to the next one
+  virtual const SMDS_MeshElement* next() { return myElems[ myIndex++ ]; }
+};
+
 SMDS_ElemIteratorPtr SMDS_PolygonalFaceOfNodes::elementsIterator
                                          (SMDSAbs_ElementType type) const
 {
@@ -145,7 +174,7 @@ SMDS_ElemIteratorPtr SMDS_PolygonalFaceOfNodes::elementsIterator
   case SMDSAbs_Node:
     return SMDS_ElemIteratorPtr(new SMDS_PolygonalFaceOfNodes_MyIterator(myNodes));
   case SMDSAbs_Edge:
-    MESSAGE("Error : edge iterator for SMDS_PolygonalFaceOfNodes not implemented");
+    return SMDS_ElemIteratorPtr(new _MyEdgeIterator( this ));
     break;
   default:
     return SMDS_ElemIteratorPtr
index 1c4fd4761bf1d4868ecf248247c3e8fd1fdcd5bb..c91f3762752cc06a1d1d7e38cebabc466a6dc8ef 100644 (file)
@@ -25,6 +25,8 @@
 
 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
 #include "SMDS_MeshNode.hxx"
+#include "SMDS_SetIterator.hxx"
+#include "SMDS_VolumeTool.hxx"
 #include "utilities.h"
 
 #include <set>
@@ -36,8 +38,8 @@ using namespace std;
 //purpose  : Create a volume of many faces
 //=======================================================================
 SMDS_PolyhedralVolumeOfNodes::SMDS_PolyhedralVolumeOfNodes
-                                (std::vector<const SMDS_MeshNode *> nodes,
-                                 std::vector<int>                   quantities)
+                                (vector<const SMDS_MeshNode *> nodes,
+                                 vector<int>                   quantities)
 : SMDS_VolumeOfNodes(NULL, NULL, NULL, NULL)
 {
   ChangeNodes(nodes, quantities);
@@ -57,51 +59,36 @@ SMDSAbs_ElementType SMDS_PolyhedralVolumeOfNodes::GetType() const
 //function : ChangeNodes
 //purpose  : 
 //=======================================================================
-bool SMDS_PolyhedralVolumeOfNodes::ChangeNodes (std::vector<const SMDS_MeshNode *> nodes,
-                                                std::vector<int>                   quantities)
+bool SMDS_PolyhedralVolumeOfNodes::ChangeNodes (const vector<const SMDS_MeshNode *>& nodes,
+                                                const vector<int>&                   quantities)
 {
   myNodesByFaces = nodes;
   myQuantities = quantities;
 
-  // Init fields of parent class
-  int aNbNodes = 0;
-  std::set<const SMDS_MeshNode *> aSet;
-  int nodes_len = nodes.size();
-  for (int j = 0; j < nodes_len; j++) {
-    if (aSet.find(nodes[j]) == aSet.end()) {
-      aSet.insert(nodes[j]);
-      aNbNodes++;
-    }
-  }
-
-  int k = 0;
-#ifndef WNT
-  const SMDS_MeshNode* aNodes [aNbNodes];
-#else
-  const SMDS_MeshNode** aNodes = (const SMDS_MeshNode **)new SMDS_MeshNode*[aNbNodes];
-#endif
-  std::set<const SMDS_MeshNode *>::iterator anIter = aSet.begin();
-  for (; anIter != aSet.end(); anIter++, k++) {
-    aNodes[k] = *anIter;
-  }
+  // Init fields of parent class, it allows to get only unique nodes(?)
 
+  set<const SMDS_MeshNode *> aSet;
+  aSet.insert( nodes.begin(), nodes.end());
   //SMDS_VolumeOfNodes::ChangeNodes(aNodes, aNbNodes);
   delete [] myNodes;
-  //myNbNodes = nodes.size();
-  myNbNodes = aNbNodes;
+  myNbNodes = aSet.size();
   myNodes = new const SMDS_MeshNode* [myNbNodes];
-  for (int i = 0; i < myNbNodes; i++) {
-    //myNodes[i] = nodes[i];
-    myNodes[i] = aNodes[i];
-  }
-
-#ifdef WNT
-  delete [] aNodes;
-#endif
+  set<const SMDS_MeshNode *>::iterator anIter = aSet.begin();
+  for (int k=0; anIter != aSet.end(); anIter++, k++)
+    myNodes[k] = *anIter;
 
   return true;
 }
 
+//=======================================================================
+//function : NbEdges
+//purpose  : 
+//=======================================================================
+int SMDS_PolyhedralVolumeOfNodes::NbNodes() const
+{
+  return myNodesByFaces.size();
+}
+
 //=======================================================================
 //function : NbEdges
 //purpose  : 
@@ -188,3 +175,87 @@ bool SMDS_PolyhedralVolumeOfNodes::ChangeNodes (const SMDS_MeshNode* nodes[],
 {
   return false;
 }
+
+/// ===================================================================
+/*!
+ * \brief Iterator on node of volume
+ */
+/// ===================================================================
+
+struct _MyIterator:public SMDS_NodeVectorElemIterator
+{
+  _MyIterator(const vector<const SMDS_MeshNode *>& nodes):
+    SMDS_NodeVectorElemIterator( nodes.begin(), nodes.end()) {}
+};
+
+/// ===================================================================
+/*!
+ * \brief Iterator on faces or edges of volume
+ */
+/// ===================================================================
+
+class _MySubIterator : public SMDS_ElemIterator
+{
+  vector< const SMDS_MeshElement* > myElems;
+  int myIndex;
+public:
+  _MySubIterator(const SMDS_MeshVolume* vol, SMDSAbs_ElementType type):myIndex(0) {
+    SMDS_VolumeTool vTool(vol);
+    if (type == SMDSAbs_Face)
+      vTool.GetAllExistingFaces( myElems );
+    else
+      vTool.GetAllExistingFaces( myElems );
+  }
+  /// Return true if and only if there are other object in this iterator
+  virtual bool more() { return myIndex < myElems.size(); }
+
+  /// Return the current object and step to the next one
+  virtual const SMDS_MeshElement* next() { return myElems[ myIndex++ ]; }
+};
+
+//================================================================================
+/*!
+ * \brief Return Iterator of sub elements
+ */
+//================================================================================
+
+SMDS_ElemIteratorPtr SMDS_PolyhedralVolumeOfNodes::elementsIterator(SMDSAbs_ElementType type) const
+{
+  switch(type)
+  {
+  case SMDSAbs_Volume:
+    return SMDS_MeshElement::elementsIterator(SMDSAbs_Volume);
+  case SMDSAbs_Node:
+    return SMDS_ElemIteratorPtr(new _MyIterator(myNodesByFaces));
+  case SMDSAbs_Face:
+    return SMDS_ElemIteratorPtr(new _MySubIterator(this,SMDSAbs_Face));
+  case SMDSAbs_Edge:
+    return SMDS_ElemIteratorPtr(new _MySubIterator(this,SMDSAbs_Edge));
+  default:
+    MESSAGE("ERROR : Iterator not implemented");
+    return SMDS_ElemIteratorPtr((SMDS_ElemIterator*)NULL);
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Return iterator on unique nodes
+ */
+//================================================================================
+
+SMDS_ElemIteratorPtr SMDS_PolyhedralVolumeOfNodes::uniqueNodesIterator() const
+{
+  return SMDS_ElemIteratorPtr
+    (new SMDS_NodeArrayElemIterator( myNodes, & myNodes[ myNbNodes ]));
+}
+
+//================================================================================
+/*!
+ * \brief Return node by its index
+ */
+//================================================================================
+
+const SMDS_MeshNode* SMDS_PolyhedralVolumeOfNodes::GetNode(const int ind) const
+{
+  return myNodesByFaces[ WrappedIndex( ind )];
+}
index ddac4c65958c8f7e977b56f778ec3b18a472bf07..99ca2e35ba5348d15c4ce3d12eedee6f505f5810 100644 (file)
@@ -42,10 +42,10 @@ class SMDS_EXPORT SMDS_PolyhedralVolumeOfNodes:public SMDS_VolumeOfNodes
   virtual SMDSAbs_ElementType GetType() const; 
   virtual bool IsPoly() const { return true; };
 
-  bool ChangeNodes (std::vector<const SMDS_MeshNode *> nodes,
-                    std::vector<int>                   quantities);
+  bool ChangeNodes (const std::vector<const SMDS_MeshNode *> & nodes,
+                    const std::vector<int> &                   quantities);
 
-  //virtual int NbNodes() const;
+  virtual int NbNodes() const;
   virtual int NbEdges() const;
   virtual int NbFaces() const;
 
@@ -56,10 +56,26 @@ class SMDS_EXPORT SMDS_PolyhedralVolumeOfNodes:public SMDS_VolumeOfNodes
   // 1 <= face_ind <= NbFaces()
   // 1 <= node_ind <= NbFaceNodes()
 
+  const std::vector<int> & GetQuanities() const { return myQuantities; }
+
   virtual void Print (std::ostream & OS) const;
 
- protected:
-  //virtual SMDS_ElemIteratorPtr elementsIterator (SMDSAbs_ElementType type) const;
+  /*!
+   * \brief Return node by its index
+   */
+  virtual const SMDS_MeshNode* GetNode(const int ind) const;
+
+  /*!
+   * \brief Return iterator on unique nodes
+   */
+  SMDS_ElemIteratorPtr uniqueNodesIterator() const;
+  /*!
+   * \brief Return nb of unique nodes
+   */
+  int NbUniqueNodes() const { return myNbNodes; }
+
+protected:
+  SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const;
 
  private:
   // usage disabled
index fa4249e6604d2db2d0ccd747c9d7cd51aaa4c3c2..3421c741229cf1b313b7e045c714fe3705f00922 100644 (file)
@@ -30,6 +30,7 @@
 #include "SMDS_SetIterator.hxx"
 #include "SMDS_IteratorOfElements.hxx"
 #include "SMDS_MeshNode.hxx"
+#include "SMDS_Mesh.hxx"
 
 #include "utilities.h"
 
@@ -241,6 +242,35 @@ SMDS_ElemIteratorPtr SMDS_QuadraticFaceOfNodes::interlacedNodesElemIterator() co
   return SMDS_ElemIteratorPtr
     (new _MyInterlacedNodeElemIterator ( interlacedNodesIterator() ));
 }
+/// ===================================================================
+/*!
+ * \brief Iterator on edges of face
+ */
+/// ===================================================================
+
+class _MyEdgeIterator : public SMDS_ElemIterator
+{
+  vector< const SMDS_MeshElement* > myElems;
+  int myIndex;
+public:
+  _MyEdgeIterator(const SMDS_QuadraticFaceOfNodes* face):myIndex(0) {
+    myElems.reserve( face->NbNodes() );
+    SMDS_ElemIteratorPtr nIt = face->interlacedNodesElemIterator();
+    const SMDS_MeshNode* n0 = face->GetNode( -1 );
+    while ( nIt->more() ) {
+      const SMDS_MeshNode* n1 = static_cast<const SMDS_MeshNode*>( nIt->next() );
+      const SMDS_MeshElement* edge = SMDS_Mesh::FindEdge( n0, n1 );
+      if ( edge )
+        myElems.push_back( edge );
+      n0 = n1;
+    }
+  }
+  /// Return true if and only if there are other object in this iterator
+  virtual bool more() { return myIndex < myElems.size(); }
+
+  /// Return the current object and step to the next one
+  virtual const SMDS_MeshElement* next() { return myElems[ myIndex++ ]; }
+};
 
 //=======================================================================
 //function : elementsIterator
@@ -257,7 +287,7 @@ SMDS_ElemIteratorPtr SMDS_QuadraticFaceOfNodes::elementsIterator
   case SMDSAbs_Node:
     return SMDS_ElemIteratorPtr(new _MyNodeIterator(myNodes));
   case SMDSAbs_Edge:
-    MESSAGE("Error : edge iterator for SMDS_QuadraticFaceOfNodes not implemented");
+    return SMDS_ElemIteratorPtr(new _MyEdgeIterator( this ));
     break;
   default:
     return SMDS_ElemIteratorPtr
index ce14eccd0bec2d8f19776b32e6da38f4dafdddbb..3709b1f3f95e169a3ef149444f6b29f5f5b07195 100644 (file)
@@ -30,6 +30,7 @@
 #include "SMDS_IteratorOfElements.hxx"
 #include "SMDS_MeshNode.hxx"
 #include "SMDS_SetIterator.hxx"
+#include "SMDS_VolumeTool.hxx"
 
 #include "utilities.h"
 
@@ -304,6 +305,31 @@ public:
     SMDS_NodeVectorElemIterator( s.begin(), s.end() ) {}
 };
 
+/// ===================================================================
+/*!
+ * \brief Iterator on faces or edges of volume
+ */
+/// ===================================================================
+
+class _MySubIterator : public SMDS_ElemIterator
+{
+  vector< const SMDS_MeshElement* > myElems;
+  int myIndex;
+public:
+  _MySubIterator(const SMDS_MeshVolume* vol, SMDSAbs_ElementType type):myIndex(0) {
+    SMDS_VolumeTool vTool(vol);
+    if (type == SMDSAbs_Face)
+      vTool.GetAllExistingFaces( myElems );
+    else
+      vTool.GetAllExistingFaces( myElems );
+  }
+  /// Return true if and only if there are other object in this iterator
+  virtual bool more() { return myIndex < myElems.size(); }
+
+  /// Return the current object and step to the next one
+  virtual const SMDS_MeshElement* next() { return myElems[ myIndex++ ]; }
+};
+
 //=======================================================================
 //function : elementsIterator
 //purpose  : 
@@ -319,10 +345,10 @@ SMDS_ElemIteratorPtr SMDS_QuadraticVolumeOfNodes::elementsIterator
   case SMDSAbs_Node:
     return SMDS_ElemIteratorPtr(new SMDS_QuadraticVolumeOfNodes_MyIterator(myNodes));
   case SMDSAbs_Edge:
-    MESSAGE("Error : edge iterator for SMDS_QuadraticVolumeOfNodes not implemented");
+    return SMDS_ElemIteratorPtr(new _MySubIterator(this,SMDSAbs_Edge));
     break;
   case SMDSAbs_Face:
-    MESSAGE("Error : face iterator for SMDS_QuadraticVolumeOfNodes not implemented");
+    return SMDS_ElemIteratorPtr(new _MySubIterator(this,SMDSAbs_Face));
     break;
   default:
     return SMDS_ElemIteratorPtr
index 05fa6c0464d7396eeaa2828eac3f95be679f2c45..9272b979e422802630f6c8bff4f2e580cca7256b 100644 (file)
 #include "SMDS_Iterator.hxx"
 
 ///////////////////////////////////////////////////////////////////////////////
-/// specific SMDS_Iterator iterating over abstract set of values like STL containers
+/// Accessors to value pointed by iterator
+///////////////////////////////////////////////////////////////////////////////
+
+namespace SMDS {
+
+  template<typename VALUE,typename VALUE_SET_ITERATOR>
+  struct SimpleAccessor {
+    static VALUE value(VALUE_SET_ITERATOR it) { return (VALUE) *it; }
+  };
+
+  template<typename VALUE,typename VALUE_SET_ITERATOR>
+  struct KeyAccessor {
+    static VALUE value(VALUE_SET_ITERATOR it) { return (VALUE) it->first; }
+  };
+
+  template<typename VALUE,typename VALUE_SET_ITERATOR>
+  struct ValueAccessor {
+    static VALUE value(VALUE_SET_ITERATOR it) { return (VALUE) it->second; }
+  };
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// SMDS_Iterator iterating over abstract set of values like STL containers
 ///
 /// BE CAREFUL: iterator pointed value is static_cast'ed to VALUE
 ///
 ///////////////////////////////////////////////////////////////////////////////
 
-template<typename VALUE, typename VALUE_SET_ITERATOR>
+template<typename VALUE,
+         typename VALUE_SET_ITERATOR,
+         typename ACCESOR=SMDS::SimpleAccessor<VALUE,VALUE_SET_ITERATOR> >
 class SMDS_SetIterator : public SMDS_Iterator<VALUE>
 {
 protected:
@@ -57,11 +81,67 @@ public:
   virtual bool more() { return _beg != _end; }
 
   /// Return the current object and step to the next one
-  virtual VALUE next() { return static_cast<VALUE>( *_beg++ ); }
+  virtual VALUE next() { return ACCESOR::value( _beg++ ); }
+};
 
+///////////////////////////////////////////////////////////////////////////////
+/// map iterators
+///////////////////////////////////////////////////////////////////////////////
+
+#include <map>
+/*!
+ * \brief iterator on values of a map
+ */
+template<typename M>
+struct SMDS_mapIterator : public SMDS_SetIterator< typename M::mapped_type, typename M::const_iterator,
+                                                   SMDS::ValueAccessor<typename M::mapped_type,
+                                                                       typename M::const_iterator> > {
+  typedef SMDS_SetIterator< typename M::mapped_type, typename M::const_iterator,
+                            SMDS::ValueAccessor<typename M::mapped_type,
+                                                typename M::const_iterator> > parent_type;
+  SMDS_mapIterator(const M& m):parent_type(m.begin(),m.end()) {}
+};
+/*!
+ * \brief reverse iterator on values of a map
+ */
+template<typename M>
+struct SMDS_mapReverseIterator : public SMDS_SetIterator< typename M::mapped_type,
+                                                          typename M::const_reverse_iterator,
+                                                          SMDS::ValueAccessor<typename M::mapped_type,
+                                                                              typename M::const_reverse_iterator> > {
+  typedef SMDS_SetIterator< typename M::mapped_type, typename M::const_reverse_iterator,
+                            SMDS::ValueAccessor<typename M::mapped_type,
+                                                typename M::const_reverse_iterator> > parent_type;
+  SMDS_mapReverseIterator(const M& m):parent_type(m.rbegin(),m.rend()) {}
+};
+/*!
+ * \brief iterator on keys of a map
+ */
+template<typename M>
+struct SMDS_mapKeyIterator : public SMDS_SetIterator< typename M::key_type, typename M::const_iterator,
+                                                      SMDS::KeyAccessor<typename M::key_type,
+                                                                        typename M::const_iterator> > {
+  typedef SMDS_SetIterator< typename M::key_type, typename M::const_iterator,
+                            SMDS::KeyAccessor<typename M::key_type,
+                                              typename M::const_iterator> > parent_type;
+  SMDS_mapKeyIterator(const M& m):parent_type(m.begin(),m.end()) {}
+};
+/*!
+ * \brief reverse iterator on keys of a map
+ */
+template<typename M>
+struct SMDS_mapKeyReverseIterator : public SMDS_SetIterator< typename M::key_type, typename M::const_iterator,
+                                                            SMDS::KeyAccessor<typename M::key_type,
+                                                                              typename M::const_iterator> > {
+  typedef SMDS_SetIterator< typename M::key_type, typename M::const_iterator,
+                            SMDS::KeyAccessor<typename M::key_type,
+                                              typename M::const_iterator> > parent_type;
+  SMDS_mapKeyReverseIterator(const M& m):parent_type(m.rbegin(),m.rend()) {}
 };
 
+///////////////////////////////////////////////////////////////////////////////
 // useful specifications
+///////////////////////////////////////////////////////////////////////////////
 
 #include <vector>
 
index 0428095da1cdc839f6395a7cdf9c8facd8872384..af3c64cf5c2ee25342407b826dd76e6b9ff6e267 100644 (file)
 #include "SMDS_VolumeOfNodes.hxx"
 #include "SMDS_MeshNode.hxx"
 #include "SMDS_SetIterator.hxx"
+#include "SMDS_VolumeTool.hxx"
 #include "utilities.h"
 
+#include <vector>
+
 using namespace std;
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -171,6 +174,12 @@ int SMDS_VolumeOfNodes::NbEdges() const
         return 0;
 }
 
+/// ===================================================================
+/*!
+ * \brief Iterator on node of volume
+ */
+/// ===================================================================
+
 class SMDS_VolumeOfNodes_MyIterator:public SMDS_NodeArrayElemIterator
 {
  public:
@@ -178,6 +187,31 @@ 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;
+  int myIndex;
+public:
+  _MySubIterator(const SMDS_VolumeOfNodes* vol, SMDSAbs_ElementType type):myIndex(0) {
+    SMDS_VolumeTool vTool(vol);
+    if (type == SMDSAbs_Face)
+      vTool.GetAllExistingFaces( myElems );
+    else
+      vTool.GetAllExistingFaces( myElems );
+  }
+  /// Return true if and only if there are other object in this iterator
+  virtual bool more() { return myIndex < myElems.size(); }
+
+  /// Return the current object and step to the next one
+  virtual const SMDS_MeshElement* next() { return myElems[ myIndex++ ]; }
+};
+
 SMDS_ElemIteratorPtr SMDS_VolumeOfNodes::elementsIterator(SMDSAbs_ElementType type) const
 {
   switch(type)
@@ -186,6 +220,10 @@ SMDS_ElemIteratorPtr SMDS_VolumeOfNodes::elementsIterator(SMDSAbs_ElementType ty
     return SMDS_MeshElement::elementsIterator(SMDSAbs_Volume);
   case SMDSAbs_Node:
     return SMDS_ElemIteratorPtr(new SMDS_VolumeOfNodes_MyIterator(myNodes,myNbNodes));
+  case SMDSAbs_Face:
+    return SMDS_ElemIteratorPtr(new _MySubIterator(this,SMDSAbs_Face));
+  case SMDSAbs_Edge:
+    return SMDS_ElemIteratorPtr(new _MySubIterator(this,SMDSAbs_Edge));
   default:
     MESSAGE("ERROR : Iterator not implemented");
     return SMDS_ElemIteratorPtr((SMDS_ElemIterator*)NULL);
index c55fff9ea97b6ac3ee0f4d3d49d0ccc47c118ebf..142da59cb16134b0c3b1ec5d717d92dfc6e06164 100644 (file)
@@ -31,6 +31,7 @@
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
+#include "SMDS_Mesh.hxx"
 
 #include "utilities.h"
 
@@ -1111,8 +1112,8 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
     return IsLinked(myVolumeNodes[theNode1Index], myVolumeNodes[theNode2Index]);
   }
 
-  int minInd = theNode1Index < theNode2Index ? theNode1Index : theNode2Index;
-  int maxInd = theNode1Index < theNode2Index ? theNode2Index : theNode1Index;
+  int minInd = min( theNode1Index, theNode2Index );
+  int maxInd = max( theNode1Index, theNode2Index );
 
   if ( minInd < 0 || maxInd > myVolumeNbNodes - 1 || maxInd == minInd )
     return false;
@@ -1217,6 +1218,65 @@ int SMDS_VolumeTool::GetNodeIndex(const SMDS_MeshNode* theNode) const
   return -1;
 }
 
+//================================================================================
+/*!
+ * \brief Fill vector with boundary faces existing in the mesh
+  * \param faces - vector of found nodes
+  * \retval int - nb of found faces
+ */
+//================================================================================
+
+int SMDS_VolumeTool::GetAllExistingFaces(vector<const SMDS_MeshElement*> & faces)
+{
+  faces.clear();
+  faces.reserve( NbFaces() );
+  for ( int iF = 0; iF < NbFaces(); ++iF ) {
+    const SMDS_MeshFace* face = 0;
+    const SMDS_MeshNode** nodes = GetFaceNodes( iF );
+    switch ( NbFaceNodes( iF )) {
+    case 3:
+      face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2] ); break;
+    case 4:
+      face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2], nodes[3] ); break;
+    case 6:
+      face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2],
+                                  nodes[3], nodes[4], nodes[5]); break;
+    case 8:
+      face = SMDS_Mesh::FindFace( nodes[0], nodes[1], nodes[2], nodes[3],
+                                  nodes[4], nodes[5], nodes[6], nodes[7]); break;
+    }
+    if ( face )
+      faces.push_back( face );
+  }
+  return faces.size();
+}
+
+
+//================================================================================
+/*!
+ * \brief Fill vector with boundary edges existing in the mesh
+  * \param edges - vector of found edges
+  * \retval int - nb of found faces
+ */
+//================================================================================
+
+int SMDS_VolumeTool::GetAllExistingEdges(vector<const SMDS_MeshElement*> & edges) const
+{
+  edges.clear();
+  edges.reserve( myVolumeNbNodes * 2 );
+  for ( int i = 0; i < myVolumeNbNodes; ++i ) {
+    for ( int j = i + 1; j < myVolumeNbNodes; ++j ) {
+      if ( IsLinked( i, j )) {
+        const SMDS_MeshElement* edge =
+          SMDS_Mesh::FindEdge( myVolumeNodes[i], myVolumeNodes[j] );
+        if ( edge )
+          edges.push_back( edge );
+      }
+    }
+  }
+  return edges.size();
+}
+
 //=======================================================================
 //function : IsFreeFace
 //purpose  : check that only one volume is build on the face nodes
@@ -1276,7 +1336,7 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex )
         continue; // opposite side
     }
     // remove a volume from volNbShared map
-    volNbShared.erase( vNbIt );
+    volNbShared.erase( vNbIt-- );
   }
 
   // here volNbShared contains only volumes laying on the
index cbff9a6ee1c17f1b2920497400eebb6b048f945e..8a1c77d43f6218496077dd748d247a6f300b09d8 100644 (file)
@@ -105,6 +105,9 @@ class SMDS_EXPORT SMDS_VolumeTool
   int GetNodeIndex(const SMDS_MeshNode* theNode) const;
   // Return an index of theNode
 
+  int GetAllExistingEdges(std::vector<const SMDS_MeshElement*> & edges) const;
+  // Fill vector with boundary edges existing in the mesh
+
   // -------------
   // info on faces
   // -------------
@@ -161,6 +164,9 @@ class SMDS_EXPORT SMDS_VolumeTool
   // Return index of a face formed by theFaceNodesIndices
   // Return -1 if a face not found
 
+  int GetAllExistingFaces(std::vector<const SMDS_MeshElement*> & faces);
+  // Fill vector with boundary faces existing in the mesh
+
   // ------------------------
   // static methods for faces
   // ------------------------
index 70dbb3f7a4cef7d43702d2debea5778f9d5169f4..7dea66551fc33228b217e751f811a4801d6ff25b 100644 (file)
@@ -38,6 +38,7 @@ salomeinclude_HEADERS = \
        SMESH_Hypothesis.hxx \
        SMESH_HypoFilter.hxx \
        SMESH_Algo.hxx \
+       SMESH_0D_Algo.hxx \
        SMESH_1D_Algo.hxx \
        SMESH_2D_Algo.hxx \
        SMESH_3D_Algo.hxx \
@@ -50,6 +51,10 @@ salomeinclude_HEADERS = \
        SMESH_SequenceOfElemPtr.hxx \
        SMESH_SequenceOfNode.hxx \
        SMESH_MesherHelper.hxx \
+       SMESH_Octree.hxx \
+       SMESH_OctreeNode.hxx \
+       SMESH_Comment.hxx \
+       SMESH_ComputeError.hxx \
        SMESH_SMESH.hxx
 
 # Libraries targets
@@ -62,6 +67,7 @@ dist_libSMESHimpl_la_SOURCES = \
        SMESH_subMesh.cxx \
        SMESH_Hypothesis.cxx \
        SMESH_Algo.cxx \
+       SMESH_0D_Algo.cxx \
        SMESH_1D_Algo.cxx \
        SMESH_2D_Algo.cxx \
        SMESH_3D_Algo.cxx \
@@ -70,7 +76,9 @@ dist_libSMESHimpl_la_SOURCES = \
        SMESH_Block.cxx \
        SMESH_Pattern.cxx \
        SMESH_HypoFilter.cxx \
-       SMESH_MesherHelper.cxx
+       SMESH_MesherHelper.cxx \
+       SMESH_Octree.cxx \
+       SMESH_OctreeNode.cxx
 
 # additionnal information to compile and link file
 libSMESHimpl_la_CPPFLAGS = \
diff --git a/src/SMESH/SMESH_0D_Algo.cxx b/src/SMESH/SMESH_0D_Algo.cxx
new file mode 100644 (file)
index 0000000..8deaf31
--- /dev/null
@@ -0,0 +1,53 @@
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : SMESH_0D_Algo.cxx
+//  Module : SMESH
+//  $Header$
+
+#include "SMESH_0D_Algo.hxx"
+#include "SMESH_Gen.hxx"
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+SMESH_0D_Algo::SMESH_0D_Algo(int hypId, int studyId, SMESH_Gen* gen)
+  : SMESH_Algo(hypId, studyId, gen)
+{
+  _type = ALGO_0D;
+  gen->_map0D_Algo[hypId] = this;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+SMESH_0D_Algo::~SMESH_0D_Algo()
+{
+}
+
diff --git a/src/SMESH/SMESH_0D_Algo.hxx b/src/SMESH/SMESH_0D_Algo.hxx
new file mode 100644 (file)
index 0000000..9064e71
--- /dev/null
@@ -0,0 +1,40 @@
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : SMESH_0D_Algo.hxx
+//  Module : SMESH
+//  $Header$
+
+#ifndef _SMESH_0D_ALGO_HXX_
+#define _SMESH_0D_ALGO_HXX_
+
+#include "SMESH_Algo.hxx"
+
+class SMESH_0D_Algo: public SMESH_Algo
+{
+public:
+  SMESH_0D_Algo(int hypId, int studyId,  SMESH_Gen* gen);
+  virtual ~SMESH_0D_Algo();
+};
+
+#endif
index a4b2c18f7eff178365910e9fd22804b7e282d1cb..16d3a99dda1c7ac9efce689b91cd043763bc9b9e 100644 (file)
@@ -27,6 +27,7 @@
 //  $Header$
 
 #include "SMESH_Algo.hxx"
+#include "SMESH_Comment.hxx"
 #include "SMESH_Gen.hxx"
 #include "SMESH_Mesh.hxx"
 #include "SMESH_HypoFilter.hxx"
 #include "SMESHDS_Mesh.hxx"
 #include "SMESHDS_SubMesh.hxx"
 
+#include <BRepAdaptor_Curve.hxx>
+#include <BRepLProp.hxx>
 #include <BRep_Tool.hxx>
 #include <GCPnts_AbscissaPoint.hxx>
 #include <GeomAdaptor_Curve.hxx>
 #include <Geom_Surface.hxx>
+#include <TopExp.hxx>
 #include <TopLoc_Location.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_ListOfShape.hxx>
 #include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
 #include <TopoDS_Face.hxx>
+#include <TopoDS_Vertex.hxx>
 #include <gp_Pnt.hxx>
 #include <gp_Pnt2d.hxx>
 #include <gp_Vec.hxx>
 
+#include <Standard_ErrorHandler.hxx>
+#include <Standard_Failure.hxx>
+
 #include "utilities.h"
 
 #include <algorithm>
@@ -65,12 +74,11 @@ using namespace std;
 SMESH_Algo::SMESH_Algo(int hypId, int studyId,
        SMESH_Gen * gen):SMESH_Hypothesis(hypId, studyId, gen)
 {
-//   _compatibleHypothesis.push_back("hypothese_bidon");
-       _type = ALGO;
-       gen->_mapAlgo[hypId] = this;
+  gen->_mapAlgo[hypId] = this;
 
-        _onlyUnaryInput = _requireDescretBoundary = true;
-        _quadraticMesh = false;
+  _onlyUnaryInput = _requireDescretBoundary = _requireShape = true;
+  _quadraticMesh = false;
+  _error = COMPERR_OK;
 }
 
 //=============================================================================
@@ -164,8 +172,7 @@ double SMESH_Algo::EdgeLength(const TopoDS_Edge & E)
   TopLoc_Location L;
   Handle(Geom_Curve) C = BRep_Tool::Curve(E, L, UMin, UMax);
   GeomAdaptor_Curve AdaptCurve(C);
-  GCPnts_AbscissaPoint gabs;
-  double length = gabs.Length(AdaptCurve, UMin, UMax);
+  double length = GCPnts_AbscissaPoint::Length(AdaptCurve, UMin, UMax);
   return length;
 }
 
@@ -378,10 +385,60 @@ bool SMESH_Algo::InitCompatibleHypoFilter( SMESH_HypoFilter & theFilter,
   return false;
 }
 
+//================================================================================
+/*!
+ * \brief Return continuity of two edges
+ * \param E1 - the 1st edge
+ * \param E2 - the 2nd edge
+ * \retval GeomAbs_Shape - regularity at the junction between E1 and E2
+ */
+//================================================================================
+
+GeomAbs_Shape SMESH_Algo::Continuity(const TopoDS_Edge & E1,
+                                     const TopoDS_Edge & E2)
+{
+  TopoDS_Vertex V = TopExp::LastVertex (E1, true);
+  if ( !V.IsSame( TopExp::FirstVertex(E2, true )))
+    if ( !TopExp::CommonVertex( E1, E2, V ))
+      return GeomAbs_C0;
+  Standard_Real u1 = BRep_Tool::Parameter( V, E1 );
+  Standard_Real u2 = BRep_Tool::Parameter( V, E2 );
+  BRepAdaptor_Curve C1( E1 ), C2( E2 );
+  try {
+#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+    OCC_CATCH_SIGNALS;
+#endif
+    return BRepLProp::Continuity(C1, C2, u1, u2);
+  }
+  catch (Standard_Failure) {
+  }
+  return GeomAbs_C0;
+}
+
+//================================================================================
+/*!
+ * \brief Return the node built on a vertex
+ * \param V - the vertex
+ * \param meshDS - mesh
+ * \retval const SMDS_MeshNode* - found node or NULL
+ */
+//================================================================================
+
+const SMDS_MeshNode* SMESH_Algo::VertexNode(const TopoDS_Vertex& V,
+                                            SMESHDS_Mesh*        meshDS)
+{
+  if ( SMESHDS_SubMesh* sm = meshDS->MeshElements(V) ) {
+    SMDS_NodeIteratorPtr nIt= sm->GetNodes();
+    if (nIt->more())
+      return nIt->next();
+  }
+  return 0;
+}
+
 //================================================================================
 /*!
  * \brief Sets event listener to submeshes if necessary
 * \param subMesh - submesh where algo is set
+ * \param subMesh - submesh where algo is set
  * 
  * After being set, event listener is notified on each event of a submesh.
  * By default non listener is set
@@ -391,3 +448,83 @@ bool SMESH_Algo::InitCompatibleHypoFilter( SMESH_HypoFilter & theFilter,
 void SMESH_Algo::SetEventListener(SMESH_subMesh* /*subMesh*/)
 {
 }
+
+//================================================================================
+/*!
+ * \brief Allow algo to do something after persistent restoration
+ * \param subMesh - restored submesh
+ *
+ * This method is called only if a submesh has HYP_OK algo_state.
+ */
+//================================================================================
+
+void SMESH_Algo::SubmeshRestored(SMESH_subMesh* /*subMesh*/)
+{
+}
+
+//================================================================================
+/*!
+ * \brief Computes mesh without geometry
+ * \param aMesh - the mesh
+ * \param aHelper - helper that must be used for adding elements to \aaMesh
+ * \retval bool - is a success
+ */
+//================================================================================
+
+bool SMESH_Algo::Compute(SMESH_Mesh & /*aMesh*/, SMESH_MesherHelper* /*aHelper*/)
+{
+  return error( COMPERR_BAD_INPUT_MESH, "Mesh built on shape expected");
+}
+
+//================================================================================
+/*!
+ * \brief store error and comment and then return ( error == COMPERR_OK )
+ */
+//================================================================================
+
+bool SMESH_Algo::error(int error, const SMESH_Comment& comment)
+{
+  _error   = error;
+  _comment = comment;
+  return ( error == COMPERR_OK );
+}
+
+//================================================================================
+/*!
+ * \brief store error and return ( error == COMPERR_OK )
+ */
+//================================================================================
+
+bool SMESH_Algo::error(SMESH_ComputeErrorPtr error)
+{
+  if ( error ) {
+    _error   = error->myName;
+    _comment = error->myComment;
+    return error->IsOK();
+  }
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief return compute error
+ */
+//================================================================================
+
+SMESH_ComputeErrorPtr SMESH_Algo::GetComputeError() const
+{
+  return SMESH_ComputeError::New( _error, _comment, this );
+}
+
+//================================================================================
+/*!
+ * \brief initialize compute error
+ */
+//================================================================================
+
+void SMESH_Algo::InitComputeError()
+{
+  _error = COMPERR_OK;
+  _comment.clear();
+}
+
index 97d1117e56d801da2532cc0a49a9a193f8dd572a..b27055c3145e97ac1012181dde43f656de74660f 100644 (file)
 #include "SMESH_SMESH.hxx"
 
 #include "SMESH_Hypothesis.hxx"
+#include "SMESH_ComputeError.hxx"
+#include "SMESH_Comment.hxx"
 
 #include <TopoDS_Shape.hxx>
 #include <TopoDS_Edge.hxx>
-#include <gp_XY.hxx>
+#include <GeomAbs_Shape.hxx>
 
 #include <string>
 #include <vector>
 #include <list>
-#include <map>
 
 class SMESH_Gen;
 class SMESH_Mesh;
 class SMESH_HypoFilter;
+class TopoDS_Vertex;
 class TopoDS_Face;
 class TopoDS_Shape;
 class SMESHDS_Mesh;
 class SMDS_MeshNode;
 class SMESH_subMesh;
+class SMESH_MesherHelper;
+
 
 class SMESH_EXPORT SMESH_Algo:public SMESH_Hypothesis
 {
@@ -101,9 +105,23 @@ public:
     * \param aMesh - the mesh
     * \param aShape - the shape
     * \retval bool - is a success
+    *
+    * Algorithms that !NeedDescretBoundary() || !OnlyUnaryInput() are
+    * to set SMESH_ComputeError returned by SMESH_submesh::GetComputeError()
+    * to report problematic subshapes
    */
   virtual bool Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) = 0;
 
+  /*!
+   * \brief Computes mesh without geometry
+    * \param aMesh - the mesh
+    * \param aHelper - helper that must be used for adding elements to \aaMesh
+    * \retval bool - is a success
+    *
+    * The method is called if ( !aMesh->HasShapeToMesh() )
+   */
+  virtual bool Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* aHelper);
+
   /*!
    * \brief Returns a list of compatible hypotheses used to mesh a shape
     * \param aMesh - the mesh 
@@ -146,15 +164,19 @@ public:
                                  const bool         ignoreAuxiliary) const;
   /*!
    * \brief Initialize my parameter values by the mesh built on the geometry
-   * \param theMesh - the built mesh
-   * \param theShape - the geometry of interest
-   * \retval bool - true if parameter values have been successfully defined
    *
    * Just return false as the algorithm does not hold parameters values
    */
   virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh,
                                    const TopoDS_Shape& theShape);
-
+  /*!
+   * \brief return compute error
+   */
+  SMESH_ComputeErrorPtr GetComputeError() const;
+  /*!
+   * \brief initialize compute error
+   */
+  void InitComputeError();
 
 public:
   // ==================================================================
@@ -176,6 +198,9 @@ public:
   bool NeedDescretBoundary() const { return _requireDescretBoundary; }
   // 3 - is a Dim-1 mesh prerequisite
 
+  bool NeedShape() const { return _requireShape; }
+  // 4 - is shape existance required
+
 public:
   // ==================================================================
   // Methods to track non hierarchical dependencies between submeshes 
@@ -191,6 +216,14 @@ public:
    */
   virtual void SetEventListener(SMESH_subMesh* subMesh);
   
+  /*!
+   * \brief Allow algo to do something after persistent restoration
+    * \param subMesh - restored submesh
+   *
+   * This method is called only if a submesh has HYP_OK algo_state.
+   */
+  virtual void SubmeshRestored(SMESH_subMesh* subMesh);
+  
 public:
   // ==================================================================
   // Common algo utilities
@@ -221,16 +254,55 @@ public:
    */
   static double EdgeLength(const TopoDS_Edge & E);
 
+  /*!
+   * \brief Return continuity of two edges
+    * \param E1 - the 1st edge
+    * \param E2 - the 2nd edge
+    * \retval GeomAbs_Shape - regularity at the junction between E1 and E2
+   */
+  static GeomAbs_Shape Continuity(const TopoDS_Edge & E1,
+                                  const TopoDS_Edge & E2);
+
+  /*!
+   * \brief Return the node built on a vertex
+    * \param V - the vertex
+    * \param meshDS - mesh
+    * \retval const SMDS_MeshNode* - found node or NULL
+   */
+  static const SMDS_MeshNode* VertexNode(const TopoDS_Vertex& V,
+                                         SMESHDS_Mesh*        meshDS);
 
 protected:
-  bool _onlyUnaryInput;
-  bool _requireDescretBoundary;
-  std::vector<std::string> _compatibleHypothesis;
+
+  /*!
+   * \brief store error and comment and then return ( error == COMPERR_OK )
+   */
+  bool error(int error, const SMESH_Comment& comment = "");
+  /*!
+   * \brief To be used as error in previous method
+   */
+  SMESH_ComputeErrorName dfltErr() const { return COMPERR_ALGO_FAILED; }
+  /*!
+   * \brief store error and return error->IsOK()
+   */
+  bool error(SMESH_ComputeErrorPtr error);
+
+protected:
+
+  std::vector<std::string>              _compatibleHypothesis;
   std::list<const SMESHDS_Hypothesis *> _appliedHypList;
   std::list<const SMESHDS_Hypothesis *> _usedHypList;
 
-  // quadratic mesh creation required
+  bool _onlyUnaryInput;
+  bool _requireDescretBoundary;
+  bool _requireShape;
+
+  // quadratic mesh creation required,
+  // is usually set trough SMESH_MesherHelper::IsQuadraticSubMesh()
   bool _quadraticMesh;
+
+  int         _error;    //!< SMESH_ComputeErrorName or anything algo specific
+  std::string _comment;  //!< any text explaining what is wrong in Compute()
 };
 
 #endif
index fd9ff01e3ae46f0b567f4b24a3b862eb780894ef..392160279d415fd71c5be80062cc48d9816b69ee 100644 (file)
@@ -304,6 +304,9 @@ public:
   // Note: to compute params of a point on a face, it is enough to set
   // TFace, TEdge's and points for that face only
 
+  // Note 2: curve adaptors need to have only Value(double), FirstParameter() and
+  // LastParameter() defined to be used by Block algoritms
+
   class SMESH_EXPORT TEdge {
     int                myCoordInd;
     double             myFirst;
diff --git a/src/SMESH/SMESH_Comment.hxx b/src/SMESH/SMESH_Comment.hxx
new file mode 100644 (file)
index 0000000..9385dab
--- /dev/null
@@ -0,0 +1,69 @@
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//
+//  Copyright (C) 2003  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
+//
+//
+// File      : SMESH_Comment.hxx
+// Created   : Wed Mar 14 18:28:45 2007
+// Author    : Edward AGAPOV (eap)
+// Module    : SMESH
+// $Header: 
+
+
+#ifndef SMESH_Comment_HeaderFile
+#define SMESH_Comment_HeaderFile
+
+# include <string>
+# include <sstream>
+
+using namespace std;
+
+/*!
+ * \brief Class to generate string from any type
+ */
+class SMESH_Comment : public string
+{
+  ostringstream _s ;
+
+public :
+
+  SMESH_Comment():string("") {}
+
+  SMESH_Comment(const SMESH_Comment& c):string() {
+    _s << c.c_str() ;
+    this->string::operator=( _s.str() );
+  }
+
+  template <class T>
+  SMESH_Comment( const T &anything ) {
+    _s << anything ;
+    this->string::operator=( _s.str() );
+  }
+
+  template <class T>
+  SMESH_Comment & operator<<( const T &anything ) {
+    _s << anything ;
+    this->string::operator=( _s.str() );
+    return *this ;
+  }
+};
+
+
+#endif
diff --git a/src/SMESH/SMESH_ComputeError.hxx b/src/SMESH/SMESH_ComputeError.hxx
new file mode 100644 (file)
index 0000000..91f2712
--- /dev/null
@@ -0,0 +1,103 @@
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : SMESH_Hypothesis.hxx
+//  Author : Edward AGAPOV (eap)
+//  Module : SMESH
+//  $Header: 
+
+#ifndef SMESH_ComputeError_HeaderFile
+#define SMESH_ComputeError_HeaderFile
+
+#include <string>
+#include <boost/shared_ptr.hpp>
+
+class SMESH_Algo;
+struct SMESH_ComputeError;
+
+typedef boost::shared_ptr<SMESH_ComputeError> SMESH_ComputeErrorPtr;
+
+// =============================================================
+
+enum SMESH_ComputeErrorName
+{
+  // If you modify it, pls update SMESH_ComputeError::CommonName() below.
+  // Positive values are for algo specific errors
+  COMPERR_OK             = -1,
+  COMPERR_BAD_INPUT_MESH = -2,  //!< wrong mesh on lower submesh
+  COMPERR_STD_EXCEPTION  = -3,  //!< some std exception raised
+  COMPERR_OCC_EXCEPTION  = -4,  //!< OCC exception raised
+  COMPERR_SLM_EXCEPTION  = -5,  //!< SALOME exception raised
+  COMPERR_EXCEPTION      = -6,  //!< other exception raised
+  COMPERR_MEMORY_PB      = -7,  //!< std::bad_alloc exception
+  COMPERR_ALGO_FAILED    = -8,  //!< algo failed for some reason
+  COMPERR_BAD_SHAPE      = -9   //!< bad geometry
+};
+
+// =============================================================
+/*!
+ * \brief Contains algorithm and description of occured error
+ */
+// =============================================================
+
+struct SMESH_ComputeError
+{
+  int               myName; //!< SMESH_ComputeErrorName or anything algo specific
+  std::string       myComment;
+  const SMESH_Algo* myAlgo;
+
+  static SMESH_ComputeErrorPtr New( int               error   = COMPERR_OK,
+                                    std::string       comment = "",
+                                    const SMESH_Algo* algo    = 0)
+  { return SMESH_ComputeErrorPtr( new SMESH_ComputeError( error, comment, algo )); }
+
+  SMESH_ComputeError(int               error   = COMPERR_OK,
+                     std::string       comment = "",
+                     const SMESH_Algo* algo    = 0)
+    :myName(error),myComment(comment),myAlgo(algo) {}
+
+  bool IsOK()     { return myName == COMPERR_OK; }
+  bool IsCommon() { return myName < 0; }
+  inline std::string CommonName() const;
+
+};
+
+#define case2char(err) case err: return #err;
+
+std::string SMESH_ComputeError::CommonName() const
+{
+  switch( myName ) {
+  case2char(COMPERR_OK            );
+  case2char(COMPERR_BAD_INPUT_MESH);
+  case2char(COMPERR_STD_EXCEPTION );
+  case2char(COMPERR_OCC_EXCEPTION );
+  case2char(COMPERR_SLM_EXCEPTION );
+  case2char(COMPERR_EXCEPTION     );
+  case2char(COMPERR_MEMORY_PB     );
+  case2char(COMPERR_ALGO_FAILED   );
+  default:;
+  }
+  return "";
+}
+
+#endif
index 9fa10ca3e8e66722e78f319d4593beb0e3404d59..3c34f2e63ef77685268dade7d3f02e6b4c8c672a 100644 (file)
@@ -124,122 +124,65 @@ SMESH_Mesh* SMESH_Gen::CreateMesh(int theStudyId, bool theIsEmbeddedMode)
 
 //=============================================================================
 /*!
- *
+ * Compute a mesh
  */
 //=============================================================================
 
 bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
 {
   MESSAGE("SMESH_Gen::Compute");
-  //   bool isDone = false;
-  /*
-     Algo : s'appuie ou non sur une geometrie
-     Si geometrie:
-     Vertex : rien Ã  faire (range le point)
-     Edge, Wire, collection d'edge et wire : 1D
-     Face, Shell, collection de Face et Shells : 2D
-     Solid, Collection de Solid : 3D
-     */
-  // *** corriger commentaires
-  // check hypothesis associated to the mesh :
-  // - only one algo : type compatible with the type of the shape
-  // - hypothesis = compatible with algo
-  //    - check if hypothesis are applicable to this algo
-  //    - check contradictions within hypothesis
-  //    (test if enough hypothesis is done further)
 
   bool ret = true;
 
-//   if ( !CheckAlgoState( aMesh, aShape ))
-//   {
-//     INFOS( "ABORT MESHING: some algos or hypothesis are missing");
-//     return false;
-//   }
-
   SMESH_subMesh *sm = aMesh.GetSubMesh(aShape);
 
-  if ( sm->GetComputeState() == SMESH_subMesh::COMPUTE_OK )
-    return true; // already computed
-
   // -----------------------------------------------------------------
   // apply algos that do not require descretized boundaries, starting
   // from the most complex shapes
   // -----------------------------------------------------------------
 
-  // map containing all subshapes in the order: vertices, edges, faces...
-  const map<int, SMESH_subMesh*>& smMap = sm->DependsOn();
-  map<int, SMESH_subMesh*>::const_reverse_iterator revItSub = smMap.rbegin();
+  const bool includeSelf = true;
+  const bool complexShapeFirst = true;
 
-  SMESH_subMesh* smToCompute = sm;
-  while ( smToCompute )
+  SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(includeSelf,
+                                                           complexShapeFirst);
+  while ( smIt->more() )
   {
+    SMESH_subMesh* smToCompute = smIt->next();
+
     const TopoDS_Shape& aSubShape = smToCompute->GetSubShape();
     if ( GetShapeDim( aSubShape ) < 1 ) break;
 
     SMESH_Algo* algo = GetAlgo( aMesh, aSubShape );
-    if (algo && !algo->NeedDescretBoundary()) {
-      if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE) {
-        ret = smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
-      } else if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE) {
-        // JFA for PAL6524
-        ret = false;
-      } else {
-      }
-    }
-    if (!ret)
-      return false;
-
-    // next subMesh
-    if (revItSub != smMap.rend())
+    if (algo && !algo->NeedDescretBoundary())
     {
-      smToCompute = (*revItSub).second;
-      revItSub++;
+      if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
+        smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+
+      if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE)
+        ret = false;;
     }
-    else
-      smToCompute = 0;
   }
 
   // -----------------------------------------------
   // mesh the rest subshapes starting from vertices
   // -----------------------------------------------
-
-  int i, nbSub = smMap.size();
-  map<int, SMESH_subMesh*>::const_iterator itSub = smMap.begin();
-  for ( i = 0; i <= nbSub; ++i ) // loop on the whole map plus <sm>
+  smIt = sm->getDependsOnIterator(includeSelf, !complexShapeFirst);
+  while ( smIt->more() )
   {
-    if ( itSub == smMap.end() )
-      smToCompute = sm;
-    else
-      smToCompute = (itSub++)->second;
-    if (smToCompute->GetComputeState() != SMESH_subMesh::READY_TO_COMPUTE) {
-      if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE)
-        ret = false;
-      continue;
-    }
-    TopoDS_Shape subShape = smToCompute->GetSubShape();
-    if ( subShape.ShapeType() != TopAbs_VERTEX )
-    {
-      if ( !smToCompute->ComputeStateEngine(SMESH_subMesh::COMPUTE) )
-        ret = false;
-    }
-    else
-    {
-      TopoDS_Vertex V1 = TopoDS::Vertex(subShape);
-      gp_Pnt P1 = BRep_Tool::Pnt(V1);
-      SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
-      SMDS_MeshNode * node = meshDS->AddNode(P1.X(), P1.Y(), P1.Z());
-      if ( node ) {  // san - increase robustness
-        meshDS->SetNodeOnVertex(node, V1);
-        smToCompute->ComputeStateEngine(SMESH_subMesh::COMPUTE);
-      }
-    }
+    SMESH_subMesh* smToCompute = smIt->next();
+
+    if (smToCompute->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE)
+      smToCompute->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+
+    if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE)
+      ret = false;
   }
 
   MESSAGE( "VSR - SMESH_Gen::Compute() finished, OK = " << ret);
   return ret;
 }
 
-
 //=======================================================================
 //function : checkConformIgnoredAlgos
 //purpose  :
@@ -301,7 +244,7 @@ static bool checkConformIgnoredAlgos(SMESH_Mesh&               aMesh,
                 "> would produce not conform mesh: "
                 "<Not Conform Mesh Allowed> hypotesis is missing");
           theErrors.push_back( SMESH_Gen::TAlgoStateError() );
-          theErrors.back().Set( SMESH_Gen::NOT_CONFORM_MESH, algo, false );
+          theErrors.back().Set( SMESH_Hypothesis::HYP_NOTCONFORM, algo, false );
         }
 
         // sub-algos will be hidden by a local <algo>
@@ -361,7 +304,7 @@ static bool checkMissing(SMESH_Gen*                aGen,
         INFOS( "ERROR: " << shapeDim << "D algorithm is missing" );
         ret = false;
         theErrors.push_back( SMESH_Gen::TAlgoStateError() );
-        theErrors.back().Set( SMESH_Gen::MISSING_ALGO, shapeDim, true );
+        theErrors.back().Set( SMESH_Hypothesis::HYP_MISSING, shapeDim, true );
       }
     }
     return ret;
@@ -373,13 +316,13 @@ static bool checkMissing(SMESH_Gen*                aGen,
     bool IsGlobalHypothesis = aGen->IsGlobalHypothesis( algo, aMesh );
     if (!IsGlobalHypothesis || !globalChecked[ algo->GetDim() ])
     {
-      SMESH_Gen::TAlgoStateErrorName errName = SMESH_Gen::MISSING_HYPO;
+      TAlgoStateErrorName errName = SMESH_Hypothesis::HYP_MISSING;
       SMESH_Hypothesis::Hypothesis_Status status;
       algo->CheckHypothesis( aMesh, aSubMesh->GetSubShape(), status );
       if ( status == SMESH_Hypothesis::HYP_BAD_PARAMETER ) {
         INFOS( "ERROR: hypothesis of " << (IsGlobalHypothesis ? "Global " : "Local ")
                << "<" << algo->GetName() << "> has a bad parameter value");
-        errName = SMESH_Gen::BAD_PARAM_VALUE;
+        errName = SMESH_Hypothesis::HYP_BAD_PARAMETER;
       } else {
         INFOS( "ERROR: " << (IsGlobalHypothesis ? "Global " : "Local ")
                << "<" << algo->GetName() << "> misses some hypothesis");
@@ -496,7 +439,7 @@ bool SMESH_Gen::GetAlgoState(SMESH_Mesh&               theMesh,
   // --------------------------------------------------------
 
 
-  // find a global algo possibly hidding sub-algos
+  // find a global algo possibly hiding sub-algos
   int dim;
   const SMESH_Algo* aGlobIgnoAlgo = 0;
   for (dim = 3; dim > 0; dim--)
@@ -564,7 +507,7 @@ bool SMESH_Gen::GetAlgoState(SMESH_Mesh&               theMesh,
   aCheckedMap.clear();
   smToCheck = sm;
   revItSub = smMap.rbegin();
-  bool checkNoAlgo = (bool) aTopAlgoDim;
+  bool checkNoAlgo = theMesh.HasShapeToMesh() ? bool( aTopAlgoDim ) : false;
   bool globalChecked[] = { false, false, false, false };
 
   // loop on theShape and its sub-shapes
@@ -597,7 +540,7 @@ bool SMESH_Gen::GetAlgoState(SMESH_Mesh&               theMesh,
     ret = false;
     INFOS( "None algorithm attached" );
     theErrors.push_back( TAlgoStateError() );
-    theErrors.back().Set( MISSING_ALGO, 1, true );
+    theErrors.back().Set( SMESH_Hypothesis::HYP_MISSING, 1, true );
   }
 
   return ret;
index b7e8639d8c165a243e2bbbbf5477ec0de02b345f..1aa8e9684f39ef46063047121d279e289e412d4b 100644 (file)
@@ -34,7 +34,9 @@
 #include "Utils_SALOME_Exception.hxx"
 
 #include "SMESH_Hypothesis.hxx"
+#include "SMESH_ComputeError.hxx"
 #include "SMESH_Algo.hxx"
+#include "SMESH_0D_Algo.hxx"
 #include "SMESH_1D_Algo.hxx"
 #include "SMESH_2D_Algo.hxx"
 #include "SMESH_3D_Algo.hxx"
 
 #include <map>
 
+typedef SMESH_Hypothesis::Hypothesis_Status TAlgoStateErrorName;
 
 typedef struct studyContextStruct
 {
-       std::map < int, SMESH_Hypothesis * >mapHypothesis;
-         std::map < int, SMESH_Mesh * >mapMesh;
-         SMESHDS_Document * myDocument;
+  std::map < int, SMESH_Hypothesis * >mapHypothesis;
+  std::map < int, SMESH_Mesh * >mapMesh;
+  SMESHDS_Document * myDocument;
 } StudyContextStruct;
 
 class SMESH_EXPORT  SMESH_Gen
@@ -60,10 +63,9 @@ class SMESH_EXPORT  SMESH_Gen
   SMESH_Gen();
   ~SMESH_Gen();
 
-//  SMESH_Hypothesis *CreateHypothesis(const char *anHyp, int studyId)
-//    throw(SALOME_Exception);
   SMESH_Mesh* CreateMesh(int theStudyId, bool theIsEmbeddedMode)
     throw(SALOME_Exception);
+
   bool Compute(::SMESH_Mesh & aMesh, const TopoDS_Shape & aShape);
 
   bool CheckAlgoState(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
@@ -71,11 +73,6 @@ class SMESH_EXPORT  SMESH_Gen
   // if Compute() would fail because of some algo bad state
 
   
-  enum TAlgoStateErrorName { NONE=0,
-                             MISSING_ALGO,
-                             MISSING_HYPO,
-                             NOT_CONFORM_MESH,
-                             BAD_PARAM_VALUE };
   struct TAlgoStateError
   {
     TAlgoStateErrorName _name;
@@ -83,7 +80,7 @@ class SMESH_EXPORT  SMESH_Gen
     int                 _algoDim;
     bool                _isGlobalAlgo;
 
-    TAlgoStateError(): _algoDim(0),_algo(0),_name(NONE) {}
+    TAlgoStateError(): _algoDim(0),_algo(0),_name(SMESH_Hypothesis::HYP_OK) {}
     void Set(TAlgoStateErrorName name, const SMESH_Algo* algo, bool isGlobal)
     { _name = name; _algo = algo; _algoDim = algo->GetDim(); _isGlobalAlgo = isGlobal; }
     void Set(TAlgoStateErrorName name, const int algoDim,      bool isGlobal)
@@ -96,7 +93,6 @@ class SMESH_EXPORT  SMESH_Gen
   // if Compute() would fail because of some algo bad state
   // theErrors list contains problems description
 
-
   StudyContextStruct *GetStudyContext(int studyId);
 
   static int GetShapeDim(const TopAbs_ShapeEnum & aShapeType);
@@ -118,6 +114,7 @@ class SMESH_EXPORT  SMESH_Gen
   int GetANewId();
 
   std::map < int, SMESH_Algo * >_mapAlgo;
+  std::map < int, SMESH_0D_Algo * >_map0D_Algo;
   std::map < int, SMESH_1D_Algo * >_map1D_Algo;
   std::map < int, SMESH_2D_Algo * >_map2D_Algo;
   std::map < int, SMESH_3D_Algo * >_map3D_Algo;
index 36564d322c4f8a04a5017a2f175f00a4ee31c593..ac80acd22fa6e9a9c5a9ae758ff97f30388b646b 100644 (file)
@@ -126,14 +126,6 @@ void SMESH_Hypothesis::NotifySubMeshesHypothesisModification()
     {
       SMESH_Mesh* mesh = (*itm).second;
       mesh->NotifySubMeshesHypothesisModification( this );
-//       const list<SMESH_subMesh*>& subMeshes =
-//      mesh->GetSubMeshUsingHypothesis(this);
-
-//       //for all subMeshes using hypothesis
-       
-//       list<SMESH_subMesh*>::const_iterator its;
-//       for (its = subMeshes.begin(); its != subMeshes.end(); its++)
-//     (*its)->ComputeStateEngine(SMESH_subMesh::MODIF_HYP);
     }
 }
 
@@ -145,9 +137,6 @@ void SMESH_Hypothesis::NotifySubMeshesHypothesisModification()
 
 const char* SMESH_Hypothesis::GetLibName() const
 {
-//   MESSAGE("SMESHDS_Hypothesis::GetLibName");
-//   SCRUTE(_LibName);
-//   SCRUTE(&_LibName);
   return _libName.c_str();
 }
 
@@ -159,6 +148,5 @@ const char* SMESH_Hypothesis::GetLibName() const
 
 void SMESH_Hypothesis::SetLibName(const char* theLibName)
 {
-//   MESSAGE("SMESHDS_Hypothesis::SetLibName");
   _libName = string(theLibName);
 }
index f4a4d18d27eec64d012d3ab0c7e5538ef77818c3..b3c8853034005222c4b77d89a945e94df65358f3 100644 (file)
@@ -42,10 +42,12 @@ class SMESH_EXPORT SMESH_Hypothesis: public SMESHDS_Hypothesis
 public:
   enum Hypothesis_Status // in the order of severity
   {
-    HYP_OK,
+    HYP_OK = 0,
     HYP_MISSING,      // algo misses a hypothesis
     HYP_CONCURENT,    // several applicable hypotheses
     HYP_BAD_PARAMETER,// hypothesis has a bad parameter value
+    HYP_HIDDEN_ALGO,  // an algo is hidden by an upper dim algo generating all-dim elements
+    HYP_HIDING_ALGO,  // an algo hides lower dim algos by generating all-dim elements
     HYP_UNKNOWN_FATAL,//  --- all statuses below should be considered as fatal
                       //      for Add/RemoveHypothesis operations
     HYP_INCOMPATIBLE, // hypothesis does not fit algo
@@ -84,7 +86,7 @@ public:
    * dimention can be assigned to the shape
    */
   virtual bool IsAuxiliary() const
-  { return GetType() == PARAM_ALGO && _param_algo_dim <= 0; }
+  { return GetType() == PARAM_ALGO && _param_algo_dim < 0; }
 
 protected:
   SMESH_Gen* _gen;
index 8181e062bd6c01c532cdbe1e5fb9bf605d835a38..cc5da1dd71bd12b56402a795c1d1d13b32351ec0 100644 (file)
@@ -49,6 +49,7 @@
 #include "DriverSTL_R_SMDS_Mesh.h"
 
 #include <BRepTools_WireExplorer.hxx>
+#include <BRepPrimAPI_MakeBox.hxx>
 #include <BRep_Builder.hxx>
 #include <gp_Pnt.hxx>
 
@@ -80,21 +81,22 @@ static int MYDEBUG = 0;
  */
 //=============================================================================
 
-SMESH_Mesh::SMESH_Mesh(int theLocalId, 
-                      int theStudyId, 
-                      SMESH_Gen* theGen,
-                      bool theIsEmbeddedMode,
+SMESH_Mesh::SMESH_Mesh(int               theLocalId, 
+                      int               theStudyId, 
+                      SMESH_Gen*        theGen,
+                      bool              theIsEmbeddedMode,
                       SMESHDS_Document* theDocument):
   _groupId( 0 )
 {
-  INFOS("SMESH_Mesh::SMESH_Mesh(int localId)");
-  _id = theLocalId;
-  _studyId = theStudyId;
-  _gen = theGen;
-  _myDocument = theDocument;
-  _idDoc = theDocument->NewMesh(theIsEmbeddedMode);
-  _myMeshDS = theDocument->GetMesh(_idDoc);
+  MESSAGE("SMESH_Mesh::SMESH_Mesh(int localId)");
+  _id            = theLocalId;
+  _studyId       = theStudyId;
+  _gen           = theGen;
+  _myDocument    = theDocument;
+  _idDoc         = theDocument->NewMesh(theIsEmbeddedMode);
+  _myMeshDS      = theDocument->GetMesh(_idDoc);
   _isShapeToMesh = false;
+  _myMeshDS->ShapeToMesh( PseudoShape() );
 }
 
 //=============================================================================
@@ -117,7 +119,7 @@ SMESH_Mesh::~SMESH_Mesh()
 
 //=============================================================================
 /*!
- * 
+ * \brief Set geometry to be meshed
  */
 //=============================================================================
 
@@ -125,7 +127,11 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape)
 {
   if(MYDEBUG) MESSAGE("SMESH_Mesh::ShapeToMesh");
 
-  if ( !_myMeshDS->ShapeToMesh().IsNull() && aShape.IsNull() )
+  if ( !aShape.IsNull() && _isShapeToMesh )
+    throw SALOME_Exception(LOCALIZED ("a shape to mesh has already been defined"));
+
+  // clear current data
+  if ( !_myMeshDS->ShapeToMesh().IsNull() )
   {
     // removal of a shape to mesh, delete objects referring to sub-shapes:
     // - sub-meshes
@@ -144,28 +150,57 @@ void SMESH_Mesh::ShapeToMesh(const TopoDS_Shape & aShape)
       else
         i_gr++;
     }
+    _mapAncestors.Clear();
     _mapPropagationChains.Clear();
+
+    // clear SMESHDS
+    TopoDS_Shape aNullShape;
+    _myMeshDS->ShapeToMesh( aNullShape );
   }
-  else
+
+  // set a new geometry
+  if ( !aShape.IsNull() )
   {
-    if (_isShapeToMesh)
-      throw SALOME_Exception(LOCALIZED ("a shape to mesh has already been defined"));
+    _myMeshDS->ShapeToMesh(aShape);
+    _isShapeToMesh = true;
+
+    // fill _mapAncestors
+    int desType, ancType;
+    for ( desType = TopAbs_VERTEX; desType > TopAbs_COMPOUND; desType-- )
+      for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- )
+        TopExp::MapShapesAndAncestors ( aShape,
+                                        (TopAbs_ShapeEnum) desType,
+                                        (TopAbs_ShapeEnum) ancType,
+                                        _mapAncestors );
   }
-  _isShapeToMesh = true;
-  _myMeshDS->ShapeToMesh(aShape);
-
-  // fill _mapAncestors
-  _mapAncestors.Clear();
-  int desType, ancType;
-  for ( desType = TopAbs_VERTEX; desType > TopAbs_COMPOUND; desType-- )
-    for ( ancType = desType - 1; ancType >= TopAbs_COMPOUND; ancType-- )
-      TopExp::MapShapesAndAncestors ( aShape,
-                                     (TopAbs_ShapeEnum) desType,
-                                     (TopAbs_ShapeEnum) ancType,
-                                     _mapAncestors );
-
-  // NRI : 24/02/03
-  //EAP: 1/9/04 TopExp::MapShapes(aShape, _subShapes); USE the same map of _myMeshDS
+}
+
+//=======================================================================
+/*!
+ * \brief Return geometry to be meshed. (It may be a PseudoShape()!)
+ */
+//=======================================================================
+
+TopoDS_Shape SMESH_Mesh::GetShapeToMesh() const
+{
+  return _myMeshDS->ShapeToMesh();
+}
+
+//=======================================================================
+/*!
+ * \brief Return a solid which is returned by GetShapeToMesh() if
+ *        a real geometry to be meshed was not set
+ */
+//=======================================================================
+
+const TopoDS_Solid& SMESH_Mesh::PseudoShape()
+{
+  static TopoDS_Solid aSolid;
+  if ( aSolid.IsNull() )
+  {
+    aSolid = BRepPrimAPI_MakeBox(1,1,1);
+  }
+  return aSolid;
 }
 
 //=======================================================================
@@ -379,11 +414,11 @@ SMESH_Hypothesis::Hypothesis_Status
     // check concurent hypotheses on ansestors
     if (ret < SMESH_Hypothesis::HYP_CONCURENT && !isGlobalHyp )
     {
-      const map < int, SMESH_subMesh * >& smMap = subMesh->DependsOn();
-      map < int, SMESH_subMesh * >::const_iterator smIt = smMap.begin();
-      for ( ; smIt != smMap.end(); smIt++ ) {
-        if ( smIt->second->IsApplicableHypotesis( anHyp )) {
-          ret2 = smIt->second->CheckConcurentHypothesis( anHyp->GetType() );
+      SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
+      while ( smIt->more() ) {
+        SMESH_subMesh* sm = smIt->next();
+        if ( sm->IsApplicableHypotesis( anHyp )) {
+          ret2 = sm->CheckConcurentHypothesis( anHyp->GetType() );
           if (ret2 > ret) {
             ret = ret2;
             break;
@@ -469,11 +504,11 @@ SMESH_Hypothesis::Hypothesis_Status
     // check concurent hypotheses on ansestors
     if (ret < SMESH_Hypothesis::HYP_CONCURENT && !IsMainShape( aSubShape ) )
     {
-      const map < int, SMESH_subMesh * >& smMap = subMesh->DependsOn();
-      map < int, SMESH_subMesh * >::const_iterator smIt = smMap.begin();
-      for ( ; smIt != smMap.end(); smIt++ ) {
-        if ( smIt->second->IsApplicableHypotesis( anHyp )) {
-          ret2 = smIt->second->CheckConcurentHypothesis( anHyp->GetType() );
+      SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
+      while ( smIt->more() ) {
+        SMESH_subMesh* sm = smIt->next();
+        if ( sm->IsApplicableHypotesis( anHyp )) {
+          ret2 = sm->CheckConcurentHypothesis( anHyp->GetType() );
           if (ret2 > ret) {
             ret = ret2;
             break;
@@ -494,17 +529,6 @@ SMESH_Hypothesis::Hypothesis_Status
  */
 //=============================================================================
 
-SMESHDS_Mesh * SMESH_Mesh::GetMeshDS()
-{
-  return _myMeshDS;
-}
-
-//=============================================================================
-/*!
- * 
- */
-//=============================================================================
-
 const list<const SMESHDS_Hypothesis*>&
 SMESH_Mesh::GetHypothesisList(const TopoDS_Shape & aSubShape) const
   throw(SALOME_Exception)
@@ -649,29 +673,6 @@ void SMESH_Mesh::ClearLog() throw(SALOME_Exception)
   _myMeshDS->GetScript()->Clear();
 }
 
-//=============================================================================
-/*!
- * 
- */
-//=============================================================================
-
-int SMESH_Mesh::GetId()
-{
-  if(MYDEBUG) MESSAGE("SMESH_Mesh::GetId");
-  return _id;
-}
-
-//=============================================================================
-/*!
- * 
- */
-//=============================================================================
-
-SMESH_Gen *SMESH_Mesh::GetGen()
-{
-  return _gen;
-}
-
 //=============================================================================
 /*!
  * Get or Create the SMESH_subMesh object implementation
@@ -814,12 +815,10 @@ SMESH_Mesh::GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp)
 //purpose  : Say all submeshes using theChangedHyp that it has been modified
 //=======================================================================
 
-void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* theChangedHyp)
+void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* hyp)
 {
   Unexpect aCatch(SalomeException);
 
-  const SMESH_Hypothesis* hyp = cSMESH_Hyp(theChangedHyp);
-
   const SMESH_Algo *foundAlgo = 0;
   SMESH_HypoFilter algoKind( SMESH_HypoFilter::IsAlgo() );
   SMESH_HypoFilter compatibleHypoKind;
@@ -857,7 +856,8 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* t
         if ( GetHypotheses( aSubShape, compatibleHypoKind, usedHyps, true ) &&
              find( usedHyps.begin(), usedHyps.end(), hyp ) != usedHyps.end() )
         {
-          aSubMesh->ComputeStateEngine(SMESH_subMesh::MODIF_HYP);
+          aSubMesh->AlgoStateEngine(SMESH_subMesh::MODIF_HYP,
+                                    const_cast< SMESH_Hypothesis*>( hyp ));
 
           if ( algo->GetDim() == 1 && IsPropagationHypothesis( aSubShape ))
             CleanMeshOnPropagationChain( aSubShape );
index 35bd13d506d37437e38541e17558adc3e0d86581..d9538fe86d4ee26719b3e2fbcd0b9916c560dd31 100644 (file)
@@ -72,25 +72,40 @@ class SMESH_Group;
 class TopTools_ListOfShape;
 class SMESH_subMesh;
 class SMESH_HypoFilter;
+class TopoDS_Solid;
 
-//typedef NMTTools_IndexedDataMapOfShapeIndexedMapOfShape IndexedMapOfChain;
 typedef SMESH_IndexedDataMapOfShapeIndexedMapOfShape IndexedMapOfChain;
 
 class SMESH_EXPORT SMESH_Mesh
 {
-  SMESH_Mesh();
-  SMESH_Mesh(const SMESH_Mesh&);
 public:
-  SMESH_Mesh(int theLocalId, 
-            int theStudyId, 
-            SMESH_Gen* theGen,
-            bool theIsEmbeddedMode,
+  SMESH_Mesh(int               theLocalId, 
+            int               theStudyId, 
+            SMESH_Gen*        theGen,
+            bool              theIsEmbeddedMode,
             SMESHDS_Document* theDocument);
   
   virtual ~SMESH_Mesh();
   
+  /*!
+   * \brief Set geometry to be meshed
+   */
   void ShapeToMesh(const TopoDS_Shape & aShape);
-  
+  /*!
+   * \brief Return geometry to be meshed. (It may be a PseudoShape()!)
+   */
+  TopoDS_Shape GetShapeToMesh() const;
+  /*!
+   * \brief Return true if there is a geometry to be meshed, not PseudoShape()
+   */
+  bool HasShapeToMesh() const { return _isShapeToMesh; }
+  /*!
+   * \brief Return a solid which is returned by GetShapeToMesh() if
+   *        a real geometry to be meshed was not set
+   */
+  static const TopoDS_Solid& PseudoShape();
+
+
   int UNVToMesh(const char* theFileName);
   /*!
    * consult DriverMED_R_SMESHDS_Mesh::ReadStatus for returned value
@@ -124,11 +139,11 @@ public:
   
   void ClearLog() throw(SALOME_Exception);
   
-  int GetId();
+  int GetId()                { return _id; }
   
-  SMESHDS_Mesh * GetMeshDS();
+  SMESHDS_Mesh * GetMeshDS() { return _myMeshDS; }
   
-  SMESH_Gen *GetGen();
+  SMESH_Gen *GetGen()        { return _gen; }
   
   SMESH_subMesh *GetSubMesh(const TopoDS_Shape & aSubShape)
     throw(SALOME_Exception);
@@ -257,7 +272,7 @@ private:
   void CleanMeshOnPropagationChain(const TopoDS_Shape& theMainEdge);
   //
   
-private:
+protected:
   int                        _id;           // id given by creator (unique within the creator instance)
   int                        _studyId;
   int                        _idDoc;        // id given by SMESHDS_Document
@@ -273,6 +288,10 @@ private:
   TopTools_IndexedDataMapOfShapeListOfShape _mapAncestors;
 
   IndexedMapOfChain _mapPropagationChains; // Propagation hypothesis management
+
+protected:
+  SMESH_Mesh() {};
+  SMESH_Mesh(const SMESH_Mesh&) {};
 };
 
 #endif
index 3ace850f359b990791c4f94da9dd860d5f23f8d1..5ff5f6d17e89d721ad74302206086a462020963a 100644 (file)
@@ -42,6 +42,7 @@
 #include "SMESH_subMesh.hxx"
 #include "SMESH_ControlsDef.hxx"
 #include "SMESH_MesherHelper.hxx"
+#include "SMESH_OctreeNode.hxx"
 
 #include "utilities.h"
 
@@ -69,6 +70,9 @@
 #include <TopoDS_Face.hxx>
 
 #include <map>
+#include <set>
+
+#define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
 
 using namespace std;
 using namespace SMESH::Controls;
@@ -82,8 +86,23 @@ typedef TNodeOfNodeListMap::iterator                                 TNodeOfNode
 typedef map<const SMDS_MeshElement*, vector<TNodeOfNodeListMapItr> > TElemOfVecOfNnlmiMap;
 //typedef map<const SMDS_MeshElement*, vector<TNodeOfNodeVecMapItr> >  TElemOfVecOfMapNodesMap;
 
+struct TNodeXYZ : public gp_XYZ {
+  TNodeXYZ( const SMDS_MeshNode* n ):gp_XYZ( n->X(), n->Y(), n->Z() ) {}
+};
+
 typedef pair< const SMDS_MeshNode*, const SMDS_MeshNode* > NLink;
 
+/*!
+ * \brief A sorted pair of nodes
+ */
+struct TLink: public NLink
+{
+  TLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2 ):NLink( n1, n2 )
+  { if ( n1->GetID() < n2->GetID() ) std::swap( first, second ); }
+  TLink(const NLink& link ):NLink( link )
+  { if ( first->GetID() < second->GetID() ) std::swap( first, second ); }
+};
+
 //=======================================================================
 //function : SMESH_MeshEditor
 //purpose  :
@@ -94,6 +113,137 @@ myMesh( theMesh )
 {
 }
 
+//=======================================================================
+/*!
+ * \brief Add element
+ */
+//=======================================================================
+
+SMDS_MeshElement*
+SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
+                             const SMDSAbs_ElementType            type,
+                             const bool                           isPoly,
+                             const int                            ID)
+{
+  SMDS_MeshElement* e = 0;
+  int nbnode = node.size();
+  SMESHDS_Mesh* mesh = GetMeshDS();
+  switch ( type ) {
+  case SMDSAbs_Edge:
+    if ( nbnode == 2 )
+      if ( ID ) 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);
+      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);
+        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);
+        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],
+                                          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],
+                                          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);
+      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);
+        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],
+                                            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],
+                                            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],
+                                            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],
+                                            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],
+                                            node[4], node[5], node[6], node[7],
+                                            node[8], node[9], node[10],node[11],
+                                            node[12],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], node[10],node[11],
+                                            node[12] );
+      else if (nbnode == 15)
+        if ( ID ) 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);
+        else      e = mesh->AddVolume      (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] );
+      else if (nbnode == 20)
+        if ( ID ) 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],
+                                            node[16],node[17],node[18],node[19],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], node[10],node[11],
+                                            node[12],node[13],node[14],node[15],
+                                            node[16],node[17],node[18],node[19] );
+    }
+  }
+  return e;
+}
+
+//=======================================================================
+/*!
+ * \brief Add element
+ */
+//=======================================================================
+
+SMDS_MeshElement* SMESH_MeshEditor::AddElement(const vector<int> &       nodeIDs,
+                                               const SMDSAbs_ElementType type,
+                                               const bool                isPoly,
+                                               const int                 ID)
+{
+  vector<const SMDS_MeshNode*> nodes;
+  nodes.reserve( nodeIDs.size() );
+  vector<int>::const_iterator id = nodeIDs.begin();
+  while ( id != nodeIDs.end() ) {
+    if ( const SMDS_MeshNode* node = GetMeshDS()->FindNode( *id++ ))
+      nodes.push_back( node );
+    else
+      return 0;
+  }
+  return AddElement( nodes, type, isPoly, ID );
+}
+
 //=======================================================================
 //function : Remove
 //purpose  : Remove a node or an element.
@@ -216,19 +366,17 @@ int SMESH_MeshEditor::FindShape (const SMDS_MeshElement * theElem)
 
 //=======================================================================
 //function : IsMedium
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 bool SMESH_MeshEditor::IsMedium(const SMDS_MeshNode*      node,
                                 const SMDSAbs_ElementType typeToCheck)
 {
   bool isMedium = false;
-  SMDS_ElemIteratorPtr it = node->GetInverseElementIterator();
-  while (it->more()) {
+  SMDS_ElemIteratorPtr it = node->GetInverseElementIterator(typeToCheck);
+  while (it->more() && !isMedium ) {
     const SMDS_MeshElement* elem = it->next();
     isMedium = elem->IsMediumNode(node);
-    if ( typeToCheck == SMDSAbs_All || elem->GetType() == typeToCheck )
-      break;
   }
   return isMedium;
 }
@@ -301,7 +449,7 @@ static bool GetNodesFromTwoTria(const SMDS_MeshElement * theTria1,
     ShiftNodesQuadTria(N2);
   }
   // now we receive following N1 and N2 (using numeration as above image)
-  // tria1 : (1 2 4 5 9 7)  and  tria2 : (3 4 2 8 9 6) 
+  // tria1 : (1 2 4 5 9 7)  and  tria2 : (3 4 2 8 9 6)
   // i.e. first nodes from both arrays determ new diagonal
   return true;
 }
@@ -338,7 +486,7 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1,
     SMDS_ElemIteratorPtr it = theTria1->nodesIterator();
     while ( it->more() ) {
       aNodes[ i ] = static_cast<const SMDS_MeshNode*>( it->next() );
-      
+
       if ( i > 2 ) // theTria2
         // find same node of theTria1
         for ( int j = 0; j < 3; j++ )
@@ -357,7 +505,7 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1,
       if ( i == 6 && it->more() )
         return false; // theTria2 is not a triangle
     }
-    
+
     // find indices of 1,2 and of A,B in theTria1
     int iA = 0, iB = 0, i1 = 0, i2 = 0;
     for ( i = 0; i < 6; i++ ) {
@@ -378,14 +526,14 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1,
     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
@@ -399,19 +547,19 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshElement * theTria1,
   //       5
   //  1 +--+--+ 2  theTria1: (1 2 4 5 9 7) or (2 4 1 9 7 5) or (4 1 2 7 5 9)
   //    |    /|    theTria2: (2 3 4 6 8 9) or (3 4 2 8 9 6) or (4 2 3 9 6 8)
-  //    |   / |  
+  //    |   / |
   //  7 +  +  + 6
   //    | /9  |
   //    |/    |
-  //  4 +--+--+ 3  
+  //  4 +--+--+ 3
   //       8
-  
+
   const SMDS_MeshNode* N1 [6];
   const SMDS_MeshNode* N2 [6];
   if(!GetNodesFromTwoTria(theTria1,theTria2,N1,N2))
     return false;
   // now we receive following N1 and N2 (using numeration as above image)
-  // tria1 : (1 2 4 5 9 7)  and  tria2 : (3 4 2 8 9 6) 
+  // tria1 : (1 2 4 5 9 7)  and  tria2 : (3 4 2 8 9 6)
   // i.e. first nodes from both arrays determ new diagonal
 
   const SMDS_MeshNode* N1new [6];
@@ -450,17 +598,16 @@ static bool findTriangles(const SMDS_MeshNode *    theNode1,
   theTria1 = theTria2 = 0;
 
   set< const SMDS_MeshElement* > emap;
-  SMDS_ElemIteratorPtr it = theNode1->GetInverseElementIterator();
+  SMDS_ElemIteratorPtr it = theNode1->GetInverseElementIterator(SMDSAbs_Face);
   while (it->more()) {
     const SMDS_MeshElement* elem = it->next();
-    if ( elem->GetType() == SMDSAbs_Face && elem->NbNodes() == 3 )
+    if ( elem->NbNodes() == 3 )
       emap.insert( elem );
   }
-  it = theNode2->GetInverseElementIterator();
+  it = theNode2->GetInverseElementIterator(SMDSAbs_Face);
   while (it->more()) {
     const SMDS_MeshElement* elem = it->next();
-    if ( elem->GetType() == SMDSAbs_Face &&
-         emap.find( elem ) != emap.end() )
+    if ( emap.find( elem ) != emap.end() )
       if ( theTria1 ) {
         // theTria1 must be element with minimum ID
         if( theTria1->GetID() < elem->GetID() ) {
@@ -530,7 +677,7 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshNode * theNode1,
       else if ( aNodes2[ i ] != theNode1 )
         i2 = i;  // node 2
     }
-    
+
     // nodes 1 and 2 should not be the same
     if ( aNodes1[ i1 ] == aNodes2[ i2 ] )
       return false;
@@ -546,7 +693,7 @@ bool SMESH_MeshEditor::InverseDiag (const SMDS_MeshNode * theNode1,
     GetMeshDS()->ChangeElementNodes( tr2, aNodes2, 3 );
 
     //MESSAGE( tr1 << tr2 );
-    
+
     return true;
   }
 
@@ -579,9 +726,8 @@ bool getQuadrangleNodes(const SMDS_MeshNode *    theQuadNodes [],
   const SMDS_MeshNode* n4 = 0;
   SMDS_ElemIteratorPtr it = tr2->nodesIterator();
   int i=0;
-  //while ( !n4 && it->more() ) {
   while ( !n4 && i<3 ) {
-    const SMDS_MeshNode * n = static_cast<const SMDS_MeshNode*>( it->next() );
+    const SMDS_MeshNode * n = cast2Node( it->next() );
     i++;
     bool isDiag = ( n == theNode1 || n == theNode2 );
     if ( !isDiag )
@@ -591,9 +737,8 @@ bool getQuadrangleNodes(const SMDS_MeshNode *    theQuadNodes [],
   int iNode = 0, iFirstDiag = -1;
   it = tr1->nodesIterator();
   i=0;
-  //while ( it->more() ) {
   while ( i<3 ) {
-    const SMDS_MeshNode * n = static_cast<const SMDS_MeshNode*>( it->next() );
+    const SMDS_MeshNode * n = cast2Node( it->next() );
     i++;
     bool isDiag = ( n == theNode1 || n == theNode2 );
     if ( isDiag ) {
@@ -664,19 +809,19 @@ bool SMESH_MeshEditor::DeleteDiag (const SMDS_MeshNode * theNode1,
   //       5
   //  1 +--+--+ 2  tr1: (1 2 4 5 9 7) or (2 4 1 9 7 5) or (4 1 2 7 5 9)
   //    |    /|    tr2: (2 3 4 6 8 9) or (3 4 2 8 9 6) or (4 2 3 9 6 8)
-  //    |   / |  
+  //    |   / |
   //  7 +  +  + 6
   //    | /9  |
   //    |/    |
-  //  4 +--+--+ 3  
+  //  4 +--+--+ 3
   //       8
-  
+
   const SMDS_MeshNode* N1 [6];
   const SMDS_MeshNode* N2 [6];
   if(!GetNodesFromTwoTria(tr1,tr2,N1,N2))
     return false;
   // now we receive following N1 and N2 (using numeration as above image)
-  // tria1 : (1 2 4 5 9 7)  and  tria2 : (3 4 2 8 9 6) 
+  // tria1 : (1 2 4 5 9 7)  and  tria2 : (3 4 2 8 9 6)
   // i.e. first nodes from both arrays determ new diagonal
 
   const SMDS_MeshNode* aNodes[8];
@@ -767,13 +912,13 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem)
       for (int iface = 1; iface <= nbFaces; iface++) {
         int inode, nbFaceNodes = aPolyedre->NbFaceNodes(iface);
         quantities[iface - 1] = nbFaceNodes;
-        
+
         for (inode = nbFaceNodes; inode >= 1; inode--) {
           const SMDS_MeshNode* curNode = aPolyedre->GetFaceNode(iface, inode);
           poly_nodes.push_back(curNode);
         }
       }
-      
+
       return GetMeshDS()->ChangePolyhedronNodes( theElem, poly_nodes, quantities );
 
     }
@@ -812,7 +957,7 @@ static double getBadRate (const SMDS_MeshElement*               theElem,
 //           theCrit is used to select a diagonal to cut
 //=======================================================================
 
-bool SMESH_MeshEditor::QuadToTri (map<int,const SMDS_MeshElement*> &   theElems,
+bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet &                   theElems,
                                   SMESH::Controls::NumericalFunctorPtr theCrit)
 {
   myLastCreatedElems.Clear();
@@ -828,9 +973,9 @@ bool SMESH_MeshEditor::QuadToTri (map<int,const SMDS_MeshElement*> &   theElems,
   Handle(Geom_Surface) surface;
   SMESH_MesherHelper   helper( *GetMesh() );
 
-  map<int, const SMDS_MeshElement * >::iterator itElem;
+  TIDSortedElemSet::iterator itElem;
   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
-    const SMDS_MeshElement* elem = (*itElem).second;
+    const SMDS_MeshElement* elem = *itElem;
     if ( !elem || elem->GetType() != SMDSAbs_Face )
       continue;
     if ( elem->NbNodes() != ( elem->IsQuadratic() ? 8 : 4 ))
@@ -899,7 +1044,7 @@ bool SMESH_MeshEditor::QuadToTri (map<int,const SMDS_MeshElement*> &   theElems,
              aNodes[ i-1 ]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE )
         {
           inFaceNode = aNodes[ i-1 ];
-        } 
+        }
       }
       // find middle point for (0,1,2,3)
       // and create a node in this point;
@@ -1030,10 +1175,10 @@ void SMESH_MeshEditor::RemoveElemFromGroups (const SMDS_MeshElement* removeelem,
                                              SMESHDS_Mesh *          aMesh)
 {
   const set<SMESHDS_GroupBase*>& groups = aMesh->GetGroups();
-  if (!groups.empty()) 
+  if (!groups.empty())
   {
     set<SMESHDS_GroupBase*>::const_iterator GrIt = groups.begin();
-    for (; GrIt != groups.end(); GrIt++) 
+    for (; GrIt != groups.end(); GrIt++)
     {
       SMESHDS_Group* grp = dynamic_cast<SMESHDS_Group*>(*GrIt);
       if (!grp || grp->IsEmpty()) continue;
@@ -1049,8 +1194,8 @@ void SMESH_MeshEditor::RemoveElemFromGroups (const SMDS_MeshElement* removeelem,
 //           theCrit is used to select a diagonal to cut
 //=======================================================================
 
-bool SMESH_MeshEditor::QuadToTri (std::map<int,const SMDS_MeshElement*> & theElems,
-                                  const bool                              the13Diag)
+bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
+                                  const bool         the13Diag)
 {
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
@@ -1062,9 +1207,9 @@ bool SMESH_MeshEditor::QuadToTri (std::map<int,const SMDS_MeshElement*> & theEle
   Handle(Geom_Surface) surface;
   SMESH_MesherHelper   helper( *GetMesh() );
 
-  map<int, const SMDS_MeshElement * >::iterator itElem;
+  TIDSortedElemSet::iterator itElem;
   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
-    const SMDS_MeshElement* elem = (*itElem).second;
+    const SMDS_MeshElement* elem = *itElem;
     if ( !elem || elem->GetType() != SMDSAbs_Face )
       continue;
     bool isquad = elem->NbNodes()==4 || elem->NbNodes()==8;
@@ -1124,7 +1269,7 @@ bool SMESH_MeshEditor::QuadToTri (std::map<int,const SMDS_MeshElement*> & theEle
              aNodes[ i-1 ]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE )
         {
           inFaceNode = aNodes[ i-1 ];
-        } 
+        }
       }
 
       // find middle point for (0,1,2,3)
@@ -1284,7 +1429,7 @@ class LinkID_Gen {
 //           fusion is still performed.
 //=======================================================================
 
-bool SMESH_MeshEditor::TriToQuad (map<int,const SMDS_MeshElement*> &       theElems,
+bool SMESH_MeshEditor::TriToQuad (TIDSortedElemSet &                   theElems,
                                   SMESH::Controls::NumericalFunctorPtr theCrit,
                                   const double                         theMaxAngle)
 {
@@ -1297,27 +1442,19 @@ bool SMESH_MeshEditor::TriToQuad (map<int,const SMDS_MeshElement*> &       theEl
     return false;
 
   SMESHDS_Mesh * aMesh = GetMeshDS();
-  //LinkID_Gen aLinkID_Gen( aMesh );
 
   // Prepare data for algo: build
   // 1. map of elements with their linkIDs
   // 2. map of linkIDs with their elements
 
-  //map< long, list< const SMDS_MeshElement* > > mapLi_listEl;
-  //map< long, list< const SMDS_MeshElement* > >::iterator itLE;
-  //map< const SMDS_MeshElement*, set< long > >  mapEl_setLi;
-  //map< const SMDS_MeshElement*, set< long > >::iterator itEL;
-
-  map< NLink, list< const SMDS_MeshElement* > > mapLi_listEl;
-  map< NLink, list< const SMDS_MeshElement* > >::iterator itLE;
-  map< const SMDS_MeshElement*, set< NLink > >  mapEl_setLi;
-  map< const SMDS_MeshElement*, set< NLink > >::iterator itEL;
+  map< TLink, list< const SMDS_MeshElement* > > mapLi_listEl;
+  map< TLink, list< const SMDS_MeshElement* > >::iterator itLE;
+  map< const SMDS_MeshElement*, set< TLink > >  mapEl_setLi;
+  map< const SMDS_MeshElement*, set< TLink > >::iterator itEL;
 
-  map<int,const SMDS_MeshElement*>::iterator itElem;
+  TIDSortedElemSet::iterator itElem;
   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
-    const SMDS_MeshElement* elem = (*itElem).second;
-    //if ( !elem || elem->NbNodes() != 3 )
-    //  continue;
+    const SMDS_MeshElement* elem = *itElem;
     if(!elem || elem->GetType() != SMDSAbs_Face ) continue;
     bool IsTria = elem->NbNodes()==3 || (elem->NbNodes()==6 && elem->IsQuadratic());
     if(!IsTria) continue;
@@ -1326,19 +1463,14 @@ bool SMESH_MeshEditor::TriToQuad (map<int,const SMDS_MeshElement*> &       theEl
     const SMDS_MeshNode* aNodes [4];
     SMDS_ElemIteratorPtr itN = elem->nodesIterator();
     int i = 0;
-    //while ( itN->more() )
     while ( i<3 )
-      aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
-    ASSERT( i == 3 );
+      aNodes[ i++ ] = cast2Node( itN->next() );
     aNodes[ 3 ] = aNodes[ 0 ];
 
     // fill maps
     for ( i = 0; i < 3; i++ ) {
-      //long linkID = aLinkID_Gen.GetLinkID( aNodes[ i ], aNodes[ i+1 ] );
-      NLink link(( aNodes[i] < aNodes[i+1] ? aNodes[i] : aNodes[i+1] ),
-                 ( aNodes[i] < aNodes[i+1] ? aNodes[i+1] : aNodes[i] ));
+      TLink link( aNodes[i], aNodes[i+1] );
       // check if elements sharing a link can be fused
-      //itLE = mapLi_listEl.find( linkID );
       itLE = mapLi_listEl.find( link );
       if ( itLE != mapLi_listEl.end() ) {
         if ((*itLE).second.size() > 1 ) // consider only 2 elems adjacent by a link
@@ -1351,10 +1483,8 @@ bool SMESH_MeshEditor::TriToQuad (map<int,const SMDS_MeshElement*> &       theEl
         (*itLE).second.push_back( elem );
       }
       else {
-        //mapLi_listEl[ linkID ].push_back( elem );
         mapLi_listEl[ link ].push_back( elem );
       }
-      //mapEl_setLi [ elem ].insert( linkID );
       mapEl_setLi [ elem ].insert( link );
     }
   }
@@ -1365,8 +1495,7 @@ bool SMESH_MeshEditor::TriToQuad (map<int,const SMDS_MeshElement*> &       theEl
     int nbElems = (*itLE).second.size();
     if ( nbElems < 2  ) {
       const SMDS_MeshElement* elem = (*itLE).second.front();
-      //long link = (*itLE).first;
-      NLink link = (*itLE).first;
+      TLink link = (*itLE).first;
       mapEl_setLi[ elem ].erase( link );
       if ( mapEl_setLi[ elem ].empty() )
         mapEl_setLi.erase( elem );
@@ -1378,7 +1507,6 @@ bool SMESH_MeshEditor::TriToQuad (map<int,const SMDS_MeshElement*> &       theEl
   while ( ! mapEl_setLi.empty() ) {
     // Look for the start element:
     // the element having the least nb of shared links
-
     const SMDS_MeshElement* startElem = 0;
     int minNbLinks = 4;
     for ( itEL = mapEl_setLi.begin(); itEL != mapEl_setLi.end(); itEL++ ) {
@@ -1393,13 +1521,11 @@ bool SMESH_MeshEditor::TriToQuad (map<int,const SMDS_MeshElement*> &       theEl
 
     // search elements to fuse starting from startElem or links of elements
     // fused earlyer - startLinks
-    //list< long > startLinks;
-    list< NLink > startLinks;
+    list< TLink > startLinks;
     while ( startElem || !startLinks.empty() ) {
       while ( !startElem && !startLinks.empty() ) {
         // Get an element to start, by a link
-        //long linkId = startLinks.front();
-        NLink linkId = startLinks.front();
+        TLink linkId = startLinks.front();
         startLinks.pop_front();
         itLE = mapLi_listEl.find( linkId );
         if ( itLE != mapLi_listEl.end() ) {
@@ -1415,19 +1541,16 @@ bool SMESH_MeshEditor::TriToQuad (map<int,const SMDS_MeshElement*> &       theEl
       if ( startElem ) {
         // Get candidates to be fused
         const SMDS_MeshElement *tr1 = startElem, *tr2 = 0, *tr3 = 0;
-        //long link12, link13;
-        NLink link12, link13;
+        const TLink *link12, *link13;
         startElem = 0;
         ASSERT( mapEl_setLi.find( tr1 ) != mapEl_setLi.end() );
-        //set< long >& setLi = mapEl_setLi[ tr1 ];
-        set< NLink >& setLi = mapEl_setLi[ tr1 ];
+        set< TLink >& setLi = mapEl_setLi[ tr1 ];
         ASSERT( !setLi.empty() );
-        //set< long >::iterator itLi;
-        set< NLink >::iterator itLi;
-        for ( itLi = setLi.begin(); itLi != setLi.end(); itLi++ ) {
-          //long linkID = (*itLi);
-          NLink linkID = (*itLi);
-          itLE = mapLi_listEl.find( linkID );
+        set< TLink >::iterator itLi;
+        for ( itLi = setLi.begin(); itLi != setLi.end(); itLi++ )
+        {
+          const TLink & link = (*itLi);
+          itLE = mapLi_listEl.find( link );
           if ( itLE == mapLi_listEl.end() )
             continue;
 
@@ -1439,50 +1562,36 @@ bool SMESH_MeshEditor::TriToQuad (map<int,const SMDS_MeshElement*> &       theEl
             continue;
           if ( tr2 ) {
             tr3 = elem;
-            link13 = linkID;
+            link13 = &link;
           }
           else {
             tr2 = elem;
-            link12 = linkID;
+            link12 = &link;
           }
 
           // add other links of elem to list of links to re-start from
-          //set< long >& links = mapEl_setLi[ elem ];
-          //set< long >::iterator it;
-          set< NLink >& links = mapEl_setLi[ elem ];
-          set< NLink >::iterator it;
+          set< TLink >& links = mapEl_setLi[ elem ];
+          set< TLink >::iterator it;
           for ( it = links.begin(); it != links.end(); it++ ) {
-            //long linkID2 = (*it);
-            NLink linkID2 = (*it);
-            if ( linkID2 != linkID )
-              startLinks.push_back( linkID2 );
+            const TLink& link2 = (*it);
+            if ( link2 != link )
+              startLinks.push_back( link2 );
           }
         }
 
         // Get nodes of possible quadrangles
         const SMDS_MeshNode *n12 [4], *n13 [4];
         bool Ok12 = false, Ok13 = false;
-        //const SMDS_MeshNode *linkNode1, *linkNode2;
         const SMDS_MeshNode *linkNode1, *linkNode2;
         if(tr2) {
-          //const SMDS_MeshNode *linkNode1 = link12.first;
-          //const SMDS_MeshNode *linkNode2 = link12.second;
-          linkNode1 = link12.first;
-          linkNode2 = link12.second;
-          //if ( tr2 &&
-          //     aLinkID_Gen.GetNodes( link12, linkNode1, linkNode2 ) &&
-          //     getQuadrangleNodes( n12, linkNode1, linkNode2, tr1, tr2 ))
-          //  Ok12 = true;
+          linkNode1 = link12->first;
+          linkNode2 = link12->second;
           if ( tr2 && getQuadrangleNodes( n12, linkNode1, linkNode2, tr1, tr2 ))
             Ok12 = true;
         }
         if(tr3) {
-          linkNode1 = link13.first;
-          linkNode2 = link13.second;
-          //if ( tr3 &&
-          //     aLinkID_Gen.GetNodes( link13, linkNode1, linkNode2 ) &&
-          //     getQuadrangleNodes( n13, linkNode1, linkNode2, tr1, tr3 ))
-          //  Ok13 = true;
+          linkNode1 = link13->first;
+          linkNode2 = link13->second;
           if ( tr3 && getQuadrangleNodes( n13, linkNode1, linkNode2, tr1, tr3 ))
             Ok13 = true;
         }
@@ -1504,7 +1613,7 @@ bool SMESH_MeshEditor::TriToQuad (map<int,const SMDS_MeshElement*> &       theEl
         mapEl_setLi.erase( tr1 );
         if ( Ok12 ) {
           mapEl_setLi.erase( tr2 );
-          mapLi_listEl.erase( link12 );
+          mapLi_listEl.erase( *link12 );
           if(tr1->NbNodes()==3) {
             if( tr1->GetID() < tr2->GetID() ) {
               aMesh->ChangeElementNodes( tr1, n12, 4 );
@@ -1522,7 +1631,7 @@ bool SMESH_MeshEditor::TriToQuad (map<int,const SMDS_MeshElement*> &       theEl
             const SMDS_MeshNode* N2 [6];
             GetNodesFromTwoTria(tr1,tr2,N1,N2);
             // now we receive following N1 and N2 (using numeration as above image)
-            // tria1 : (1 2 4 5 9 7)  and  tria2 : (3 4 2 8 9 6) 
+            // tria1 : (1 2 4 5 9 7)  and  tria2 : (3 4 2 8 9 6)
             // i.e. first nodes from both arrays determ new diagonal
             const SMDS_MeshNode* aNodes[8];
             aNodes[0] = N1[0];
@@ -1549,7 +1658,7 @@ bool SMESH_MeshEditor::TriToQuad (map<int,const SMDS_MeshElement*> &       theEl
         }
         else if ( Ok13 ) {
           mapEl_setLi.erase( tr3 );
-          mapLi_listEl.erase( link13 );
+          mapLi_listEl.erase( *link13 );
           if(tr1->NbNodes()==3) {
             if( tr1->GetID() < tr2->GetID() ) {
               aMesh->ChangeElementNodes( tr1, n13, 4 );
@@ -1567,7 +1676,7 @@ bool SMESH_MeshEditor::TriToQuad (map<int,const SMDS_MeshElement*> &       theEl
             const SMDS_MeshNode* N2 [6];
             GetNodesFromTwoTria(tr1,tr3,N1,N2);
             // now we receive following N1 and N2 (using numeration as above image)
-            // tria1 : (1 2 4 5 9 7)  and  tria2 : (3 4 2 8 9 6) 
+            // tria1 : (1 2 4 5 9 7)  and  tria2 : (3 4 2 8 9 6)
             // i.e. first nodes from both arrays determ new diagonal
             const SMDS_MeshNode* aNodes[8];
             aNodes[0] = N1[0];
@@ -1884,6 +1993,55 @@ bool SMESH_MeshEditor::SortHexaNodes (const SMDS_Mesh * theMesh,
   return true;
 }*/
 
+//================================================================================
+/*!
+ * \brief Return nodes linked to the given one
+  * \param theNode - the node
+  * \param linkedNodes - the found nodes
+  * \param type - the type of elements to check
+  *
+  * Medium nodes are ignored
+ */
+//================================================================================
+
+void SMESH_MeshEditor::GetLinkedNodes( const SMDS_MeshNode* theNode,
+                                       TIDSortedElemSet &   linkedNodes,
+                                       SMDSAbs_ElementType  type )
+{
+  SMDS_ElemIteratorPtr elemIt = theNode->GetInverseElementIterator(type);
+  while ( elemIt->more() )
+  {
+    const SMDS_MeshElement* elem = elemIt->next();
+    SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
+    if ( elem->GetType() == SMDSAbs_Volume )
+    {
+      SMDS_VolumeTool vol( elem );
+      while ( nodeIt->more() ) {
+        const SMDS_MeshNode* n = cast2Node( nodeIt->next() );
+        if ( theNode != n && vol.IsLinked( theNode, n ))
+          linkedNodes.insert( n );
+      }
+    }
+    else
+    {
+      for ( int i = 0; nodeIt->more(); ++i ) {
+        const SMDS_MeshNode* n = cast2Node( nodeIt->next() );
+        if ( n == theNode ) {
+          int iBefore = i - 1;
+          int iAfter  = i + 1;
+          if ( elem->IsQuadratic() ) {
+            int nb = elem->NbNodes() / 2;
+            iAfter  = SMESH_MesherHelper::WrapIndex( iAfter, nb );
+            iBefore = SMESH_MesherHelper::WrapIndex( iBefore, nb );
+          }
+          linkedNodes.insert( elem->GetNode( iAfter ));
+          linkedNodes.insert( elem->GetNode( iBefore ));
+        }
+      }
+    }
+  }
+}
+
 //=======================================================================
 //function : laplacianSmooth
 //purpose  : pulls theNode toward the center of surrounding nodes directly
@@ -1896,39 +2054,15 @@ void laplacianSmooth(const SMDS_MeshNode*                 theNode,
 {
   // find surrounding nodes
 
-  set< const SMDS_MeshNode* > nodeSet;
-  SMDS_ElemIteratorPtr elemIt = theNode->GetInverseElementIterator();
-  while ( elemIt->more() )
-  {
-    const SMDS_MeshElement* elem = elemIt->next();
-    if ( elem->GetType() != SMDSAbs_Face )
-      continue;
-
-    for ( int i = 0; i < elem->NbNodes(); ++i ) {
-      if ( elem->GetNode( i ) == theNode ) {
-        // add linked nodes
-        int iBefore = i - 1;
-        int iAfter = i + 1;
-        if ( elem->IsQuadratic() ) {
-          int nbCorners = elem->NbNodes() / 2;
-          if ( iAfter >= nbCorners )
-            iAfter = 0; // elem->GetNode() wraps index
-          if ( iBefore == -1 )
-            iBefore = nbCorners - 1;
-        }
-        nodeSet.insert( elem->GetNode( iAfter ));
-        nodeSet.insert( elem->GetNode( iBefore ));
-        break;
-      }
-    }
-  }
+  TIDSortedElemSet nodeSet;
+  SMESH_MeshEditor::GetLinkedNodes( theNode, nodeSet, SMDSAbs_Face );
 
   // compute new coodrs
 
   double coord[] = { 0., 0., 0. };
-  set< const SMDS_MeshNode* >::iterator nodeSetIt = nodeSet.begin();
+  TIDSortedElemSet::iterator nodeSetIt = nodeSet.begin();
   for ( ; nodeSetIt != nodeSet.end(); nodeSetIt++ ) {
-    const SMDS_MeshNode* node = (*nodeSetIt);
+    const SMDS_MeshNode* node = cast2Node(*nodeSetIt);
     if ( theSurface.IsNull() ) { // smooth in 3D
       coord[0] += node->X();
       coord[1] += node->Y();
@@ -1980,12 +2114,10 @@ void centroidalSmooth(const SMDS_MeshNode*                 theNode,
 
   // compute new XYZ
 
-  SMDS_ElemIteratorPtr elemIt = theNode->GetInverseElementIterator();
+  SMDS_ElemIteratorPtr elemIt = theNode->GetInverseElementIterator(SMDSAbs_Face);
   while ( elemIt->more() )
   {
     const SMDS_MeshElement* elem = elemIt->next();
-    if ( elem->GetType() != SMDSAbs_Face )
-      continue;
     nbElems++;
 
     gp_XYZ elemCenter(0.,0.,0.);
@@ -2056,12 +2188,12 @@ static bool getClosestUV (Extrema_GenExtPS& projector,
 //           on edges and boundary nodes are always fixed.
 //=======================================================================
 
-void SMESH_MeshEditor::Smooth (map<int,const SMDS_MeshElement*> & theElems,
-                               set<const SMDS_MeshNode*> &    theFixedNodes,
-                               const SmoothMethod             theSmoothMethod,
-                               const int                      theNbIterations,
-                               double                         theTgtAspectRatio,
-                               const bool                     the2D)
+void SMESH_MeshEditor::Smooth (TIDSortedElemSet &          theElems,
+                               set<const SMDS_MeshNode*> & theFixedNodes,
+                               const SmoothMethod          theSmoothMethod,
+                               const int                   theNbIterations,
+                               double                      theTgtAspectRatio,
+                               const bool                  the2D)
 {
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
@@ -2082,15 +2214,15 @@ void SMESH_MeshEditor::Smooth (map<int,const SMDS_MeshElement*> & theElems,
     SMDS_FaceIteratorPtr fIt = aMesh->facesIterator();
     while ( fIt->more() ) {
       const SMDS_MeshElement* face = fIt->next();
-      theElems.insert( make_pair(face->GetID(),face) );
+      theElems.insert( face );
     }
   }
   // get all face ids theElems are on
   set< int > faceIdSet;
-  map<int, const SMDS_MeshElement* >::iterator itElem;
+  TIDSortedElemSet::iterator itElem;
   if ( the2D )
     for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
-      int fId = FindShape( (*itElem).second );
+      int fId = FindShape( *itElem );
       // check that corresponding submesh exists and a shape is face
       if (fId &&
           faceIdSet.find( fId ) == faceIdSet.end() &&
@@ -2153,7 +2285,7 @@ void SMESH_MeshEditor::Smooth (map<int,const SMDS_MeshElement*> & theElems,
       if ( faceSubMesh && nbElemOnFace == faceSubMesh->NbElements() )
         break; // all elements found
 
-      const SMDS_MeshElement* elem = (*itElem).second;
+      const SMDS_MeshElement* elem = *itElem;
       if ( !elem || elem->GetType() != SMDSAbs_Face || elem->NbNodes() < 3 ||
           ( faceSubMesh && !faceSubMesh->Contains( elem ))) {
         ++itElem;
@@ -2183,13 +2315,12 @@ void SMESH_MeshEditor::Smooth (map<int,const SMDS_MeshElement*> & theElems,
         {
           // check if all faces around the node are on faceSubMesh
           // because a node on edge may be bound to face
-          SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator();
+          SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator(SMDSAbs_Face);
           bool all = true;
           if ( faceSubMesh ) {
             while ( eIt->more() && all ) {
               const SMDS_MeshElement* e = eIt->next();
-              if ( e->GetType() == SMDSAbs_Face )
-                all = faceSubMesh->Contains( e );
+              all = faceSubMesh->Contains( e );
             }
           }
           if ( all )
@@ -2215,10 +2346,10 @@ void SMESH_MeshEditor::Smooth (map<int,const SMDS_MeshElement*> & theElems,
         if ( uvMap.find( node ) == uvMap.end() )
           uvCheckNodes.push_back( node );
         // add nodes of elems sharing node
-//         SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator();
+//         SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator(SMDSAbs_Face);
 //         while ( eIt->more() ) {
 //           const SMDS_MeshElement* e = eIt->next();
-//           if ( e != elem && e->GetType() == SMDSAbs_Face ) {
+//           if ( e != elem ) {
 //             SMDS_ElemIteratorPtr nIt = e->nodesIterator();
 //             while ( nIt->more() ) {
 //               const SMDS_MeshNode* n =
@@ -2397,11 +2528,9 @@ void SMESH_MeshEditor::Smooth (map<int,const SMDS_MeshElement*> & theElems,
           uvMap2[ nSeam ] = &listUV.back();
 
           // collect movable nodes linked to ones on seam in nodesNearSeam
-          SMDS_ElemIteratorPtr eIt = nSeam->GetInverseElementIterator();
+          SMDS_ElemIteratorPtr eIt = nSeam->GetInverseElementIterator(SMDSAbs_Face);
           while ( eIt->more() ) {
             const SMDS_MeshElement* e = eIt->next();
-            if ( e->GetType() != SMDSAbs_Face )
-              continue;
             int nbUseMap1 = 0, nbUseMap2 = 0;
             SMDS_ElemIteratorPtr nIt = e->nodesIterator();
             int nn = 0, nbn =  e->NbNodes();
@@ -2549,7 +2678,7 @@ void SMESH_MeshEditor::Smooth (map<int,const SMDS_MeshElement*> & theElems,
               gp_XY uv2 = helper.GetNodeUV( face, Ns[i+2], Ns[i] );
               gp_XY uv = ( uv1 + uv2 ) / 2.;
               gp_Pnt xyz = surface->Value( uv.X(), uv.Y() );
-              x = xyz.X(); y = xyz.Y(); z = xyz.Z(); 
+              x = xyz.X(); y = xyz.Y(); z = xyz.Z();
             }
             else {
               x = (Ns[i]->X() + Ns[i+2]->X())/2;
@@ -2566,7 +2695,7 @@ void SMESH_MeshEditor::Smooth (map<int,const SMDS_MeshElement*> & theElems,
         }
       }
     }
-    
+
   } // loop on face ids
 
 }
@@ -2616,8 +2745,11 @@ static void sweepElement(SMESHDS_Mesh*                         aMesh,
   // Loop on elem nodes:
   // find new nodes and detect same nodes indices
   int nbNodes = elem->NbNodes();
+  //---PR
   //list<const SMDS_MeshNode*>::const_iterator itNN[ nbNodes ];
   vector<list<const SMDS_MeshNode*>::const_iterator> itNN( nbNodes );
+  itNN.reserve(nbNodes);
+  //---PR
   //const SMDS_MeshNode* prevNod[ nbNodes ], *nextNod[ nbNodes ];
   vector<const SMDS_MeshNode*> prevNod( nbNodes );
   vector<const SMDS_MeshNode*> nextNod( nbNodes );
@@ -2793,7 +2925,7 @@ static void sweepElement(SMESHDS_Mesh*                         aMesh,
         if ( nbSame == 0 )       // --- hexahedron
           aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ], prevNod[ 3 ],
                                        nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ], nextNod[ 3 ]);
-        
+
         else if ( nbSame == 1 ) { // --- pyramid + pentahedron
           aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ],  prevNod[ iAfterSame ],
                                        nextNod[ iAfterSame ], nextNod[ iBeforeSame ],
@@ -2857,7 +2989,7 @@ static void sweepElement(SMESHDS_Mesh*                         aMesh,
         // realized for extrusion only
         //vector<const SMDS_MeshNode*> polyedre_nodes (nbNodes*2 + 4*nbNodes);
         //vector<int> quantities (nbNodes + 2);
-        
+
         //quantities[0] = nbNodes; // bottom of prism
         //for (int inode = 0; inode < nbNodes; inode++) {
         //  polyedre_nodes[inode] = prevNod[inode];
@@ -2867,7 +2999,7 @@ static void sweepElement(SMESHDS_Mesh*                         aMesh,
         //for (int inode = 0; inode < nbNodes; inode++) {
         //  polyedre_nodes[nbNodes + inode] = nextNod[inode];
         //}
-        
+
         //for (int iface = 0; iface < nbNodes; iface++) {
         //  quantities[iface + 2] = 4;
         //  int inextface = (iface == nbNodes - 1) ? 0 : iface + 1;
@@ -2925,12 +3057,12 @@ static void sweepElement(SMESHDS_Mesh*                         aMesh,
 //purpose  : create 1D and 2D elements around swept elements
 //=======================================================================
 
-static void makeWalls (SMESHDS_Mesh*                 aMesh,
-                       TNodeOfNodeListMap &          mapNewNodes,
-                       TElemOfElemListMap &          newElemsMap,
-                       TElemOfVecOfNnlmiMap &        elemNewNodesMap,
-                       map<int,const SMDS_MeshElement*>& elemSet,
-                       const int nbSteps,
+static void makeWalls (SMESHDS_Mesh*            aMesh,
+                       TNodeOfNodeListMap &     mapNewNodes,
+                       TElemOfElemListMap &     newElemsMap,
+                       TElemOfVecOfNnlmiMap &   elemNewNodesMap,
+                       TIDSortedElemSet&        elemSet,
+                       const int                nbSteps,
                        SMESH_SequenceOfElemPtr& myLastCreatedElems)
 {
   ASSERT( newElemsMap.size() == elemNewNodesMap.size() );
@@ -2953,7 +3085,7 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
         nbInitElems = 0;
         highType = type;
       }
-      if ( elemSet.find(el->GetID()) != elemSet.end() )
+      if ( elemSet.find(el) != elemSet.end() )
         nbInitElems++;
     }
     if ( nbInitElems < 2 ) {
@@ -2999,8 +3131,8 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
 
     bool hasFreeLinks = false;
 
-    map<int,const SMDS_MeshElement*> avoidSet;
-    avoidSet.insert( make_pair(elem->GetID(),elem) );
+    TIDSortedElemSet avoidSet;
+    avoidSet.insert( elem );
 
     set<const SMDS_MeshNode*> aFaceLastNodes;
     int iNode, nbNodes = vecNewNodes.size();
@@ -3201,11 +3333,12 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
 //purpose  :
 //=======================================================================
 
-void SMESH_MeshEditor::RotationSweep(map<int,const SMDS_MeshElement*> & theElems,
-                                     const gp_Ax1&                  theAxis,
-                                     const double                   theAngle,
-                                     const int                      theNbSteps,
-                                     const double                   theTol)
+void SMESH_MeshEditor::RotationSweep(TIDSortedElemSet & theElems,
+                                     const gp_Ax1&      theAxis,
+                                     const double       theAngle,
+                                     const int          theNbSteps,
+                                     const double       theTol,
+                                     const bool         theMakeWalls)
 {
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
@@ -3226,10 +3359,10 @@ void SMESH_MeshEditor::RotationSweep(map<int,const SMDS_MeshElement*> & theElems
   TElemOfElemListMap newElemsMap;
 
   // loop on theElems
-  map<int, const SMDS_MeshElement* >::iterator itElem;
+  TIDSortedElemSet::iterator itElem;
   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
-    const SMDS_MeshElement* elem = (*itElem).second;
-    if ( !elem )
+    const SMDS_MeshElement* elem = *itElem;
+    if ( !elem || elem->GetType() == SMDSAbs_Volume )
       continue;
     vector<TNodeOfNodeListMapItr> & newNodesItVec = mapElemNewNodes[ elem ];
     newNodesItVec.reserve( elem->NbNodes() );
@@ -3304,14 +3437,15 @@ void SMESH_MeshEditor::RotationSweep(map<int,const SMDS_MeshElement*> & theElems
     sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], theNbSteps, myLastCreatedElems );
   }
 
-  makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, theNbSteps, myLastCreatedElems );
-
+  if ( theMakeWalls )
+    makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes,
+               theElems, theNbSteps, myLastCreatedElems );
 }
 
 
 //=======================================================================
 //function : CreateNode
-//purpose  : 
+//purpose  :
 //=======================================================================
 const SMDS_MeshNode* SMESH_MeshEditor::CreateNode(const double x,
                                                   const double y,
@@ -3343,7 +3477,7 @@ const SMDS_MeshNode* SMESH_MeshEditor::CreateNode(const double x,
       gp_Pnt P2(aN->X(),aN->Y(),aN->Z());
       if(P1.Distance(P2)<tolnode)
         return aN;
-    }    
+    }
   }
 
   // create new node and return it
@@ -3358,13 +3492,12 @@ const SMDS_MeshNode* SMESH_MeshEditor::CreateNode(const double x,
 //purpose  :
 //=======================================================================
 
-void SMESH_MeshEditor::ExtrusionSweep
-                    (map<int,const SMDS_MeshElement*> & theElems,
-                     const gp_Vec&                  theStep,
-                     const int                      theNbSteps,
-                     TElemOfElemListMap&            newElemsMap,
-                     const int                      theFlags,
-                     const double                   theTolerance)
+void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet &  theElems,
+                                       const gp_Vec&       theStep,
+                                       const int           theNbSteps,
+                                       TElemOfElemListMap& newElemsMap,
+                                       const int           theFlags,
+                                       const double        theTolerance)
 {
   ExtrusParam aParams;
   aParams.myDir = gp_Dir(theStep);
@@ -3384,12 +3517,11 @@ void SMESH_MeshEditor::ExtrusionSweep
 //purpose  :
 //=======================================================================
 
-void SMESH_MeshEditor::ExtrusionSweep
-                    (map<int,const SMDS_MeshElement*> & theElems,
-                     ExtrusParam&                   theParams,
-                     TElemOfElemListMap&            newElemsMap,
-                     const int                      theFlags,
-                     const double                   theTolerance)
+void SMESH_MeshEditor::ExtrusionSweep (TIDSortedElemSet &  theElems,
+                                       ExtrusParam&        theParams,
+                                       TElemOfElemListMap& newElemsMap,
+                                       const int           theFlags,
+                                       const double        theTolerance)
 {
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
@@ -3404,11 +3536,11 @@ void SMESH_MeshEditor::ExtrusionSweep
   //TElemOfVecOfMapNodesMap mapElemNewNodes;
 
   // loop on theElems
-  map<int, const SMDS_MeshElement* >::iterator itElem;
+  TIDSortedElemSet::iterator itElem;
   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
     // check element type
-    const SMDS_MeshElement* elem = (*itElem).second;
-    if ( !elem )
+    const SMDS_MeshElement* elem = *itElem;
+    if ( !elem  || elem->GetType() == SMDSAbs_Volume )
       continue;
 
     vector<TNodeOfNodeListMapItr> & newNodesItVec = mapElemNewNodes[ elem ];
@@ -3569,13 +3701,13 @@ protected:
 //purpose  :
 //=======================================================================
 SMESH_MeshEditor::Extrusion_Error
-  SMESH_MeshEditor::ExtrusionAlongTrack (std::map<int,const SMDS_MeshElement*> & theElements,
-                                        SMESH_subMesh* theTrack,
+  SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
+                                        SMESH_subMesh*       theTrack,
                                         const SMDS_MeshNode* theN1,
-                                        const bool theHasAngles,
-                                        std::list<double>& theAngles,
-                                        const bool theHasRefPoint,
-                                        const gp_Pnt& theRefPoint)
+                                        const bool           theHasAngles,
+                                        list<double>&        theAngles,
+                                        const bool           theHasRefPoint,
+                                        const gp_Pnt&        theRefPoint)
 {
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
@@ -3585,7 +3717,7 @@ SMESH_MeshEditor::Extrusion_Error
   double aT1, aT2, aT, aAngle, aX, aY, aZ;
   std::list<double> aPrms;
   std::list<double>::iterator aItD;
-  std::map<int, const SMDS_MeshElement* >::iterator itElem;
+  TIDSortedElemSet::iterator itElem;
 
   Standard_Real aTx1, aTx2, aL2, aTolVec, aTolVec2;
   gp_Pnt aP3D, aV0;
@@ -3725,7 +3857,7 @@ SMESH_MeshEditor::Extrusion_Error
 
     itElem = theElements.begin();
     for ( ; itElem != theElements.end(); itElem++ ) {
-      const SMDS_MeshElement* elem = (*itElem).second;
+      const SMDS_MeshElement* elem = *itElem;
 
       SMDS_ElemIteratorPtr itN = elem->nodesIterator();
       while ( itN->more() ) {
@@ -3754,7 +3886,7 @@ SMESH_MeshEditor::Extrusion_Error
 
   for ( itElem = theElements.begin(); itElem != theElements.end(); itElem++ ) {
     // check element type
-    const SMDS_MeshElement* elem = (*itElem).second;
+    const SMDS_MeshElement* elem = *itElem;
     aTypeE = elem->GetType();
     if ( !elem || ( aTypeE != SMDSAbs_Face && aTypeE != SMDSAbs_Edge ) )
       continue;
@@ -3899,9 +4031,9 @@ SMESH_MeshEditor::Extrusion_Error
 //purpose  :
 //=======================================================================
 
-void SMESH_MeshEditor::Transform (map<int,const SMDS_MeshElement*> & theElems,
-                                  const gp_Trsf&                 theTrsf,
-                                  const bool                     theCopy)
+void SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems,
+                                  const gp_Trsf&     theTrsf,
+                                  const bool         theCopy)
 {
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
@@ -3923,12 +4055,12 @@ void SMESH_MeshEditor::Transform (map<int,const SMDS_MeshElement*> & theElems,
 
   // elements sharing moved nodes; those of them which have all
   // nodes mirrored but are not in theElems are to be reversed
-  map<int,const SMDS_MeshElement*> inverseElemSet;
+  TIDSortedElemSet inverseElemSet;
 
   // loop on theElems
-  map<int, const SMDS_MeshElement* >::iterator itElem;
+  TIDSortedElemSet::iterator itElem;
   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
-    const SMDS_MeshElement* elem = (*itElem).second;
+    const SMDS_MeshElement* elem = *itElem;
     if ( !elem )
       continue;
 
@@ -3964,8 +4096,8 @@ void SMESH_MeshEditor::Transform (map<int,const SMDS_MeshElement*> & theElems,
       if ( !theCopy && needReverse ) {
         SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator();
         while ( invElemIt->more() ) {
-          const SMDS_MeshElement* iel = invElemIt->next(); 
-          inverseElemSet.insert( make_pair(iel->GetID(),iel) );
+          const SMDS_MeshElement* iel = invElemIt->next();
+          inverseElemSet.insert( iel );
         }
       }
     }
@@ -3977,7 +4109,7 @@ void SMESH_MeshEditor::Transform (map<int,const SMDS_MeshElement*> & theElems,
     return;
 
   if ( !inverseElemSet.empty()) {
-    map<int,const SMDS_MeshElement*>::iterator invElemIt = inverseElemSet.begin();
+    TIDSortedElemSet::iterator invElemIt = inverseElemSet.begin();
     for ( ; invElemIt != inverseElemSet.end(); invElemIt++ )
       theElems.insert( *invElemIt );
   }
@@ -4002,7 +4134,7 @@ void SMESH_MeshEditor::Transform (map<int,const SMDS_MeshElement*> & theElems,
   };
 
   for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
-    const SMDS_MeshElement* elem = (*itElem).second;
+    const SMDS_MeshElement* elem = *itElem;
     if ( !elem || elem->GetType() == SMDSAbs_Node )
       continue;
 
@@ -4130,7 +4262,7 @@ void SMESH_MeshEditor::Transform (map<int,const SMDS_MeshElement*> & theElems,
     }
 
     // find transformed nodes
-    const SMDS_MeshNode* nodes[8];
+    vector<const SMDS_MeshNode*> nodes(nbNodes);
     int iNode = 0;
     SMDS_ElemIteratorPtr itN = elem->nodesIterator();
     while ( itN->more() ) {
@@ -4145,63 +4277,14 @@ void SMESH_MeshEditor::Transform (map<int,const SMDS_MeshElement*> & theElems,
       continue; // not all nodes transformed
 
     if ( theCopy ) {
-      // add a new element
-      switch ( elemType ) {
-      case SMDSAbs_Edge:
-        if ( nbNodes == 2 )
-          myLastCreatedElems.Append(aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ] ));
-        else
-          myLastCreatedElems.Append(aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ));
-        break;
-      case SMDSAbs_Face:
-        if ( nbNodes == 3 )
-          myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ));
-        else if(nbNodes==4)
-          myLastCreatedElems.Append(aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ]));
-        else if(nbNodes==6)
-          myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
-                                             nodes[4], nodes[5]));
-        else // nbNodes==8
-          myLastCreatedElems.Append(aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
-                                             nodes[4], nodes[5], nodes[6], nodes[7]));
-        break;
-      case SMDSAbs_Volume:
-        if ( nbNodes == 4 )
-          myLastCreatedElems.Append(aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ] ));
-        else if ( nbNodes == 8 )
-          myLastCreatedElems.Append(aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ],
-                                               nodes[ 4 ], nodes[ 5 ], nodes[ 6 ] , nodes[ 7 ]));
-        else if ( nbNodes == 6 )
-          myLastCreatedElems.Append(aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ],
-                                               nodes[ 4 ], nodes[ 5 ]));
-        else if ( nbNodes == 5 )
-          myLastCreatedElems.Append(aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ],
-                                               nodes[ 4 ]));
-        else if(nbNodes==10)
-          myLastCreatedElems.Append(aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
-                                               nodes[5], nodes[6], nodes[7], nodes[8], nodes[9]));
-        else if(nbNodes==13)
-          myLastCreatedElems.Append(aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
-                                               nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
-                                               nodes[10], nodes[11], nodes[12]));
-        else if(nbNodes==15)
-          myLastCreatedElems.Append(aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
-                                               nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
-                                               nodes[10], nodes[11], nodes[12], nodes[13], nodes[14]));
-        else // nbNodes==20
-          myLastCreatedElems.Append(aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
-                                               nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
-                                               nodes[10], nodes[11], nodes[12], nodes[13], nodes[14],
-                                               nodes[15], nodes[16], nodes[17], nodes[18], nodes[19]));
-        break;
-      default:;
-      }
+      if ( SMDS_MeshElement* copy = AddElement( nodes, elem->GetType(), elem->IsPoly() ))
+        myLastCreatedElems.Append( copy );
     }
     else
     {
       // reverse element as it was reversed by transformation
       if ( nbNodes > 2 )
-        aMesh->ChangeElementNodes( elem, nodes, nbNodes );
+        aMesh->ChangeElementNodes( elem, &nodes[0], nbNodes );
     }
   }
 }
@@ -4209,7 +4292,8 @@ void SMESH_MeshEditor::Transform (map<int,const SMDS_MeshElement*> & theElems,
 //=======================================================================
 //function : FindCoincidentNodes
 //purpose  : Return list of group of nodes close to each other within theTolerance
-//           Search among theNodes or in the whole mesh if theNodes is empty.
+//           Search among theNodes or in the whole mesh if theNodes is empty using
+//           an Octree algorithm
 //=======================================================================
 
 void SMESH_MeshEditor::FindCoincidentNodes (set<const SMDS_MeshNode*> & theNodes,
@@ -4219,48 +4303,123 @@ void SMESH_MeshEditor::FindCoincidentNodes (set<const SMDS_MeshNode*> & theNodes
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
 
-  double tol2 = theTolerance * theTolerance;
-
-  list<const SMDS_MeshNode*> nodes;
+  set<const SMDS_MeshNode*> nodes;
   if ( theNodes.empty() )
   { // get all nodes in the mesh
     SMDS_NodeIteratorPtr nIt = GetMeshDS()->nodesIterator();
     while ( nIt->more() )
-      nodes.push_back( nIt->next() );
+      nodes.insert( nodes.end(),nIt->next());
   }
   else
+    nodes=theNodes;
+  SMESH_OctreeNode::FindCoincidentNodes ( nodes, &theGroupsOfNodes, theTolerance);
+
+}
+
+//=======================================================================
+/*!
+ * \brief Implementation of search for the node closest to point
+ */
+//=======================================================================
+
+struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher
+{
+  /*!
+   * \brief Constructor
+   */
+  SMESH_NodeSearcherImpl( const SMESHDS_Mesh* theMesh )
   {
-    nodes.insert( nodes.end(), theNodes.begin(), theNodes.end() );
+    set<const SMDS_MeshNode*> nodes;
+    if ( theMesh ) {
+      SMDS_NodeIteratorPtr nIt = theMesh->nodesIterator();
+      while ( nIt->more() )
+        nodes.insert( nodes.end(), nIt->next() );
+    }
+    myOctreeNode = new SMESH_OctreeNode(nodes) ;
   }
-
-  list<const SMDS_MeshNode*>::iterator it2, it1 = nodes.begin();
-  for ( ; it1 != nodes.end(); it1++ )
+  /*!
+   * \brief Do it's job
+   */
+  const SMDS_MeshNode* FindClosestTo( const gp_Pnt& thePnt )
   {
-    const SMDS_MeshNode* n1 = *it1;
-    gp_Pnt p1( n1->X(), n1->Y(), n1->Z() );
-
-    list<const SMDS_MeshNode*> * groupPtr = 0;
-    it2 = it1;
-    for ( it2++; it2 != nodes.end(); it2++ )
+    SMDS_MeshNode tgtNode( thePnt.X(), thePnt.Y(), thePnt.Z() );
+    list<const SMDS_MeshNode*> nodes;
+    const double precision = 1e-6;
+    myOctreeNode->NodesAround( &tgtNode, &nodes, precision );
+
+    double minSqDist = DBL_MAX;
+    Bnd_B3d box;
+    if ( nodes.empty() )  // get all nodes of OctreeNode's closest to thePnt
     {
-      const SMDS_MeshNode* n2 = *it2;
-      gp_Pnt p2( n2->X(), n2->Y(), n2->Z() );
-      if ( p1.SquareDistance( p2 ) <= tol2 )
+      // sort leafs by their distance from thePnt
+      typedef map< double, SMESH_OctreeNode* > TDistTreeMap;
+      TDistTreeMap treeMap;
+      list< SMESH_OctreeNode* > treeList;
+      list< SMESH_OctreeNode* >::iterator trIt;
+      treeList.push_back( myOctreeNode );
+      for ( trIt = treeList.begin(); trIt != treeList.end(); ++trIt)
       {
-        if ( !groupPtr ) {
-          theGroupsOfNodes.push_back( list<const SMDS_MeshNode*>() );
-          groupPtr = & theGroupsOfNodes.back();
-          groupPtr->push_back( n1 );
+        SMESH_OctreeNode* tree = *trIt;
+        if ( !tree->isLeaf() ) { // put children to the queue
+          SMESH_OctreeNodeIteratorPtr cIt = tree->GetChildrenIterator();
+          while ( cIt->more() )
+            treeList.push_back( cIt->next() );
         }
-        if(groupPtr->front()>n2)
-          groupPtr->push_front( n2 );
-        else
-          groupPtr->push_back( n2 );
-        it2 = nodes.erase( it2 );
-        it2--;
+        else if ( tree->NbNodes() ) { // put tree to treeMap
+          tree->getBox( box );
+          double sqDist = thePnt.SquareDistance( 0.5 * ( box.CornerMin() + box.CornerMax() ));
+          pair<TDistTreeMap::iterator,bool> it_in = treeMap.insert( make_pair( sqDist, tree ));
+          if ( !it_in.second ) // not unique distance to box center
+            treeMap.insert( it_in.first, make_pair( sqDist - 1e-13*treeMap.size(), tree ));
+        }
+      }
+      // find distance after which there is no sense to check tree's
+      double sqLimit = DBL_MAX;
+      TDistTreeMap::iterator sqDist_tree = treeMap.begin();
+      if ( treeMap.size() > 5 ) {
+        SMESH_OctreeNode* closestTree = sqDist_tree->second;
+        closestTree->getBox( box );
+        double limit = sqrt( sqDist_tree->first ) + sqrt ( box.SquareExtent() );
+        sqLimit = limit * limit;
+      }
+      // get all nodes from trees
+      for ( ; sqDist_tree != treeMap.end(); ++sqDist_tree) {
+        if ( sqDist_tree->first > sqLimit )
+          break;
+        SMESH_OctreeNode* tree = sqDist_tree->second;
+        tree->NodesAround( tree->GetNodeIterator()->next(), &nodes );
       }
     }
+    // find closest among nodes
+    minSqDist = DBL_MAX;
+    const SMDS_MeshNode* closestNode = 0;
+    list<const SMDS_MeshNode*>::iterator nIt = nodes.begin();
+    for ( ; nIt != nodes.end(); ++nIt ) {
+      double sqDist = thePnt.SquareDistance( TNodeXYZ( *nIt ) );
+      if ( minSqDist > sqDist ) {
+        closestNode = *nIt;
+        minSqDist = sqDist;
+      }
+    }
+    return closestNode;
   }
+  /*!
+   * \brief Destructor
+   */
+  ~SMESH_NodeSearcherImpl() { delete myOctreeNode; }
+private:
+  SMESH_OctreeNode* myOctreeNode;
+};
+
+//=======================================================================
+/*!
+ * \brief Return SMESH_NodeSearcher
+ */
+//=======================================================================
+
+SMESH_NodeSearcher* SMESH_MeshEditor::GetNodeSearcher() 
+{
+  return new SMESH_NodeSearcherImpl( GetMeshDS() );
 }
 
 //=======================================================================
@@ -4577,7 +4736,7 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
         else
           isOk = false;
         break;
-      case 8: { 
+      case 8: {
         if(elem->IsQuadratic()) { // Quadratic quadrangle
           //   1    5    2
           //    +---+---+
@@ -4894,88 +5053,143 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
 }
 
 
-// =================================================
+// ========================================================
 // class   : SortableElement
-// purpose : auxilary
-// =================================================
+// purpose : allow sorting elements basing on their nodes
+// ========================================================
 class SortableElement : public set <const SMDS_MeshElement*>
 {
  public:
 
   SortableElement( const SMDS_MeshElement* theElem )
     {
-      myID = theElem->GetID();
+      myElem = theElem;
       SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator();
       while ( nodeIt->more() )
         this->insert( nodeIt->next() );
     }
 
-  const long GetID() const
-    { return myID; }
+  const SMDS_MeshElement* Get() const
+    { return myElem; }
 
-  void SetID(const long anID) const
-    { myID = anID; }
+  void Set(const SMDS_MeshElement* e) const
+    { myElem = e; }
 
 
  private:
-  mutable long myID;
+  mutable const SMDS_MeshElement* myElem;
 };
 
+//=======================================================================
+//function : FindEqualElements
+//purpose  : Return list of group of elements built on the same nodes.
+//           Search among theElements or in the whole mesh if theElements is empty
+//=======================================================================
+void SMESH_MeshEditor::FindEqualElements(set<const SMDS_MeshElement*> & theElements,
+                                        TListOfListOfElementsID &      theGroupsOfElementsID)
+{
+  myLastCreatedElems.Clear();
+  myLastCreatedNodes.Clear();
+
+  typedef set<const SMDS_MeshElement*> TElemsSet;
+  typedef map< SortableElement, int > TMapOfNodeSet;
+  typedef list<int> TGroupOfElems;
+
+  TElemsSet elems;
+  if ( theElements.empty() )
+  { // get all elements in the mesh
+    SMDS_ElemIteratorPtr eIt = GetMeshDS()->elementsIterator();
+    while ( eIt->more() )
+      elems.insert( elems.end(), eIt->next());
+  }
+  else
+    elems = theElements;
+
+  vector< TGroupOfElems > arrayOfGroups;
+  TGroupOfElems groupOfElems;
+  TMapOfNodeSet mapOfNodeSet;
+
+  TElemsSet::iterator elemIt = elems.begin();
+  for ( int i = 0, j=0; elemIt != elems.end(); ++elemIt, ++j ) {
+    const SMDS_MeshElement* curElem = *elemIt;
+    SortableElement SE(curElem);
+    int ind = -1;
+    // check uniqueness
+    pair< TMapOfNodeSet::iterator, bool> pp = mapOfNodeSet.insert(make_pair(SE, i));
+    if( !(pp.second) ) {
+      TMapOfNodeSet::iterator& itSE = pp.first;
+      ind = (*itSE).second;
+      arrayOfGroups[ind].push_back(curElem->GetID());
+    }
+    else {
+      groupOfElems.clear();
+      groupOfElems.push_back(curElem->GetID());
+      arrayOfGroups.push_back(groupOfElems);
+      i++;
+    }
+  }
+
+  vector< TGroupOfElems >::iterator groupIt = arrayOfGroups.begin();
+  for ( ; groupIt != arrayOfGroups.end(); ++groupIt ) {
+    groupOfElems = *groupIt;
+    if ( groupOfElems.size() > 1 ) {
+      groupOfElems.sort();
+      theGroupsOfElementsID.push_back(groupOfElems);
+    }
+  }
+}
 
 //=======================================================================
-//function : MergeEqualElements
-//purpose  : Remove all but one of elements built on the same nodes.
+//function : MergeElements
+//purpose  : In each given group, substitute all elements by the first one.
 //=======================================================================
 
-void SMESH_MeshEditor::MergeEqualElements()
+void SMESH_MeshEditor::MergeElements(TListOfListOfElementsID & theGroupsOfElementsID)
 {
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
 
+  typedef list<int> TListOfIDs;
+  TListOfIDs rmElemIds; // IDs of elems to remove
+
   SMESHDS_Mesh* aMesh = GetMeshDS();
 
-  SMDS_EdgeIteratorPtr   eIt = aMesh->edgesIterator();
-  SMDS_FaceIteratorPtr   fIt = aMesh->facesIterator();
-  SMDS_VolumeIteratorPtr vIt = aMesh->volumesIterator();
-
-  list< int > rmElemIds; // IDs of elems to remove
-
-  for ( int iDim = 1; iDim <= 3; iDim++ ) {
-
-    set< SortableElement > setOfNodeSet;
-    while ( 1 ) {
-      // get next element
-      const SMDS_MeshElement* elem = 0;
-      if ( iDim == 1 ) {
-        if ( eIt->more() ) elem = eIt->next();
-      } else if ( iDim == 2 ) {
-        if ( fIt->more() ) elem = fIt->next();
-      } else {
-        if ( vIt->more() ) elem = vIt->next();
-      }
-      if ( !elem ) break;
-
-      SortableElement SE(elem);
-
-      // check uniqueness
-      pair< set<SortableElement>::iterator, bool> pp = setOfNodeSet.insert(SE);
-      if( !(pp.second) ) {
-        set<SortableElement>::iterator itSE = pp.first;
-        SortableElement SEold = *itSE;
-        if( SEold.GetID() > SE.GetID() ) {
-          rmElemIds.push_back( SEold.GetID() );
-          (*itSE).SetID(SE.GetID());
-        }
-        else {
-          rmElemIds.push_back( SE.GetID() );
-        }
-      }
+  TListOfListOfElementsID::iterator groupsIt = theGroupsOfElementsID.begin();
+  while ( groupsIt != theGroupsOfElementsID.end() ) {
+    TListOfIDs& aGroupOfElemID = *groupsIt;
+    aGroupOfElemID.sort();
+    int elemIDToKeep = aGroupOfElemID.front();
+    const SMDS_MeshElement* elemToKeep = aMesh->FindElement(elemIDToKeep);
+    aGroupOfElemID.pop_front();
+    TListOfIDs::iterator idIt = aGroupOfElemID.begin();
+    while ( idIt != aGroupOfElemID.end() ) {
+      int elemIDToRemove = *idIt;
+      const SMDS_MeshElement* elemToRemove = aMesh->FindElement(elemIDToRemove);
+      // add the kept element in groups of removed one (PAL15188)
+      AddToSameGroups( elemToKeep, elemToRemove, aMesh );
+      rmElemIds.push_back( elemIDToRemove );
+      ++idIt;
     }
+    ++groupsIt;
   }
 
   Remove( rmElemIds, false );
 }
 
+//=======================================================================
+//function : MergeEqualElements
+//purpose  : Remove all but one of elements built on the same nodes.
+//=======================================================================
+
+void SMESH_MeshEditor::MergeEqualElements()
+{
+  set<const SMDS_MeshElement*> aMeshElements; /* empty input -
+                                                to merge equal elements in the whole mesh */
+  TListOfListOfElementsID aGroupsOfElementsID;
+  FindEqualElements(aMeshElements, aGroupsOfElementsID);
+  MergeElements(aGroupsOfElementsID);
+}
+
 //=======================================================================
 //function : FindFaceInSet
 //purpose  : Return a face having linked nodes n1 and n2 and which is
@@ -4984,19 +5198,18 @@ void SMESH_MeshEditor::MergeEqualElements()
 //=======================================================================
 
 const SMDS_MeshElement*
-  SMESH_MeshEditor::FindFaceInSet(const SMDS_MeshNode*                n1,
-                                  const SMDS_MeshNode*                n2,
-                                  const map<int,const SMDS_MeshElement*>& elemSet,
-                                  const map<int,const SMDS_MeshElement*>& avoidSet)
+  SMESH_MeshEditor::FindFaceInSet(const SMDS_MeshNode*    n1,
+                                  const SMDS_MeshNode*    n2,
+                                  const TIDSortedElemSet& elemSet,
+                                  const TIDSortedElemSet& avoidSet)
 
 {
-  SMDS_ElemIteratorPtr invElemIt = n1->GetInverseElementIterator();
+  SMDS_ElemIteratorPtr invElemIt = n1->GetInverseElementIterator(SMDSAbs_Face);
   while ( invElemIt->more() ) { // loop on inverse elements of n1
     const SMDS_MeshElement* elem = invElemIt->next();
-    if (elem->GetType() != SMDSAbs_Face ||
-        avoidSet.find( elem->GetID() ) != avoidSet.end() )
+    if (avoidSet.find( elem ) != avoidSet.end() )
       continue;
-    if ( !elemSet.empty() && elemSet.find( elem->GetID() ) == elemSet.end())
+    if ( !elemSet.empty() && elemSet.find( elem ) == elemSet.end())
       continue;
     // get face nodes and find index of n1
     int i1, nbN = elem->NbNodes(), iNode = 0;
@@ -5070,9 +5283,9 @@ static const SMDS_MeshElement* findAdjacentFace(const SMDS_MeshNode* n1,
                                                 const SMDS_MeshNode* n2,
                                                 const SMDS_MeshElement* elem)
 {
-  map<int,const SMDS_MeshElement*> elemSet, avoidSet;
+  TIDSortedElemSet elemSet, avoidSet;
   if ( elem )
-    avoidSet.insert ( make_pair(elem->GetID(),elem) );
+    avoidSet.insert ( elem );
   return SMESH_MeshEditor::FindFaceInSet( n1, n2, elemSet, avoidSet );
 }
 
@@ -5113,7 +5326,7 @@ bool SMESH_MeshEditor::FindFreeBorder (const SMDS_MeshNode*             theFirst
 
     list< const SMDS_MeshElement* > curElemList;
     list< const SMDS_MeshNode* > nStartList;
-    SMDS_ElemIteratorPtr invElemIt = nStart->facesIterator();
+    SMDS_ElemIteratorPtr invElemIt = nStart->GetInverseElementIterator(SMDSAbs_Face);
     while ( invElemIt->more() ) {
       const SMDS_MeshElement* e = invElemIt->next();
       if ( e == curElem || foundElems.insert( e ).second ) {
@@ -5888,11 +6101,11 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
         }
       }
     }
-    
+
     // create new elements
     SMESHDS_Mesh *aMesh = GetMeshDS();
     int aShapeId = FindShape( theFace );
-    
+
     i1 = 0; i2 = 1;
     for ( iSplit = 0; iSplit < nbSplits - 1; iSplit++ ) {
       SMDS_MeshElement* newElem = 0;
@@ -5909,7 +6122,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
       if ( aShapeId && newElem )
         aMesh->SetMeshElementOnShape( newElem, aShapeId );
     }
-    
+
     // change nodes of theFace
     const SMDS_MeshNode* newNodes[ 4 ];
     newNodes[ 0 ] = linkNodes[ i1 ];
@@ -5934,7 +6147,7 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     il1 = il1 - nbshift;
     // now have to insert nodes between n0 and n1 or n1 and n2 (see below)
     //   n0      n1     n2    n0      n1     n2
-    //     +-----+-----+        +-----+-----+ 
+    //     +-----+-----+        +-----+-----+
     //      \         /         |           |
     //       \       /          |           |
     //      n5+     +n3       n7+           +n3
@@ -6043,11 +6256,9 @@ void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode*        theBetweenNode
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
 
-  SMDS_ElemIteratorPtr invElemIt = theBetweenNode1->GetInverseElementIterator();
+  SMDS_ElemIteratorPtr invElemIt = theBetweenNode1->GetInverseElementIterator(SMDSAbs_Volume);
   while (invElemIt->more()) { // loop on inverse elements of theBetweenNode1
     const SMDS_MeshElement* elem = invElemIt->next();
-    if (elem->GetType() != SMDSAbs_Volume)
-      continue;
 
     // check, if current volume has link theBetweenNode1 - theBetweenNode2
     SMDS_VolumeTool aVolume (elem);
@@ -6121,90 +6332,93 @@ void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode*        theBetweenNode
 }
 
 //=======================================================================
-//function : ConvertElemToQuadratic
-//purpose  :
+/*!
+ * \brief Convert elements contained in a submesh to quadratic
+ * \retval int - nb of checked elements
+ */
 //=======================================================================
-void SMESH_MeshEditor::ConvertElemToQuadratic(SMESHDS_SubMesh *theSm,
-                                              SMESH_MesherHelper* theHelper,
-                                             const bool theForce3d)
+
+int SMESH_MeshEditor::ConvertElemToQuadratic(SMESHDS_SubMesh *   theSm,
+                                              SMESH_MesherHelper& theHelper,
+                                             const bool          theForce3d)
 {
-  if( !theSm ) return;
-  SMESHDS_Mesh* meshDS = GetMeshDS();
+  int nbElem = 0;
+  if( !theSm ) return nbElem;
   SMDS_ElemIteratorPtr ElemItr = theSm->GetElements();
   while(ElemItr->more())
   {
+    nbElem++;
     const SMDS_MeshElement* elem = ElemItr->next();
-    if( !elem ) continue;
+    if( !elem || elem->IsQuadratic() ) continue;
 
     int id = elem->GetID();
     int nbNodes = elem->NbNodes();
     vector<const SMDS_MeshNode *> aNds (nbNodes);
-    
+
     for(int i = 0; i < nbNodes; i++)
     {
       aNds[i] = elem->GetNode(i);
     }
-
     SMDSAbs_ElementType aType = elem->GetType();
+
+    theSm->RemoveElement(elem);
+    GetMeshDS()->SMDS_Mesh::RemoveFreeElement(elem);
+
     const SMDS_MeshElement* NewElem = 0;
 
     switch( aType )
     {
     case SMDSAbs_Edge :
     {
-      meshDS->RemoveFreeElement(elem, theSm);  
-      NewElem = theHelper->AddQuadraticEdge(aNds[0], aNds[1], id, theForce3d);
+      NewElem = theHelper.AddEdge(aNds[0], aNds[1], id, theForce3d);
       break;
     }
     case SMDSAbs_Face :
     {
-      if(elem->IsQuadratic()) continue;
-
-      meshDS->RemoveFreeElement(elem, theSm);
       switch(nbNodes)
       {
       case 3:
-       NewElem = theHelper->AddFace(aNds[0], aNds[1], aNds[2], id, theForce3d);
+       NewElem = theHelper.AddFace(aNds[0], aNds[1], aNds[2], id, theForce3d);
        break;
       case 4:
-       NewElem = theHelper->AddFace(aNds[0], aNds[1], aNds[2], aNds[3], id, theForce3d);
+       NewElem = theHelper.AddFace(aNds[0], aNds[1], aNds[2], aNds[3], id, theForce3d);
        break;
       default:
        continue;
       }
-      break;  
+      break;
     }
     case SMDSAbs_Volume :
     {
-      if( elem->IsQuadratic() ) continue;
-
-      meshDS->RemoveFreeElement(elem, theSm);
       switch(nbNodes)
       {
       case 4:
-       NewElem = theHelper->AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], id, true);
+       NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], id, true);
        break;
       case 6:
-       NewElem = theHelper->AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], aNds[4], aNds[5], id, true);
+       NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], aNds[4], aNds[5], id, true);
        break;
       case 8:
-       NewElem = theHelper->AddVolume(aNds[0], aNds[1], aNds[2], aNds[3],
-                                      aNds[4], aNds[5], aNds[6], aNds[7], id, true);
+       NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3],
+                                      aNds[4], aNds[5], aNds[6], aNds[7], id, true);
        break;
       default:
        continue;
       }
-      break;  
+      break;
     }
     default :
       continue;
     }
     if( NewElem )
     {
-      AddToSameGroups( NewElem, elem, meshDS);
+      AddToSameGroups( NewElem, elem, GetMeshDS());
       theSm->AddElement( NewElem );
     }
+    if ( NewElem != elem )
+      RemoveElemFromGroups (elem, GetMeshDS());
   }
+  return nbElem;
 }
 
 //=======================================================================
@@ -6215,42 +6429,44 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
 {
   SMESHDS_Mesh* meshDS = GetMeshDS();
 
-  SMESH_MesherHelper* aHelper = new SMESH_MesherHelper(*myMesh);
-  aHelper->SetKeyIsQuadratic( true );
-  const TopoDS_Shape& aShape = meshDS->ShapeToMesh();
+  SMESH_MesherHelper aHelper(*myMesh);
+  aHelper.SetIsQuadratic( true );
 
-  if ( !aShape.IsNull() && GetMesh()->GetSubMeshContaining(aShape) )
+  int nbCheckedElems = 0;
+  if ( myMesh->HasShapeToMesh() )
   {
-    SMESH_subMesh *aSubMesh = GetMesh()->GetSubMeshContaining(aShape);
-    
-    const map < int, SMESH_subMesh * >& aMapSM = aSubMesh->DependsOn();
-    map < int, SMESH_subMesh * >::const_iterator itsub;
-    for (itsub = aMapSM.begin(); itsub != aMapSM.end(); itsub++)
+    if ( SMESH_subMesh *aSubMesh = myMesh->GetSubMeshContaining(myMesh->GetShapeToMesh()))
     {
-      SMESHDS_SubMesh *sm = ((*itsub).second)->GetSubMeshDS();
-      aHelper->SetSubShape( (*itsub).second->GetSubShape() );
-      ConvertElemToQuadratic(sm, aHelper, theForce3d);
+      SMESH_subMeshIteratorPtr smIt = aSubMesh->getDependsOnIterator(true,false);
+      while ( smIt->more() ) {
+        SMESH_subMesh* sm = smIt->next();
+        if ( SMESHDS_SubMesh *smDS = sm->GetSubMeshDS() ) {
+          aHelper.SetSubShape( sm->GetSubShape() );
+          nbCheckedElems += ConvertElemToQuadratic(smDS, aHelper, theForce3d);
+        }
+      }
     }
-    aHelper->SetSubShape( aSubMesh->GetSubShape() );
-    ConvertElemToQuadratic(aSubMesh->GetSubMeshDS(), aHelper, theForce3d);
   }
-  else
+  int totalNbElems = meshDS->NbEdges() + meshDS->NbFaces() + meshDS->NbVolumes();
+  if ( nbCheckedElems < totalNbElems ) // not all elements in submeshes
   {
     SMDS_EdgeIteratorPtr aEdgeItr = meshDS->edgesIterator();
     while(aEdgeItr->more())
     {
       const SMDS_MeshEdge* edge = aEdgeItr->next();
-      if(edge)
+      if(edge && !edge->IsQuadratic())
       {
        int id = edge->GetID();
        const SMDS_MeshNode* n1 = edge->GetNode(0);
        const SMDS_MeshNode* n2 = edge->GetNode(1);
 
-       RemoveElemFromGroups (edge, meshDS);
        meshDS->SMDS_Mesh::RemoveFreeElement(edge);
 
-        const SMDS_QuadraticEdge* NewEdge = aHelper->AddQuadraticEdge(n1, n2, id, theForce3d);
-        AddToSameGroups(NewEdge, edge, meshDS);
+        const SMDS_MeshEdge* NewEdge = aHelper.AddEdge(n1, n2, id, theForce3d);
+        if ( NewEdge )
+          AddToSameGroups(NewEdge, edge, meshDS);
+        if ( NewEdge != edge )
+          RemoveElemFromGroups (edge, meshDS);
       }
     }
     SMDS_FaceIteratorPtr aFaceItr = meshDS->facesIterator();
@@ -6258,7 +6474,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
     {
       const SMDS_MeshFace* face = aFaceItr->next();
       if(!face || face->IsQuadratic() ) continue;
-      
+
       int id = face->GetID();
       int nbNodes = face->NbNodes();
       vector<const SMDS_MeshNode *> aNds (nbNodes);
@@ -6268,29 +6484,31 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
        aNds[i] = face->GetNode(i);
       }
 
-      RemoveElemFromGroups (face, meshDS); 
       meshDS->SMDS_Mesh::RemoveFreeElement(face);
 
       SMDS_MeshFace * NewFace = 0;
       switch(nbNodes)
       {
       case 3:
-       NewFace = aHelper->AddFace(aNds[0], aNds[1], aNds[2], id, theForce3d);
+       NewFace = aHelper.AddFace(aNds[0], aNds[1], aNds[2], id, theForce3d);
        break;
       case 4:
-       NewFace = aHelper->AddFace(aNds[0], aNds[1], aNds[2], aNds[3], id, theForce3d);
+       NewFace = aHelper.AddFace(aNds[0], aNds[1], aNds[2], aNds[3], id, theForce3d);
        break;
       default:
        continue;
       }
-      AddToSameGroups(NewFace, face, meshDS);
+      if ( NewFace )
+        AddToSameGroups(NewFace, face, meshDS);
+      if ( NewFace != face )
+        RemoveElemFromGroups (face, meshDS);
     }
     SMDS_VolumeIteratorPtr aVolumeItr = meshDS->volumesIterator();
     while(aVolumeItr->more())
     {
       const SMDS_MeshVolume* volume = aVolumeItr->next();
       if(!volume || volume->IsQuadratic() ) continue;
-      
+
       int id = volume->GetID();
       int nbNodes = volume->NbNodes();
       vector<const SMDS_MeshNode *> aNds (nbNodes);
@@ -6300,149 +6518,127 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d)
        aNds[i] = volume->GetNode(i);
       }
 
-      RemoveElemFromGroups (volume, meshDS);
       meshDS->SMDS_Mesh::RemoveFreeElement(volume);
 
       SMDS_MeshVolume * NewVolume = 0;
       switch(nbNodes)
       {
       case 4:
-       NewVolume = aHelper->AddVolume(aNds[0], aNds[1], aNds[2],
-                                       aNds[3], id, true );
+       NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2],
+                                      aNds[3], id, true );
        break;
       case 6:
-       NewVolume = aHelper->AddVolume(aNds[0], aNds[1], aNds[2],
-                                       aNds[3], aNds[4], aNds[5], id, true);
+       NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2],
+                                      aNds[3], aNds[4], aNds[5], id, true);
        break;
       case 8:
-       NewVolume = aHelper->AddVolume(aNds[0], aNds[1], aNds[2], aNds[3],
-                                      aNds[4], aNds[5], aNds[6], aNds[7], id, true);
+       NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3],
+                                      aNds[4], aNds[5], aNds[6], aNds[7], id, true);
        break;
       default:
        continue;
       }
-      AddToSameGroups(NewVolume, volume, meshDS);
+      if ( NewVolume )
+        AddToSameGroups(NewVolume, volume, meshDS);
+      if ( NewVolume != volume )
+        RemoveElemFromGroups (volume, meshDS);
     }
   }
-  delete aHelper;
 }
 
 //=======================================================================
-//function : RemoveQuadElem
-//purpose  :
+/*!
+ * \brief Convert quadratic elements to linear ones and remove quadratic nodes
+ * \retval int - nb of checked elements
+ */
 //=======================================================================
-void SMESH_MeshEditor::RemoveQuadElem(SMESHDS_SubMesh *theSm, 
-                                     SMDS_ElemIteratorPtr theItr,
-                                     RemoveQuadNodeMap& theRemoveNodeMap)
+
+int SMESH_MeshEditor::RemoveQuadElem(SMESHDS_SubMesh *    theSm,
+                                     SMDS_ElemIteratorPtr theItr,
+                                     const int            theShapeID)
 {
+  int nbElem = 0;
   SMESHDS_Mesh* meshDS = GetMeshDS();
   while( theItr->more() )
   {
     const SMDS_MeshElement* elem = theItr->next();
-    if( elem )
+    nbElem++;
+    if( elem && elem->IsQuadratic())
     {
-      if( !elem->IsQuadratic() )
-        continue;
-      
       int id = elem->GetID();
-
-      int nbNodes = elem->NbNodes(), idx = 0;
-      vector<const SMDS_MeshNode *> aNds; 
+      int nbNodes = elem->NbNodes();
+      vector<const SMDS_MeshNode *> aNds, mediumNodes;
+      aNds.reserve( nbNodes );
+      mediumNodes.reserve( nbNodes );
 
       for(int i = 0; i < nbNodes; i++)
       {
        const SMDS_MeshNode* n = elem->GetNode(i);
 
        if( elem->IsMediumNode( n ) )
-       {
-         ItRemoveQuadNodeMap itRNM = theRemoveNodeMap.find( n );
-         if( itRNM == theRemoveNodeMap.end() )
-         {
-           theRemoveNodeMap.insert(RemoveQuadNodeMap::value_type( n,theSm ));
-         }
-       }
-       else 
+          mediumNodes.push_back( n );
+       else
          aNds.push_back( n );
       }
+      if( aNds.empty() ) continue;
+      SMDSAbs_ElementType aType = elem->GetType();
 
-      idx = aNds.size();
-      if( !idx ) continue;
-      SMDSAbs_ElementType aType = elem->GetType();      
-
-      //remove old quadratic elements
-      meshDS->RemoveFreeElement( elem, theSm );
+      //remove old quadratic element
+      meshDS->SMDS_Mesh::RemoveFreeElement( elem );
+      if ( theSm )
+        theSm->RemoveElement( elem );
 
-      SMDS_MeshElement * NewElem = 0;
-      switch(aType)
-      {
-        case SMDSAbs_Edge:
-         NewElem = meshDS->AddEdgeWithID( aNds[0], aNds[1] ,id );
-         break;
-       case SMDSAbs_Face:
-         if( idx==3 ) NewElem = meshDS->AddFaceWithID( aNds[0],
-                                   aNds[1], aNds[2], id );
-         if( idx==4 ) NewElem = meshDS->AddFaceWithID( aNds[0],
-                                  aNds[1], aNds[2], aNds[3],id );
-         break;
-       case SMDSAbs_Volume:
-         if( idx==4 ) NewElem = meshDS->AddVolumeWithID( aNds[0],
-                                  aNds[1], aNds[2], aNds[3], id );
-         if( idx==6 ) NewElem = meshDS->AddVolumeWithID( aNds[0],
-                                  aNds[1], aNds[2], aNds[3],
-                                  aNds[4], aNds[5], id );
-         if( idx==8 ) NewElem = meshDS->AddVolumeWithID(aNds[0],
-                                  aNds[1], aNds[2], aNds[3],
-                                  aNds[4], aNds[5], aNds[6],
-                                  aNds[7] ,id );
-         break;
-       default:
-         break;
-      }
-
-      AddToSameGroups(NewElem, elem, meshDS);
-      if( theSm )
+      SMDS_MeshElement * NewElem = AddElement( aNds, aType, false, id );
+      if ( NewElem )
+        AddToSameGroups(NewElem, elem, meshDS);
+      if ( NewElem != elem )
+        RemoveElemFromGroups (elem, meshDS);
+      if( theSm && NewElem )
        theSm->AddElement( NewElem );
+
+      // remove medium nodes
+      vector<const SMDS_MeshNode*>::iterator nIt = mediumNodes.begin();
+      for ( ; nIt != mediumNodes.end(); ++nIt ) {
+        const SMDS_MeshNode* n = *nIt;
+        if ( n->NbInverseNodes() == 0 ) {
+          if ( n->GetPosition()->GetShapeId() != theShapeID )
+            meshDS->RemoveFreeNode( n, meshDS->MeshElements
+                                    ( n->GetPosition()->GetShapeId() ));
+          else
+            meshDS->RemoveFreeNode( n, theSm );
+       }
+      }
     }
   }
+  return nbElem;
 }
+
 //=======================================================================
 //function : ConvertFromQuadratic
 //purpose  :
 //=======================================================================
 bool  SMESH_MeshEditor::ConvertFromQuadratic()
 {
-  SMESHDS_Mesh* meshDS = GetMeshDS();
-  RemoveQuadNodeMap aRemoveNodeMap;
-
-  const TopoDS_Shape& aShape = meshDS->ShapeToMesh();
-
-  if ( !aShape.IsNull() && GetMesh()->GetSubMeshContaining(aShape) )
+  int nbCheckedElems = 0;
+  if ( myMesh->HasShapeToMesh() )
   {
-    SMESH_subMesh *aSubMesh = GetMesh()->GetSubMeshContaining(aShape);
-    
-    const map < int, SMESH_subMesh * >& aMapSM = aSubMesh->DependsOn();
-    map < int, SMESH_subMesh * >::const_iterator itsub;
-    for (itsub = aMapSM.begin(); itsub != aMapSM.end(); itsub++)
+    if ( SMESH_subMesh *aSubMesh = myMesh->GetSubMeshContaining(myMesh->GetShapeToMesh()))
     {
-      SMESHDS_SubMesh *sm = ((*itsub).second)->GetSubMeshDS();
-      if( sm )
-       RemoveQuadElem( sm, sm->GetElements(), aRemoveNodeMap );
+      SMESH_subMeshIteratorPtr smIt = aSubMesh->getDependsOnIterator(true,false);
+      while ( smIt->more() ) {
+        SMESH_subMesh* sm = smIt->next();
+        if ( SMESHDS_SubMesh *smDS = sm->GetSubMeshDS() )
+          nbCheckedElems += RemoveQuadElem( smDS, smDS->GetElements(), sm->GetId() );
+      }
     }
-    SMESHDS_SubMesh *Sm = aSubMesh->GetSubMeshDS();
-    if( Sm )
-      RemoveQuadElem( Sm, Sm->GetElements(), aRemoveNodeMap );
   }
-  else
+  
+  int totalNbElems =
+    GetMeshDS()->NbEdges() + GetMeshDS()->NbFaces() + GetMeshDS()->NbVolumes();
+  if ( nbCheckedElems < totalNbElems ) // not all elements in submeshes
   {
     SMESHDS_SubMesh *aSM = 0;
-    RemoveQuadElem( aSM, meshDS->elementsIterator(), aRemoveNodeMap );
-  }
-
-  //remove all quadratic nodes 
-  ItRemoveQuadNodeMap itRNM = aRemoveNodeMap.begin();
-  for ( ; itRNM != aRemoveNodeMap.end(); itRNM++ ) 
-  {
-    meshDS->RemoveFreeNode( (*itRNM).first, (*itRNM).second  );        
+    RemoveQuadElem( aSM, GetMeshDS()->elementsIterator(), 0 );
   }
 
   return true;
@@ -6454,12 +6650,12 @@ bool  SMESH_MeshEditor::ConvertFromQuadratic()
 //=======================================================================
 
 SMESH_MeshEditor::Sew_Error
-  SMESH_MeshEditor::SewSideElements (map<int,const SMDS_MeshElement*>& theSide1,
-                                     map<int,const SMDS_MeshElement*>& theSide2,
-                                     const SMDS_MeshNode*          theFirstNode1,
-                                     const SMDS_MeshNode*          theFirstNode2,
-                                     const SMDS_MeshNode*          theSecondNode1,
-                                     const SMDS_MeshNode*          theSecondNode2)
+  SMESH_MeshEditor::SewSideElements (TIDSortedElemSet&    theSide1,
+                                     TIDSortedElemSet&    theSide2,
+                                     const SMDS_MeshNode* theFirstNode1,
+                                     const SMDS_MeshNode* theFirstNode2,
+                                     const SMDS_MeshNode* theSecondNode1,
+                                     const SMDS_MeshNode* theSecondNode2)
 {
   myLastCreatedElems.Clear();
   myLastCreatedNodes.Clear();
@@ -6490,16 +6686,16 @@ SMESH_MeshEditor::Sew_Error
   set<const SMDS_MeshElement*> * faceSetPtr[] = { &faceSet1, &faceSet2 };
   set<const SMDS_MeshElement*>  * volSetPtr[] = { &volSet1,  &volSet2  };
   set<const SMDS_MeshNode*>    * nodeSetPtr[] = { &nodeSet1, &nodeSet2 };
-  map<int,const SMDS_MeshElement*> * elemSetPtr[] = { &theSide1, &theSide2 };
+  TIDSortedElemSet * elemSetPtr[] = { &theSide1, &theSide2 };
   int iSide, iFace, iNode;
 
   for ( iSide = 0; iSide < 2; iSide++ ) {
     set<const SMDS_MeshNode*>    * nodeSet = nodeSetPtr[ iSide ];
-    map<int,const SMDS_MeshElement*> * elemSet = elemSetPtr[ iSide ];
+    TIDSortedElemSet * elemSet = elemSetPtr[ iSide ];
     set<const SMDS_MeshElement*> * faceSet = faceSetPtr[ iSide ];
     set<const SMDS_MeshElement*> * volSet  = volSetPtr [ iSide ];
     set<const SMDS_MeshElement*>::iterator vIt;
-    map<int,const SMDS_MeshElement*>::iterator eIt;
+    TIDSortedElemSet::iterator eIt;
     set<const SMDS_MeshNode*>::iterator    nIt;
 
     // check that given nodes belong to given elements
@@ -6507,7 +6703,7 @@ SMESH_MeshEditor::Sew_Error
     const SMDS_MeshNode* n2 = ( iSide == 0 ) ? theSecondNode1 : theSecondNode2;
     int firstIndex = -1, secondIndex = -1;
     for (eIt = elemSet->begin(); eIt != elemSet->end(); eIt++ ) {
-      const SMDS_MeshElement* elem = (*eIt).second;
+      const SMDS_MeshElement* elem = *eIt;
       if ( firstIndex  < 0 ) firstIndex  = elem->GetNodeIndex( n1 );
       if ( secondIndex < 0 ) secondIndex = elem->GetNodeIndex( n2 );
       if ( firstIndex > -1 && secondIndex > -1 ) break;
@@ -6528,7 +6724,7 @@ SMESH_MeshEditor::Sew_Error
     // loop on the given element of a side
     for (eIt = elemSet->begin(); eIt != elemSet->end(); eIt++ ) {
       //const SMDS_MeshElement* elem = *eIt;
-      const SMDS_MeshElement* elem = (*eIt).second;
+      const SMDS_MeshElement* elem = *eIt;
       if ( elem->GetType() == SMDSAbs_Face ) {
         faceSet->insert( elem );
         set <const SMDS_MeshNode*> faceNodeSet;
@@ -6548,7 +6744,7 @@ SMESH_MeshEditor::Sew_Error
     // ------------------------------------------------------------------------------
 
     for ( nIt = nodeSet->begin(); nIt != nodeSet->end(); nIt++ ) { // loop on nodes of iSide
-      SMDS_ElemIteratorPtr fIt = (*nIt)->facesIterator();
+      SMDS_ElemIteratorPtr fIt = (*nIt)->GetInverseElementIterator(SMDSAbs_Face);
       while ( fIt->more() ) { // loop on faces sharing a node
         const SMDS_MeshElement* f = fIt->next();
         if ( faceSet->find( f ) == faceSet->end() ) {
@@ -6644,7 +6840,7 @@ SMESH_MeshEditor::Sew_Error
                 const SMDS_MeshElement* e = invElemIt->next();
                 if ( faceSet->find( e ) != faceSet->end() )
                   nbSharedNodes++;
-                if ( elemSet->find( e->GetID() ) != elemSet->end() )
+                if ( elemSet->find( e ) != elemSet->end() )
                   nbSharedNodes++;
               }
             }
@@ -6661,10 +6857,10 @@ SMESH_MeshEditor::Sew_Error
             // choose a face most close to the bary center of the opposite side
             gp_XYZ aBC( 0., 0., 0. );
             set <const SMDS_MeshNode*> addedNodes;
-            map<int,const SMDS_MeshElement*> * elemSet2 = elemSetPtr[ 1 - iSide ];
+            TIDSortedElemSet * elemSet2 = elemSetPtr[ 1 - iSide ];
             eIt = elemSet2->begin();
             for ( eIt = elemSet2->begin(); eIt != elemSet2->end(); eIt++ ) {
-              SMDS_ElemIteratorPtr nodeIt = (*eIt).second->nodesIterator();
+              SMDS_ElemIteratorPtr nodeIt = (*eIt)->nodesIterator();
               while ( nodeIt->more() ) { // loop on free face nodes
                 const SMDS_MeshNode* n =
                   static_cast<const SMDS_MeshNode*>( nodeIt->next() );
@@ -6708,7 +6904,7 @@ SMESH_MeshEditor::Sew_Error
 //       // ----------------------------------------------------------
 //       if ( nodeSetSize != nodeSet->size() ) {
 //         for ( ; nIt != nodeSet->end(); nIt++ ) { // loop on nodes of iSide
-//           SMDS_ElemIteratorPtr fIt = (*nIt)->facesIterator();
+//           SMDS_ElemIteratorPtr fIt = (*nIt)->GetInverseElementIterator(SMDSAbs_Face);
 //           while ( fIt->more() ) { // loop on faces sharing a node
 //             const SMDS_MeshElement* f = fIt->next();
 //             if ( faceSet->find( f ) == faceSet->end() ) {
@@ -6792,7 +6988,7 @@ SMESH_MeshEditor::Sew_Error
       set< const SMDS_MeshElement* > fMap;
       for ( int i = 0; i < 2; i++ ) { // loop on 2 nodes of a link
         const SMDS_MeshNode* n = i ? n1 : n2; // a node of a link
-        SMDS_ElemIteratorPtr fIt = n->facesIterator();
+        SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator(SMDSAbs_Face);
         while ( fIt->more() ) { // loop on faces sharing a node
           const SMDS_MeshElement* f = fIt->next();
           if (faceSet->find( f ) != faceSet->end() && // f is in face set
@@ -7039,20 +7235,9 @@ SMESH_MeshEditor::Sew_Error
   return aResult;
 }
 
-/*!
- * \brief A sorted pair of nodes
- */
-struct TLink: public NLink
-{
-  TLink(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2 ):NLink( n1, n2 )
-  { if ( n1 < n2 ) std::swap( first, second ); }
-  TLink(const NLink& link ):NLink( link )
-  { if ( first < second ) std::swap( first, second ); }
-};
-
 //================================================================================
   /*!
-   * \brief Find corresponding nodes in two sets of faces 
+   * \brief Find corresponding nodes in two sets of faces
     * \param theSide1 - first face set
     * \param theSide2 - second first face
     * \param theFirstNode1 - a boundary node of set 1
@@ -7118,11 +7303,10 @@ SMESH_MeshEditor::FindMatchingNodes(set<const SMDS_MeshElement*>& theSide1,
         // during a loop of the first node, we find all faces around n1,
         // during a loop of the second node, we find one face sharing both n1 and n2
         const SMDS_MeshNode* n = iNode ? n1 : n2; // a node of a link
-        SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator();
+        SMDS_ElemIteratorPtr fIt = n->GetInverseElementIterator(SMDSAbs_Face);
         while ( fIt->more() ) { // loop on faces sharing a node
           const SMDS_MeshElement* f = fIt->next();
-          if (f->GetType() == SMDSAbs_Face &&
-              faceSet->find( f ) != faceSet->end() && // f is in face set
+          if (faceSet->find( f ) != faceSet->end() && // f is in face set
               ! facesOfNode1.insert( f ).second ) // f encounters twice
           {
             if ( face[ iSide ] ) {
index d7a79328e9fc0b49b2f214bec1a60e9b5bfb86e6..9b56a1f6c3de6f2c31d83e0dab22ab7a58b533d5 100644 (file)
 #include "SMESH_Controls.hxx"
 #include "SMESH_SequenceOfNode.hxx"
 #include "SMESH_SequenceOfElemPtr.hxx"
-#include "gp_Dir.hxx"
 #include "TColStd_HSequenceOfReal.hxx"
 #include "SMESH_MesherHelper.hxx"
 #include "SMDS_MeshElement.hxx"
 
+#include <gp_Dir.hxx>
+
 #include <list>
 #include <map>
 
-typedef map<const SMDS_MeshElement*,
-            list<const SMDS_MeshElement*> > TElemOfElemListMap;
-typedef map<const SMDS_MeshNode*, const SMDS_MeshNode*> TNodeNodeMap;
-
-typedef map<const SMDS_MeshNode*, SMESHDS_SubMesh*>           RemoveQuadNodeMap;
-typedef map<const SMDS_MeshNode*, SMESHDS_SubMesh*>::iterator ItRemoveQuadNodeMap;
+typedef std::map<const SMDS_MeshElement*,
+                 std::list<const SMDS_MeshElement*> >        TElemOfElemListMap;
+typedef std::map<const SMDS_MeshNode*, const SMDS_MeshNode*> TNodeNodeMap;
 
 class SMDS_MeshFace;
 class SMDS_MeshNode;
@@ -57,30 +55,57 @@ class gp_Ax1;
 class gp_Vec;
 class gp_Pnt;
 
+// ============================================================
+/*!
+ * \brief Set of elements sorted by ID, to be used to assure
+ *  predictability of edition
+ */
+// ============================================================
+
+template < class TMeshElem = SMDS_MeshElement>
+struct TIDCompare {
+  bool operator () (const TMeshElem* e1, const TMeshElem* e2) const
+  { return e1->GetID() < e2->GetID(); }
+};
+typedef std::set< const SMDS_MeshElement*, TIDCompare< SMDS_MeshElement> > TIDSortedElemSet;
+
+// ============================================================
+/*!
+ * \brief Searcher for the node closest to point
+ */
+// ============================================================
+
+struct SMESH_NodeSearcher
+{
+  virtual const SMDS_MeshNode* FindClosestTo( const gp_Pnt& pnt ) = 0;
+};
+
+// ============================================================
+/*!
+ * \brief Editor of a mesh
+ */
+// ============================================================
+
 class SMESH_EXPORT SMESH_MeshEditor {
+
 public:
 
-  // define a set of elements sorted by ID, to be used to assure
-  // predictability of edition
-  struct TIDCompare {
-    bool operator () (const SMDS_MeshElement* e1, const SMDS_MeshElement* e2)
-    { return e1->GetID() < e2->GetID(); }
-  };
-  typedef set< const SMDS_MeshElement*, TIDCompare > TIDSortedElemSet;
+  SMESH_MeshEditor( SMESH_Mesh* theMesh );
 
   /*!
-   * \brief Insert element in a map of elements sorted by ID
-    * \param elem - element to insert
-    * \param elemMap - the map to fill in
+   * \brief Add element
    */
-  static void Insert(const SMDS_MeshElement*                 elem,
-                     std::map<int,const SMDS_MeshElement*> & elemMap) {
-    elemMap.insert( make_pair( elem->GetID(), elem ));
-  }
-  
-public:
-
-  SMESH_MeshEditor( SMESH_Mesh* theMesh );
+  SMDS_MeshElement* AddElement(const std::vector<const SMDS_MeshNode*> & nodes,
+                               const SMDSAbs_ElementType                 type,
+                               const bool                                isPoly,
+                               const int                                 ID = 0);
+  /*!
+   * \brief Add element
+   */
+  SMDS_MeshElement* AddElement(const std::vector<int>  & nodeIDs,
+                               const SMDSAbs_ElementType type,
+                               const bool                isPoly,
+                               const int                 ID = 0);
 
   bool Remove (const std::list< int >& theElemIDs, const bool isNodes);
   // Remove a node or an element.
@@ -116,7 +141,7 @@ public:
    *                       is still performed; theMaxAngle is mesured in radians.
    * \retval bool - Success or not.
    */
-  bool TriToQuad (std::map<int,const SMDS_MeshElement*> & theElems,
+  bool TriToQuad (TIDSortedElemSet &                   theElems,
                   SMESH::Controls::NumericalFunctorPtr theCriterion,
                   const double                         theMaxAngle);
 
@@ -126,7 +151,7 @@ public:
    * \param theCriterion - Is used to choose a diagonal for splitting.
    * \retval bool - Success or not.
    */
-  bool QuadToTri (std::map<int,const SMDS_MeshElement*> &  theElems,
+  bool QuadToTri (TIDSortedElemSet &                   theElems,
                   SMESH::Controls::NumericalFunctorPtr theCriterion);
 
   /*!
@@ -135,8 +160,8 @@ public:
    * \param the13Diag - Is used to choose a diagonal for splitting.
    * \retval bool - Success or not.
    */
-  bool QuadToTri (std::map<int,const SMDS_MeshElement*> & theElems,
-                  const bool                          the13Diag);
+  bool QuadToTri (TIDSortedElemSet & theElems,
+                  const bool         the13Diag);
 
   /*!
    * \brief Find better diagonal for splitting.
@@ -150,12 +175,12 @@ public:
 
   enum SmoothMethod { LAPLACIAN = 0, CENTROIDAL };
 
-  void Smooth (std::map<int,const SMDS_MeshElement*> & theElements,
-               std::set<const SMDS_MeshNode*> &    theFixedNodes,
-               const SmoothMethod                  theSmoothMethod,
-               const int                           theNbIterations,
-               double                              theTgtAspectRatio = 1.0,
-               const bool                          the2D = true);
+  void Smooth (TIDSortedElemSet &               theElements,
+               std::set<const SMDS_MeshNode*> & theFixedNodes,
+               const SmoothMethod               theSmoothMethod,
+               const int                        theNbIterations,
+               double                           theTgtAspectRatio = 1.0,
+               const bool                       the2D = true);
   // Smooth theElements using theSmoothMethod during theNbIterations
   // or until a worst element has aspect ratio <= theTgtAspectRatio.
   // Aspect Ratio varies in range [1.0, inf].
@@ -166,11 +191,12 @@ public:
   // on geometrical faces
 
 
-  void RotationSweep (std::map<int,const SMDS_MeshElement*> & theElements,
-                      const gp_Ax1&                       theAxis,
-                      const double                        theAngle,
-                      const int                           theNbSteps,
-                      const double                        theToler);
+  void RotationSweep (TIDSortedElemSet & theElements,
+                      const gp_Ax1&      theAxis,
+                      const double       theAngle,
+                      const int          theNbSteps,
+                      const double       theToler,
+                      const bool         theMakeWalls=true);
   // Generate new elements by rotation of theElements around theAxis
   // by theAngle by theNbSteps
 
@@ -216,12 +242,12 @@ public:
    *   EXTRUSION_FLAG_SEW is set
    */
   void ExtrusionSweep
-           (map<int,const SMDS_MeshElement*> & theElems,
-            const gp_Vec&                  theStep,
-            const int                      theNbSteps,
-            TElemOfElemListMap&            newElemsMap,
-            const int                      theFlags = EXTRUSION_FLAG_BOUNDARY,
-            const double                   theTolerance = 1.e-6);
+           (TIDSortedElemSet &  theElems,
+            const gp_Vec&       theStep,
+            const int           theNbSteps,
+            TElemOfElemListMap& newElemsMap,
+            const int           theFlags = EXTRUSION_FLAG_BOUNDARY,
+            const double        theTolerance = 1.e-6);
   
   /*!
    * Generate new elements by extrusion of theElements
@@ -233,11 +259,11 @@ public:
    *   EXTRUSION_FLAG_SEW is set
    * param theParams - special structure for manage of extrusion
    */
-  void ExtrusionSweep (map<int,const SMDS_MeshElement*> & theElems,
-                       ExtrusParam&                   theParams,
-                       TElemOfElemListMap&            newElemsMap,
-                       const int                      theFlags,
-                       const double                   theTolerance);
+  void ExtrusionSweep (TIDSortedElemSet &  theElems,
+                       ExtrusParam&        theParams,
+                       TElemOfElemListMap& newElemsMap,
+                       const int           theFlags,
+                       const double        theTolerance);
 
 
   // Generate new elements by extrusion of theElements 
@@ -253,19 +279,19 @@ public:
     EXTR_CANT_GET_TANGENT
     };
   
-  Extrusion_Error ExtrusionAlongTrack (std::map<int,const SMDS_MeshElement*> & theElements,
-                                       SMESH_subMesh*                      theTrackPattern,
-                                       const SMDS_MeshNode*                theNodeStart,
-                                       const bool                          theHasAngles,
-                                       std::list<double>&                  theAngles,
-                                       const bool                          theHasRefPoint,
-                                       const gp_Pnt&                       theRefPoint);
+  Extrusion_Error ExtrusionAlongTrack (TIDSortedElemSet &   theElements,
+                                       SMESH_subMesh*       theTrackPattern,
+                                       const SMDS_MeshNode* theNodeStart,
+                                       const bool           theHasAngles,
+                                       std::list<double>&   theAngles,
+                                       const bool           theHasRefPoint,
+                                       const gp_Pnt&        theRefPoint);
   // Generate new elements by extrusion of theElements along path given by theTrackPattern,
   // theHasAngles are the rotation angles, base point can be given by theRefPoint
 
-  void Transform (std::map<int,const SMDS_MeshElement*> & theElements,
-                  const gp_Trsf&                      theTrsf,
-                  const bool                          theCopy);
+  void Transform (TIDSortedElemSet & theElements,
+                  const gp_Trsf&     theTrsf,
+                  const bool         theCopy);
   // Move or copy theElements applying theTrsf to their nodes
 
   typedef std::list< std::list< const SMDS_MeshNode* > > TListOfListOfNodes;
@@ -276,6 +302,11 @@ public:
   // Return list of group of nodes close to each other within theTolerance.
   // Search among theNodes or in the whole mesh if theNodes is empty.
 
+  /*!
+   * \brief Return SMESH_NodeSearcher
+   */
+  SMESH_NodeSearcher* GetNodeSearcher();
+
   int SimplifyFace (const vector<const SMDS_MeshNode *> faceNodes,
                     vector<const SMDS_MeshNode *>&      poly_nodes,
                     vector<int>&                        quantities) const;
@@ -286,6 +317,16 @@ public:
   // In each group, the cdr of nodes are substituted by the first one
   // in all elements.
 
+  typedef std::list< std::list< int > > TListOfListOfElementsID;
+
+  void FindEqualElements(std::set<const SMDS_MeshElement*> & theElements,
+                        TListOfListOfElementsID &           theGroupsOfElementsID);
+  // Return list of group of elements build on the same nodes.
+  // Search among theElements or in the whole mesh if theElements is empty.
+
+  void MergeElements(TListOfListOfElementsID & theGroupsOfElementsID);
+  // In each group remove all but first of elements.
+
   void MergeEqualElements();
   // Remove all but one of elements built on the same nodes.
   // Return nb of successfully merged groups.
@@ -348,12 +389,12 @@ public:
   // nodes are inserted.
   // Return false, if sewing failed.
 
-  Sew_Error SewSideElements (std::map<int,const SMDS_MeshElement*>& theSide1,
-                             std::map<int,const SMDS_MeshElement*>& theSide2,
-                             const SMDS_MeshNode*               theFirstNode1ToMerge,
-                             const SMDS_MeshNode*               theFirstNode2ToMerge,
-                             const SMDS_MeshNode*               theSecondNode1ToMerge,
-                             const SMDS_MeshNode*               theSecondNode2ToMerge);
+  Sew_Error SewSideElements (TIDSortedElemSet&    theSide1,
+                             TIDSortedElemSet&    theSide2,
+                             const SMDS_MeshNode* theFirstNode1ToMerge,
+                             const SMDS_MeshNode* theFirstNode2ToMerge,
+                             const SMDS_MeshNode* theSecondNode1ToMerge,
+                             const SMDS_MeshNode* theSecondNode2ToMerge);
   // Sew two sides of a mesh. Nodes belonging to theSide1 are
   // merged with nodes of elements of theSide2.
   // Number of elements in theSide1 and in theSide2 must be
@@ -402,13 +443,20 @@ public:
 
   static void RemoveElemFromGroups (const SMDS_MeshElement* removeelem,
                                     SMESHDS_Mesh *          aMesh);
-  // remove elemToAdd from the groups 
+  // remove elemToAdd from the groups
+
+  /*!
+   * \brief Return nodes linked to the given one in elements of the type
+   */
+  static void GetLinkedNodes( const SMDS_MeshNode* node,
+                              TIDSortedElemSet &   linkedNodes,
+                              SMDSAbs_ElementType  type = SMDSAbs_All );
 
   static const SMDS_MeshElement*
-    FindFaceInSet(const SMDS_MeshNode*                     n1,
-                  const SMDS_MeshNode*                     n2,
-                  const std::map<int,const SMDS_MeshElement*>& elemSet,
-                  const std::map<int,const SMDS_MeshElement*>& avoidSet);
+    FindFaceInSet(const SMDS_MeshNode*    n1,
+                  const SMDS_MeshNode*    n2,
+                  const TIDSortedElemSet& elemSet,
+                  const TIDSortedElemSet& avoidSet);
   // Return a face having linked nodes n1 and n2 and which is
   // - not in avoidSet,
   // - in elemSet provided that !elemSet.empty()
@@ -449,23 +497,28 @@ public:
 
   SMESHDS_Mesh * GetMeshDS() { return myMesh->GetMeshDS(); }
 
-  SMESH_SequenceOfElemPtr GetLastCreatedNodes() { return myLastCreatedNodes; }
+  const SMESH_SequenceOfElemPtr& GetLastCreatedNodes() const { return myLastCreatedNodes; }
 
-  SMESH_SequenceOfElemPtr GetLastCreatedElems() { return myLastCreatedElems; }
+  const SMESH_SequenceOfElemPtr& GetLastCreatedElems() const { return myLastCreatedElems; }
 
 private:
 
-  void ConvertElemToQuadratic(SMESHDS_SubMesh *theSm,
-                              SMESH_MesherHelper* theHelper,
-                             const bool theForce3d);
-  //Auxiliary function for "ConvertToQuadratic" is intended to convert
-  //elements contained in submesh to quadratic
-
-  void RemoveQuadElem( SMESHDS_SubMesh *theSm,
-                      SMDS_ElemIteratorPtr theItr,
-                      RemoveQuadNodeMap& theRemoveNodeMap);
-  //Auxiliary function for "ConvertFromQuadratic" is intended to convert quadratic
-  //element to ordinary and for removing quadratic nodes
+  /*!
+   * \brief Convert elements contained in a submesh to quadratic
+    * \retval int - nb of checked elements
+   */
+  int ConvertElemToQuadratic(SMESHDS_SubMesh *   theSm,
+                             SMESH_MesherHelper& theHelper,
+                             const bool          theForce3d);
+
+  /*!
+   * \brief Convert quadratic elements to linear ones and remove quadratic nodes
+    * \retval int - nb of checked elements
+   */
+  int RemoveQuadElem( SMESHDS_SubMesh *    theSm,
+                      SMDS_ElemIteratorPtr theItr,
+                      const int            theShapeID);
+  //Auxiliary function for "ConvertFromQuadratic" is intended to 
 
 private:
 
index c3e420317ad626a35470b08c8dfd25b6d74c0384..02627a0e6a9957d486a78ba8405f8a730dbd53f9 100644 (file)
 
 #define RETURN_BAD_RESULT(msg) { MESSAGE(msg); return false; }
 
+//================================================================================
+/*!
+ * \brief Constructor
+ */
+//================================================================================
+
+SMESH_MesherHelper::SMESH_MesherHelper(SMESH_Mesh& theMesh)
+  : myMesh(&theMesh), myShapeID(-1), myCreateQuadratic(false)
+{
+  mySetElemOnShape = ( ! myMesh->HasShapeToMesh() );
+}
+
 //=======================================================================
 //function : CheckShape
 //purpose  : 
@@ -115,7 +127,7 @@ void SMESH_MesherHelper::SetSubShape(const int aShID)
   if ( aShID == myShapeID )
     return;
   if ( aShID > 1 )
-    SetSubShape( GetMesh()->GetMeshDS()->IndexToShape( aShID ));
+    SetSubShape( GetMeshDS()->IndexToShape( aShID ));
   else
     SetSubShape( TopoDS_Shape() );
 }
@@ -282,7 +294,7 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face&   F,
     // edge and recieve value from this pcurve
     const SMDS_EdgePosition* epos =
       static_cast<const SMDS_EdgePosition*>(n->GetPosition().get());
-    SMESHDS_Mesh* meshDS = GetMesh()->GetMeshDS();
+    SMESHDS_Mesh* meshDS = GetMeshDS();
     int edgeID = Pos->GetShapeId();
     TopoDS_Edge E = TopoDS::Edge(meshDS->IndexToShape(edgeID));
     double f, l;
@@ -326,7 +338,7 @@ double SMESH_MesherHelper::GetNodeU(const TopoDS_Edge&   E,
     param =  epos->GetUParameter();
   }
   else if(Pos->GetTypeOfPosition()==SMDS_TOP_VERTEX) {
-    SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS();
+    SMESHDS_Mesh * meshDS = GetMeshDS();
     int vertexID = n->GetPosition()->GetShapeId();
     const TopoDS_Vertex& V = TopoDS::Vertex(meshDS->IndexToShape(vertexID));
     param =  BRep_Tool::Parameter( V, E );
@@ -478,68 +490,108 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1,
 }
 
 //=======================================================================
-//function : AddQuadraticEdge
-//purpose  : 
+/*!
+ * Creates a node
+ */
+//=======================================================================
+
+SMDS_MeshNode* SMESH_MesherHelper::AddNode(double x, double y, double z, int ID)
+{
+  SMESHDS_Mesh * meshDS = GetMeshDS();
+  SMDS_MeshNode* node = 0;
+  if ( ID )
+    node = meshDS->AddNodeWithID( x, y, z, ID );
+  else
+    node = meshDS->AddNode( x, y, z );
+  if ( mySetElemOnShape && myShapeID > 0 ) {
+    switch ( myShape.ShapeType() ) {
+    case TopAbs_SOLID:  meshDS->SetNodeInVolume( node, myShapeID); break;
+    case TopAbs_SHELL:  meshDS->SetNodeInVolume( node, myShapeID); break;
+    case TopAbs_FACE:   meshDS->SetNodeOnFace(   node, myShapeID); break;
+    case TopAbs_EDGE:   meshDS->SetNodeOnEdge(   node, myShapeID); break;
+    case TopAbs_VERTEX: meshDS->SetNodeOnVertex( node, myShapeID); break;
+    default: ;
+    }
+  }
+  return node;
+}
+
 //=======================================================================
-/**
- * Special function for creation quadratic edge
+/*!
+ * Creates quadratic or linear edge
  */
-SMDS_QuadraticEdge* SMESH_MesherHelper::AddQuadraticEdge(const SMDS_MeshNode* n1,
-                                                         const SMDS_MeshNode* n2,
-                                                         const int id,
-                                                        const bool force3d)
+//=======================================================================
+
+SMDS_MeshEdge* SMESH_MesherHelper::AddEdge(const SMDS_MeshNode* n1,
+                                                const SMDS_MeshNode* n2,
+                                                const int id,
+                                                const bool force3d)
 {
-  SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS();
+  SMESHDS_Mesh * meshDS = GetMeshDS();
   
-  const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
-  
-  myCreateQuadratic = true;
+  SMDS_MeshEdge* edge = 0;
+  if (myCreateQuadratic) {
+    const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
+    if(id)
+      edge = meshDS->AddEdgeWithID(n1, n2, n12, id);
+    else
+      edge = meshDS->AddEdge(n1, n2, n12);
+  }
+  else {
+    if(id)
+      edge = meshDS->AddEdgeWithID(n1, n2, id);
+    else
+      edge = meshDS->AddEdge(n1, n2);
+  }
 
-  if(id)
-    return  (SMDS_QuadraticEdge*)(meshDS->AddEdgeWithID(n1, n2, n12, id));
-  else
-    return  (SMDS_QuadraticEdge*)(meshDS->AddEdge(n1, n2, n12));
+  if ( mySetElemOnShape && myShapeID > 0 )
+    meshDS->SetMeshElementOnShape( edge, myShapeID );
+
+  return edge;
 }
 
-//=======================================================================
-//function : AddFace
-//purpose  : 
 //=======================================================================
 /*!
- * Special function for creation quadratic triangle
+ * Creates quadratic or linear triangle
  */
+//=======================================================================
+
 SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1,
                                            const SMDS_MeshNode* n2,
                                            const SMDS_MeshNode* n3,
                                            const int id,
                                           const bool force3d)
 {
-  SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS();
+  SMESHDS_Mesh * meshDS = GetMeshDS();
+  SMDS_MeshFace* elem = 0;
   if(!myCreateQuadratic) {
     if(id)
-      return  meshDS->AddFaceWithID(n1, n2, n3, id);
+      elem = meshDS->AddFaceWithID(n1, n2, n3, id);
     else
-      return  meshDS->AddFace(n1, n2, n3);
+      elem = meshDS->AddFace(n1, n2, n3);
   }
+  else {
+    const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
+    const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
+    const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,force3d);
 
-  const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
-  const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
-  const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,force3d);
+    if(id)
+      elem = meshDS->AddFaceWithID(n1, n2, n3, n12, n23, n31, id);
+    else
+      elem = meshDS->AddFace(n1, n2, n3, n12, n23, n31);
+  }
+  if ( mySetElemOnShape && myShapeID > 0 )
+    meshDS->SetMeshElementOnShape( elem, myShapeID );
 
-  if(id)
-    return  meshDS->AddFaceWithID(n1, n2, n3, n12, n23, n31, id);
-  else
-    return  meshDS->AddFace(n1, n2, n3, n12, n23, n31);
+  return elem;
 }
 
-
-//=======================================================================
-//function : AddFace
-//purpose  : 
 //=======================================================================
 /*!
- * Special function for creation quadratic quadrangle
+ * Creates quadratic or linear quadrangle
  */
+//=======================================================================
+
 SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1,
                                            const SMDS_MeshNode* n2,
                                            const SMDS_MeshNode* n3,
@@ -547,33 +599,37 @@ SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1,
                                            const int id,
                                           const bool force3d)
 {
-  SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS();
+  SMESHDS_Mesh * meshDS = GetMeshDS();
+  SMDS_MeshFace* elem = 0;
   if(!myCreateQuadratic) {
     if(id)
-      return  meshDS->AddFaceWithID(n1, n2, n3, n4, id);
+      elem = meshDS->AddFaceWithID(n1, n2, n3, n4, id);
     else
-      return  meshDS->AddFace(n1, n2, n3, n4);
+      elem = meshDS->AddFace(n1, n2, n3, n4);
   }
+  else {
+    const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
+    const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
+    const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
+    const SMDS_MeshNode* n41 = GetMediumNode(n4,n1,force3d);
 
-  const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
-  const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
-  const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
-  const SMDS_MeshNode* n41 = GetMediumNode(n4,n1,force3d);
+    if(id)
+      elem = meshDS->AddFaceWithID(n1, n2, n3, n4, n12, n23, n34, n41, id);
+    else
+      elem = meshDS->AddFace(n1, n2, n3, n4, n12, n23, n34, n41);
+  }
+  if ( mySetElemOnShape && myShapeID > 0 )
+    meshDS->SetMeshElementOnShape( elem, myShapeID );
 
-  if(id)
-    return  meshDS->AddFaceWithID(n1, n2, n3, n4, n12, n23, n34, n41, id);
-  else
-    return  meshDS->AddFace(n1, n2, n3, n4, n12, n23, n34, n41);
+  return elem;
 }
 
-
-//=======================================================================
-//function : AddVolume
-//purpose  : 
 //=======================================================================
 /*!
- * Special function for creation quadratic volume
+ * Creates quadratic or linear volume
  */
+//=======================================================================
+
 SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
                                                const SMDS_MeshNode* n2,
                                                const SMDS_MeshNode* n3,
@@ -583,37 +639,43 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
                                                const int id,
                                               const bool force3d)
 {
-  SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS();
+  SMESHDS_Mesh * meshDS = GetMeshDS();
+  SMDS_MeshVolume* elem = 0;
   if(!myCreateQuadratic) {
     if(id)
-      return meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, id);
+      elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, id);
     else
-      return meshDS->AddVolume(n1, n2, n3, n4, n5, n6);
+      elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6);
   }
+  else {
+    const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
+    const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
+    const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,force3d);
 
-  const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
-  const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
-  const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,force3d);
+    const SMDS_MeshNode* n45 = GetMediumNode(n4,n5,force3d);
+    const SMDS_MeshNode* n56 = GetMediumNode(n5,n6,force3d);
+    const SMDS_MeshNode* n64 = GetMediumNode(n6,n4,force3d);
 
-  const SMDS_MeshNode* n45 = GetMediumNode(n4,n5,force3d);
-  const SMDS_MeshNode* n56 = GetMediumNode(n5,n6,force3d);
-  const SMDS_MeshNode* n64 = GetMediumNode(n6,n4,force3d);
+    const SMDS_MeshNode* n14 = GetMediumNode(n1,n4,force3d);
+    const SMDS_MeshNode* n25 = GetMediumNode(n2,n5,force3d);
+    const SMDS_MeshNode* n36 = GetMediumNode(n3,n6,force3d);
 
-  const SMDS_MeshNode* n14 = GetMediumNode(n1,n4,force3d);
-  const SMDS_MeshNode* n25 = GetMediumNode(n2,n5,force3d);
-  const SMDS_MeshNode* n36 = GetMediumNode(n3,n6,force3d);
+    if(id)
+      elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, 
+                                     n12, n23, n31, n45, n56, n64, n14, n25, n36, id);
+    else
+      elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6,
+                               n12, n23, n31, n45, n56, n64, n14, n25, n36);
+  }
+  if ( mySetElemOnShape && myShapeID > 0 )
+    meshDS->SetMeshElementOnShape( elem, myShapeID );
 
-  if(id)
-    return meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, 
-                                   n12, n23, n31, n45, n56, n64, n14, n25, n36, id);
-  else
-    return meshDS->AddVolume(n1, n2, n3, n4, n5, n6,
-                             n12, n23, n31, n45, n56, n64, n14, n25, n36);
+  return elem;
 }
 
 //=======================================================================
 /*!
- * Special function for creation quadratic volume
+ * Creates quadratic or linear volume
  */
 //=======================================================================
 
@@ -624,31 +686,37 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
                                                const int id, 
                                               const bool force3d)
 {
-  SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS();
+  SMESHDS_Mesh * meshDS = GetMeshDS();
+  SMDS_MeshVolume* elem = 0;
   if(!myCreateQuadratic) {
     if(id)
-      return meshDS->AddVolumeWithID(n1, n2, n3, n4, id);
+      elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, id);
     else
-      return meshDS->AddVolume(n1, n2, n3, n4);
+      elem = meshDS->AddVolume(n1, n2, n3, n4);
   }
+  else {
+    const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
+    const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
+    const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,force3d);
 
-  const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
-  const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
-  const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,force3d);
+    const SMDS_MeshNode* n14 = GetMediumNode(n1,n4,force3d);
+    const SMDS_MeshNode* n24 = GetMediumNode(n2,n4,force3d);
+    const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
 
-  const SMDS_MeshNode* n14 = GetMediumNode(n1,n4,force3d);
-  const SMDS_MeshNode* n24 = GetMediumNode(n2,n4,force3d);
-  const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
+    if(id)
+      elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n12, n23, n31, n14, n24, n34, id);
+    else
+      elem = meshDS->AddVolume(n1, n2, n3, n4, n12, n23, n31, n14, n24, n34);
+  }
+  if ( mySetElemOnShape && myShapeID > 0 )
+    meshDS->SetMeshElementOnShape( elem, myShapeID );
 
-  if(id)
-    return meshDS->AddVolumeWithID(n1, n2, n3, n4, n12, n23, n31, n14, n24, n34, id);
-  else
-    return meshDS->AddVolume(n1, n2, n3, n4, n12, n23, n31, n14, n24, n34);
+  return elem;
 }
 
 //=======================================================================
 /*!
- * Special function for creation quadratic pyramid
+ * Creates quadratic or linear pyramid
  */
 //=======================================================================
 
@@ -660,37 +728,43 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
                                                const int id, 
                                               const bool force3d)
 {
+  SMDS_MeshVolume* elem = 0;
   if(!myCreateQuadratic) {
     if(id)
-      return GetMeshDS()->AddVolumeWithID(n1, n2, n3, n4, n5, id);
+      elem = GetMeshDS()->AddVolumeWithID(n1, n2, n3, n4, n5, id);
     else
-      return GetMeshDS()->AddVolume(n1, n2, n3, n4, n5);
+      elem = GetMeshDS()->AddVolume(n1, n2, n3, n4, n5);
   }
+  else {
+    const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
+    const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
+    const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
+    const SMDS_MeshNode* n41 = GetMediumNode(n4,n1,force3d);
 
-  const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
-  const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
-  const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
-  const SMDS_MeshNode* n41 = GetMediumNode(n4,n1,force3d);
+    const SMDS_MeshNode* n15 = GetMediumNode(n1,n5,force3d);
+    const SMDS_MeshNode* n25 = GetMediumNode(n2,n5,force3d);
+    const SMDS_MeshNode* n35 = GetMediumNode(n3,n5,force3d);
+    const SMDS_MeshNode* n45 = GetMediumNode(n4,n5,force3d);
 
-  const SMDS_MeshNode* n15 = GetMediumNode(n1,n5,force3d);
-  const SMDS_MeshNode* n25 = GetMediumNode(n2,n5,force3d);
-  const SMDS_MeshNode* n35 = GetMediumNode(n3,n5,force3d);
-  const SMDS_MeshNode* n45 = GetMediumNode(n4,n5,force3d);
+    if(id)
+      elem = GetMeshDS()->AddVolumeWithID ( n1,  n2,  n3,  n4,  n5,
+                                            n12, n23, n34, n41,
+                                            n15, n25, n35, n45,
+                                            id);
+    else
+      elem = GetMeshDS()->AddVolume( n1,  n2,  n3,  n4,  n5,
+                                     n12, n23, n34, n41,
+                                     n15, n25, n35, n45);
+  }
+  if ( mySetElemOnShape && myShapeID > 0 )
+    GetMeshDS()->SetMeshElementOnShape( elem, myShapeID );
 
-  if(id)
-    return GetMeshDS()->AddVolumeWithID ( n1,  n2,  n3,  n4,  n5,
-                                          n12, n23, n34, n41,
-                                          n15, n25, n35, n45,
-                                          id);
-  else
-    return GetMeshDS()->AddVolume( n1,  n2,  n3,  n4,  n5,
-                                   n12, n23, n34, n41,
-                                   n15, n25, n35, n45);
+  return elem;
 }
 
 //=======================================================================
 /*!
- * Special function for creation of quadratic hexahedron
+ * Creates quadratic or linear hexahedron
  */
 //=======================================================================
 
@@ -705,37 +779,43 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1,
                                                const int id,
                                               const bool force3d)
 {
-  SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS();
+  SMESHDS_Mesh * meshDS = GetMeshDS();
+  SMDS_MeshVolume* elem = 0;
   if(!myCreateQuadratic) {
     if(id)
-      return meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, id);
+      elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8, id);
     else
-      return meshDS->AddVolume(n1, n2, n3, n4, n5, n6, n7, n8);
+      elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6, n7, n8);
   }
+  else {
+    const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
+    const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
+    const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
+    const SMDS_MeshNode* n41 = GetMediumNode(n4,n1,force3d);
 
-  const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d);
-  const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,force3d);
-  const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,force3d);
-  const SMDS_MeshNode* n41 = GetMediumNode(n4,n1,force3d);
+    const SMDS_MeshNode* n56 = GetMediumNode(n5,n6,force3d);
+    const SMDS_MeshNode* n67 = GetMediumNode(n6,n7,force3d);
+    const SMDS_MeshNode* n78 = GetMediumNode(n7,n8,force3d);
+    const SMDS_MeshNode* n85 = GetMediumNode(n8,n5,force3d);
 
-  const SMDS_MeshNode* n56 = GetMediumNode(n5,n6,force3d);
-  const SMDS_MeshNode* n67 = GetMediumNode(n6,n7,force3d);
-  const SMDS_MeshNode* n78 = GetMediumNode(n7,n8,force3d);
-  const SMDS_MeshNode* n85 = GetMediumNode(n8,n5,force3d);
+    const SMDS_MeshNode* n15 = GetMediumNode(n1,n5,force3d);
+    const SMDS_MeshNode* n26 = GetMediumNode(n2,n6,force3d);
+    const SMDS_MeshNode* n37 = GetMediumNode(n3,n7,force3d);
+    const SMDS_MeshNode* n48 = GetMediumNode(n4,n8,force3d);
 
-  const SMDS_MeshNode* n15 = GetMediumNode(n1,n5,force3d);
-  const SMDS_MeshNode* n26 = GetMediumNode(n2,n6,force3d);
-  const SMDS_MeshNode* n37 = GetMediumNode(n3,n7,force3d);
-  const SMDS_MeshNode* n48 = GetMediumNode(n4,n8,force3d);
+    if(id)
+      elem = meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8,
+                                     n12, n23, n34, n41, n56, n67,
+                                     n78, n85, n15, n26, n37, n48, id);
+    else
+      elem = meshDS->AddVolume(n1, n2, n3, n4, n5, n6, n7, n8,
+                               n12, n23, n34, n41, n56, n67,
+                               n78, n85, n15, n26, n37, n48);
+  }
+  if ( mySetElemOnShape && myShapeID > 0 )
+    meshDS->SetMeshElementOnShape( elem, myShapeID );
 
-  if(id)
-    return meshDS->AddVolumeWithID(n1, n2, n3, n4, n5, n6, n7, n8,
-                                   n12, n23, n34, n41, n56, n67,
-                                   n78, n85, n15, n26, n37, n48, id);
-  else
-    return meshDS->AddVolume(n1, n2, n3, n4, n5, n6, n7, n8,
-                             n12, n23, n34, n41, n56, n67,
-                             n78, n85, n15, n26, n37, n48);
+  return elem;
 }
 
 //=======================================================================
@@ -871,7 +951,7 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap,
   const SMDS_MeshNode* node;
   while ( nIt->more() ) {
     node = nIt->next();
-    if(IsMedium(node))
+    if(IsMedium(node, SMDSAbs_Edge))
       continue;
     const SMDS_EdgePosition* pos =
       dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition().get() );
@@ -914,12 +994,12 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap,
   // try to load the rest nodes
 
   // get all faces from theFace
-  map<int,const SMDS_MeshElement*> allFaces, foundFaces;
+  TIDSortedElemSet allFaces, foundFaces;
   eIt = smFace->GetElements();
   while ( eIt->more() ) {
     const SMDS_MeshElement* e = eIt->next();
     if ( e->GetType() == SMDSAbs_Face )
-      allFaces.insert( make_pair(e->GetID(),e) );
+      allFaces.insert( e );
   }
   // Starting from 2 neighbour nodes on theBaseEdge, look for a face
   // the nodes belong to, and between the nodes of the found face,
@@ -967,7 +1047,7 @@ bool SMESH_MesherHelper::LoadNodeColumns(TParam2ColumnMap & theParam2ColumnMap,
             RETURN_BAD_RESULT( "Too many nodes in column "<< col <<": "<< row+1);
           }
           par_nVec_2->second[ row ] = node;
-          foundFaces.insert( make_pair(face->GetID(),face) );
+          foundFaces.insert( face );
           n2 = node;
           if ( nbFaceNodes==4 ) {
             n1 = par_nVec_1->second[ row ];
index ae366be6b0f317c2b2908541e5eecca609783e4d..7798a0e122a61243f4ddd81a8fa63015ed0e7af8 100644 (file)
@@ -57,6 +57,15 @@ class SMESH_EXPORT SMESH_MesherHelper
 public:
   // ---------- PUBLIC UTILITIES ----------
   
+  /*!
+   * \brief Returns true if given node is medium
+    * \param n - node to check
+    * \param typeToCheck - type of elements containing the node to ask about node status
+    * \retval bool - check result
+   */
+  static bool IsMedium(const SMDS_MeshNode*      node,
+                       const SMDSAbs_ElementType typeToCheck = SMDSAbs_All);
+
   /*!
    * \brief Load nodes bound to face into a map of node columns
     * \param theParam2ColumnMap - map of node columns to fill
@@ -97,119 +106,73 @@ public:
   }
 
 public:
-  // ---------- PUBLIC METHODS ----------
+  // ---------- PUBLIC INSTANCE METHODS ----------
 
-  /// Empty constructor
-  SMESH_MesherHelper(SMESH_Mesh& theMesh)
-    { myMesh=(void *)&theMesh; myCreateQuadratic = false; myShapeID=-1;}
+  // constructor
+  SMESH_MesherHelper(SMESH_Mesh& theMesh);
 
-  SMESH_Mesh* GetMesh() const { return (SMESH_Mesh*)myMesh; }
+  SMESH_Mesh* GetMesh() const { return myMesh; }
     
   SMESHDS_Mesh* GetMeshDS() const { return GetMesh()->GetMeshDS(); }
     
-  /// Copy constructor
-  //Standard_EXPORT SMESH_MesherHelper (const SMESH_MesherHelper& theOther);
-
-  /// Destructor
-  //Standard_EXPORT virtual ~SMESH_MesherHelper ();
-
-  /**
-   * Check submesh for given shape
-   * Check if all elements on this shape
-   * are quadratic, if yes => set true to myCreateQuadratic 
-   * (default value is false). Also fill myNLinkNodeMap
-   * Returns myCreateQuadratic
+  /*!
+   * Check submesh for given shape: if all elements on this shape are quadratic,
+   * quadratic elements will be created. Also fill myNLinkNodeMap
    */
   bool IsQuadraticSubMesh(const TopoDS_Shape& theShape);
-
   /*!
-   * \brief Returns true if given node is medium
-    * \param n - node to check
-    * \param typeToCheck - type of elements containing the node to ask about node status
-    * \retval bool - check result
+   * \brief Set order of elements to create without calling IsQuadraticSubMesh()
    */
-  static bool IsMedium(const SMDS_MeshNode*      node,
-                       const SMDSAbs_ElementType typeToCheck = SMDSAbs_All);
-
-  /**
-   * Auxilary function for filling myNLinkNodeMap
-   */
-  void AddNLinkNode(const SMDS_MeshNode* n1,
-                    const SMDS_MeshNode* n2,
-                    const SMDS_MeshNode* n12);
-
-  /**
-   * Auxilary function for filling myNLinkNodeMap
+  void SetIsQuadratic(const bool theBuildQuadratic)
+  { myCreateQuadratic = theBuildQuadratic; }
+  /*!
+   * \brief Return myCreateQuadratic flag
    */
-  void AddNLinkNodeMap(const NLinkNodeMap& aMap)
-    { myNLinkNodeMap.insert(aMap.begin(), aMap.end()); }
+  bool GetIsQuadratic() const { return myCreateQuadratic; }
 
-  /**
-   * Returns myNLinkNodeMap
+  /*!
+   * \brief To set created elements on the shape set by IsQuadraticSubMesh()
+   *        or the next methods. By defaul elements are set on the shape if
+   *        a mesh has no shape to be meshed
    */
-  const NLinkNodeMap& GetNLinkNodeMap() { return myNLinkNodeMap; }
+  void SetElementsOnShape(bool toSet) { mySetElemOnShape = toSet; }
 
   /*!
-   * \brief Return node UV on face
-    * \param F - the face
-    * \param n - the node
-    * \param inFaceNode - a node of element being created located inside a face
-    * \retval gp_XY - resulting UV
-   * 
-   * Auxilary function called form GetMediumNode()
+   * \brief Set shape to make elements on without calling IsQuadraticSubMesh()
    */
-  gp_XY GetNodeUV(const TopoDS_Face&   F,
-                  const SMDS_MeshNode* n,
-                  const SMDS_MeshNode* inFaceNode=0) const;
-
+  void SetSubShape(const int           subShapeID);//!==SMESHDS_Mesh::ShapeToIndex(shape)
+  void SetSubShape(const TopoDS_Shape& subShape);
   /*!
-   * \brief Check if inFaceNode argument is necessary for call GetNodeUV(F,..)
-    * \param F - the face
-    * \retval bool - return true if the face is periodic
-    *
-    * if F is Null, answer about subshape set through IsQuadraticSubMesh() or
-    * SetSubShape()
+   * \brief Return ID of the shape set by IsQuadraticSubMesh() or SetSubShape() 
+    * \retval int - shape index in SMESHDS
    */
-  bool GetNodeUVneedInFaceNode(const TopoDS_Face& F = TopoDS_Face()) const;
-
+  int GetSubShapeID() const { return myShapeID; }
   /*!
-   * \brief Return  U on edge
-    * \param F - the edge
-    * \param n - the node
-    * \retval double - resulting U
-   * 
-   * Auxilary function called from GetMediumNode()
+   * \brief Return the shape set by IsQuadraticSubMesh() or SetSubShape() 
    */
-  double GetNodeU(const TopoDS_Edge&  E,
-                  const SMDS_MeshNode* n);
-
+  TopoDS_Shape GetSubShape() const  { return myShape; }
 
-  /**
-   * Special function for search or creation medium node
+  /*!
+   * Creates a node
    */
-  const SMDS_MeshNode* GetMediumNode(const SMDS_MeshNode* n1,
-                                     const SMDS_MeshNode* n2,
-                                     const bool force3d);
-
-  /**
-   * Special function for creation quadratic edge
+  SMDS_MeshNode* AddNode(double x, double y, double z, int ID = 0);
+  /*!
+   * Creates quadratic or linear edge
    */
-  SMDS_QuadraticEdge* AddQuadraticEdge(const SMDS_MeshNode* n1,
-                                       const SMDS_MeshNode* n2,
-                                       const int id = 0, 
-                                      const bool force3d = true);
-
-  /**
-   * Special function for creation quadratic triangle
+  SMDS_MeshEdge* AddEdge(const SMDS_MeshNode* n1,
+                         const SMDS_MeshNode* n2,
+                         const int id = 0, 
+                         const bool force3d = true);
+  /*!
+   * Creates quadratic or linear triangle
    */
   SMDS_MeshFace* AddFace(const SMDS_MeshNode* n1,
                          const SMDS_MeshNode* n2,
                          const SMDS_MeshNode* n3,
                          const int id=0, 
                         const bool force3d = false);
-
-  /**
-   * Special function for creation quadratic quadrangle
+  /*!
+   * Creates quadratic or linear quadrangle
    */
   SMDS_MeshFace* AddFace(const SMDS_MeshNode* n1,
                          const SMDS_MeshNode* n2,
@@ -217,9 +180,8 @@ public:
                          const SMDS_MeshNode* n4,
                          const int id = 0,
                         const bool force3d = false);
-
-  /**
-   * Special function for creation quadratic tetraahedron
+  /*!
+   * Creates quadratic or linear tetraahedron
    */
   SMDS_MeshVolume* AddVolume(const SMDS_MeshNode* n1,
                              const SMDS_MeshNode* n2,
@@ -227,10 +189,8 @@ public:
                              const SMDS_MeshNode* n4,
                              const int id = 0,
                             const bool force3d = true);
-
-
-  /**
-   * Special function for creation quadratic pyramid
+  /*!
+   * Creates quadratic or linear pyramid
    */
   SMDS_MeshVolume* AddVolume(const SMDS_MeshNode* n1,
                              const SMDS_MeshNode* n2,
@@ -239,9 +199,8 @@ public:
                              const SMDS_MeshNode* n5,
                              const int id = 0,
                             const bool force3d = true);
-
-  /**
-   * Special function for creation quadratic pentahedron
+  /*!
+   * Creates quadratic or linear pentahedron
    */
   SMDS_MeshVolume* AddVolume(const SMDS_MeshNode* n1,
                              const SMDS_MeshNode* n2,
@@ -251,9 +210,8 @@ public:
                              const SMDS_MeshNode* n6,
                              const int id = 0, 
                             const bool force3d = true);
-
-  /**
-   * Special function for creation quadratic hexahedron
+  /*!
+   * Creates quadratic or linear hexahedron
    */
   SMDS_MeshVolume* AddVolume(const SMDS_MeshNode* n1,
                              const SMDS_MeshNode* n2,
@@ -265,45 +223,26 @@ public:
                              const SMDS_MeshNode* n8,
                              const int id = 0, 
                             bool force3d = true);
-
-  
   /*!
-   * \brief Set order of elements to create
-    * \param theBuildQuadratic - to build quadratic or not
-   * 
-   * To be used for quadratic elements creation without preceding
-   * IsQuadraticSubMesh() or AddQuadraticEdge() call
-   */
-  void SetKeyIsQuadratic(const bool theBuildQuadratic)
-  { myCreateQuadratic = theBuildQuadratic; }
-
-  /*!
-   * \brief Return myCreateQuadratic flag
-    * \retval bool - myCreateQuadratic value
-   */
-  bool GetIsQuadratic() const { return myCreateQuadratic; }
-
-  /*!
-   * \brief Set shape to make elements on
-    * \param subShape, subShapeID - shape or its ID (==SMESHDS_Mesh::ShapeToIndex(shape))
+   * \brief Return U of the given node on the edge
    */
-  void SetSubShape(const int           subShapeID);
-  void SetSubShape(const TopoDS_Shape& subShape);
-
+  double GetNodeU(const TopoDS_Edge&   theEdge,
+                  const SMDS_MeshNode* theNode);
   /*!
-   * \brief Return shape or its ID, on which created elements are added
-    * \retval int - shape index in SMESHDS
-    *
-    * Shape is set by calling either IsQuadraticSubMesh() or SetSubShape() 
+   * \brief Return node UV on face
+    * \param inFaceNode - a node of element being created located inside a face
    */
-  int GetSubShapeID() const { return myShapeID; }
+  gp_XY GetNodeUV(const TopoDS_Face&   F,
+                  const SMDS_MeshNode* n,
+                  const SMDS_MeshNode* inFaceNode=0) const;
   /*!
-   * \brief Return shape or its ID, on which created elements are added
-    * \retval TopoDS_Shape - shape
+   * \brief Check if inFaceNode argument is necessary for call GetNodeUV(F,..)
+    * \retval bool - return true if the face is periodic
     *
-    * Shape is set by calling either IsQuadraticSubMesh() or SetSubShape() 
+    * if F is Null, answer about subshape set through IsQuadraticSubMesh() or
+    * SetSubShape()
    */
-  TopoDS_Shape GetSubShape() const  { return myShape; }
+  bool GetNodeUVneedInFaceNode(const TopoDS_Face& F = TopoDS_Face()) const;
 
   /*!
    * \brief Check if shape is a seam edge or it's vertex
@@ -323,21 +262,42 @@ public:
    */
   bool IsSeamShape(const TopoDS_Shape& subShape) const
   { return IsSeamShape( GetMeshDS()->ShapeToIndex( subShape )); }
-
   /*!
    * \brief Check if the shape set through IsQuadraticSubMesh() or SetSubShape()
    *        has a seam edge
     * \retval bool - true if it has
    */
   bool HasSeam() const { return !mySeamShapeIds.empty(); }
-
   /*!
    * \brief Return index of periodic parametric direction of a closed face
     * \retval int - 1 for U, 2 for V direction
    */
   int GetPeriodicIndex() const { return myParIndex; }
 
- protected:
+  /**
+   * Special function for search or creation medium node
+   */
+  const SMDS_MeshNode* GetMediumNode(const SMDS_MeshNode* n1,
+                                     const SMDS_MeshNode* n2,
+                                     const bool force3d);
+  /*!
+   * Auxilary function for filling myNLinkNodeMap
+   */
+  void AddNLinkNode(const SMDS_MeshNode* n1,
+                    const SMDS_MeshNode* n2,
+                    const SMDS_MeshNode* n12);
+  /**
+   * Auxilary function for filling myNLinkNodeMap
+   */
+  void AddNLinkNodeMap(const NLinkNodeMap& aMap)
+    { myNLinkNodeMap.insert(aMap.begin(), aMap.end()); }
+
+  /**
+   * Returns myNLinkNodeMap
+   */
+  const NLinkNodeMap& GetNLinkNodeMap() const { return myNLinkNodeMap; }
+
+protected:
 
   /*!
    * \brief Select UV on either of 2 pcurves of a seam edge, closest to the given UV
@@ -349,20 +309,23 @@ public:
 
  private:
 
-  void* myMesh;
-
-  int myShapeID;
-
-  // Key for creation quadratic faces
-  bool myCreateQuadratic;
+  // Forbiden copy constructor
+  SMESH_MesherHelper (const SMESH_MesherHelper& theOther) {};
 
   // special map for using during creation quadratic faces
-  NLinkNodeMap myNLinkNodeMap;
+  NLinkNodeMap    myNLinkNodeMap;
 
   std::set< int > mySeamShapeIds;
   double          myPar1, myPar2; // bounds of a closed periodic surface
   int             myParIndex;     // bounds' index (1-U, 2-V)
+
   TopoDS_Shape    myShape;
+  SMESH_Mesh*     myMesh;
+  int             myShapeID;
+
+  // to create quadratic elements
+  bool            myCreateQuadratic;
+  bool            mySetElemOnShape;
 
 };
 
index 5b224ae5d8ff163c56c6b4a097cb6373e3f43bea..93d241c7e3232ec29be81313474a3c444e08ec34 100644 (file)
@@ -71,8 +71,9 @@ SMESH_Octree::~SMESH_Octree ()
 //===========================================================================
 void SMESH_Octree::setBox(const Bnd_B3d* box)
 {
-  delete myBox;
-  myBox=new Bnd_B3d(*box);
+//   delete myBox;
+//   myBox=new Bnd_B3d(*box);
+  *myBox = *box;
 }
 
 //===========================================================================
@@ -81,11 +82,12 @@ void SMESH_Octree::setBox(const Bnd_B3d* box)
  * \param box          - Set box to the 3d Bounding Box of the Octree
  */
 //===========================================================================
-void SMESH_Octree::getBox(Bnd_B3d* box)
+void SMESH_Octree::getBox(Bnd_B3d& box)
 {
-  if(box != NULL)
-    delete box;
-  box = new Bnd_B3d (*myBox);
+//   if(box != NULL)
+//     delete box;
+//   box = new Bnd_B3d (*myBox);
+  box = *myBox;
 }
 
 //===========================================================================
@@ -135,7 +137,7 @@ void SMESH_Octree::Compute()
 //=================================================================
 void SMESH_Octree::buildChildren()
 {
-  myChildren = new (SMESH_Octree*)[8];
+  myChildren = new SMESH_Octree*[8];
 
   gp_XYZ min = myBox->CornerMin();
   gp_XYZ max = myBox->CornerMax();
index d9615b8dd8e7a5cc93c32acef9c6f3a120e6e08f..525bc62ad8b07c4e2daf11c77c8fb33b5d8c1f24 100644 (file)
@@ -56,11 +56,14 @@ public:
   void                   setBox(const Bnd_B3d* box);
 
   // Set box to the 3d Bounding Box of the Octree
-  void                   getBox(Bnd_B3d* box);
+  void                   getBox(Bnd_B3d & box);
 
   // Compute the bigger dimension of the box
   static double          maxSize(const Bnd_B3d* box);
 
+  // Return its level
+  int                    level() const { return myLevel; }
+
 protected:
   // Constructor for children (has to be implemented in inherited classes)
   virtual SMESH_Octree* allocateOctreeChild() = 0;
index 52f1e3071799bb048975583044fe08ad98c4b7b5..16fb784fb791811c74f6a599e4c2e2f9e38147c4 100644 (file)
 // Module    : SMESH
 
 #include "SMESH_OctreeNode.hxx"
+
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_SetIterator.hxx"
 #include <gp_Pnt.hxx>
-#include <SMDS_MeshNode.hxx>
 
 using namespace std;
 
@@ -42,7 +44,7 @@ using namespace std;
  * \param minBoxSize - Minimal size of the Octree Box
  */
 //================================================================
-SMESH_OctreeNode::SMESH_OctreeNode (set<const SMDS_MeshNode*> theNodes, const int maxLevel,
+SMESH_OctreeNode::SMESH_OctreeNode (const set<const SMDS_MeshNode*> & theNodes, const int maxLevel,
                                     const int maxNbNodes , const double minBoxSize )
   :SMESH_Octree(maxLevel,minBoxSize),
   myMaxNbNodes(maxNbNodes),
@@ -119,11 +121,10 @@ const bool SMESH_OctreeNode::isInside(const SMDS_MeshNode * Node, const double p
   bool Out = 1 ;
   if (precision<=0.)
      return !(myBox->IsOut(gp_XYZ(X,Y,Z)));
-  Bnd_B3d * BoxWithPrecision = new Bnd_B3d();
+  Bnd_B3d BoxWithPrecision;
   getBox(BoxWithPrecision);
-  BoxWithPrecision->Enlarge(precision);
-  Out=BoxWithPrecision->IsOut(gp_XYZ(X,Y,Z));
-  delete BoxWithPrecision;
+  BoxWithPrecision.Enlarge(precision);
+  Out=BoxWithPrecision.IsOut(gp_XYZ(X,Y,Z));
   return !(Out);
 }
 
@@ -325,3 +326,28 @@ void SMESH_OctreeNode::FindCoincidentNodes( const SMDS_MeshNode * Node,
   }
 }
 
+//================================================================================
+/*!
+ * \brief Return iterator over children
+ */
+//================================================================================
+
+SMESH_OctreeNodeIteratorPtr SMESH_OctreeNode::GetChildrenIterator()
+{
+  return SMESH_OctreeNodeIteratorPtr
+    ( new SMDS_SetIterator< SMESH_OctreeNode*, SMESH_Octree** >
+      ( myChildren, ( isLeaf() ? myChildren : &myChildren[ 8 ] )));
+}
+
+//================================================================================
+/*!
+ * \brief Return nodes iterator
+ */
+//================================================================================
+
+SMDS_NodeIteratorPtr SMESH_OctreeNode::GetNodeIterator()
+{
+  return SMDS_NodeIteratorPtr
+    ( new SMDS_SetIterator< SMDS_pNode, set< SMDS_pNode >::const_iterator >
+      ( myNodes.begin(), myNodes.end() ));
+}
index ce8bfde26566f2fc490d26dd47250144b465bbd1..4feb86842c154c8757068b6282ce76d83a36b4db 100644 (file)
 
 #include "SMESH_Octree.hxx"
 
+#include <list>
+#include <set>
+
+#include "SMDS_ElemIterator.hxx"
+
 //forward declaration
 class SMDS_MeshNode;
+class SMESH_OctreeNode;
 
-#include <list>
-#include <set>
+typedef SMDS_Iterator<SMESH_OctreeNode*>            SMESH_OctreeNodeIterator;
+typedef boost::shared_ptr<SMESH_OctreeNodeIterator> SMESH_OctreeNodeIteratorPtr;
 
 class SMESH_OctreeNode : public SMESH_Octree{
 
 public:
 
   // Constructor
-  SMESH_OctreeNode (set<const SMDS_MeshNode*>  theNodes, const int maxLevel = -1,
+  SMESH_OctreeNode (const set<const SMDS_MeshNode*>& theNodes, const int maxLevel = -1,
                     const int maxNbNodes = 5 , const double minBoxSize = 0.);
 
 //=============================
@@ -75,8 +81,20 @@ public:
                                            list< list< const SMDS_MeshNode*> >* theGroupsOfNodes,
                                            const double theTolerance = 0.00001, const int maxLevel = -1,
                                            const int maxNbNodes = 5);
-
-  protected:
+  /*!
+   * \brief Return iterator over children
+   */
+  SMESH_OctreeNodeIteratorPtr GetChildrenIterator();
+  /*!
+   * \brief Return nodes iterator
+   */
+  SMDS_NodeIteratorPtr        GetNodeIterator();
+  /*!
+   * \brief Return nb nodes in a tree
+   */
+  int                         NbNodes() const { return myNbNodes; }
+
+protected:
 
 //=============================
 /*!
index 03bce5e4eba33e9c2bb38f63d8a48131214f786b..44396d2afbd43cc0d247785edf3431f7148ea1a8 100644 (file)
@@ -3257,11 +3257,11 @@ void SMESH_Pattern::
   myPolyElems.reserve( myIdsOnBoundary.size() );
 
   // make a set of refined elements
-  map<int,const SMDS_MeshElement* > avoidSet, elemSet;
+  TIDSortedElemSet avoidSet, elemSet;
   std::vector<const SMDS_MeshElement*>::iterator itv =  myElements.begin();
   for(; itv!=myElements.end(); itv++) {
     const SMDS_MeshElement* el = (*itv);
-    avoidSet.insert( make_pair(el->GetID(),el) );
+    avoidSet.insert( el );
   }
   //avoidSet.insert( myElements.begin(), myElements.end() );
 
@@ -3293,7 +3293,7 @@ void SMESH_Pattern::
           SMESH_MeshEditor::FindFaceInSet( n1, n2, elemSet, avoidSet );
         if ( face )
         {
-          avoidSet.insert ( make_pair(face->GetID(),face) );
+          avoidSet.insert ( face );
           myPolyElems.push_back( face );
 
           // some links of <face> are split;
@@ -3414,7 +3414,7 @@ void SMESH_Pattern::
         while ( eIt->more() )
         {
           const SMDS_MeshElement* elem = eIt->next();
-          if ( !volTool.Set( elem ) || !avoidSet.insert( make_pair(elem->GetID(),elem) ).second )
+          if ( !volTool.Set( elem ) || !avoidSet.insert( elem ).second )
             continue; // skip faces or refined elements
           // add polyhedron definition
           myPolyhedronQuantities.push_back(vector<int> ());
index 7c290171fca60a2daee8f0edbf82a36b68806d7e..7c9cba60ff66d9ac8dee4bcae61db7eae66d316f 100644 (file)
 
 #include "SMESH_subMesh.hxx"
 
-#include "SMESH_subMeshEventListener.hxx"
-#include "SMESH_Gen.hxx"
-#include "SMESH_Mesh.hxx"
-#include "SMESH_Hypothesis.hxx"
 #include "SMESH_Algo.hxx"
+#include "SMESH_Gen.hxx"
 #include "SMESH_HypoFilter.hxx"
+#include "SMESH_Hypothesis.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_MesherHelper.hxx"
+#include "SMESH_subMeshEventListener.hxx"
+#include "SMESH_Comment.hxx"
+#include "SMDS_SetIterator.hxx"
 
 #include "utilities.h"
 #include "OpUtil.hxx"
 
 #include <BRep_Builder.hxx>
-
+#include <BRep_Tool.hxx>
 #include <TopExp.hxx>
-#include <TopoDS_Compound.hxx>
-#include <TopTools_MapOfShape.hxx>
-#include <TopTools_ListOfShape.hxx>
-#include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
-
-#ifdef _DEBUG_
-#include <gp_Pnt.hxx>
-#include <BRep_Tool.hxx>
-#include <TopoDS.hxx>
 #include <TopTools_IndexedMapOfShape.hxx>
-#endif
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Compound.hxx>
+#include <gp_Pnt.hxx>
 
 #include <Standard_Failure.hxx>
 #include <Standard_ErrorHandler.hxx>
 
+using namespace std;
+
 //=============================================================================
 /*!
  *  default constructor:
  */
 //=============================================================================
 
-SMESH_subMesh::SMESH_subMesh(int Id, SMESH_Mesh * father, SMESHDS_Mesh * meshDS,
-       const TopoDS_Shape & aSubShape)
+SMESH_subMesh::SMESH_subMesh(int                  Id,
+                             SMESH_Mesh *         father,
+                             SMESHDS_Mesh *       meshDS,
+                             const TopoDS_Shape & aSubShape)
 {
        _subShape = aSubShape;
-       _meshDS = meshDS;
        _subMeshDS = meshDS->MeshElements(_subShape);   // may be null ...
        _father = father;
        _Id = Id;
-       _dependenceAnalysed = false;
+       _dependenceAnalysed = _alwaysComputed = false;
 
        if (_subShape.ShapeType() == TopAbs_VERTEX)
        {
@@ -95,6 +97,7 @@ SMESH_subMesh::~SMESH_subMesh()
 {
   MESSAGE("SMESH_subMesh::~SMESH_subMesh");
   // ****
+  DeleteOwnListeners();
 }
 
 //=============================================================================
@@ -117,16 +120,8 @@ int SMESH_subMesh::GetId() const
 
 SMESHDS_SubMesh * SMESH_subMesh::GetSubMeshDS()
 {
-  // submesh appears in DS only when a mesher set nodes and elements on it
-  if (_subMeshDS==NULL)
-  {
-    _subMeshDS = _meshDS->MeshElements(_subShape);     // may be null ...
-//     if (_subMeshDS==NULL)
-//     {
-//       MESSAGE("problem... subMesh still empty");
-//     }
-  }
-  return _subMeshDS;
+  // submesh appears in DS only when a mesher set nodes and elements on a shape
+  return _subMeshDS ? _subMeshDS : _subMeshDS = _father->GetMeshDS()->MeshElements(_subShape); // may be null
 }
 
 //=============================================================================
@@ -137,9 +132,10 @@ SMESHDS_SubMesh * SMESH_subMesh::GetSubMeshDS()
 
 SMESHDS_SubMesh* SMESH_subMesh::CreateSubMeshDS()
 {
-  if ( !GetSubMeshDS() )
-    _meshDS->NewSubMesh( _meshDS->ShapeToIndex( _subShape ) );
-
+  if ( !GetSubMeshDS() ) {
+    SMESHDS_Mesh* meshDS = _father->GetMeshDS();
+    meshDS->NewSubMesh( meshDS->ShapeToIndex( _subShape ) );
+  }
   return GetSubMeshDS();
 }
 
@@ -151,29 +147,65 @@ SMESHDS_SubMesh* SMESH_subMesh::CreateSubMeshDS()
 
 SMESH_subMesh *SMESH_subMesh::GetFirstToCompute()
 {
-  const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
-  SMESH_subMesh *firstToCompute = 0;
+  SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(true,false);
+  while ( smIt->more() ) {
+    SMESH_subMesh *sm = smIt->next();
+    if ( sm->GetComputeState() == READY_TO_COMPUTE )
+      return sm;
+  }
+  return 0;                     // nothing to compute
+}
 
-  map < int, SMESH_subMesh * >::const_iterator itsub;
-  for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
-  {
-    SMESH_subMesh *sm = (*itsub).second;
-    bool readyToCompute = (sm->GetComputeState() == READY_TO_COMPUTE);
-    if (readyToCompute)
+//================================================================================
+/*!
+ * \brief Allow algo->Compute() if a subshape of lower dim is meshed but
+ *        none mesh entity is bound to it (PAL13615, 2nd part)
+ */
+//================================================================================
+
+void SMESH_subMesh::SetIsAlwaysComputed(bool isAlCo)
+{
+  _alwaysComputed = isAlCo;
+  if ( _alwaysComputed )
+    _computeState = COMPUTE_OK;
+  else
+    ComputeStateEngine( CHECK_COMPUTE_STATE );
+}
+
+//=======================================================================
+//function : IsMeshComputed
+//purpose  : check if _subMeshDS contains mesh elements
+//=======================================================================
+
+bool SMESH_subMesh::IsMeshComputed() const
+{
+  if ( _alwaysComputed )
+    return true;
+  // algo may bind a submesh not to _subShape, eg 3D algo
+  // sets nodes on SHELL while _subShape may be SOLID
+
+  SMESHDS_Mesh* meshDS = _father->GetMeshDS();
+  int dim = SMESH_Gen::GetShapeDim( _subShape );
+  int type = _subShape.ShapeType();
+  for ( ; type <= TopAbs_VERTEX; type++) {
+    if ( dim == SMESH_Gen::GetShapeDim( (TopAbs_ShapeEnum) type ))
     {
-      firstToCompute = sm;
-      break;
+      TopExp_Explorer exp( _subShape, (TopAbs_ShapeEnum) type );
+      for ( ; exp.More(); exp.Next() )
+      {
+        if ( SMESHDS_SubMesh * smDS = meshDS->MeshElements( exp.Current() ))
+        {
+          bool computed = (dim > 0) ? smDS->NbElements() : smDS->NbNodes();
+          if ( computed )
+            return true;
+        }
+      }
     }
+    else
+      break;
   }
-  if (firstToCompute)
-  {
-    return firstToCompute;     // a subMesh of this
-  }
-  if (_computeState == READY_TO_COMPUTE)
-  {
-    return this;               // this
-  }
-  return 0;                     // nothing to compute
+
+  return false;
 }
 
 //=============================================================================
@@ -184,31 +216,26 @@ SMESH_subMesh *SMESH_subMesh::GetFirstToCompute()
 
 bool SMESH_subMesh::SubMeshesComputed()
 {
-  //MESSAGE("SMESH_subMesh::SubMeshesComputed");
-  const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
-
   int myDim = SMESH_Gen::GetShapeDim( _subShape );
   int dimToCheck = myDim - 1;
   bool subMeshesComputed = true;
-  map < int, SMESH_subMesh * >::const_iterator itsub;
-  for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
+  // check subMeshes with upper dimension => reverse iteration
+  SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,true);
+  while ( smIt->more() )
   {
-    SMESH_subMesh *sm = (*itsub).second;
+    SMESH_subMesh *sm = smIt->next();
+    if ( sm->_alwaysComputed )
+      continue;
     const TopoDS_Shape & ss = sm->GetSubShape();
     // MSV 07.04.2006: restrict checking to myDim-1 only. Ex., there is no sense
     // in checking of existence of edges if the algo needs only faces. Moreover,
     // degenerated edges may have no submesh, as after computing NETGEN_2D.
     int dim = SMESH_Gen::GetShapeDim( ss );
     if (dim < dimToCheck)
-      continue;
+      break; // the rest subMeshes are all of less dimension
     SMESHDS_SubMesh * ds = sm->GetSubMeshDS();
-    // PAL10974.
-    // There are some tricks with compute states, e.g. Penta_3D leaves
-    // one face with READY_TO_COMPUTE state in order to be able to
-    // recompute 3D when a locale triangle hypo changes (see PAL7428).
-    // So we check if mesh is really present
     bool computeOk = (sm->GetComputeState() == COMPUTE_OK ||
-                      (ds && ( ds->GetNodes()->more() || ds->GetElements()->more() )));
+                      (ds && ( ds->NbNodes() || ds->NbElements() )));
     if (!computeOk)
     {
       int type = ss.ShapeType();
@@ -273,16 +300,12 @@ bool SMESH_subMesh::SubMeshesComputed()
 
 bool SMESH_subMesh::SubMeshesReady()
 {
-  MESSAGE("SMESH_subMesh::SubMeshesReady");
-  const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
-
   bool subMeshesReady = true;
-  map < int, SMESH_subMesh * >::const_iterator itsub;
-  for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
-  {
-    SMESH_subMesh *sm = (*itsub).second;
-    bool computeOk = ((sm->GetComputeState() == COMPUTE_OK)
-                      || (sm->GetComputeState() == READY_TO_COMPUTE));
+  SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,true);
+  while ( smIt->more() ) {
+    SMESH_subMesh *sm = smIt->next();
+    bool computeOk = (sm->GetComputeState() == COMPUTE_OK ||
+                      sm->GetComputeState() == READY_TO_COMPUTE);
     if (!computeOk)
     {
       subMeshesReady = false;
@@ -305,7 +328,7 @@ bool SMESH_subMesh::SubMeshesReady()
  */
 //=============================================================================
 
-const map < int, SMESH_subMesh * >&SMESH_subMesh::DependsOn()
+const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn()
 {
   if (_dependenceAnalysed)
     return _mapDepend;
@@ -481,6 +504,7 @@ bool SMESH_subMesh::IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis,
 
   // hypothesis
   switch ( theShapeType ) {
+  case TopAbs_VERTEX:
   case TopAbs_EDGE:
   case TopAbs_FACE:
   case TopAbs_SOLID:
@@ -522,31 +546,47 @@ SMESH_Hypothesis::Hypothesis_Status
 
   SMESH_Hypothesis::Hypothesis_Status aux_ret, ret = SMESH_Hypothesis::HYP_OK;
 
-  int dim = SMESH_Gen::GetShapeDim(_subShape);
+  SMESHDS_Mesh* meshDS =_father->GetMeshDS();
+  SMESH_Gen*    gen    =_father->GetGen();
+  SMESH_Algo*   algo   = 0;
 
-  if (dim < 1)
+  if (_subShape.ShapeType() == TopAbs_VERTEX )
   {
-    _algoState = HYP_OK;
-    if (event == ADD_HYP || event == ADD_ALGO)
-      return SMESH_Hypothesis::HYP_BAD_DIM; // do not allow to assign any hyp
-    else
-      return SMESH_Hypothesis::HYP_OK;
+    if ( anHyp->GetDim() != 0) {
+      if (event == ADD_HYP || event == ADD_ALGO)
+        return SMESH_Hypothesis::HYP_BAD_DIM;
+      else
+        return SMESH_Hypothesis::HYP_OK;
+    }
+    // 0D hypothesis
+    else if ( _algoState == HYP_OK ) { // update default _algoState
+      _algoState = NO_ALGO;
+      algo = gen->GetAlgo(*_father, _subShape);
+      if ( algo ) {
+        _algoState = MISSING_HYP;
+        if ( algo->CheckHypothesis(*_father,_subShape, aux_ret))
+          _algoState = HYP_OK;
+      }
+    }
   }
 
-  SMESH_Gen* gen   =_father->GetGen();
-  SMESH_Algo* algo = 0;
   int oldAlgoState = _algoState;
-  bool modifiedHyp = false;  // if set to true, force event MODIF_ALGO_STATE
-                             // in ComputeStateEngine
+  bool modifiedHyp = (event == MODIF_HYP);  // if set to true, force event MODIF_ALGO_STATE
+
+  bool isApplicableHyp = IsApplicableHypotesis( anHyp );
 
-  // ----------------------
-  // check mesh conformity
-  // ----------------------
-  if (event == ADD_ALGO)
+  if (event == ADD_ALGO || event == ADD_FATHER_ALGO)
   {
-    if (IsApplicableHypotesis( anHyp ) &&
-        !_father->IsNotConformAllowed() &&
-        !IsConform( static_cast< SMESH_Algo* >( anHyp )))
+    // -------------------------------------------
+    // check if a shape needed by algo is present
+    // -------------------------------------------
+    algo = static_cast< SMESH_Algo* >( anHyp );
+    if ( !_father->HasShapeToMesh() && algo->NeedShape() )
+      return SMESH_Hypothesis::HYP_BAD_GEOMETRY;
+    // ----------------------
+    // check mesh conformity
+    // ----------------------
+    if (isApplicableHyp && !_father->IsNotConformAllowed() && !IsConform( algo ))
       return SMESH_Hypothesis::HYP_NOTCONFORM;
   }
 
@@ -555,16 +595,17 @@ SMESH_Hypothesis::Hypothesis_Status
   // ----------------------------------
   if (event == ADD_HYP || event == ADD_ALGO)
   {
-    if ( ! CanAddHypothesis( anHyp ))
+    if ( ! CanAddHypothesis( anHyp )) // check dimension
       return SMESH_Hypothesis::HYP_BAD_DIM;
 
     if ( /*!anHyp->IsAuxiliary() &&*/ GetSimilarAttached( _subShape, anHyp ) )
       return SMESH_Hypothesis::HYP_ALREADY_EXIST;
 
-    if ( !_meshDS->AddHypothesis(_subShape, anHyp))
+    if ( !meshDS->AddHypothesis(_subShape, anHyp))
       return SMESH_Hypothesis::HYP_ALREADY_EXIST;
 
     // Serve Propagation of 1D hypothesis
+    // NOTE: it is possible to re-implement Propagation using EventListener
     if (event == ADD_HYP) {
       bool isPropagationOk = true;
       bool isPropagationHyp = ( strcmp( "Propagation", anHyp->GetName() ) == 0 );
@@ -612,10 +653,11 @@ SMESH_Hypothesis::Hypothesis_Status
   // --------------------------
   if (event == REMOVE_HYP || event == REMOVE_ALGO)
   {
-    if (!_meshDS->RemoveHypothesis(_subShape, anHyp))
+    if (!meshDS->RemoveHypothesis(_subShape, anHyp))
       return SMESH_Hypothesis::HYP_OK; // nothing changes
 
     // Serve Propagation of 1D hypothesis
+    // NOTE: it is possible to re-implement Propagation using EventListener
     if (event == REMOVE_HYP)
     {
       bool isPropagationOk = true;
@@ -670,7 +712,7 @@ SMESH_Hypothesis::Hypothesis_Status
   // ------------------
   // analyse algo state
   // ------------------
-  if (!IsApplicableHypotesis( anHyp ))
+  if (!isApplicableHyp)
     return ret; // not applicable hypotheses do not change algo state
 
   switch (_algoState)
@@ -688,7 +730,7 @@ SMESH_Hypothesis::Hypothesis_Status
       if (algo->CheckHypothesis((*_father),_subShape, aux_ret))
         SetAlgoState(HYP_OK);
       else if ( algo->IsStatusFatal( aux_ret )) {
-        _meshDS->RemoveHypothesis(_subShape, anHyp);
+        meshDS->RemoveHypothesis(_subShape, anHyp);
         ret = aux_ret;
       }
       else
@@ -696,9 +738,7 @@ SMESH_Hypothesis::Hypothesis_Status
       break;
     }
     case REMOVE_HYP:
-      break;
     case REMOVE_ALGO:
-      break;
     case ADD_FATHER_HYP:
       break;
     case ADD_FATHER_ALGO: {    // Algo just added in father
@@ -725,6 +765,7 @@ SMESH_Hypothesis::Hypothesis_Status
       }
       break;
     }
+    case MODIF_HYP: break;
     default:
       ASSERT(0);
       break;
@@ -742,10 +783,10 @@ SMESH_Hypothesis::Hypothesis_Status
       if ( algo->CheckHypothesis((*_father),_subShape, ret ))
         SetAlgoState(HYP_OK);
       if (SMESH_Hypothesis::IsStatusFatal( ret ))
-        _meshDS->RemoveHypothesis(_subShape, anHyp);
+        meshDS->RemoveHypothesis(_subShape, anHyp);
       else if (!_father->IsUsedHypothesis( anHyp, this ))
       {
-        _meshDS->RemoveHypothesis(_subShape, anHyp);
+        meshDS->RemoveHypothesis(_subShape, anHyp);
         ret = SMESH_Hypothesis::HYP_INCOMPATIBLE;
       }
       break;
@@ -756,7 +797,7 @@ SMESH_Hypothesis::Hypothesis_Status
       if ( algo->CheckHypothesis((*_father),_subShape, aux_ret ))// ignore hyp status
         SetAlgoState(HYP_OK);
       else if ( algo->IsStatusFatal( aux_ret )) {
-        _meshDS->RemoveHypothesis(_subShape, anHyp);
+        meshDS->RemoveHypothesis(_subShape, anHyp);
         ret = aux_ret;
       }
       else
@@ -780,6 +821,7 @@ SMESH_Hypothesis::Hypothesis_Status
       }
       break;
     }
+    case MODIF_HYP: // assigned hypothesis value may become good
     case ADD_FATHER_HYP: {
       algo = gen->GetAlgo((*_father), _subShape);
       ASSERT(algo);
@@ -843,7 +885,7 @@ SMESH_Hypothesis::Hypothesis_Status
       if (SMESH_Hypothesis::IsStatusFatal( ret ))
       {
         MESSAGE("do not add extra hypothesis");
-        _meshDS->RemoveHypothesis(_subShape, anHyp);
+        meshDS->RemoveHypothesis(_subShape, anHyp);
       }
       else
       {
@@ -896,6 +938,7 @@ SMESH_Hypothesis::Hypothesis_Status
       }
       break;
     }
+    case MODIF_HYP: // hypothesis value may become bad
     case ADD_FATHER_HYP: {  // new father hypothesis ?
       algo = gen->GetAlgo((*_father), _subShape);
       ASSERT(algo);
@@ -970,22 +1013,51 @@ SMESH_Hypothesis::Hypothesis_Status
     break;
   }
 
-  if ( _algoState != oldAlgoState )
+  // detect algorithm hiding
+  //
+  if ( ret == SMESH_Hypothesis::HYP_OK &&
+       ( event == ADD_ALGO || event == ADD_FATHER_ALGO ) &&
+       algo->GetName() == anHyp->GetName() )
   {
-    if (_algoState == HYP_OK )
-      algo->SetEventListener( this );
-    if ( oldAlgoState == HYP_OK )
-      DeleteOwnListeners();
+    // is algo hidden?
+    SMESH_Gen* gen = _father->GetGen();
+    TopTools_ListIteratorOfListOfShape it( _father->GetAncestors( _subShape ));
+    for ( ; ( ret == SMESH_Hypothesis::HYP_OK && it.More()); it.Next() ) {
+      if ( SMESH_Algo* upperAlgo = gen->GetAlgo( *_father, it.Value() ))
+        if ( !upperAlgo->NeedDescretBoundary() )
+          ret = SMESH_Hypothesis::HYP_HIDDEN_ALGO;
+    }
+    // is algo hiding?
+    if ( ret == SMESH_Hypothesis::HYP_OK && !algo->NeedDescretBoundary() ) {
+      map<int, SMESH_subMesh*>::reverse_iterator i_sm = _mapDepend.rbegin();
+      for ( ; ( ret == SMESH_Hypothesis::HYP_OK && i_sm != _mapDepend.rend()) ; ++i_sm )
+        if ( gen->GetAlgo( *_father, i_sm->second->_subShape ))
+          ret = SMESH_Hypothesis::HYP_HIDING_ALGO;
+    }
   }
+
+  bool stateChange = ( _algoState != oldAlgoState );
+
+  if ( stateChange && _algoState == HYP_OK ) // hyp becomes OK
+    algo->SetEventListener( this );
+
   NotifyListenersOnEvent( event, ALGO_EVENT, anHyp );
 
-  if (_algoState != oldAlgoState || modifiedHyp)
+  if ( stateChange && oldAlgoState == HYP_OK ) { // hyp becomes KO
+    DeleteOwnListeners();
+    if (_subShape.ShapeType() == TopAbs_VERTEX ) {
+      // restore default states
+      _algoState = HYP_OK;
+      _computeState = READY_TO_COMPUTE;
+    }
+  }
+
+  if (stateChange || modifiedHyp)
     ComputeStateEngine(MODIF_ALGO_STATE);
 
   return ret;
 }
 
-
 //=======================================================================
 //function : IsConform
 //purpose  : check if a conform mesh will be produced by the Algo
@@ -994,18 +1066,22 @@ SMESH_Hypothesis::Hypothesis_Status
 bool SMESH_subMesh::IsConform(const SMESH_Algo* theAlgo)
 {
 //  MESSAGE( "SMESH_subMesh::IsConform" );
-
   if ( !theAlgo ) return false;
 
+  // Suppose that theAlgo is applicable to _subShape, do not check it here
+  //if ( !IsApplicableHypotesis( theAlgo )) return false;
+
   // check only algo that doesn't NeedDescretBoundary(): because mesh made
   // on a sub-shape will be ignored by theAlgo
-  if ( theAlgo->NeedDescretBoundary() )
+  if ( theAlgo->NeedDescretBoundary() ||
+       !theAlgo->OnlyUnaryInput() ) // all adjacent shapes will be meshed by this algo?
     return true;
 
   SMESH_Gen* gen =_father->GetGen();
 
   // only local algo is to be checked
-  if ( gen->IsGlobalHypothesis( theAlgo, *_father ))
+  //if ( gen->IsGlobalHypothesis( theAlgo, *_father ))
+  if ( _subShape.ShapeType() == _father->GetMeshDS()->ShapeToMesh().ShapeType() )
     return true;
 
   // check algo attached to adjacent shapes
@@ -1026,9 +1102,8 @@ bool SMESH_subMesh::IsConform(const SMESH_Algo* theAlgo)
       // check algo attached to smAdjacent
       SMESH_Algo * algo = gen->GetAlgo((*_father), adjacent);
       if (algo &&
-          //algo != theAlgo &&
-          !algo->NeedDescretBoundary() /*&&
-          !gen->IsGlobalHypothesis( algo, *_father )*/)
+          !algo->NeedDescretBoundary() &&
+          algo->OnlyUnaryInput())
         return false; // NOT CONFORM MESH WILL BE PRODUCED
     }
   }
@@ -1056,20 +1131,15 @@ SMESH_Hypothesis::Hypothesis_Status
   SMESH_subMesh::SubMeshesAlgoStateEngine(int event,
                                           SMESH_Hypothesis * anHyp)
 {
-  //MESSAGE("SMESH_subMesh::SubMeshesAlgoStateEngine");
   SMESH_Hypothesis::Hypothesis_Status ret = SMESH_Hypothesis::HYP_OK;
   //EAP: a wire (dim==1) should notify edges (dim==1)
   //EAP: int dim = SMESH_Gen::GetShapeDim(_subShape);
   if (_subShape.ShapeType() < TopAbs_EDGE ) // wire,face etc
   {
-    const map < int, SMESH_subMesh * >&subMeshes = DependsOn();
-
-    map < int, SMESH_subMesh * >::const_iterator itsub;
-    for (itsub = subMeshes.begin(); itsub != subMeshes.end(); itsub++)
-    {
-      SMESH_subMesh *sm = (*itsub).second;
+    SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
+    while ( smIt->more() ) {
       SMESH_Hypothesis::Hypothesis_Status ret2 =
-        sm->AlgoStateEngine(event, anHyp);
+        smIt->next()->AlgoStateEngine(event, anHyp);
       if ( ret2 > ret )
         ret = ret2;
     }
@@ -1085,15 +1155,9 @@ SMESH_Hypothesis::Hypothesis_Status
 
 void SMESH_subMesh::CleanDependsOn()
 {
-  //MESSAGE("SMESH_subMesh::CleanDependsOn");
-
-  const map < int, SMESH_subMesh * >&dependson = DependsOn();
-  map < int, SMESH_subMesh * >::const_iterator its;
-  for (its = dependson.begin(); its != dependson.end(); its++)
-  {
-    SMESH_subMesh *sm = (*its).second;
-    sm->ComputeStateEngine(CLEAN);
-  }
+  SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
+  while ( smIt->more() )
+    smIt->next()->ComputeStateEngine(CLEAN);
 }
 
 //=============================================================================
@@ -1172,8 +1236,10 @@ static void cleanSubMesh( SMESH_subMesh * subMesh )
       while (itn->more()) {
         const SMDS_MeshNode * node = itn->next();
         //MESSAGE( " RM node: "<<node->GetID());
-        //meshDS->RemoveNode(node);
-        meshDS->RemoveFreeNode(node, subMeshDS);
+        if ( node->NbInverseNodes() == 0 )
+          meshDS->RemoveFreeNode(node, subMeshDS);
+        else // for StdMeshers_CompositeSegment_1D: node in one submesh, edge in another
+          meshDS->RemoveNode(node);
       }
     }
   }
@@ -1187,25 +1253,36 @@ static void cleanSubMesh( SMESH_subMesh * subMesh )
 
 bool SMESH_subMesh::ComputeStateEngine(int event)
 {
+  _computeError.reset();
+
   //MESSAGE("SMESH_subMesh::ComputeStateEngine");
   //SCRUTE(_computeState);
   //SCRUTE(event);
 
-  int dim = SMESH_Gen::GetShapeDim(_subShape);
-
-  if (dim < 1)
+  if (_subShape.ShapeType() == TopAbs_VERTEX)
   {
-    if ( IsMeshComputed() )
+    _computeState = READY_TO_COMPUTE;
+    SMESHDS_SubMesh* smDS = GetSubMeshDS();
+    if ( smDS && smDS->NbNodes() ) {
       _computeState = COMPUTE_OK;
-    else
-      _computeState = READY_TO_COMPUTE;
+    }
+    else if ( event == COMPUTE && !_alwaysComputed ) {
+      const TopoDS_Vertex & V = TopoDS::Vertex( _subShape );
+      gp_Pnt P = BRep_Tool::Pnt(V);
+      if ( SMDS_MeshNode * n = _father->GetMeshDS()->AddNode(P.X(), P.Y(), P.Z()) ) {
+        _father->GetMeshDS()->SetNodeOnVertex(n,_Id);
+        _computeState = COMPUTE_OK;
+      }
+    }
+    if ( event == MODIF_ALGO_STATE )
+      CleanDependants();
     return true;
   }
   SMESH_Gen *gen = _father->GetGen();
   SMESH_Algo *algo = 0;
   bool ret = true;
   SMESH_Hypothesis::Hypothesis_Status hyp_status;
-  algo_state oldAlgoState = (algo_state) GetAlgoState();
+  //algo_state oldAlgoState = (algo_state) GetAlgoState();
 
   switch (_computeState)
   {
@@ -1215,21 +1292,12 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
   case NOT_READY:
     switch (event)
     {
-    case MODIF_HYP:
     case MODIF_ALGO_STATE:
       algo = gen->GetAlgo((*_father), _subShape);
       if (algo && !algo->NeedDescretBoundary())
         CleanDependsOn(); // clean sub-meshes with event CLEAN
-      if (algo)
-      {
-        ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
-        if (ret)
-          _computeState = READY_TO_COMPUTE;
-      }
-      if ( _computeState == READY_TO_COMPUTE )
-          SetAlgoState(HYP_OK);
-      else
-          SetAlgoState(MISSING_HYP);
+      if ( _algoState == HYP_OK )
+        _computeState = READY_TO_COMPUTE;
       break;
     case COMPUTE:              // nothing to do
       break;
@@ -1240,7 +1308,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
     case SUBMESH_COMPUTED:     // nothing to do
       break;
     case SUBMESH_RESTORED:
-      ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE );
+      ComputeSubMeshStateEngine( SUBMESH_RESTORED );
       break;
     case MESH_ENTITY_REMOVED:
       break;
@@ -1259,21 +1327,15 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
   case READY_TO_COMPUTE:
     switch (event)
     {
-    case MODIF_HYP:
     case MODIF_ALGO_STATE:
-      algo = gen->GetAlgo((*_father), _subShape);
-      if (algo && !algo->NeedDescretBoundary())
-        CleanDependsOn(); // clean sub-meshes with event CLEAN
       _computeState = NOT_READY;
+      algo = gen->GetAlgo((*_father), _subShape);
       if (algo)
       {
-        ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
-        if (ret) {
-          SetAlgoState(HYP_OK); // it might be KO if BAD_PARAM_VALUE
+        if (!algo->NeedDescretBoundary())
+          CleanDependsOn(); // clean sub-meshes with event CLEAN
+        if ( _algoState == HYP_OK )
           _computeState = READY_TO_COMPUTE;
-        }
-        else
-          SetAlgoState(MISSING_HYP);
       }
       break;
     case COMPUTE:
@@ -1289,60 +1351,99 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
           break;
         }
         // check submeshes needed
-        if (algo->NeedDescretBoundary())
-          ret = SubMeshesComputed();
-        if (!ret)
-        {
-          MESSAGE("Some SubMeshes not computed");
-          _computeState = FAILED_TO_COMPUTE;
-          break;
+        if (_father->HasShapeToMesh() ) {
+          bool subComputed = SubMeshesComputed();
+          ret = ( algo->NeedDescretBoundary() ? subComputed :
+                  ( !subComputed || _father->IsNotConformAllowed() ));
+          if (!ret) {
+            _computeState = FAILED_TO_COMPUTE;
+            if ( !algo->NeedDescretBoundary() )
+              _computeError =
+                SMESH_ComputeError::New(COMPERR_BAD_INPUT_MESH,"Unexpected submesh",algo);
+            break;
+          }
         }
         // compute
         CleanDependants();
         RemoveSubMeshElementsAndNodes();
-       {
-         try {
+        ret = false;
+        _computeState = FAILED_TO_COMPUTE;
+        _computeError = SMESH_ComputeError::New(COMPERR_OK,"",algo);
+        try {
 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
-            OCC_CATCH_SIGNALS;
+          OCC_CATCH_SIGNALS;
 #endif
-           if (!algo->NeedDescretBoundary() && !algo->OnlyUnaryInput())
-             ret = ApplyToCollection( algo, GetCollection( gen, algo ) );
-           else
-             ret = algo->Compute((*_father), _subShape);
-         }
-         catch (Standard_Failure) {
-           MESSAGE( "Exception in algo->Compute() ");
-           ret = false;
-         }
-       }
+          algo->InitComputeError();
+          if ( !_father->HasShapeToMesh() ) // no shape
+          {
+            SMESH_MesherHelper helper( *_father );
+            helper.SetSubShape( _subShape );
+            helper.SetElementsOnShape( true );
+            ret = algo->Compute(*_father, &helper );
+          }
+          else
+          {
+            if (!algo->NeedDescretBoundary() && !algo->OnlyUnaryInput()) {
+              ret = ApplyToCollection( algo, GetCollection( gen, algo ) );
+              break;
+            }
+            else {
+              ret = algo->Compute((*_father), _subShape);
+            }
+          }
+          if ( !ret )
+            _computeError = algo->GetComputeError();
+        }
+        catch (Standard_Failure& exc) {
+          if ( !_computeError ) _computeError = SMESH_ComputeError::New();
+          _computeError->myName    = COMPERR_OCC_EXCEPTION;
+          _computeError->myComment = exc.GetMessageString();
+        }
+        catch ( SALOME_Exception& S_ex ) {
+          if ( !_computeError ) _computeError = SMESH_ComputeError::New();
+          _computeError->myName    = COMPERR_SLM_EXCEPTION;
+          _computeError->myComment = S_ex.what();
+        }
+        catch ( std::bad_alloc& exc ) {
+          if ( _computeError ) {
+            _computeError->myName    = COMPERR_MEMORY_PB;
+            _computeError->myComment = exc.what();
+          }
+          throw exc;
+        }
+        catch ( std::exception& exc ) {
+          if ( !_computeError ) _computeError = SMESH_ComputeError::New();
+          _computeError->myName    = COMPERR_STD_EXCEPTION;
+          _computeError->myComment = exc.what();
+        }
+        catch ( ... ) {
+          if ( _computeError )
+            _computeError->myName = COMPERR_EXCEPTION;
+          else
+            ret = false;
+        }
+        if ( ret && _computeError && !_computeError->IsOK() ) {
+          ret = false;
+        }
+        if (ret) { // check if anything was built
+          ret = ( GetSubMeshDS() && ( GetSubMeshDS()->NbElements() || GetSubMeshDS()->NbNodes() ));
+        }
         if (!ret)
         {
-          MESSAGE("problem in algo execution: failed to compute");
-          // release ALGO from responsibilty of partially built mesh
-          RemoveSubMeshElementsAndNodes();
-          _computeState = FAILED_TO_COMPUTE;
-          if (!algo->NeedDescretBoundary())
-            UpdateSubMeshState( FAILED_TO_COMPUTE );
-
-#ifdef _DEBUG_
-          // Show vertices location of a failed shape
-          cout << algo->GetName() << " failed on shape with the following vertices:" << endl;
-          TopTools_IndexedMapOfShape vMap;
-          TopExp::MapShapes( _subShape, TopAbs_VERTEX, vMap );
-          for ( int iv = 1; iv <= vMap.Extent(); ++iv ) {
-            gp_Pnt P( BRep_Tool::Pnt( TopoDS::Vertex( vMap( iv ) )));
-            cout << P.X() << " " << P.Y() << " " << P.Z() << " " << endl;
-          }
-#endif
-          break;
+          // Set _computeError
+          if ( !_computeError )
+            _computeError = SMESH_ComputeError::New();
+          if ( _computeError->IsOK() )
+            _computeError->myName = COMPERR_ALGO_FAILED;
         }
         else
         {
-          _computeState = COMPUTE_OK;
+          _computeError.reset();
           UpdateDependantsState( SUBMESH_COMPUTED ); // send event SUBMESH_COMPUTED
-          if (!algo->NeedDescretBoundary())
-            UpdateSubMeshState( COMPUTE_OK );
         }
+        if ( !algo->NeedDescretBoundary() )
+          UpdateSubMeshState( ret ? COMPUTE_OK : FAILED_TO_COMPUTE );
+        CheckComputeError( algo );
       }
       break;
     case CLEAN:
@@ -1365,7 +1466,9 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
       // check if a mesh is already computed that may
       // happen after retrieval from a file
       ComputeStateEngine( CHECK_COMPUTE_STATE );
-      ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE );
+      ComputeSubMeshStateEngine( SUBMESH_RESTORED );
+      algo = gen->GetAlgo(*_father, _subShape);
+      if (algo) algo->SubmeshRestored( this );
       break;
     case MESH_ENTITY_REMOVED:
       break;
@@ -1384,7 +1487,6 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
   case COMPUTE_OK:
     switch (event)
     {
-    case MODIF_HYP:
     case MODIF_ALGO_STATE:
       ComputeStateEngine( CLEAN );
       algo = gen->GetAlgo((*_father), _subShape);
@@ -1397,21 +1499,16 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
       CleanDependants();  // clean sub-meshes, dependant on this one, with event CLEAN
       RemoveSubMeshElementsAndNodes();
       _computeState = NOT_READY;
-      algo = gen->GetAlgo((*_father), _subShape);
-      if (algo)
-      {
-        ret = algo->CheckHypothesis((*_father), _subShape, hyp_status);
-        if (ret)
-          _computeState = READY_TO_COMPUTE;
-        else
-          SetAlgoState(MISSING_HYP);
-      }
+      if ( _algoState == HYP_OK )
+        _computeState = READY_TO_COMPUTE;
       break;
     case SUBMESH_COMPUTED:      // nothing to do
       break;
     case SUBMESH_RESTORED:
       ComputeStateEngine( CHECK_COMPUTE_STATE );
-      ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE );
+      ComputeSubMeshStateEngine( SUBMESH_RESTORED );
+      algo = gen->GetAlgo(*_father, _subShape);
+      if (algo) algo->SubmeshRestored( this );
       break;
     case MESH_ENTITY_REMOVED:
       UpdateDependantsState( CHECK_COMPUTE_STATE );
@@ -1436,12 +1533,6 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
   case FAILED_TO_COMPUTE:
     switch (event)
     {
-    case MODIF_HYP:
-      if (_algoState == HYP_OK)
-        _computeState = READY_TO_COMPUTE;
-      else
-        _computeState = NOT_READY;
-      break;
     case MODIF_ALGO_STATE:
       if (_algoState == HYP_OK)
         _computeState = READY_TO_COMPUTE;
@@ -1453,10 +1544,6 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
     case CLEAN:
       CleanDependants(); // submeshes dependent on me should be cleaned as well
       RemoveSubMeshElementsAndNodes();
-      if (_algoState == HYP_OK)
-        _computeState = READY_TO_COMPUTE;
-      else
-        _computeState = NOT_READY;
       break;
     case SUBMESH_COMPUTED:      // allow retry compute
       if (_algoState == HYP_OK)
@@ -1465,7 +1552,7 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
         _computeState = NOT_READY;
       break;
     case SUBMESH_RESTORED:
-      ComputeSubMeshStateEngine( CHECK_COMPUTE_STATE );
+      ComputeSubMeshStateEngine( SUBMESH_RESTORED );
       break;
     case MESH_ENTITY_REMOVED:
       break;
@@ -1490,19 +1577,64 @@ bool SMESH_subMesh::ComputeStateEngine(int event)
     break;
   }
 
-  if ( _algoState != oldAlgoState || event == MODIF_HYP )
-  {
-    if ( oldAlgoState == HYP_OK )
-      DeleteOwnListeners();
-    if (_algoState == HYP_OK && algo )
-      algo->SetEventListener( this );
-  }
   NotifyListenersOnEvent( event, COMPUTE_EVENT );
 
-  //SCRUTE(_computeState);
   return ret;
 }
 
+//=======================================================================
+/*!
+ * \brief Update compute_state by _computeError
+ */
+//=======================================================================
+
+bool SMESH_subMesh::CheckComputeError(SMESH_Algo* theAlgo)
+{
+  bool noErrors = ( !_computeError || _computeError->IsOK() );
+  if ( !noErrors )
+  {
+    if ( !_computeError->myAlgo )
+      _computeError->myAlgo = theAlgo;
+
+    // Show error
+    SMESH_Comment text;
+    text << theAlgo->GetName() << " failed on subshape " << _Id << " with error ";
+    if (_computeError->IsCommon() )
+      text << _computeError->CommonName();
+    else
+      text << _computeError->myName;
+    if ( _computeError->myComment.size() > 0 )
+      text << " \"" << _computeError->myComment << "\"";
+
+#ifdef _DEBUG_
+    cout << text << endl;
+    // Show vertices location of a failed shape
+    cout << "Subshape vertices (first 10):" << endl;
+    TopTools_IndexedMapOfShape vMap;
+    TopExp::MapShapes( _subShape, TopAbs_VERTEX, vMap );
+    for ( int iv = 1; iv <= vMap.Extent() && iv < 11; ++iv ) {
+      gp_Pnt P( BRep_Tool::Pnt( TopoDS::Vertex( vMap( iv ) )));
+      cout << P.X() << " " << P.Y() << " " << P.Z() << " " << endl;
+    }
+#else
+    INFOS( text );
+#endif
+    _computeState = FAILED_TO_COMPUTE;
+  }
+  else
+  {
+    _computeState = COMPUTE_OK;
+  }
+  // Check state of submeshes
+  if ( !theAlgo->NeedDescretBoundary() /*&& theAlgo->OnlyUnaryInput()*/ ) {
+    SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
+    while ( smIt->more() )
+      if ( !smIt->next()->CheckComputeError( theAlgo ))
+        noErrors = false;
+  }
+  return noErrors;
+}
+
 //=======================================================================
 //function : ApplyToCollection
 //purpose  : Apply theAlgo to all subshapes in theCollection
@@ -1514,32 +1646,32 @@ bool SMESH_subMesh::ApplyToCollection (SMESH_Algo*         theAlgo,
   MESSAGE("SMESH_subMesh::ApplyToCollection");
   ASSERT ( !theAlgo->NeedDescretBoundary() );
 
-  bool ret = false;
+  if ( _computeError )
+    _computeError->myName = COMPERR_OK;
 
-
-  ret = theAlgo->Compute( *_father, theCollection );
+  bool ok = theAlgo->Compute( *_father, theCollection );
 
   // set _computeState of subshapes
   TopExp_Explorer anExplorer( theCollection, _subShape.ShapeType() );
   for ( ; anExplorer.More(); anExplorer.Next() )
   {
-    const TopoDS_Shape& aSubShape = anExplorer.Current();
-    SMESH_subMesh* subMesh = _father->GetSubMeshContaining( aSubShape );
-    if ( subMesh )
+    if ( SMESH_subMesh* subMesh = _father->GetSubMeshContaining( anExplorer.Current() ))
     {
-      if (ret)
+      bool localOK = subMesh->CheckComputeError( theAlgo );
+      if ( !ok && localOK && !subMesh->IsMeshComputed() )
       {
-        subMesh->_computeState = COMPUTE_OK;
-        subMesh->UpdateDependantsState( SUBMESH_COMPUTED );
-        subMesh->UpdateSubMeshState( COMPUTE_OK );
-      }
-      else
-      {
-        subMesh->_computeState = FAILED_TO_COMPUTE;
+        subMesh->_computeError = theAlgo->GetComputeError();
+        if ( subMesh->_computeError->IsOK() )
+          _computeError = SMESH_ComputeError::New(COMPERR_ALGO_FAILED);
+        localOK = CheckComputeError( theAlgo );
       }
+      if ( localOK )
+        subMesh->UpdateDependantsState( SUBMESH_COMPUTED );
+      subMesh->UpdateSubMeshState( localOK ? COMPUTE_OK : FAILED_TO_COMPUTE );
     }
   }
-  return ret;
+
+  return true;
 }
 
 
@@ -1550,13 +1682,9 @@ bool SMESH_subMesh::ApplyToCollection (SMESH_Algo*         theAlgo,
 
 void SMESH_subMesh::UpdateSubMeshState(const compute_state theState)
 {
-  const map<int, SMESH_subMesh*>& smMap = DependsOn();
-  map<int, SMESH_subMesh*>::const_iterator itsub;
-  for (itsub = smMap.begin(); itsub != smMap.end(); itsub++)
-  {
-    SMESH_subMesh* sm = (*itsub).second;
-    sm->_computeState = theState;
-  }
+  SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
+  while ( smIt->more() )
+    smIt->next()->_computeState = theState;
 }
 
 //=======================================================================
@@ -1566,13 +1694,9 @@ void SMESH_subMesh::UpdateSubMeshState(const compute_state theState)
 
 void SMESH_subMesh::ComputeSubMeshStateEngine(int event)
 {
-  const map<int, SMESH_subMesh*>& smMap = DependsOn();
-  map<int, SMESH_subMesh*>::const_iterator itsub;
-  for (itsub = smMap.begin(); itsub != smMap.end(); itsub++)
-  {
-    SMESH_subMesh* sm = (*itsub).second;
-    sm->ComputeStateEngine(event);
-  }
+  SMESH_subMeshIteratorPtr smIt = getDependsOnIterator(false,false);
+  while ( smIt->more() )
+    smIt->next()->ComputeStateEngine(event);
 }
 
 //=======================================================================
@@ -1649,37 +1773,6 @@ void SMESH_subMesh::RemoveSubMeshElementsAndNodes()
   }
 }
 
-//=======================================================================
-//function : IsMeshComputed
-//purpose  : check if _subMeshDS contains mesh elements
-//=======================================================================
-
-bool SMESH_subMesh::IsMeshComputed() const
-{
-  // algo may bind a submesh not to _subShape, eg 3D algo
-  // sets nodes on SHELL while _subShape may be SOLID
-
-  int dim = SMESH_Gen::GetShapeDim( _subShape );
-  int type = _subShape.ShapeType();
-  for ( ; type <= TopAbs_VERTEX; type++) {
-    if ( dim == SMESH_Gen::GetShapeDim( (TopAbs_ShapeEnum) type ))
-    {
-      TopExp_Explorer exp( _subShape, (TopAbs_ShapeEnum) type );
-      for ( ; exp.More(); exp.Next() )
-      {
-        SMESHDS_SubMesh * smDS = _meshDS->MeshElements( exp.Current() );
-        if ( smDS && ( smDS->NbElements() || smDS->NbNodes()))
-          return true;
-      }
-    }
-    else
-      break;
-  }
-
-  return false;
-}
-
-
 //=======================================================================
 //function : GetCollection
 //purpose  : return a shape containing all sub-shapes of the MainShape that can be
@@ -1712,14 +1805,17 @@ TopoDS_Shape SMESH_subMesh::GetCollection(SMESH_Gen * theGen, SMESH_Algo* theAlg
   {
     const TopoDS_Shape& S = anExplorer.Current();
     SMESH_subMesh* subMesh = _father->GetSubMesh( S );
-    SMESH_Algo* anAlgo = theGen->GetAlgo( *_father, S );
-
-    if (subMesh->GetComputeState() == READY_TO_COMPUTE &&
-        anAlgo == theAlgo &&
-        anAlgo->GetUsedHypothesis( *_father, S, ignoreAuxiliaryHyps ) == aUsedHyp)
+    if ( subMesh == this )
     {
       aBuilder.Add( aCompound, S );
     }
+    else if ( subMesh->GetComputeState() == READY_TO_COMPUTE )
+    {
+      SMESH_Algo* anAlgo = theGen->GetAlgo( *_father, S );
+      if (anAlgo == theAlgo &&
+          anAlgo->GetUsedHypothesis( *_father, S, ignoreAuxiliaryHyps ) == aUsedHyp)
+        aBuilder.Add( aCompound, S );
+    }
   }
 
   return aCompound;
@@ -1757,7 +1853,7 @@ const SMESH_Hypothesis* SMESH_subMesh::GetSimilarAttached(const TopoDS_Shape&
 //=======================================================================
 //function : CheckConcurentHypothesis
 //purpose  : check if there are several applicable hypothesis attached to
-//           ansestors
+//           ancestors
 //=======================================================================
 
 SMESH_Hypothesis::Hypothesis_Status
@@ -1830,7 +1926,15 @@ void SMESH_subMesh::SetEventListener(EventListener*     listener,
 
 void SMESH_subMesh::SetEventListener(EventListener* listener, EventListenerData* data)
 {
-  myEventListeners.insert( make_pair( listener, data ));
+  map< EventListener*, EventListenerData* >::iterator l_d =
+    myEventListeners.find( listener );
+  if ( l_d != myEventListeners.end() ) {
+    if ( l_d->second && l_d->second->IsDeletable() )
+      delete l_d->second;
+    l_d->second = data;
+  }
+  else 
+    myEventListeners.insert( make_pair( listener, data ));
 }
 
 //================================================================================
@@ -1882,8 +1986,8 @@ void SMESH_subMesh::DeleteEventListener(EventListener* listener)
   map< EventListener*, EventListenerData* >::iterator l_d =
     myEventListeners.find( listener );
   if ( l_d != myEventListeners.end() ) {
-    if ( l_d->first->IsDeletable() ) delete l_d->first;
-    if ( l_d->second->IsDeletable() ) delete l_d->second;
+    if ( l_d->first  && l_d->first->IsDeletable() )  delete l_d->first;
+    if ( l_d->second && l_d->second->IsDeletable() ) delete l_d->second;
     myEventListeners.erase( l_d );
   }
 }
@@ -1921,7 +2025,7 @@ void SMESH_subMeshEventListener::ProcessEvent(const int          event,
                                               const int          eventType,
                                               SMESH_subMesh*     subMesh,
                                               EventListenerData* data,
-                                              SMESH_Hypothesis*  /*hyp*/)
+                                              const SMESH_Hypothesis*  /*hyp*/)
 {
   if ( data && !data->mySubMeshes.empty() &&
        eventType == SMESH_subMesh::COMPUTE_EVENT)
@@ -1939,3 +2043,69 @@ void SMESH_subMeshEventListener::ProcessEvent(const int          event,
     }
   }
 }
+
+namespace {
+
+  //================================================================================
+  /*!
+   * \brief Iterator over submeshes and optionally prepended or appended one
+   */
+  //================================================================================
+
+  struct _Iterator : public SMDS_Iterator<SMESH_subMesh*>
+  {
+    _Iterator(SMDS_Iterator<SMESH_subMesh*>* subIt,
+              SMESH_subMesh*                 prepend,
+              SMESH_subMesh*                 append): myIt(subIt),myAppend(append)
+    {
+      myCur = prepend ? prepend : myIt->more() ? myIt->next() : 0;
+    }
+    /// Return true if and only if there are other object in this iterator
+    virtual bool more()
+    {
+      return myCur;
+    }
+    /// Return the current object and step to the next one
+    virtual SMESH_subMesh* next()
+    {
+      SMESH_subMesh* res = myCur;
+      if ( myIt->more() ) { myCur = myIt->next(); }
+      else                { myCur = myAppend; myAppend = 0; }
+      return res;
+    }
+    /// ~
+    ~_Iterator()
+    { delete myIt; }
+    ///
+    SMESH_subMesh                 *myAppend, *myCur;
+    SMDS_Iterator<SMESH_subMesh*> *myIt;
+  };
+}
+
+//================================================================================
+/*!
+ * \brief  Return iterator on the submeshes this one depends on
+  * \param includeSelf - this submesh to be returned also
+  * \param reverse - if true, complex shape submeshes go first
+ */
+//================================================================================
+
+SMESH_subMeshIteratorPtr SMESH_subMesh::getDependsOnIterator(const bool includeSelf,
+                                                             const bool reverse)
+{
+  SMESH_subMesh *prepend=0, *append=0;
+  if ( includeSelf ) {
+    if ( reverse ) prepend = this;
+    else            append = this;
+  }
+  typedef map < int, SMESH_subMesh * > TMap;
+  if ( reverse )
+  {
+    return SMESH_subMeshIteratorPtr
+      ( new _Iterator( new SMDS_mapReverseIterator<TMap>( DependsOn() ), prepend, append ));
+  }
+  {
+    return SMESH_subMeshIteratorPtr
+      ( new _Iterator( new SMDS_mapIterator<TMap>( DependsOn() ), prepend, append ));
+  }
+}
index 8e09b5c6f46ffd4bf248142b763d530a6e235efa..001c40203b276d7970b239b00829bd416f232239 100644 (file)
 #include "SMESHDS_Mesh.hxx"
 #include "SMESHDS_SubMesh.hxx"
 #include "SMESH_Hypothesis.hxx"
+#include "SMESH_ComputeError.hxx"
+
 #include "Utils_SALOME_Exception.hxx"
+
 #include <TopoDS_Shape.hxx>
-#include <TColStd_IndexedMapOfTransient.hxx>
-#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
 
-#include <set>
 #include <list>
 #include <map>
 
@@ -49,10 +49,14 @@ class SMESH_Algo;
 class SMESH_Gen;
 class SMESH_subMeshEventListener;
 class SMESH_subMeshEventListenerData;
+class SMESH_subMesh;
 
 typedef SMESH_subMeshEventListener     EventListener;
 typedef SMESH_subMeshEventListenerData EventListenerData;
 
+typedef boost::shared_ptr< SMDS_Iterator<SMESH_subMesh*> > SMESH_subMeshIteratorPtr;
+
+
 class SMESH_EXPORT SMESH_subMesh
 {
  public:
@@ -62,9 +66,6 @@ class SMESH_EXPORT SMESH_subMesh
 
   int GetId() const;
 
-  //   bool Contains(const TopoDS_Shape & aSubShape)
-  //     throw (SALOME_Exception);
-
   SMESH_Mesh* GetFather() { return _father; }
   
   SMESHDS_SubMesh * GetSubMeshDS();
@@ -74,8 +75,13 @@ class SMESH_EXPORT SMESH_subMesh
 
   SMESH_subMesh *GetFirstToCompute();
 
-  const map < int, SMESH_subMesh * >&DependsOn();
+  const map < int, SMESH_subMesh * >& DependsOn();
   //const map < int, SMESH_subMesh * >&Dependants();
+  /*!
+   * \brief Return iterator on the submeshes this one depends on
+   */
+  SMESH_subMeshIteratorPtr getDependsOnIterator(const bool includeSelf,
+                                                const bool complexShapeFirst);
 
   const TopoDS_Shape & GetSubShape() const;
 
@@ -90,14 +96,15 @@ class SMESH_EXPORT SMESH_subMesh
     };
   enum algo_event
   {
-    ADD_HYP, ADD_ALGO,
-    REMOVE_HYP, REMOVE_ALGO,
-    ADD_FATHER_HYP, ADD_FATHER_ALGO,
-    REMOVE_FATHER_HYP, REMOVE_FATHER_ALGO
+    ADD_HYP          , ADD_ALGO,
+    REMOVE_HYP       , REMOVE_ALGO,
+    ADD_FATHER_HYP   , ADD_FATHER_ALGO,
+    REMOVE_FATHER_HYP, REMOVE_FATHER_ALGO,
+    MODIF_HYP
     };
   enum compute_event
   {
-    MODIF_HYP, MODIF_ALGO_STATE, COMPUTE,
+    MODIF_ALGO_STATE, COMPUTE,
     CLEAN, SUBMESH_COMPUTED, SUBMESH_RESTORED,
     MESH_ENTITY_REMOVED, CHECK_COMPUTE_STATE
     };
@@ -115,12 +122,10 @@ class SMESH_EXPORT SMESH_subMesh
     * \param listener - the listener to store
     * \param data - the listener data to store
     * \param where - the submesh to store the listener and it's data
-    * \param deleteListener - if true then the listener will be deleted as
-    *        it is removed from where submesh
    * 
-   * It remembers the submesh where it puts the listener in order to delete
+   * The method remembers the submesh \awhere it puts the listener in order to delete
    * them when HYP_OK algo_state is lost
-   * After being set, event listener is notified on each event of where submesh.
+   * After being set, event listener is notified on each event of \awhere submesh.
    */
   void SetEventListener(EventListener*     listener,
                         EventListenerData* data,
@@ -182,6 +187,7 @@ public:
 
   int GetAlgoState() const { return _algoState; }
   int GetComputeState() const { return _computeState; };
+  SMESH_ComputeErrorPtr& GetComputeError() { return _computeError; }
 
   void DumpAlgoState(bool isMain);
 
@@ -208,6 +214,13 @@ public:
   bool IsMeshComputed() const;
   // check if _subMeshDS contains mesh elements
 
+  /*!
+   * \brief Allow algo->Compute() if a subshape of lower dim is meshed but
+   *        none mesh entity is bound to it
+   */
+  void SetIsAlwaysComputed(bool isAlCo);
+
+
 protected:
   // ==================================================================
   void InsertDependence(const TopoDS_Shape aSubShape);
@@ -224,32 +237,54 @@ protected:
   void CleanDependsOn();
   void SetAlgoState(int state);
 
+  /*!
+   * \brief Return a shape containing all sub-shapes of the MainShape that can be
+   * meshed at once along with _subShape
+   */
   TopoDS_Shape GetCollection(SMESH_Gen * theGen, SMESH_Algo* theAlgo);
-  // return a shape containing all sub-shapes of the MainShape that can be
-  // meshed at once along with _subShape
 
+  /*!
+   * \brief Apply theAlgo to all subshapes in theCollection
+   */
   bool ApplyToCollection (SMESH_Algo*         theAlgo,
                           const TopoDS_Shape& theCollection);
-  // Apply theAlgo to all subshapes in theCollection
 
+  /*!
+   * \brief Update compute_state by _computeError
+    * \retval bool - false if there are errors
+   */
+  bool CheckComputeError(SMESH_Algo* theAlgo);
+
+  /*!
+   * \brief Return a hypothesis attached to theShape.
+   * 
+   * If theHyp is provided, similar but not same hypotheses
+   * is returned; else an applicable ones having theHypType
+   * is returned
+   */
   const SMESH_Hypothesis* GetSimilarAttached(const TopoDS_Shape&      theShape,
                                              const SMESH_Hypothesis * theHyp,
                                              const int                theHypType = 0);
-  // return a hypothesis attached to theShape.
-  // If theHyp is provided, similar but not same hypotheses
-  // is returned; else an applicable ones having theHypType
-  // is returned
-  
-  TopoDS_Shape _subShape;
-  SMESHDS_Mesh * _meshDS;
-  SMESHDS_SubMesh * _subMeshDS;
-  int _Id;
-  SMESH_Mesh *_father;
+  // 
+
+protected:
+
+  TopoDS_Shape          _subShape;
+  SMESHDS_SubMesh *     _subMeshDS;
+  SMESH_Mesh *          _father;
+  int                   _Id;
+
   map < int, SMESH_subMesh * >_mapDepend;
-  bool _dependenceAnalysed;
+  bool                  _dependenceAnalysed;
+
+  int                   _algoState;
+  int                   _computeState;
+  SMESH_ComputeErrorPtr _computeError;
 
-  int _algoState;
-  int _computeState;
+  // allow algo->Compute() if a subshape of lower dim is meshed but
+  // none mesh entity is bound to it. Eg StdMeshers_CompositeSegment_1D can
+  // mesh several edges as a whole and leave some of them  without mesh entities
+  bool                  _alwaysComputed;
 
 };
 
index 7f538c34ec123ec80d0f249f2f47dc2ff186a024..1eb216cf6604cb380d5a9ab370fa41774bdd7e6a 100644 (file)
@@ -64,7 +64,7 @@ public:
                             const int          eventType,
                             SMESH_subMesh*     subMesh,
                             SMESH_subMeshEventListenerData* data,
-                            SMESH_Hypothesis*  hyp = 0);
+                            const SMESH_Hypothesis*         hyp = 0);
 };
 
 // ------------------------------------------------------------------
index 135b0fa85d350b3c653c1f3a553f5e03646e5447..dd44ec9648768e7d809215fbac9d540f8b7113c2 100644 (file)
@@ -621,7 +621,11 @@ SMESH_Client::SMESH_Client(CORBA::ORB_ptr theORB,
     if ( MYDEBUG )
       MESSAGE("Info: The same process, update mesh by pointer ");
     // just set client mesh pointer to server mesh pointer
-    SMESH_Mesh* aMesh = reinterpret_cast<SMESH_Mesh*>(theMesh->GetMeshPtr());
+    //SMESH_Mesh* aMesh = reinterpret_cast<SMESH_Mesh*>(theMesh->GetMeshPtr());
+    CORBA::LongLong pointeur = theMesh->GetMeshPtr();
+    cerr <<"SMESH_Client::SMESH_Client pointeur " << pointeur << endl;
+    SMESH_Mesh* aMesh = reinterpret_cast<SMESH_Mesh*> (pointeur);
+    cerr <<"SMESH_Client::SMESH_Client aMesh " << aMesh << endl;
     if(aMesh->GetMeshDS()->IsEmbeddedMode()){
       mySMESHDSMesh = aMesh->GetMeshDS();
       mySMDSMesh = mySMESHDSMesh;
index 904ee1ec9732da99b01a784ca5a87b3b89d9119b..2b09ed32872dc755915848f5e0c0df0124822282 100644 (file)
@@ -47,7 +47,7 @@ public:
   virtual std::ostream & SaveTo(std::ostream & save)=0;
   virtual std::istream & LoadFrom(std::istream & load)=0;
 
-enum hypothesis_type {PARAM_ALGO, ALGO, ALGO_1D, ALGO_2D, ALGO_3D};
+enum hypothesis_type {PARAM_ALGO, ALGO_0D, ALGO_1D, ALGO_2D, ALGO_3D};
 
 protected:
   std::string _name;
index 36e185f8a94854228a98f33907a794cf86404c43..3351960a8ca6041ba7c66e27b7353e4dee2e191b 100644 (file)
@@ -110,25 +110,18 @@ void SMESHDS_Mesh::ShapeToMesh(const TopoDS_Shape & S)
 //=======================================================================
 
 bool SMESHDS_Mesh::AddHypothesis(const TopoDS_Shape & SS,
-       const SMESHDS_Hypothesis * H)
+                                 const SMESHDS_Hypothesis * H)
 {
-       //list<const SMESHDS_Hypothesis *>& alist=myShapeToHypothesis[SS];
-  
-  if ( !myShapeToHypothesis.IsBound( SS ) )
-    myShapeToHypothesis.Bind( SS, list<const SMESHDS_Hypothesis *>() );
-
-  list<const SMESHDS_Hypothesis *>& alist = myShapeToHypothesis.ChangeFind( SS );
+  list<const SMESHDS_Hypothesis *>& alist=
+    myShapeToHypothesis[SS.Oriented(TopAbs_FORWARD)]; // ignore orientation of SS
 
-    
+  //Check if the Hypothesis is still present
+  list<const SMESHDS_Hypothesis*>::iterator ith=find(alist.begin(),alist.end(), H );
 
-       //Check if the Hypothesis is still present
-       list<const SMESHDS_Hypothesis*>::iterator ith=alist.begin();
+  if (alist.end() != ith) return false;
 
-       for (; ith!=alist.end(); ith++)
-               if (H == *ith) return false;
-
-       alist.push_back(H);
-       return true;
+  alist.push_back(H);
+  return true;
 }
 
 //=======================================================================
@@ -136,34 +129,23 @@ bool SMESHDS_Mesh::AddHypothesis(const TopoDS_Shape & SS,
 //purpose  : 
 //=======================================================================
 
-bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape & S,
-       const SMESHDS_Hypothesis * H)
+bool SMESHDS_Mesh::RemoveHypothesis(const TopoDS_Shape &       S,
+                                    const SMESHDS_Hypothesis * H)
 {
-       /*ShapeToHypothesis::iterator its=myShapeToHypothesis.find(S);
-       if(its!=myShapeToHypothesis.end())
-       {
-               list<const SMESHDS_Hypothesis*>::iterator ith=(*its).second.begin();
+  ShapeToHypothesis::iterator its=
+    myShapeToHypothesis.find(S.Oriented(TopAbs_FORWARD)); // ignore orientation of S
 
-               for (; ith!=(*its).second.end(); ith++)
-                       if (H == *ith)
-                       {
-                               (*its).second.erase(ith);
-                               return true;
-                       }
-       }*/
-  if ( myShapeToHypothesis.IsBound( S ) )
+  if(its!=myShapeToHypothesis.end())
   {
-    list<const SMESHDS_Hypothesis *>& alist = myShapeToHypothesis.ChangeFind( S );
-    list<const SMESHDS_Hypothesis*>::iterator ith = alist.begin();
-
-               for (; ith != alist.end(); ith++)
-                       if (H == *ith)
-                       {
-                               alist.erase(ith);
-                               return true;
-                       }
+    list<const SMESHDS_Hypothesis *>& alist=(*its).second;
+    list<const SMESHDS_Hypothesis*>::iterator ith=find(alist.begin(),alist.end(), H );
+    if (ith != alist.end())
+    {
+      alist.erase(ith);
+      return true;
+    }
   }
-       return false;
+  return false;
 }
 
 //=======================================================================
@@ -1039,14 +1021,16 @@ list<int> SMESHDS_Mesh::SubMeshIndices()
 //purpose  : 
 //=======================================================================
 
-const list<const SMESHDS_Hypothesis*>& SMESHDS_Mesh::GetHypothesis(
-       const TopoDS_Shape & S) const
+const list<const SMESHDS_Hypothesis*>&
+SMESHDS_Mesh::GetHypothesis(const TopoDS_Shape & S) const
 {
-       if ( myShapeToHypothesis.IsBound(S) )
-               return myShapeToHypothesis.Find(S);
+  ShapeToHypothesis::const_iterator its=
+    myShapeToHypothesis.find(S.Oriented(TopAbs_FORWARD)); // ignore orientation of S
+  if (its!=myShapeToHypothesis.end())
+    return its->second;
 
-       static list<const SMESHDS_Hypothesis*> empty;
-       return empty;
+  static list<const SMESHDS_Hypothesis*> empty;
+  return empty;
 }
 
 //=======================================================================
@@ -1084,7 +1068,7 @@ bool SMESHDS_Mesh::HasMeshElements(const TopoDS_Shape & S)
 //=======================================================================
 bool SMESHDS_Mesh::HasHypothesis(const TopoDS_Shape & S)
 {
-       return myShapeToHypothesis.IsBound(S);
+  return myShapeToHypothesis.find(S.Oriented(TopAbs_FORWARD))!=myShapeToHypothesis.end();
 }
 
 //=======================================================================
index 967e21a67287b052df1a1bdee3a40138cd77b3d7..dac69c0204b0eee73a462d9c4124cf198e420640 100644 (file)
@@ -62,6 +62,7 @@ public:
   bool IsEmbeddedMode();
 
   void ShapeToMesh(const TopoDS_Shape & S);
+  TopoDS_Shape ShapeToMesh() const;
   bool AddHypothesis(const TopoDS_Shape & SS, const SMESHDS_Hypothesis * H);
   bool RemoveHypothesis(const TopoDS_Shape & S, const SMESHDS_Hypothesis * H);
   
@@ -401,12 +402,11 @@ public:
                             const TopoDS_Shape & S);
   void UnSetMeshElementOnShape(const SMDS_MeshElement * anElt,
                               const TopoDS_Shape & S);
-  TopoDS_Shape ShapeToMesh() const;
   bool HasMeshElements(const TopoDS_Shape & S);
   SMESHDS_SubMesh * MeshElements(const TopoDS_Shape & S) const;
   SMESHDS_SubMesh * MeshElements(const int Index);
   std::list<int> SubMeshIndices();
-  const std::map<int,SMESHDS_SubMesh*>& SubMeshes()
+  const std::map<int,SMESHDS_SubMesh*>& SubMeshes() const
   { return myShapeIndexToSubMesh; }
 
   bool HasHypothesis(const TopoDS_Shape & S);
index 349f95dde088d6a1d9273430b7c840303ca94674..7bb9d1e0eef7be63a466cb18d9b0daf47f338a6a 100644 (file)
@@ -103,7 +103,11 @@ dist_libSMESH_la_SOURCES = \
        SMESHGUI_ShapeByMeshDlg.cxx \
        SMESHGUI_AddQuadraticElementDlg.cxx \
        SMESHGUI_ConvToQuadDlg.cxx \
-       SMESHGUI_ConvToQuadOp.cxx
+       SMESHGUI_ConvToQuadOp.cxx \
+       SMESHGUI_BuildCompoundDlg.cxx \
+       SMESHGUI_ComputeDlg.cxx \
+       SMESHGUI_MakeNodeAtPointDlg.cxx \
+       SMESHGUI_MeshEditPreview.cxx
 
 MOC_FILES = \
        SMESHGUI_moc.cxx \
@@ -151,7 +155,10 @@ MOC_FILES = \
        SMESHGUI_ShapeByMeshDlg_moc.cxx \
        SMESHGUI_AddQuadraticElementDlg_moc.cxx \
        SMESHGUI_ConvToQuadDlg_moc.cxx \
-       SMESHGUI_ConvToQuadOp_moc.cxx
+       SMESHGUI_ConvToQuadOp_moc.cxx \
+       SMESHGUI_BuildCompoundDlg_moc.cxx \
+       SMESHGUI_ComputeDlg_moc.cxx \
+       SMESHGUI_MakeNodeAtPointDlg_moc.cxx
 
 nodist_libSMESH_la_SOURCES= \
        $(MOC_FILES)
index e570b199dac05fba338acdf48bc0d7a0e45e49e6..89ce6fe7a9880b49a2f379d8650046e5c2b9fae2 100644 (file)
@@ -17,7 +17,7 @@
 //  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
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 //  File   : SMESHGUI.cxx
 //  Author : Nicolas REJNERI
@@ -57,7 +57,6 @@
 #include "SMESHGUI_RotationDlg.h"
 #include "SMESHGUI_SymmetryDlg.h"
 #include "SMESHGUI_SewingDlg.h"
-#include "SMESHGUI_MergeNodesDlg.h"
 #include "SMESHGUI_EditMeshDlg.h"
 #include "SMESHGUI_MeshPatternDlg.h"
 #include "SMESHGUI_Selection.h"
@@ -65,6 +64,9 @@
 #include "SMESHGUI_ConvToQuadOp.h"
 #include "SMESHGUI_MeshOp.h"
 #include "SMESHGUI_Displayer.h"
+#include "SMESHGUI_MakeNodeAtPointDlg.h"
+#include "SMESHGUI_BuildCompoundDlg.h"
+#include "SMESHGUI_ComputeDlg.h"
 
 #include "SMESHGUI_Utils.h"
 #include "SMESHGUI_GEOMGenUtils.h"
 
 #include "SALOMEconfig.h"
 #include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
 
 // QT Includes
 #define         INCLUDE_MENUITEM_DEF
@@ -257,6 +260,7 @@ using namespace std;
       if ( !aMesh->_is_nil() ) {
        QString aFilter, aTitle = QObject::tr("Export mesh");
        QMap<QString, SMESH::MED_VERSION> aFilterMap;
+       QMap<QString, int> aFilterMapSTL;
        switch ( theCommandID ) {
        case 125:
        case 122:
@@ -296,6 +300,36 @@ using namespace std;
             aFilter = QObject::tr("IDEAS files (*.unv)");
           }
          break;
+       case 140:
+       case 141:
+          {
+           // export STL
+           /*
+             there must be check on others mesh elements not equal triangles
+           */
+           if (aMesh->NbTriangles() < 1) {
+              int aRet = SUIT_MessageBox::warn1
+                (SMESHGUI::desktop(),
+                 QObject::tr("SMESH_WRN_WARNING"),
+                 QObject::tr("SMESH_EXPORT_STL1").arg(anIObject->getName()),
+                 QObject::tr("SMESH_BUT_OK"));
+             return;
+            }
+           if (!(aMesh->NbElements() - aMesh->NbTriangles())) {
+              int aRet = SUIT_MessageBox::warn2
+                (SMESHGUI::desktop(),
+                 QObject::tr("SMESH_WRN_WARNING"),
+                 QObject::tr("SMESH_EXPORT_STL2").arg(anIObject->getName()),
+                 QObject::tr("SMESH_BUT_YES"),  QObject::tr("SMESH_BUT_NO"),
+                 0, 1, 0);
+              if (aRet)
+                return;
+            }
+
+            aFilterMapSTL.insert( QObject::tr("STL ASCII  (*.stl)"), 1 ); // 1 - ASCII mode
+            aFilterMapSTL.insert( QObject::tr("STL Binary (*.stl)"), 0 ); // 0 - Binary mode
+          }
+         break;
        default:
          return;
        }
@@ -303,13 +337,35 @@ using namespace std;
        QString aFilename;
        SMESH::MED_VERSION aFormat;
        // Init the parameter with the default value
+       bool aIsASCII_STL = true;
        bool toCreateGroups = false;
        SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
        if ( resMgr )
          toCreateGroups = resMgr->booleanValue( "SMESH", "auto_groups", false );
-       
-       if ( theCommandID != 122 && theCommandID != 125 )
+
+       if ( theCommandID != 122 && theCommandID != 125 && theCommandID != 140 && theCommandID != 141)
+
          aFilename = SUIT_FileDlg::getFileName(SMESHGUI::desktop(), "", aFilter, aTitle, false);
+
+       else if(theCommandID == 140 || theCommandID == 141) { // Export to STL
+         QStringList filters;
+          QMap<QString, int>::const_iterator it = aFilterMapSTL.begin();
+          for ( ; it != aFilterMapSTL.end(); ++it )
+            filters.push_back( it.key() );
+
+          SUIT_FileDlg* fd = new SUIT_FileDlg( SMESHGUI::desktop(), false, true, true );
+          fd->setCaption( aTitle );
+          fd->setFilters( filters );
+          fd->setSelectedFilter( QObject::tr("STL ASCII  (*.stl)") );
+          bool is_ok = false;
+          while (!is_ok) {
+            fd->exec();
+            aFilename = fd->selectedFile();
+            aIsASCII_STL = (aFilterMapSTL[fd->selectedFilter()]) == 1 ? true: false;
+            is_ok = true;
+         }
+          delete fd;
+       }
        else {
           QStringList filters;
           QMap<QString, SMESH::MED_VERSION>::const_iterator it = aFilterMap.begin();
@@ -354,6 +410,17 @@ using namespace std;
          SUIT_OverrideCursor wc;
 
          try {
+           bool Renumber = false ;
+           // PAL 14172  : Check of we have to renumber or not from the preferences before export
+           if (resMgr)
+             Renumber= resMgr->booleanValue("SMESH","renumbering");
+           if (Renumber){
+             SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
+             aMeshEditor->RenumberNodes();
+             aMeshEditor->RenumberElements();
+             if ( SMESHGUI::automaticUpdate() )
+               SMESH::UpdateView();
+             }
            switch ( theCommandID ) {
            case 125:
            case 122:
@@ -367,6 +434,10 @@ using namespace std;
            case 123:
              aMesh->ExportUNV( aFilename.latin1() );
              break;
+           case 140:
+           case 141:
+             aMesh->ExportSTL( aFilename.latin1(), aIsASCII_STL );
+             break;
            default:
              break;
            }
@@ -797,7 +868,7 @@ using namespace std;
 
             _PTR(SObject) aMeshSO = SMESH::FindSObject(aMesh);
             if (aMeshSO)
-              SMESH::ModifiedMesh(aMeshSO, false);
+              SMESH::ModifiedMesh(aMeshSO, false, aMesh->NbNodes()==0);
           }
           else {
             IObject = new SALOME_InteractiveObject
@@ -844,7 +915,7 @@ SMESH::SMESH_Gen_var SMESHGUI::myComponentSMESH = SMESH::SMESH_Gen::_nil();
 //=============================================================================
 SMESHGUI::SMESHGUI() :
 SalomeApp_Module( "SMESH" )
-{  
+{
   if ( CORBA::is_nil( myComponentSMESH ) )
   {
     CORBA::Boolean anIsEmbeddedMode;
@@ -1136,6 +1207,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case 124:
   case 125:
   case 126:
+  case 140:
+  case 141:
     {
       ::ExportMeshToFile(theCommandID);
       break;
@@ -1228,11 +1301,11 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
          }
        }
       }
-      
-      // PAL13338 -->
-      if ( ( theCommandID==301 || theCommandID==302 ) && !checkLock(aStudy) && !automaticUpdate() ) 
+
+      // PAL13338 + PAL15161 -->
+      if ( ( theCommandID==301 || theCommandID==302 ) && !checkLock(aStudy) /*&& !automaticUpdate()*/ )
        SMESH::UpdateView();
-      // PAL13338 <--
+      // PAL13338 + PAL15161 <--
 
       if (anAction == SMESH::eErase) {
        SALOME_ListIO l1;
@@ -1288,93 +1361,87 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
 
   case 701:                                    // COMPUTE MESH
     {
-      if(checkLock(aStudy)) break;
-
-      LightApp_SelectionMgr *Sel = selectionMgr();
-      SALOME_ListIO selected; Sel->selectedObjects( selected );
-
-      if ( vtkwnd ) {
-       int nbSel = selected.Extent();
-       if (nbSel != 1){
-          SUIT_MessageBox::warn1(desktop(),
-                                 tr("SMESH_WRN_WARNING"),
-                                 tr("SMESH_WRN_NO_AVAILABLE_DATA"),
-                                 tr("SMESH_BUT_OK"));
-         break;
-       }
+      if (checkLock(aStudy)) break;
 
-       SMESH::SMESH_Mesh_var aMesh;
-       SMESH::SMESH_subMesh_var aSubMesh;
-       Handle(SALOME_InteractiveObject) IObject = selected.First();
-       if (IObject->hasEntry()) {
-         _PTR(SObject) aMeshSObj = aStudy->FindObjectID(IObject->getEntry());
-         GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh( aMeshSObj );
-         if ( aShapeObject->_is_nil() ) {
-           // imported mesh
-           break;
-         }
-         if( aMeshSObj ) {
-           aMesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>(aMeshSObj);
-           aSubMesh = SMESH::SObjectToInterface<SMESH::SMESH_subMesh>(aMeshSObj);
-            if ( !aSubMesh->_is_nil() )
-             aMesh = aSubMesh->GetFather();
-
-           if (!aMesh->_is_nil()) {
-//               if(!GetSMESHGen()->IsReadyToCompute(aMesh,aShapeObject)) {
+      startOperation( 701 );
+//       LightApp_SelectionMgr *Sel = selectionMgr();
+//       SALOME_ListIO selected; Sel->selectedObjects( selected );
+
+//       int nbSel = selected.Extent();
+//       if (nbSel != 1) {
+//         SUIT_MessageBox::warn1(desktop(),
+//                                tr("SMESH_WRN_WARNING"),
+//                                tr("SMESH_WRN_NO_AVAILABLE_DATA"),
+//                                tr("SMESH_BUT_OK"));
+//         break;
+//       }
+
+//       SMESH::SMESH_Mesh_var aMesh;
+//       SMESH::SMESH_subMesh_var aSubMesh;
+//       Handle(SALOME_InteractiveObject) IObject = selected.First();
+//       if (IObject->hasEntry()) {
+//         _PTR(SObject) aMeshSObj = aStudy->FindObjectID(IObject->getEntry());
+//         GEOM::GEOM_Object_var aShapeObject = SMESH::GetShapeOnMeshOrSubMesh( aMeshSObj );
+//         if ( aShapeObject->_is_nil() ) {
+//           // imported mesh
+//           break;
+//         }
+//         if ( aMeshSObj ) {
+//           aMesh = SMESH::SObjectToInterface<SMESH::SMESH_Mesh>(aMeshSObj);
+//           aSubMesh = SMESH::SObjectToInterface<SMESH::SMESH_subMesh>(aMeshSObj);
+//           if ( !aSubMesh->_is_nil() )
+//             aMesh = aSubMesh->GetFather();
+
+//           if (!aMesh->_is_nil()) {
+//             SMESH::algo_error_array_var errors = GetSMESHGen()->GetAlgoState(aMesh,aShapeObject);
+//             if ( errors->length() > 0 ) {
+//               SUIT_MessageBox::warn1(desktop(),
+//                                      tr("SMESH_WRN_WARNING"),
+//                                      SMESH::GetMessageOnAlgoStateErrors( errors.in() ),
+//                                      tr("SMESH_BUT_OK"));
+//               break;
+//             }
+
+//             try {
+//               if (GetSMESHGen()->Compute(aMesh, aShapeObject))
+//                 SMESH::ModifiedMesh(aMeshSObj, true);
+//               else
 //                 SUIT_MessageBox::warn1(desktop(),
 //                                        tr("SMESH_WRN_WARNING"),
-//                                        tr("SMESH_WRN_MISSING_PARAMETERS"),
+//                                        tr("SMESH_WRN_COMPUTE_FAILED"),
 //                                        tr("SMESH_BUT_OK"));
-//                 break;
+//             }
+//             catch(const SALOME::SALOME_Exception & S_ex){
+//               SalomeApp_Tools::QtCatchCorbaException(S_ex);
+//             }
+
+//             updateObjBrowser();
+
+//             if (automaticUpdate()) {
+//               SVTK_ViewWindow* aVTKView = SMESH::GetViewWindow(this, /*create*/true);
+//               if (aVTKView) {
+//                 CORBA::Long anId = aStudy->StudyId();
+//                 TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId, IObject->getEntry());
+//                 if (aVisualObj) {
+//                   aVisualObj->Update();
+//                   SMESH_Actor* anActor = SMESH::FindActorByEntry(IObject->getEntry());
+//                   if (!anActor) {
+//                     anActor = SMESH::CreateActor(aStudy, IObject->getEntry());
+//                     if (anActor) {
+//                       SMESH::DisplayActor(aVTKView, anActor); //apo
+//                       SMESH::FitAll();
+//                     }
+//                   }
+//                   SMESH::RepaintCurrentView();
+//                   Sel->setSelectedObjects( selected );
+//                 }
 //               }
-              SMESH::algo_error_array_var errors = GetSMESHGen()->GetAlgoState(aMesh,aShapeObject);
-              if ( errors->length() > 0 ) {
-                SUIT_MessageBox::warn1(desktop(),
-                                       tr("SMESH_WRN_WARNING"),
-                                       SMESH::GetMessageOnAlgoStateErrors( errors.in() ),
-                                       tr("SMESH_BUT_OK"));
-                break;
-              }
-              try{
-                if (GetSMESHGen()->Compute(aMesh,aShapeObject))
-                  SMESH::ModifiedMesh(aMeshSObj,true);
-                else
-                  SUIT_MessageBox::warn1(desktop(),
-                                         tr("SMESH_WRN_WARNING"),
-                                         tr("SMESH_WRN_COMPUTE_FAILED"),
-                                         tr("SMESH_BUT_OK"));
-              }
-              catch(const SALOME::SALOME_Exception & S_ex){
-                SalomeApp_Tools::QtCatchCorbaException(S_ex);
-              }
-            }
-         }
-       }
-        CORBA::Long anId = aStudy->StudyId();
-        TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId,IObject->getEntry());
-        if ( automaticUpdate() && aVisualObj){
-          aVisualObj->Update();
-          SMESH_Actor* anActor = SMESH::FindActorByEntry(IObject->getEntry());
-          if(!anActor){
-            anActor = SMESH::CreateActor(aStudy,IObject->getEntry());
-            if(anActor){
-             SMESH::DisplayActor(view,anActor); //apo
-             SMESH::FitAll();
-           }
-         }
-         SMESH::RepaintCurrentView();
-       }
-      }
-      else{
-       SUIT_MessageBox::warn1(desktop(),
-                             tr("SMESH_WRN_WARNING"),
-                             tr("SMESH_WRN_VIEWER_VTK"),
-                             tr("SMESH_BUT_OK"));
-      }
-      updateObjBrowser();
-      Sel->setSelectedObjects( selected );
-      break;
+//             }
+//           }
+//         }
+//       }
     }
+    break;
 
   case 702:  // Create mesh
     startOperation( 702 );
@@ -1385,6 +1452,13 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case 704: // Edit mesh/sub-mesh
     startOperation( 704 );
     break;
+  case 710: // Build compound mesh
+    {
+      if (checkLock(aStudy)) break;
+      EmitSignalDeactivateDialog();
+      new SMESHGUI_BuildCompoundDlg( this );
+    }
+    break;
   case 407: // DIAGONAL INVERSION
   case 408: // Delete diagonal
     {
@@ -1932,18 +2006,18 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
        int type;
 
        switch (theCommandID) {
-       case 4034:                                      
+       case 4034:
          type = QUAD_EDGE; break;
-       case 4035:                                      
+       case 4035:
          type = QUAD_TRIANGLE; break;
-       case 4036:                                     
+       case 4036:
          type = QUAD_QUADRANGLE; break;
-       case 4037:                                     
+       case 4037:
          type = QUAD_TETRAHEDRON; break;
-       case 4038:                                     
-         type = QUAD_PYRAMID; break; 
-       case 4039:                                     
-         type = QUAD_PENTAHEDRON; break; 
+       case 4038:
+         type = QUAD_PYRAMID; break;
+       case 4039:
+         type = QUAD_PENTAHEDRON; break;
        case 4040:
          type = QUAD_HEXAHEDRON;
          break;
@@ -2078,7 +2152,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       if(checkLock(aStudy)) break;
       if(vtkwnd) {
        EmitSignalDeactivateDialog();
-       new SMESHGUI_MergeNodesDlg( this );
+       new SMESHGUI_EditMeshDlg( this, 0 );
       }
       else {
        SUIT_MessageBox::warn1(desktop(),
@@ -2087,15 +2161,12 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       }
       break;
     }
-  case 4066: // MERGE EQUAL ELEMENTS
+  case 4066:                                   // MERGE EQUAL ELEMENTS
     {
       if (checkLock(aStudy)) break;
       if (vtkwnd) {
        EmitSignalDeactivateDialog();
-       new SMESHGUI_EditMeshDlg(this,
-                                 "SMESH_MERGE_ELEMENTS_TITLE",
-                                 "ICON_DLG_MERGE_ELEMENTS",
-                                 1); // MergeEqualElemets
+       new SMESHGUI_EditMeshDlg( this, 1 );
       } else {
        SUIT_MessageBox::warn1(desktop(),
                              tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK"),
@@ -2104,6 +2175,10 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
       break;
     }
 
+  case 4067: // MAKE MESH PASS THROUGH POINT
+    startOperation( 4067 );
+    break;
+
   case 5105: // Library of selection filters
   {
     static QValueList<int> aTypes;
@@ -2329,15 +2404,18 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction(  121, "DAT" );
   createSMESHAction(  122, "MED" );
   createSMESHAction(  123, "UNV" );
+  createSMESHAction(  140, "STL" );
   createSMESHAction(  124, "EXPORT_DAT" );
   createSMESHAction(  125, "EXPORT_MED" );
   createSMESHAction(  126, "EXPORT_UNV" );
+  createSMESHAction(  141, "EXPORT_STL" );
   createSMESHAction(   33, "DELETE",          "ICON_DELETE" );
   createSMESHAction( 5105, "SEL_FILTER_LIB" );
   createSMESHAction(  701, "COMPUTE",         "ICON_COMPUTE" );
   createSMESHAction(  702, "CREATE_MESH",     "ICON_DLG_INIT_MESH" );
   createSMESHAction(  703, "CREATE_SUBMESH",  "ICON_DLG_ADD_SUBMESH" );
   createSMESHAction(  704, "EDIT_MESHSUBMESH","ICON_DLG_EDIT_MESH" );
+  createSMESHAction(  710, "BUILD_COMPOUND",  "ICON_BUILD_COMPOUND" );
   createSMESHAction(  801, "CREATE_GROUP",    "ICON_SMESH_TREE_GROUP" );
   createSMESHAction(  802, "CONSTRUCT_GROUP", "ICON_CONSTRUCT_GROUP" );
   createSMESHAction(  803, "EDIT_GROUP",      "ICON_EDIT_GROUP" );
@@ -2380,6 +2458,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( 4064, "SEW",             "ICON_SMESH_SEWING_FREEBORDERS" );
   createSMESHAction( 4065, "MERGE",           "ICON_SMESH_MERGE_NODES" );
   createSMESHAction( 4066, "MERGE_ELEMENTS",  "ICON_DLG_MERGE_ELEMENTS" );
+  createSMESHAction( 4067, "MESH_THROU_POINT","ICON_DLG_MESH_THROU_POINT" );
   createSMESHAction(  406, "MOVE",            "ICON_DLG_MOVE_NODE" );
   createSMESHAction(  407, "INV",             "ICON_DLG_MESH_DIAGONAL" );
   createSMESHAction(  408, "UNION2",          "ICON_UNION2TRI" );
@@ -2452,6 +2531,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( 121, exportId, -1 );
   createMenu( 122, exportId, -1 );
   createMenu( 123, exportId, -1 );
+  createMenu( 140, exportId, -1 ); // export to stl STL
 
   createMenu( separator(), fileId, 10 );
 
@@ -2462,6 +2542,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( 702, meshId, -1 );
   createMenu( 703, meshId, -1 );
   createMenu( 704, meshId, -1 );
+  createMenu( 710, meshId, -1 );
   createMenu( separator(), meshId, -1 );
   createMenu( 701, meshId, -1 );
   createMenu( separator(), meshId, -1 );
@@ -2528,6 +2609,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( 4066, transfId, -1 );
 
   createMenu( 406, modifyId, -1 );
+  createMenu( 4067,modifyId, -1 );
   createMenu( 407, modifyId, -1 );
   createMenu( 408, modifyId, -1 );
   createMenu( 409, modifyId, -1 );
@@ -2552,6 +2634,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createTool( 702, meshTb );
   createTool( 703, meshTb );
   createTool( 704, meshTb );
+  createTool( 710, meshTb );
   createTool( separator(), meshTb );
   createTool( 701, meshTb );
   createTool( separator(), meshTb );
@@ -2613,6 +2696,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createTool( separator(), addRemTb );
 
   createTool( 406, modifyTb );
+  createTool( 4067,modifyTb );
   createTool( 407, modifyTb );
   createTool( 408, modifyTb );
   createTool( 409, modifyTb );
@@ -2669,6 +2753,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   QString only_one_non_empty = QString( " && %1=1 && numberOfNodes>0" ).arg( QtxPopupMgr::Selection::defSelCountParam() );
   createPopupItem( 125, OB, mesh, only_one_non_empty );    // EXPORT_MED
   createPopupItem( 126, OB, mesh, only_one_non_empty );    // EXPORT_UNV
+  createPopupItem( 141, OB, mesh, only_one_non_empty );    // EXPORT_STL
   createPopupItem( 33, OB, subMesh + " " + group );        // DELETE
   popupMgr()->insert( separator(), -1, 0 );
 
@@ -3012,7 +3097,8 @@ void SMESHGUI::createPreferences()
 
   int exportgroup = addPreference( tr( "PREF_GROUP_EXPORT" ), genTab );
   addPreference( tr( "PREF_AUTO_GROUPS" ), exportgroup, LightApp_Preferences::Bool, "SMESH", "auto_groups" );
-  
+  int renumber=addPreference( tr( "PREF_RENUMBER" ), exportgroup, LightApp_Preferences::Bool, "SMESH", "renumbering" );
+
   int meshTab = addPreference( tr( "PREF_TAB_MESH" ) );
   int nodeGroup = addPreference( tr( "PREF_GROUP_NODES" ), meshTab );
 
@@ -3149,7 +3235,7 @@ void SMESHGUI::preferencesChanged( const QString& sect, const QString& name )
     float aTol = 1.00000009999999;
     std::string aWarning;
     SUIT_ResourceMgr* aResourceMgr = SMESH::GetResourceMgr(this);
-    if( name=="selection_object_color" || name=="selection_element_color" || 
+    if( name=="selection_object_color" || name=="selection_element_color" ||
         name=="selection_width" || name=="highlight_color" || name=="highlight_width" ||
         name=="selection_precision_node" || name=="selection_precision_element" )
       SMESH::UpdateSelectionProp( this );
@@ -3157,7 +3243,9 @@ void SMESHGUI::preferencesChanged( const QString& sect, const QString& name )
       sbX1 = aResourceMgr->doubleValue("SMESH", "scalar_bar_vertical_x", sbX1);
       sbW = aResourceMgr->doubleValue("SMESH", "scalar_bar_vertical_width", sbW);
       if(sbX1+sbW > aTol){
-       aWarning = "Origin and Size Vertical: X+Width > 1\n";   
+       aWarning = "Origin and Size Vertical: X+Width > 1\n";
+       sbX1=0.01;
+       sbW=0.05;
        aResourceMgr->setValue("SMESH", "scalar_bar_vertical_x", sbX1);
        aResourceMgr->setValue("SMESH", "scalar_bar_vertical_width", sbW);
       }
@@ -3193,7 +3281,7 @@ void SMESHGUI::preferencesChanged( const QString& sect, const QString& name )
        aResourceMgr->setValue("SMESH", "scalar_bar_horizontal_height",sbH);
       }
     }
-    
+
     if(aWarning.size() != 0){
       aWarning += "The default values are applied instead.";
       SUIT_MessageBox::warn1(SMESHGUI::desktop(),
@@ -3267,6 +3355,9 @@ LightApp_Operation* SMESHGUI::createOperation( const int id ) const
   // to do : create operation here
   switch( id )
   {
+    case 701: // Compute mesh
+      op = new SMESHGUI_ComputeOp();
+    break;
     case 702: // Create mesh
       op = new SMESHGUI_MeshOp( true, true );
     break;
@@ -3279,6 +3370,9 @@ LightApp_Operation* SMESHGUI::createOperation( const int id ) const
     case 417: //convert to quadratic
       op = new SMESHGUI_ConvToQuadOp();
     break;
+    case 4067: // make mesh pass through point
+      op = new SMESHGUI_MakeNodeAtPointOp();
+      break;
     default:
     break;
   }
index 3d51f663a9b17f5598bd3b05dfa44e08793d5939..854c25a94410ea0e25d97de23134ece361b4b206 100644 (file)
@@ -55,6 +55,8 @@
 
 #include "utilities.h"
 
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
 // OCCT Includes
 #include <TColStd_MapOfInteger.hxx>
 #include <TColStd_IndexedMapOfInteger.hxx>
index 19ac2836e9ed111472c86f19c49780fe37d79906..82a3728a221f6f170d31cabc8eb57cbcd9e32863 100644 (file)
@@ -46,6 +46,8 @@
 
 #include "utilities.h"
 
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
 // OCCT Includes
 #include <TColStd_MapOfInteger.hxx>
 #include <TColStd_IndexedMapOfInteger.hxx>
diff --git a/src/SMESHGUI/SMESHGUI_BuildCompoundDlg.cxx b/src/SMESHGUI/SMESHGUI_BuildCompoundDlg.cxx
new file mode 100644 (file)
index 0000000..3216064
--- /dev/null
@@ -0,0 +1,506 @@
+//  SMESH SMESHGUI : GUI for SMESH component
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : SMESHGUI_BuildCompoundDlg.cxx
+//  Author : Alexander KOVALEV
+//  Module : SMESH
+
+#include "SMESHGUI_BuildCompoundDlg.h"
+
+#include "SMESHGUI.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_SpinBox.h"
+#include "SMESHGUI_VTKUtils.h"
+
+#include "SMESH_TypeFilter.hxx"
+
+#include "SUIT_Desktop.h"
+#include "SUIT_Session.h"
+#include "SUIT_MessageBox.h"
+#include "SalomeApp_Study.h"
+
+#include "LightApp_Application.h"
+
+#include "SALOME_ListIO.hxx"
+
+#include "utilities.h"
+
+// QT Includes
+#include <qapplication.h>
+#include <qbuttongroup.h>
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+#include <qlayout.h>
+#include <qpixmap.h>
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qsizepolicy.h>
+#include <qstring.h>
+
+#include <vector>
+#include <set>
+
+//=================================================================================
+// name    : SMESHGUI_BuildCompoundDlg
+// Purpose :
+//=================================================================================
+SMESHGUI_BuildCompoundDlg::SMESHGUI_BuildCompoundDlg( SMESHGUI* theModule)
+  : QDialog(SMESH::GetDesktop(theModule), "SMESHGUI_BuildCompoundDlg", false, WStyle_Customize |
+            WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | Qt::WDestructiveClose),
+    mySMESHGUI(theModule),
+    mySelectionMgr(SMESH::GetSelectionMgr(theModule))
+{
+  setCaption(tr("SMESH_BUILD_COMPOUND_TITLE"));
+
+  SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
+  QPixmap image0 (aResMgr->loadPixmap("SMESH", tr("ICON_DLG_BUILD_COMPOUND_MESH")));
+  QPixmap image1 (aResMgr->loadPixmap("SMESH", tr("ICON_SELECT")));
+
+  setSizeGripEnabled(TRUE);
+  SMESHGUI_BuildCompoundDlgLayout = new QGridLayout (this);
+  SMESHGUI_BuildCompoundDlgLayout->setSpacing(6);
+  SMESHGUI_BuildCompoundDlgLayout->setMargin(11);
+
+  /***************************************************************/
+  GroupConstructors = new QButtonGroup (this, "GroupConstructors");
+  GroupConstructors->setTitle(tr("COMPOUND" ));
+  GroupConstructors->setExclusive(TRUE);
+  GroupConstructors->setColumnLayout(0, Qt::Vertical);
+  GroupConstructors->layout()->setSpacing(0);
+  GroupConstructors->layout()->setMargin(0);
+  GroupConstructorsLayout = new QGridLayout (GroupConstructors->layout());
+  GroupConstructorsLayout->setAlignment(Qt::AlignTop);
+  GroupConstructorsLayout->setSpacing(6);
+  GroupConstructorsLayout->setMargin(11);
+  Constructor1 = new QRadioButton (GroupConstructors, "Constructor1");
+  Constructor1->setText(tr(""));
+  Constructor1->setPixmap(image0);
+  Constructor1->setChecked(TRUE);
+  GroupConstructorsLayout->addWidget(Constructor1, 0, 0);
+  SMESHGUI_BuildCompoundDlgLayout->addWidget(GroupConstructors, 0, 0);
+
+  /***************************************************************/
+  GroupName = new QGroupBox (this, "GroupName");
+  GroupName->setTitle(tr("RESULT_NAME" ));
+  GroupName->setColumnLayout(0, Qt::Vertical);
+  GroupName->layout()->setSpacing(0);
+  GroupName->layout()->setMargin(0);
+  GroupNameLayout = new QGridLayout (GroupName->layout());
+  GroupNameLayout->setAlignment(Qt::AlignTop);
+  GroupNameLayout->setSpacing(6);
+  GroupNameLayout->setMargin(11);
+  TextLabelName = new QLabel (GroupName, "TextLabelName");
+  TextLabelName->setText(tr("SMESH_NAME"));
+  GroupNameLayout->addWidget(TextLabelName, 0, 0);
+  LineEditName = new QLineEdit (GroupName, "LineEditName");
+  GroupNameLayout->addWidget(LineEditName, 0, 1);
+  SMESHGUI_BuildCompoundDlgLayout->addWidget(GroupName, 1, 0);
+
+  /***************************************************************/
+  GroupArgs = new QGroupBox (this, "GroupArgs");
+  GroupArgs->setTitle(tr("SMESH_ARGUMENTS" ));
+  GroupArgs->setColumnLayout(0, Qt::Vertical);
+  GroupArgs->layout()->setSpacing(0);
+  GroupArgs->layout()->setMargin(0);
+  GroupArgsLayout = new QGridLayout (GroupArgs->layout());
+  GroupArgsLayout->setAlignment(Qt::AlignTop);
+  GroupArgsLayout->setSpacing(6);
+  GroupArgsLayout->setMargin(11);
+
+  TextLabelMeshes = new QLabel (GroupArgs, "TextLabelMeshes");
+  TextLabelMeshes->setText(tr("MESHES"));
+  TextLabelMeshes->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+  GroupArgsLayout->addWidget(TextLabelMeshes, 0, 0);
+  SelectButton = new QPushButton (GroupArgs, "SelectButton");
+  SelectButton->setText(tr(""));
+  SelectButton->setPixmap(image1);
+  SelectButton->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+  GroupArgsLayout->addWidget(SelectButton, 0, 1);
+  LineEditMeshes = new QLineEdit (GroupArgs, "LineEditMeshes");
+  LineEditMeshes->setReadOnly(true);
+  GroupArgsLayout->addMultiCellWidget(LineEditMeshes, 0, 0, 2, 3);
+
+  TextLabelUnion = new QLabel (GroupArgs, "TextLabelUnion");
+  TextLabelUnion->setText(tr("PROCESSING_IDENTICAL_GROUPS"));
+  TextLabelUnion->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+  GroupArgsLayout->addMultiCellWidget(TextLabelUnion, 1, 1, 0, 2);
+  ComboBoxUnion = new QComboBox(GroupArgs, "ComboBoxUnion");
+  GroupArgsLayout->addMultiCellWidget(ComboBoxUnion, 1, 1, 3, 3);
+
+  CheckBoxMerge = new QCheckBox(GroupArgs, "CheckBoxMerge");
+  CheckBoxMerge->setText(tr("MERGE_NODES_AND_ELEMENTS" ));
+  GroupArgsLayout->addMultiCellWidget(CheckBoxMerge, 2, 2, 0, 3);
+
+  TextLabelTol = new QLabel (GroupArgs, "TextLabelTol");
+  TextLabelTol->setText(tr("SMESH_TOLERANCE"));
+  TextLabelTol->setAlignment(Qt::AlignCenter);
+  GroupArgsLayout->addMultiCellWidget(TextLabelTol, 3, 3, 0, 1);
+  SpinBoxTol = new SMESHGUI_SpinBox (GroupArgs, "SpinBoxTol");
+  SpinBoxTol->RangeStepAndValidator(0.0, COORD_MAX, 0.1, 6);
+  GroupArgsLayout->addMultiCellWidget(SpinBoxTol, 3, 3, 2, 3);
+
+  SMESHGUI_BuildCompoundDlgLayout->addWidget(GroupArgs, 2, 0);
+
+  /***************************************************************/
+  GroupButtons = new QGroupBox (this, "GroupButtons");
+  GroupButtons->setGeometry(QRect(10, 10, 281, 48));
+  GroupButtons->setTitle(tr("" ));
+  GroupButtons->setColumnLayout(0, Qt::Vertical);
+  GroupButtons->layout()->setSpacing(0);
+  GroupButtons->layout()->setMargin(0);
+  GroupButtonsLayout = new QGridLayout (GroupButtons->layout());
+  GroupButtonsLayout->setAlignment(Qt::AlignTop);
+  GroupButtonsLayout->setSpacing(6);
+  GroupButtonsLayout->setMargin(11);
+  buttonHelp = new QPushButton(GroupButtons, "buttonHelp");
+  buttonHelp->setText(tr("SMESH_BUT_HELP" ));
+  buttonHelp->setAutoDefault(TRUE);
+  GroupButtonsLayout->addWidget(buttonHelp, 0, 4);
+  buttonCancel = new QPushButton (GroupButtons, "buttonCancel");
+  buttonCancel->setText(tr("SMESH_BUT_CLOSE" ));
+  buttonCancel->setAutoDefault(TRUE);
+  GroupButtonsLayout->addWidget(buttonCancel, 0, 3);
+  buttonApply = new QPushButton (GroupButtons, "buttonApply");
+  buttonApply->setText(tr("SMESH_BUT_APPLY" ));
+  buttonApply->setAutoDefault(TRUE);
+  GroupButtonsLayout->addWidget(buttonApply, 0, 1);
+  QSpacerItem* spacer_9 = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+  GroupButtonsLayout->addItem(spacer_9, 0, 2);
+  buttonOk = new QPushButton (GroupButtons, "buttonOk");
+  buttonOk->setText(tr("SMESH_BUT_OK" ));
+  buttonOk->setAutoDefault(TRUE);
+  buttonOk->setDefault(TRUE);
+  GroupButtonsLayout->addWidget(buttonOk, 0, 0);
+  SMESHGUI_BuildCompoundDlgLayout->addWidget(GroupButtons, 3, 0);
+
+  myHelpFileName = "building_compounds.htm";
+
+  Init(); // Initialisations
+}
+
+//=================================================================================
+// function : ~SMESHGUI_BuildCompoundDlg()
+// purpose  : Destroys the object and frees any allocated resources
+//=================================================================================
+SMESHGUI_BuildCompoundDlg::~SMESHGUI_BuildCompoundDlg()
+{
+  // no need to delete child widgets, Qt does it all for us
+}
+
+//=================================================================================
+// function : Init()
+// purpose  :
+//=================================================================================
+void SMESHGUI_BuildCompoundDlg::Init()
+{
+  GroupName->show();
+  GroupArgs->show();
+  mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+
+  myMesh = SMESH::SMESH_Mesh::_nil();
+
+  myMeshFilter = new SMESH_TypeFilter (MESH);
+
+  myMeshArray = new SMESH::mesh_array();
+
+  // signals and slots connections
+  connect(buttonOk    , SIGNAL(clicked()), this, SLOT(ClickOnOk()));
+  connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()));
+  connect(buttonApply , SIGNAL(clicked()), this, SLOT(ClickOnApply()));
+  connect(buttonHelp,   SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
+
+  connect(SelectButton, SIGNAL(clicked()), this, SLOT(SelectionIntoArgument()));
+
+  connect(CheckBoxMerge, SIGNAL(toggled(bool)), this, SLOT(onSelectMerge(bool)));
+
+  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+
+  connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
+  connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs())       , this, SLOT(ClickOnCancel()));
+
+  this->show(); // displays Dialog
+
+  LineEditName->setText(GetDefaultName(tr("COMPOUND_MESH")));
+  LineEditMeshes->setFocus();
+
+  ComboBoxUnion->insertItem(tr("UNITE"));
+  ComboBoxUnion->insertItem(tr("RENAME"));
+  ComboBoxUnion->setCurrentItem(0);
+
+  CheckBoxMerge->setChecked(false);
+
+  TextLabelTol->setEnabled(CheckBoxMerge->isChecked());
+  SpinBoxTol->SetValue(1e-05);
+
+  SpinBoxTol->setEnabled(CheckBoxMerge->isChecked());
+
+  mySelectionMgr->clearFilters();
+  mySelectionMgr->installFilter(myMeshFilter);
+
+  SelectionIntoArgument();
+}
+
+//=================================================================================
+// function : GetDefaultName()
+// purpose  :
+//=================================================================================
+QString SMESHGUI_BuildCompoundDlg::GetDefaultName(const QString& theOperation)
+{
+  QString aName = "";
+
+  // collect all object names of SMESH component
+  SalomeApp_Study* appStudy =
+    dynamic_cast<SalomeApp_Study*>( SUIT_Session::session()->activeApplication()->activeStudy() );
+  if ( !appStudy ) return aName;
+  _PTR(Study) aStudy = appStudy->studyDS();
+
+  std::set<std::string> aSet;
+  _PTR(SComponent) aMeshCompo (aStudy->FindComponent("SMESH"));
+  if (aMeshCompo) {
+    _PTR(ChildIterator) it (aStudy->NewChildIterator(aMeshCompo));
+    _PTR(SObject) obj;
+    for (it->InitEx(true); it->More(); it->Next()) {
+      obj = it->Value();
+      aSet.insert(obj->GetName());
+    }
+  }
+
+  // build a unique name
+  int aNumber = 0;
+  bool isUnique = false;
+  while (!isUnique) {
+    aName = theOperation + "_" + QString::number(++aNumber);
+    isUnique = (aSet.count(aName.latin1()) == 0);
+  }
+
+  return aName;
+}
+
+//=================================================================================
+// function : ClickOnApply()
+// purpose  :
+//=================================================================================
+bool SMESHGUI_BuildCompoundDlg::ClickOnApply()
+{
+  if (mySMESHGUI->isActiveStudyLocked())
+    return false;
+  if (!myMesh->_is_nil()) {
+    try        {
+      QApplication::setOverrideCursor(Qt::waitCursor);
+      
+      SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen();
+      // concatenate meshes
+      SMESH::SMESH_Mesh_var aCompoundMesh = 
+       aSMESHGen->Concatenate(myMeshArray, 
+                              !(ComboBoxUnion->currentItem()), 
+                              CheckBoxMerge->isChecked(), 
+                              SpinBoxTol->GetValue());
+      
+      SMESH::SetName( SMESH::FindSObject( aCompoundMesh ), LineEditName->text().latin1() );
+      QApplication::restoreOverrideCursor();
+      mySMESHGUI->updateObjBrowser();
+    } catch(...) {
+      return false;
+    }
+
+    LineEditName->setText(GetDefaultName(tr("COMPOUND_MESH")));
+
+    //mySelectionMgr->clearSelected();
+    SMESH::UpdateView();
+    return true;
+  }
+  return false;
+}
+
+//=================================================================================
+// function : ClickOnOk()
+// purpose  :
+//=================================================================================
+void SMESHGUI_BuildCompoundDlg::ClickOnOk()
+{
+  if (ClickOnApply())
+    ClickOnCancel();
+}
+
+//=================================================================================
+// function : ClickOnCancel()
+// purpose  :
+//=================================================================================
+void SMESHGUI_BuildCompoundDlg::ClickOnCancel()
+{
+  //mySelectionMgr->clearSelected();
+  mySelectionMgr->clearFilters();
+  disconnect(mySelectionMgr, 0, this, 0);
+  mySMESHGUI->ResetState();
+  reject();
+}
+
+//=================================================================================
+// function : ClickOnHelp()
+// purpose  :
+//=================================================================================
+void SMESHGUI_BuildCompoundDlg::ClickOnHelp()
+{
+  LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
+  if (app) 
+    app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
+  else {
+    SUIT_MessageBox::warn1(0, QObject::tr("WRN_WARNING"),
+                          QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                          arg(app->resourceMgr()->stringValue("ExternalBrowser", "application")).arg(myHelpFileName),
+                          QObject::tr("BUT_OK"));
+  }
+}
+
+//=================================================================================
+// function : SelectionIntoArgument()
+// purpose  : Called when selection as changed or other case
+//=================================================================================
+void SMESHGUI_BuildCompoundDlg::SelectionIntoArgument()
+{
+  if (!GroupButtons->isEnabled()) // inactive
+    return;
+
+  QString aString = "";
+
+  SALOME_ListIO aList;
+  mySelectionMgr->selectedObjects(aList);
+  int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
+
+  if (nbSel != 0) {
+    myMeshArray->length(nbSel);
+    for (int i = 0; nbSel != 0; i++, nbSel--) {
+      Handle(SALOME_InteractiveObject) IO = aList.First();
+      aList.RemoveFirst();
+      myMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO);
+      myMeshArray[i] = myMesh;
+    }
+  }
+  else {
+    myMesh = SMESH::SMESH_Mesh::_nil();
+    aString = "";
+  }
+
+  LineEditMeshes->setText(aString);
+
+  bool isEnabled = (!myMesh->_is_nil());
+  buttonOk->setEnabled(isEnabled);
+  buttonApply->setEnabled(isEnabled);
+}
+
+//=================================================================================
+// function : DeactivateActiveDialog()
+// purpose  :
+//=================================================================================
+void SMESHGUI_BuildCompoundDlg::DeactivateActiveDialog()
+{
+  if (GroupConstructors->isEnabled()) {
+    GroupConstructors->setEnabled(false);
+    GroupName->setEnabled(false);
+    GroupArgs->setEnabled(false);
+    GroupButtons->setEnabled(false);
+    mySMESHGUI->ResetState();
+    mySMESHGUI->SetActiveDialogBox(0);
+  }
+}
+
+//=================================================================================
+// function : ActivateThisDialog()
+// purpose  :
+//=================================================================================
+void SMESHGUI_BuildCompoundDlg::ActivateThisDialog()
+{
+  /* Emit a signal to deactivate the active dialog */
+  mySMESHGUI->EmitSignalDeactivateDialog();
+  GroupConstructors->setEnabled(true);
+  GroupName->setEnabled(true);
+  GroupArgs->setEnabled(true);
+  GroupButtons->setEnabled(true);
+
+  mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+  SelectionIntoArgument();
+}
+
+//=================================================================================
+// function : enterEvent()
+// purpose  :
+//=================================================================================
+void SMESHGUI_BuildCompoundDlg::enterEvent(QEvent* e)
+{
+  if (GroupConstructors->isEnabled())
+    return;
+  ActivateThisDialog();
+}
+
+//=================================================================================
+// function : closeEvent()
+// purpose  :
+//=================================================================================
+void SMESHGUI_BuildCompoundDlg::closeEvent(QCloseEvent* e)
+{
+  /* same than click on cancel button */
+  this->ClickOnCancel();
+}
+
+//=======================================================================
+//function : hideEvent
+//purpose  : caused by ESC key
+//=======================================================================
+void SMESHGUI_BuildCompoundDlg::hideEvent (QHideEvent * e)
+{
+  if (!isMinimized())
+    ClickOnCancel();
+}
+
+
+//=================================================================================
+// function : keyPressEvent()
+// purpose  :
+//=================================================================================
+void SMESHGUI_BuildCompoundDlg::keyPressEvent( QKeyEvent* e )
+{
+  QDialog::keyPressEvent( e );
+  if ( e->isAccepted() )
+    return;
+
+  if ( e->key() == Key_F1 )
+    {
+      e->accept();
+      ClickOnHelp();
+    }
+}
+
+
+//=================================================================================
+// function : onSelectMerge()
+// purpose  :
+//=================================================================================
+void SMESHGUI_BuildCompoundDlg::onSelectMerge(bool toMerge)
+{
+  TextLabelTol->setEnabled(toMerge);
+  SpinBoxTol->setEnabled(toMerge);
+  
+}
diff --git a/src/SMESHGUI/SMESHGUI_BuildCompoundDlg.h b/src/SMESHGUI/SMESHGUI_BuildCompoundDlg.h
new file mode 100644 (file)
index 0000000..c7bc29c
--- /dev/null
@@ -0,0 +1,135 @@
+//  SMESH SMESHGUI : GUI for SMESH component
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : SMESHGUI_BuildCompoundDlg.h
+//  Author : Alexander KOVALEV
+//  Module : SMESH
+
+#ifndef SMESHGUI_BuildCompoundDlg_H
+#define SMESHGUI_BuildCompoundDlg_H
+
+#include "LightApp_SelectionMgr.h"
+#include "SUIT_SelectionFilter.h"
+
+// QT Includes
+#include <qdialog.h>
+
+#include <vector>
+
+// Open CASCADE Includes
+
+class QGridLayout;
+class QButtonGroup;
+class QGroupBox;
+class QLabel;
+class QLineEdit;
+class QPushButton;
+class QRadioButton;
+class SMESHGUI;
+class QCheckBox;
+class SMESHGUI_SpinBox;
+class QComboBox;
+class QSizePolicy;
+class QString;
+
+// IDL Headers
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_Gen)
+
+//=================================================================================
+// class    : SMESHGUI_BuildCompoundDlg
+// purpose  :
+//=================================================================================
+class SMESHGUI_BuildCompoundDlg : public QDialog
+{
+  Q_OBJECT;
+
+ public:
+
+  SMESHGUI_BuildCompoundDlg (SMESHGUI  * theModule);
+  ~SMESHGUI_BuildCompoundDlg();
+
+public :
+  static QString GetDefaultName(const QString& theOperation);
+
+ private:
+  void Init();
+  void closeEvent (QCloseEvent*);
+  void enterEvent (QEvent*);              /* mouse enter the QWidget */
+  void hideEvent  (QHideEvent*);          /* ESC key */
+  void keyPressEvent(QKeyEvent*);
+
+ private:
+  SMESHGUI*               mySMESHGUI;     /* Current SMESHGUI object */
+  LightApp_SelectionMgr*  mySelectionMgr; /* User shape selection */
+
+  SMESH::SMESH_Mesh_var   myMesh;
+  SUIT_SelectionFilter*   myMeshFilter;
+  SMESH::mesh_array_var   myMeshArray;
+
+  // Widgets
+  QButtonGroup* GroupConstructors;
+  QRadioButton* Constructor1;
+
+  QGroupBox* GroupButtons;
+  QPushButton* buttonOk;
+  QPushButton* buttonCancel;
+  QPushButton* buttonApply;
+  QPushButton* buttonHelp;
+
+  QGroupBox* GroupName;
+  QLabel* TextLabelName;
+  QLineEdit* LineEditName;
+
+  QGroupBox* GroupArgs;
+  QLabel* TextLabelMeshes;
+  QPushButton* SelectButton;
+  QLineEdit* LineEditMeshes;
+  QLabel* TextLabelUnion;
+  QComboBox* ComboBoxUnion;
+  QCheckBox* CheckBoxMerge;
+  QLabel* TextLabelTol;
+  SMESHGUI_SpinBox* SpinBoxTol;
+
+  //protected:
+  QGridLayout* SMESHGUI_BuildCompoundDlgLayout;
+  QGridLayout* GroupConstructorsLayout;
+  QGridLayout* GroupButtonsLayout;
+  QGridLayout* GroupNameLayout;
+  QGridLayout* GroupArgsLayout;
+
+  QString myHelpFileName;
+
+ private slots:
+  void ClickOnOk();
+  void ClickOnCancel();
+  bool ClickOnApply();
+  void ClickOnHelp();
+  void SelectionIntoArgument();
+  void DeactivateActiveDialog();
+  void ActivateThisDialog();
+  void onSelectMerge(bool);
+};
+
+#endif // SMESHGUI_BuildCompoundDlg_H
diff --git a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx
new file mode 100644 (file)
index 0000000..873e4c6
--- /dev/null
@@ -0,0 +1,1055 @@
+//  SMESH SMESHGUI : GUI for SMESH component
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : SMESHGUI_ComputeDlg.cxx
+//  Author : Edward AGAPOV
+//  Module : SMESH
+
+#include "SMESHGUI_ComputeDlg.h"
+
+#include "SMESHGUI.h"
+#include "SMESHGUI_GEOMGenUtils.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_HypothesesUtils.h"
+
+#include "SMDS_SetIterator.hxx"
+
+#include "GEOMBase.h"
+#include "GEOM_Actor.h"
+
+#include "LightApp_SelectionMgr.h"
+#include "LightApp_UpdateFlags.h"
+#include "SALOMEDSClient_SObject.hxx"
+#include "SALOME_ListIO.hxx"
+#include "SVTK_ViewWindow.h"
+#include "SVTK_ViewModel.h"
+#include "SalomeApp_Tools.h"
+#include "SalomeApp_Application.h"
+#include "SUIT_ResourceMgr.h"
+#include "SUIT_OverrideCursor.h"
+#include "SUIT_MessageBox.h"
+#include "SUIT_Desktop.h"
+#include "SUIT_Study.h"
+#include "OB_Browser.h"
+
+// OCCT Includes
+#include <BRep_Tool.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopoDS.hxx>
+
+#include <TopLoc_Location.hxx>
+#include <Poly_Triangulation.hxx>
+#include <Bnd_Box.hxx>
+#include <BRepBndLib.hxx>
+#include <BRepMesh_IncrementalMesh.hxx>
+
+// QT Includes
+#include <qframe.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qlabel.h>
+#include <qbuttongroup.h>
+#include <qradiobutton.h>
+#include <qtable.h>
+#include <qhbox.h>
+#include <qhgroupbox.h>
+
+#include <vtkProperty.h>
+
+// IDL Headers
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Gen)
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+
+#include <vector>
+#include <set>
+
+
+#define SPACING 5
+#define MARGIN  10
+
+#define COLONIZE(str)   (QString(str).contains(":") > 0 ? QString(str) : QString(str) + " :" )
+
+#define _SEPARATOR(father) \
+{\
+  /*new QLabel(father); new QLabel(father); new QLabel(father)*/;\
+  (new QFrame(father))->setFrameStyle(QFrame::HLine | QFrame::Sunken);\
+  (new QFrame(father))->setFrameStyle(QFrame::HLine | QFrame::Sunken);\
+  (new QFrame(father))->setFrameStyle(QFrame::HLine | QFrame::Sunken);\
+  (new QFrame(father))->setFrameStyle(QFrame::HLine | QFrame::Sunken);\
+}
+
+enum TCol { COL_ALGO = 0, COL_SHAPE, COL_ERROR, COL_SHAPEID, COL_PUBLISHED, NB_COLUMNS };
+
+using namespace SMESH;
+
+namespace SMESH {
+  
+  // =========================================================================================
+  /*!
+   * \brief Class showing shapes without publishing
+   */
+  // =========================================================================================
+
+  class TShapeDisplayer
+  {
+  public:
+    // -----------------------------------------------------------------------
+    TShapeDisplayer(): myViewWindow(0)
+    {
+      myProperty = vtkProperty::New();
+      myProperty->SetRepresentationToWireframe();
+      myProperty->SetColor( 250, 0, 250 );
+      myProperty->SetAmbientColor( 250, 0, 250 );
+      myProperty->SetDiffuseColor( 250, 0, 250 );
+      //myProperty->SetSpecularColor( 250, 0, 250 );
+      myProperty->SetLineWidth( 5 );
+    }
+    // -----------------------------------------------------------------------
+    ~TShapeDisplayer()
+    {
+      DeleteActors();
+      myProperty->Delete();
+    }
+    // -----------------------------------------------------------------------
+    void DeleteActors()
+    {
+      if ( hasViewWindow() ) {
+        TActorIterator actorIt = actorIterator();
+        while ( actorIt.more() )
+          if (VTKViewer_Actor* anActor = actorIt.next()) {
+            myViewWindow->RemoveActor( anActor );
+            //anActor->Delete();
+          }
+      }
+      myIndexToShape.Clear();
+      myActors.clear();
+      myShownActors.clear();
+      myBuiltSubs.clear();
+    }
+    // -----------------------------------------------------------------------
+    void SetVisibility (bool theVisibility)
+    {
+      TActorIterator actorIt = shownIterator();
+      while ( actorIt.more() )
+        if (VTKViewer_Actor* anActor = actorIt.next())
+          anActor->SetVisibility(theVisibility);
+      SMESH::RepaintCurrentView();
+    }
+    // -----------------------------------------------------------------------
+    bool HasReadyActorsFor (int subShapeID, GEOM::GEOM_Object_var aMainShape )
+    {
+      string mainEntry;
+      if ( !aMainShape->_is_nil() )
+        mainEntry = aMainShape->GetStudyEntry();
+      return ( myMainEntry == mainEntry &&
+               myBuiltSubs.find( subShapeID ) != myBuiltSubs.end() );
+    }
+    // -----------------------------------------------------------------------
+    void Show( int subShapeID, GEOM::GEOM_Object_var aMainShape, bool only = false)
+    {
+      SVTK_ViewWindow* aViewWindow  = SMESH::GetViewWindow( SMESHGUI::GetSMESHGUI() );
+      string mainEntry;
+      if ( !aMainShape->_is_nil() )
+        mainEntry = aMainShape->GetStudyEntry();
+      if ( myMainEntry != mainEntry || aViewWindow != myViewWindow ) { // remove actors
+        DeleteActors();
+        TopoDS_Shape aShape;
+        if ( !aMainShape->_is_nil() && GEOMBase::GetShape(aMainShape, aShape)) {
+          checkTriangulation( aShape );
+          TopExp::MapShapes(aShape, myIndexToShape);
+          myActors.resize( myIndexToShape.Extent(), 0 );
+          myShownActors.reserve( myIndexToShape.Extent() );
+        }
+        myMainEntry  = mainEntry;
+        myViewWindow = aViewWindow;
+      }
+      if ( only ) { // hide shown actors
+        TActorIterator actorIt = shownIterator();
+        while ( actorIt.more() )
+          if (VTKViewer_Actor* anActor = actorIt.next())
+            anActor->SetVisibility(false);
+        myShownActors.clear();
+      }
+      // find actors to show
+      TopoDS_Shape aShape = myIndexToShape( subShapeID );
+      if ( !aShape.IsNull() ) {
+        TopAbs_ShapeEnum type( aShape.ShapeType() >= TopAbs_WIRE ? TopAbs_EDGE : TopAbs_FACE );
+        for ( TopExp_Explorer exp( aShape, type ); exp.More(); exp.Next() ) {
+          //checkTriangulation( exp.Current() );
+          if ( GEOM_Actor* anActor = getActor( exp.Current() ))
+            myShownActors.push_back( anActor );
+        }
+        if ( type == TopAbs_FACE ) {
+          for ( TopExp_Explorer exp( aShape, TopAbs_EDGE ); exp.More(); exp.Next() ) {
+            const TopoDS_Edge & edge = TopoDS::Edge( exp.Current() );
+            if ( !BRep_Tool::Degenerated( edge ))
+              if ( GEOM_Actor* anActor = getActor( exp.Current() ))
+                myShownActors.push_back( anActor );
+          }
+        }
+      }
+      myBuiltSubs.insert( subShapeID );
+      SetVisibility(true);
+    }
+    // -----------------------------------------------------------------------
+
+  private:
+
+    typedef std::vector<GEOM_Actor*> TActorVec;
+    TActorVec                  myActors;
+    TActorVec                  myShownActors;
+    TopTools_IndexedMapOfShape myIndexToShape;
+    string                     myMainEntry;
+    SVTK_ViewWindow*           myViewWindow;
+    vtkProperty*               myProperty;
+    std::set<int>              myBuiltSubs;
+
+    // -----------------------------------------------------------------------
+    typedef SMDS_SetIterator< GEOM_Actor*, TActorVec::const_iterator> TActorIterator;
+    TActorIterator actorIterator() {
+      return TActorIterator( myActors.begin(), myActors.end() );
+    }
+    TActorIterator shownIterator() {
+      return TActorIterator( myShownActors.begin(), myShownActors.end() );
+    }
+    // -----------------------------------------------------------------------
+    GEOM_Actor* getActor(const TopoDS_Shape& shape)
+    {
+      int index = myIndexToShape.FindIndex( shape ) - 1;
+      if ( index < 0 || index >= myActors.size() )
+        return 0;
+      GEOM_Actor* & actor = myActors[ index ];
+      if ( !actor ) {
+        actor = GEOM_Actor::New();
+        if ( actor ) {
+          actor->setInputShape(shape,0,0);
+          //actor->SetProperty(myProperty);
+          actor->SetShadingProperty(myProperty);
+          actor->SetWireframeProperty(myProperty);
+          actor->SetPreviewProperty(myProperty);
+          actor->PickableOff();
+          //         if ( shape.ShapeType() == TopAbs_EDGE )
+          //           actor->SubShapeOn();
+          myViewWindow->AddActor( actor );
+        }
+      }
+      return actor;
+    }
+    // -----------------------------------------------------------------------
+    void checkTriangulation(const TopoDS_Shape& shape)
+    {
+      TopLoc_Location aLoc;
+      Standard_Boolean alreadymesh = Standard_True;
+      TopExp_Explorer ex(shape, TopAbs_FACE);
+      if ( ex.More() )
+        for (; ex.More(); ex.Next()) {
+          const TopoDS_Face& aFace = TopoDS::Face(ex.Current());
+          Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc);
+          if(aPoly.IsNull()) { alreadymesh = Standard_False; break; }
+        }
+      else
+        for (ex.Init(shape, TopAbs_EDGE); ex.More(); ex.Next()) {
+          const TopoDS_Edge& edge = TopoDS::Edge(ex.Current());
+          Handle(Poly_Polygon3D) aPoly = BRep_Tool::Polygon3D(edge, aLoc);
+          if(aPoly.IsNull()) { alreadymesh = Standard_False; break; }
+        }
+      if (alreadymesh) return;
+      // Compute default deflection
+      Bnd_Box B;
+      BRepBndLib::Add(shape, B);
+      Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
+      B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
+      double deflection = Max( aXmax-aXmin , Max ( aYmax-aYmin , aZmax-aZmin)) * 0.01 *4;
+      BRepMesh_IncrementalMesh MESH(shape,deflection);
+    }
+    // -----------------------------------------------------------------------
+    bool hasViewWindow() const
+    {
+      if ( !myViewWindow ) return false;
+
+      if ( SalomeApp_Application* anApp = SMESHGUI::GetSMESHGUI()->getApp() )
+        return FindVtkViewWindow( anApp->getViewManager(SVTK_Viewer::Type(), false ),
+                                  myViewWindow );
+      return false;
+    }
+  };
+
+  // =========================================================================================
+  /*!
+   * \brief Return text describing an error
+   */
+#define CASE2TEXT(enum) case SMESH::enum: text = QObject::tr( #enum ); break;
+  QString errorText(int errCode, const char* comment)
+  {
+    QString text;
+    switch ( errCode ) {
+      CASE2TEXT( COMPERR_OK            );
+      CASE2TEXT( COMPERR_BAD_INPUT_MESH);
+      CASE2TEXT( COMPERR_STD_EXCEPTION );
+      CASE2TEXT( COMPERR_OCC_EXCEPTION );
+      CASE2TEXT( COMPERR_SLM_EXCEPTION );
+      CASE2TEXT( COMPERR_EXCEPTION     );
+      CASE2TEXT( COMPERR_MEMORY_PB     );
+      CASE2TEXT( COMPERR_BAD_SHAPE     );
+    case SMESH::COMPERR_ALGO_FAILED:
+      if ( strlen(comment) == 0 )
+        text = QObject::tr("COMPERR_ALGO_FAILED");
+      break;
+    default:
+      text = QString("#%1").arg( -errCode );
+    }
+    if ( text.length() > 0 ) text += ". ";
+    return text + comment;
+  }
+  // -----------------------------------------------------------------------
+  /*!
+   * \brief Return SO of a subshape
+   */
+  _PTR(SObject) getSubShapeSO( int subShapeID, GEOM::GEOM_Object_var aMainShape)
+  {
+    _PTR(SObject) so = SMESH::FindSObject(aMainShape);
+    if ( subShapeID == 1 || !so )
+      return so;
+    _PTR(ChildIterator) it;
+    if (_PTR(Study) study = SMESH::GetActiveStudyDocument())
+      it =  study->NewChildIterator(so);
+    _PTR(SObject) subSO;
+    if ( it ) {
+      for ( it->InitEx(true); !subSO && it->More(); it->Next() ) {
+        GEOM::GEOM_Object_var geom = SMESH::SObjectToInterface<GEOM::GEOM_Object>( it->Value() );
+        if ( !geom->_is_nil() ) {
+          GEOM::ListOfLong_var list = geom->GetSubShapeIndices();
+          if ( list->length() == 1 && list[0] == subShapeID )
+            subSO = it->Value();
+        }
+      }
+    }
+    return subSO;
+  }
+  // -----------------------------------------------------------------------
+  /*!
+   * \brief Return subshape by ID
+   */
+  GEOM::GEOM_Object_ptr getSubShape( int subShapeID, GEOM::GEOM_Object_var aMainShape)
+  {
+    GEOM::GEOM_Object_var aSubShape;
+    if ( subShapeID == 1 )
+      aSubShape = aMainShape;
+    else if ( _PTR(SObject) so = getSubShapeSO( subShapeID, aMainShape ))
+      aSubShape = SMESH::SObjectToInterface<GEOM::GEOM_Object>( so );
+    else
+      aSubShape = SMESH::GetSubShape( aMainShape, subShapeID );
+    return aSubShape._retn();
+  }
+  // -----------------------------------------------------------------------
+  /*!
+   * \brief Return shape type name
+   */
+#define CASE2NAME(enum) case GEOM::enum: name = QObject::tr( "GEOM_" #enum ); break;
+  QString shapeTypeName(GEOM::GEOM_Object_var aShape, const char* dflt = "" )
+  {
+    QString name = dflt;
+    if ( !aShape->_is_nil() ) {
+      switch ( aShape->GetShapeType() ) {
+      CASE2NAME( VERTEX    );
+      CASE2NAME( EDGE      );
+      CASE2NAME( WIRE      );
+      CASE2NAME( FACE      );
+      CASE2NAME( SHELL     );
+      CASE2NAME( SOLID     );
+      CASE2NAME( COMPSOLID );
+      CASE2NAME( COMPOUND  );
+      default:;
+      }
+    }
+    return name;
+  }
+  // -----------------------------------------------------------------------
+  /*!
+   * \brief Return text describing a subshape
+   */
+  QString shapeText(int subShapeID, GEOM::GEOM_Object_var aMainShape )
+  {
+    QString text;
+    if ( _PTR(SObject) aSO = getSubShapeSO( subShapeID, aMainShape ))
+      text = aSO->GetName();
+    else {
+      text = QString("#%1").arg( subShapeID );
+      QString typeName = shapeTypeName( getSubShape( subShapeID, aMainShape ));
+      if ( typeName.length() )
+        text += QString(" (%1)").arg(typeName);
+    }
+    return text;
+  }
+  // -----------------------------------------------------------------------
+  /*!
+   * \brief Return text describing a subshape
+   */
+  bool getSelectedRows(QTable* table, list< int > & rows)
+  {
+    rows.clear();
+    int nbSel = table->numSelections();
+    for ( int i = 0; i < nbSel; ++i )
+    {
+      QTableSelection selected = table->selection(i);
+      if ( !selected.isActive() ) continue;
+      for ( int row = selected.topRow(); row <= selected.bottomRow(); ++row )
+        rows.push_back( row );
+    }
+    return !rows.empty();
+  }
+
+} // namespace SMESH
+
+
+// =========================================================================================
+/*!
+ * \brief Box showing mesh info
+ */
+// =========================================================================================
+
+SMESHGUI_MeshInfosBox::SMESHGUI_MeshInfosBox(const bool full, QWidget* theParent)
+  :QGroupBox( 4, Qt::Horizontal, tr("SMESH_MESHINFO_TITLE"), theParent ), myFull( full )
+{
+  // title
+  QLabel* lab1 = new QLabel(this);
+  QLabel* lab2 = new QLabel(tr("SMESH_MESHINFO_ORDER0"), this );
+  QLabel* lab3 = new QLabel(tr("SMESH_MESHINFO_ORDER1"), this );
+  QLabel* lab4 = new QLabel(tr("SMESH_MESHINFO_ORDER2"), this );
+
+  QFont italic = lab1->font(); italic.setItalic(true);
+  QFont bold   = lab1->font(); bold.setBold(true);
+
+  lab1->setMinimumWidth(100); lab1->setFont( italic );
+  lab2->setMinimumWidth(100); lab2->setFont( italic );
+  lab3->setMinimumWidth(100); lab3->setFont( italic );
+  lab4->setMinimumWidth(100); lab4->setFont( italic );
+
+  if ( myFull )
+  {
+    // nodes
+    (new QLabel(COLONIZE(tr("SMESH_MESHINFO_NODES")), this ))->setFont( bold );
+    myNbNode = new QLabel( this );
+    new QLabel(this);
+    new QLabel(this);
+
+    _SEPARATOR(this);
+
+    // edges
+    (new QLabel(COLONIZE(tr("SMESH_MESHINFO_EDGES")), this ))->setFont( bold );
+    myNbEdge = new QLabel( this );
+    myNbLinEdge = new QLabel( this );
+    myNbQuadEdge = new QLabel( this );
+
+    _SEPARATOR(this);
+
+    // faces
+    (new QLabel(COLONIZE(tr("SMESH_MESHINFO_FACES")), this))->setFont( bold );
+    myNbFace     = new QLabel( this );
+    myNbLinFace  = new QLabel( this );
+    myNbQuadFace = new QLabel( this );
+    // triangles
+    new QLabel(COLONIZE(tr("SMESH_MESHINFO_TRIANGLES")), this );
+    myNbTrai     = new QLabel( this );
+    myNbLinTrai  = new QLabel( this );
+    myNbQuadTrai = new QLabel( this );
+    // quadrangles
+    new QLabel(COLONIZE(tr("SMESH_MESHINFO_QUADRANGLES")), this );
+    myNbQuad     = new QLabel( this );
+    myNbLinQuad  = new QLabel( this );
+    myNbQuadQuad = new QLabel( this );
+    // poligones
+    new QLabel(COLONIZE(tr("SMESH_MESHINFO_POLYGONES")), this );
+    myNbPolyg    = new QLabel( this );
+    new QLabel("",this );
+    new QLabel("", this );
+
+    _SEPARATOR(this);
+
+    // volumes
+    (new QLabel(COLONIZE(tr("SMESH_MESHINFO_VOLUMES")), this))->setFont( bold );
+    myNbVolum     = new QLabel( this );
+    myNbLinVolum  = new QLabel( this );
+    myNbQuadVolum = new QLabel( this );
+    // tetras
+    new QLabel(COLONIZE(tr("SMESH_MESHINFO_TETRAS")), this );
+    myNbTetra     = new QLabel( this );
+    myNbLinTetra  = new QLabel( this );
+    myNbQuadTetra = new QLabel( this );
+    // hexas
+    new QLabel(COLONIZE(tr("SMESH_MESHINFO_HEXAS")), this );
+    myNbHexa      = new QLabel( this );
+    myNbLinHexa   = new QLabel( this );
+    myNbQuadHexa  = new QLabel( this );
+    // pyras
+    new QLabel(COLONIZE(tr("SMESH_MESHINFO_PYRAS")), this );
+    myNbPyra      = new QLabel( this );
+    myNbLinPyra   = new QLabel( this );
+    myNbQuadPyra  = new QLabel( this );
+    // prisms
+    new QLabel(COLONIZE(tr("SMESH_MESHINFO_PRISMS")), this );
+    myNbPrism     = new QLabel( this );
+    myNbLinPrism  = new QLabel( this );
+    myNbQuadPrism = new QLabel( this );
+    // polyedres
+    new QLabel(COLONIZE(tr("SMESH_MESHINFO_POLYEDRES")), this );
+    myNbPolyh     = new QLabel( this );
+    new QLabel("", this );
+    new QLabel("", this );
+  }
+  else
+  {
+    // nodes
+    new QLabel(COLONIZE(tr("SMESH_MESHINFO_NODES")), this );
+    myNbNode      = new QLabel( this );
+    new QLabel(this);
+    new QLabel(this);
+
+    // edges
+    new QLabel(COLONIZE(tr("SMESH_MESHINFO_EDGES")), this );
+    myNbEdge      = new QLabel( this );
+    myNbLinEdge   = new QLabel( this );
+    myNbQuadEdge  = new QLabel( this );
+
+    // faces
+    new QLabel(COLONIZE(tr("SMESH_MESHINFO_FACES")), this);
+    myNbFace      = new QLabel( this );
+    myNbLinFace   = new QLabel( this );
+    myNbQuadFace  = new QLabel( this );
+
+    // volumes
+    new QLabel(COLONIZE(tr("SMESH_MESHINFO_VOLUMES")), this);
+    myNbVolum     = new QLabel( this );
+    myNbLinVolum  = new QLabel( this );
+    myNbQuadVolum = new QLabel( this );
+  }
+}
+
+// =========================================================================================
+/*!
+ * \brief Set mesh info
+ */
+// =========================================================================================
+
+void SMESHGUI_MeshInfosBox::SetInfoByMesh(SMESH::SMESH_Mesh_var mesh)
+{
+  const SMESH::ElementOrder lin = SMESH::ORDER_LINEAR;
+  int nbTot, nbLin;
+
+  // nodes
+  myNbNode     ->setText( QString("%1").arg( mesh->NbNodes() ));
+
+  // edges
+  nbTot = mesh->NbEdges(), nbLin = mesh->NbEdgesOfOrder(lin);
+  myNbEdge     ->setText( QString("%1").arg( nbTot ));
+  myNbLinEdge  ->setText( QString("%1").arg( nbLin ));
+  myNbQuadEdge ->setText( QString("%1").arg( nbTot - nbLin ));
+
+  // faces
+  nbTot = mesh->NbFaces(), nbLin = mesh->NbFacesOfOrder(lin);
+  myNbFace     ->setText( QString("%1").arg( nbTot ));
+  myNbLinFace  ->setText( QString("%1").arg( nbLin ));
+  myNbQuadFace ->setText( QString("%1").arg( nbTot - nbLin ));
+
+  // volumes
+  nbTot = mesh->NbVolumes(), nbLin = mesh->NbVolumesOfOrder(lin);
+  myNbVolum    ->setText( QString("%1").arg( nbTot ));
+  myNbLinVolum ->setText( QString("%1").arg( nbLin ));
+  myNbQuadVolum->setText( QString("%1").arg( nbTot - nbLin ));
+
+  if ( myFull )
+  {
+    // triangles
+    nbTot = mesh->NbTriangles(), nbLin = mesh->NbTrianglesOfOrder(lin);
+    myNbTrai     ->setText( QString("%1").arg( nbTot ));
+    myNbLinTrai  ->setText( QString("%1").arg( nbLin ));
+    myNbQuadTrai ->setText( QString("%1").arg( nbTot - nbLin ));
+    // quadrangles
+    nbTot = mesh->NbQuadrangles(), nbLin = mesh->NbQuadranglesOfOrder(lin);
+    myNbQuad     ->setText( QString("%1").arg( nbTot ));
+    myNbLinQuad  ->setText( QString("%1").arg( nbLin ));
+    myNbQuadQuad ->setText( QString("%1").arg( nbTot - nbLin ));
+    // poligones
+    myNbPolyg    ->setText( QString("%1").arg( mesh->NbPolygons() ));
+
+    // tetras
+    nbTot = mesh->NbTetras(), nbLin = mesh->NbTetrasOfOrder(lin);
+    myNbTetra    ->setText( QString("%1").arg( nbTot ));
+    myNbLinTetra ->setText( QString("%1").arg( nbLin ));
+    myNbQuadTetra->setText( QString("%1").arg( nbTot - nbLin ));
+    // hexas
+    nbTot = mesh->NbHexas(), nbLin = mesh->NbHexasOfOrder(lin);
+    myNbHexa     ->setText( QString("%1").arg( nbTot ));
+    myNbLinHexa  ->setText( QString("%1").arg( nbLin ));
+    myNbQuadHexa ->setText( QString("%1").arg( nbTot - nbLin ));
+    // pyras
+    nbTot = mesh->NbPyramids(), nbLin = mesh->NbPyramidsOfOrder(lin);
+    myNbPyra     ->setText( QString("%1").arg( nbTot ));
+    myNbLinPyra  ->setText( QString("%1").arg( nbLin ));
+    myNbQuadPyra ->setText( QString("%1").arg( nbTot - nbLin ));
+    // prisms
+    nbTot = mesh->NbPrisms(), nbLin = mesh->NbPrismsOfOrder(lin);
+    myNbPrism    ->setText( QString("%1").arg( nbTot ));
+    myNbLinPrism ->setText( QString("%1").arg( nbLin ));
+    myNbQuadPrism->setText( QString("%1").arg( nbTot - nbLin ));
+    // polyedres
+    myNbPolyh    ->setText( QString("%1").arg( mesh->NbPolyhedrons() ));
+  }
+}
+
+// =========================================================================================
+/*!
+ * \brief Dialog to compute a mesh and show computation errors
+ */
+//=======================================================================
+
+SMESHGUI_ComputeDlg::SMESHGUI_ComputeDlg(): SMESHGUI_Dialog( 0, false, true, OK/* | Help*/ )
+{
+  QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame(), 0, SPACING);
+
+  QFrame* aMainFrame = createMainFrame  (mainFrame());
+
+  aDlgLay->addWidget(aMainFrame);
+
+  aDlgLay->setStretchFactor(aMainFrame, 1);
+}
+
+//=======================================================================
+// function : createMainFrame()
+// purpose  : Create frame containing dialog's fields
+//=======================================================================
+
+#define CASE2HEADER(enum) case enum: header = QObject::tr( #enum "_HEADER" ); break;
+
+QFrame* SMESHGUI_ComputeDlg::createMainFrame (QWidget* theParent)
+{
+  QFrame* aFrame = new QFrame(theParent);
+
+  SUIT_ResourceMgr* rm = resourceMgr();
+  QPixmap iconCompute (rm->loadPixmap("SMESH", tr("ICON_COMPUTE")));
+
+  // constructor
+
+  QButtonGroup* aPixGrp = new QButtonGroup(1, Qt::Vertical, tr("CONSTRUCTOR"), aFrame);
+  aPixGrp->setExclusive(TRUE);
+  QRadioButton* aRBut = new QRadioButton(aPixGrp);
+  aRBut->setPixmap(iconCompute);
+  aRBut->setChecked(TRUE);
+
+  // Mesh name
+
+  QHGroupBox* nameBox = new QHGroupBox(tr("SMESH_MESHINFO_NAME"), aFrame );
+  myMeshName = new QLabel(nameBox);
+
+  // Mesh Info
+
+  myBriefInfo = new SMESHGUI_MeshInfosBox(false, aFrame);
+  myFullInfo  = new SMESHGUI_MeshInfosBox(true,  aFrame);
+
+  // errors
+
+  myErrorGroup = new QGroupBox(tr("ERRORS"), aFrame, "errorGrBox");
+  myTable      = new QTable( 1, NB_COLUMNS, myErrorGroup, "myTable");
+  myShowBtn    = new QPushButton(tr("SHOW_SHAPE"), myErrorGroup, "myShowBtn");
+  myPublishBtn = new QPushButton(tr("PUBLISH_SHAPE"), myErrorGroup, "myPublishBtn");
+
+  myTable->setReadOnly( TRUE );
+  myTable->hideColumn( COL_PUBLISHED );
+  myTable->hideColumn( COL_SHAPEID );
+  myTable->setColumnStretchable( COL_ERROR, 1 );
+  for ( int col = 0; col < NB_COLUMNS; ++col ) {
+    QString header;
+    switch ( col ) {
+    CASE2HEADER( COL_ALGO     );
+    CASE2HEADER( COL_SHAPE    );
+    CASE2HEADER( COL_ERROR    );
+    CASE2HEADER( COL_SHAPEID  );
+    CASE2HEADER( COL_PUBLISHED);
+    }
+    myTable->horizontalHeader()->setLabel( col, header );
+  }
+
+  myErrorGroup->setColumnLayout(0, Qt::Vertical);
+  myErrorGroup->layout()->setSpacing(0);
+  myErrorGroup->layout()->setMargin(0);
+  QGridLayout* grpLayout = new QGridLayout(myErrorGroup->layout());
+  grpLayout->setAlignment(Qt::AlignTop);
+  grpLayout->setSpacing(SPACING);
+  grpLayout->setMargin(MARGIN);
+  grpLayout->addMultiCellWidget( myTable,   0, 2, 0, 0 );
+  grpLayout->addWidget         ( myShowBtn,    0, 1 );
+  grpLayout->addWidget         ( myPublishBtn, 1, 1 );
+  grpLayout->setRowStretch( 2, 1 );
+
+  QVBoxLayout* aLay = new QVBoxLayout(aFrame);
+  aLay->addWidget( aPixGrp );
+  aLay->addWidget( nameBox );
+  aLay->addWidget( myBriefInfo );
+  aLay->addWidget( myFullInfo );
+  aLay->addWidget( myErrorGroup );
+  aLay->setStretchFactor( myErrorGroup, 1 );
+
+  return aFrame;
+}
+
+//================================================================================
+/*!
+ * \brief Constructor
+*/
+//================================================================================
+
+SMESHGUI_ComputeOp::SMESHGUI_ComputeOp()
+{
+  myDlg = new SMESHGUI_ComputeDlg;
+  myTShapeDisplayer = new TShapeDisplayer();
+  myHelpFileName = "/files/about_meshes.htm";
+
+  // connect signals and slots
+  connect(myDlg->myShowBtn,    SIGNAL (clicked()), SLOT(onPreviewShape()));
+  connect(myDlg->myPublishBtn, SIGNAL (clicked()), SLOT(onPublishShape()));
+  connect(table(),SIGNAL(selectionChanged()), SLOT(currentCellChanged()));
+}
+
+//=======================================================================
+// function : startOperation()
+// purpose  : Init dialog fields, connect signals and slots, show dialog
+//=======================================================================
+
+void SMESHGUI_ComputeOp::startOperation()
+{
+  SMESHGUI_Operation::startOperation();
+
+  SMESH::SMESH_Mesh_var          aMesh;
+  SMESH::compute_error_array_var anErrors;
+
+  myMainShape = GEOM::GEOM_Object::_nil();
+
+  // COMPUTE MESH
+
+  bool computeFailed = true;
+  int nbNodes = 0, nbEdges = 0, nbFaces = 0, nbVolums = 0;
+
+  LightApp_SelectionMgr *Sel = selectionMgr();
+  SALOME_ListIO selected; Sel->selectedObjects( selected );
+
+  int nbSel = selected.Extent();
+  if (nbSel != 1) {
+    SUIT_MessageBox::warn1(desktop(),
+                           tr("SMESH_WRN_WARNING"),
+                           tr("SMESH_WRN_NO_AVAILABLE_DATA"),
+                           tr("SMESH_BUT_OK"));
+    onCancel();
+    return;
+  }
+
+  Handle(SALOME_InteractiveObject) IObject = selected.First();
+  aMesh = SMESH::GetMeshByIO(IObject);
+  if (!aMesh->_is_nil()) {
+    myMainShape = aMesh->GetShapeToMesh();
+    if ( !myMainShape->_is_nil() ) {
+      SMESH::SMESH_Gen_var gen = getSMESHGUI()->GetSMESHGen();
+      SMESH::algo_error_array_var errors = gen->GetAlgoState(aMesh,myMainShape);
+      if ( errors->length() > 0 ) {
+        SUIT_MessageBox::warn1(desktop(), tr("SMESH_WRN_WARNING"),
+                               SMESH::GetMessageOnAlgoStateErrors( errors.in() ),
+                               tr("SMESH_BUT_OK"));
+        onCancel();
+        return;
+      }
+      try {
+        if (gen->Compute(aMesh, myMainShape)) {
+          computeFailed = false;
+        }
+        else {
+          anErrors = gen->GetComputeErrors( aMesh, myMainShape );
+//           if ( anErrors->length() == 0 ) {
+//             SUIT_MessageBox::warn1(desktop(),
+//                                    tr("SMESH_WRN_WARNING"),
+//                                    tr("SMESH_WRN_COMPUTE_FAILED"),
+//                                    tr("SMESH_BUT_OK"));
+//             onCancel();
+//             return;
+//           }
+        }
+        if ( _PTR(SObject) aMeshSObj = SMESH::FindSObject(aMesh)) {
+          SMESH::ModifiedMesh(aMeshSObj, !computeFailed, aMesh->NbNodes() == 0);
+          myDlg->myMeshName->setText( aMeshSObj->GetName() );
+        }
+      }
+      catch(const SALOME::SALOME_Exception & S_ex){
+        SalomeApp_Tools::QtCatchCorbaException(S_ex);
+      }
+      update( UF_ObjBrowser | UF_Model );
+
+      if ( getSMESHGUI()->automaticUpdate() ) {
+        SVTK_ViewWindow* aVTKView = SMESH::GetViewWindow(getSMESHGUI(), true);
+        if (aVTKView) {
+          int anId = study()->id();
+          TVisualObjPtr aVisualObj = SMESH::GetVisualObj(anId, IObject->getEntry());
+          if (aVisualObj) {
+            aVisualObj->Update();
+            SMESH_Actor* anActor = SMESH::FindActorByEntry(IObject->getEntry());
+            if (!anActor) {
+              anActor = SMESH::CreateActor(studyDS(), IObject->getEntry());
+              if (anActor) {
+                SMESH::DisplayActor(aVTKView, anActor); //apo
+                SMESH::FitAll();
+              }
+            }
+            SMESH::RepaintCurrentView();
+            Sel->setSelectedObjects( selected );
+          }
+        }
+      }
+    }
+  }
+
+  myDlg->setCaption(tr( computeFailed ? "SMESH_WRN_COMPUTE_FAILED" : "SMESH_COMPUTE_SUCCEED"));
+
+  // SHOW ERRORS
+
+  bool noError = ( !anErrors.operator->() || anErrors->length() == 0 );
+
+  QTable* tbl = myDlg->myTable;
+
+  if ( noError )
+  {
+    //tbl->setNumRows(0);
+    myDlg->myFullInfo->SetInfoByMesh( aMesh );
+    myDlg->myFullInfo->show();
+    myDlg->myBriefInfo->hide();
+    myDlg->myErrorGroup->hide();
+  }
+  else
+  {
+    myDlg->myBriefInfo->SetInfoByMesh( aMesh );
+    myDlg->myBriefInfo->show();
+    myDlg->myFullInfo->hide();
+    myDlg->myErrorGroup->show();
+
+    // fill table of errors
+    tbl->setNumRows( anErrors->length() );
+    bool hasShape = aMesh->HasShapeToMesh();
+    if ( !hasShape ) tbl->hideColumn( COL_SHAPE );
+    else             tbl->showColumn( COL_SHAPE );
+    tbl->setColumnWidth( COL_ERROR, 200 );
+
+    for ( int row = 0; row < anErrors->length(); ++row )
+    {
+      SMESH::ComputeError & err = anErrors[ row ];
+      tbl->setText( row, COL_ALGO,    err.algoName.in() );
+      tbl->setText( row, COL_ERROR,   errorText( err.code, err.comment.in() ));
+      tbl->setText( row, COL_SHAPEID, QString("%1").arg( err.subShapeID ));
+
+      QString text = hasShape ? shapeText( err.subShapeID, myMainShape ) : QString("");
+      tbl->setText( row, COL_SHAPE,   text );
+
+      text = ( !hasShape || getSubShapeSO( err.subShapeID, myMainShape )) ? "PUBLISHED" : "";
+      tbl->setText( row, COL_PUBLISHED, text ); // if text=="", "PUBLISH" button enabled
+
+      tbl->item( row, COL_ERROR )->setWordWrap( TRUE );
+      tbl->adjustRow( row );
+    }
+    tbl->adjustColumn( COL_ALGO );
+    tbl->adjustColumn( COL_SHAPE );
+
+    tbl->setCurrentCell(0,0);
+    currentCellChanged(); // to update buttons
+  }
+
+  myDlg->show();
+}
+
+//================================================================================
+/*!
+ * \brief Stops operation
+ */
+//================================================================================
+
+void SMESHGUI_ComputeOp::stopOperation()
+{
+  SMESHGUI_Operation::stopOperation();
+  myTShapeDisplayer->SetVisibility( false );
+}
+
+//================================================================================
+/*!
+ * \brief publish selected subshape
+ */
+//================================================================================
+
+void SMESHGUI_ComputeOp::onPublishShape()
+{
+  GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
+  SALOMEDS::Study_var study = SMESHGUI::GetSMESHGen()->GetCurrentStudy();
+
+  list< int > rows;
+  list< int >::iterator row;
+  getSelectedRows( table(), rows );
+  for ( row = rows.begin(); row != rows.end(); ++row )
+  {
+    int curSub = table()->text(*row, COL_SHAPEID).toInt();
+    GEOM::GEOM_Object_var shape = getSubShape( curSub, myMainShape );
+    if ( !shape->_is_nil() && ! getSubShapeSO( curSub, myMainShape ))
+    {
+      if ( !getSubShapeSO( 1, myMainShape )) // the main shape not published
+      {
+        QString name = GEOMBase::GetDefaultName( shapeTypeName( myMainShape, "MAIN_SHAPE" ));
+        SALOMEDS::SObject_var so =
+          geomGen->AddInStudy( study, myMainShape, name, GEOM::GEOM_Object::_nil());
+        // look for myMainShape in the table
+        for ( int r = 0, nr = table()->numRows(); r < nr; ++r ) {
+          if ( table()->text(r, COL_SHAPEID) == "1" ) {
+            if ( so->_is_nil() ) {
+              table()->setText( r, COL_SHAPE, so->GetName() );
+              table()->setText( r, COL_PUBLISHED, so->GetID() );
+            }
+            break;
+          }
+        }
+        if ( curSub == 1 ) continue;
+      }
+      QString name = GEOMBase::GetDefaultName( shapeTypeName( shape, "ERROR_SHAPE" ));
+      SALOMEDS::SObject_var so = geomGen->AddInStudy( study, shape, name, myMainShape);
+      if ( !so->_is_nil() ) {
+        table()->setText( *row, COL_SHAPE, so->GetName() );
+        table()->setText( *row, COL_PUBLISHED, so->GetID() );
+      }
+    }
+  }
+  getSMESHGUI()->getApp()->updateObjectBrowser();
+  currentCellChanged(); // to update buttons
+}
+
+//================================================================================
+/*!
+ * \brief SLOT called when a selected cell in table() changed
+ */
+//================================================================================
+
+void SMESHGUI_ComputeOp::currentCellChanged()
+{
+  myTShapeDisplayer->SetVisibility( false );
+
+  bool publishEnable = 0, showEnable = 0, showOnly = 1;
+  list< int > rows;
+  list< int >::iterator row;
+  getSelectedRows( table(), rows );
+  for ( row = rows.begin(); row != rows.end(); ++row )
+  {
+    bool hasData     = ( !table()->text(*row, COL_SHAPE).isEmpty() );
+    bool isPublished = ( !table()->text(*row, COL_PUBLISHED).isEmpty() );
+    if ( hasData && !isPublished )
+      publishEnable = true;
+
+    int curSub = table()->text(*row, COL_SHAPEID).toInt();
+    bool prsReady = myTShapeDisplayer->HasReadyActorsFor( curSub, myMainShape );
+    if ( prsReady ) {
+      myTShapeDisplayer->Show( curSub, myMainShape, showOnly );
+      showOnly = false;
+    }
+    else {
+      showEnable = true;
+    }
+  }
+  myDlg->myPublishBtn->setEnabled( publishEnable );
+  myDlg->myShowBtn->setEnabled( showEnable );
+}
+
+//================================================================================
+/*!
+ * \brief update preview
+ */
+//================================================================================
+
+void SMESHGUI_ComputeOp::onPreviewShape()
+{
+  if ( myTShapeDisplayer )
+  {
+    SUIT_OverrideCursor aWaitCursor;
+    list< int > rows;
+    list< int >::iterator row;
+    getSelectedRows( table(), rows );
+
+    bool showOnly = true;
+    for ( row = rows.begin(); row != rows.end(); ++row )
+    {
+      int curSub = table()->text(*row, COL_SHAPEID).toInt();
+      if ( curSub > 0 ) {
+        myTShapeDisplayer->Show( curSub, myMainShape, showOnly );
+        showOnly = false;
+      }
+    }
+    currentCellChanged(); // to update buttons
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+ */
+//================================================================================
+
+SMESHGUI_ComputeOp::~SMESHGUI_ComputeOp()
+{
+  if ( myTShapeDisplayer ) delete myTShapeDisplayer;
+}
+
+//================================================================================
+/*!
+ * \brief Gets dialog of this operation
+ * \retval LightApp_Dialog* - pointer to dialog of this operation
+ */
+//================================================================================
+
+LightApp_Dialog* SMESHGUI_ComputeOp::dlg() const
+{
+  return myDlg;
+}
+
+//================================================================================
+/*!
+ * \brief perform it's intention action: compute mesh
+ */
+//================================================================================
+
+bool SMESHGUI_ComputeOp::onApply()
+{
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Return a table
+ */
+//================================================================================
+
+QTable* SMESHGUI_ComputeOp::table()
+{
+  return myDlg->myTable;
+}
diff --git a/src/SMESHGUI/SMESHGUI_ComputeDlg.h b/src/SMESHGUI/SMESHGUI_ComputeDlg.h
new file mode 100644 (file)
index 0000000..bb42524
--- /dev/null
@@ -0,0 +1,145 @@
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : SMESHGUI_ComputeDlg.h
+//  Author : Edward AGAPOV
+//  Module : SMESH
+
+
+#ifndef SMESHGUI_ComputeDlg_H
+#define SMESHGUI_ComputeDlg_H
+
+#include "SMESHGUI_Dialog.h"
+#include "SMESHGUI_SelectionOp.h"
+
+#include "VTKViewer.h"
+
+#include "SALOMEconfig.h"
+#include CORBA_SERVER_HEADER(GEOM_Gen)
+
+#include <qgroupbox.h>
+
+class QFrame;
+class QPushButton;
+class QTable;
+class QLabel;
+class SMESHGUI_ComputeDlg;
+class GEOM_Actor;
+
+namespace SMESH {
+  class TShapeDisplayer;
+}
+
+/*!
+ * \brief Operation to compute a mesh and show computation errors
+ */
+class SMESHGUI_ComputeOp: public SMESHGUI_Operation
+{
+  Q_OBJECT
+
+public:
+  SMESHGUI_ComputeOp();
+  virtual ~SMESHGUI_ComputeOp();
+
+  virtual LightApp_Dialog*       dlg() const;
+
+protected:
+
+  virtual void                   startOperation();
+  virtual void                   stopOperation();
+
+protected slots:
+  virtual bool                   onApply();
+
+private slots:
+
+  void                           onPreviewShape();
+  void                           onPublishShape();
+  void                           currentCellChanged();
+
+private:
+
+  QTable*                        table();
+
+  SMESHGUI_ComputeDlg*      myDlg;
+
+  GEOM::GEOM_Object_var     myMainShape;
+  SMESH::TShapeDisplayer*   myTShapeDisplayer;
+};
+
+/*!
+ * \brief Box showing mesh info
+ */
+
+class SMESHGUI_MeshInfosBox : public QGroupBox
+{
+  Q_OBJECT
+public:
+
+  SMESHGUI_MeshInfosBox(const bool full, QWidget* theParent);
+  void SetInfoByMesh(SMESH::SMESH_Mesh_var mesh);
+
+private:
+
+  bool    myFull;
+  QLabel* myNbNode;
+  QLabel* myNbEdge,  *myNbLinEdge,  *myNbQuadEdge;
+  QLabel* myNbTrai,  *myNbLinTrai,  *myNbQuadTrai;
+  QLabel* myNbQuad,  *myNbLinQuad,  *myNbQuadQuad;
+  QLabel* myNbFace,  *myNbLinFace,  *myNbQuadFace;
+  QLabel* myNbPolyg;
+  QLabel* myNbHexa,  *myNbLinHexa,  *myNbQuadHexa;
+  QLabel* myNbTetra, *myNbLinTetra, *myNbQuadTetra;
+  QLabel* myNbPyra,  *myNbLinPyra,  *myNbQuadPyra;
+  QLabel* myNbPrism, *myNbLinPrism, *myNbQuadPrism;
+  QLabel* myNbVolum, *myNbLinVolum, *myNbQuadVolum;
+  QLabel* myNbPolyh;
+};
+
+/*!
+ * \brief Dialog to compute a mesh and show computation errors
+ */
+
+class SMESHGUI_ComputeDlg : public SMESHGUI_Dialog
+{
+  Q_OBJECT
+
+public:
+                               SMESHGUI_ComputeDlg();
+
+private:
+
+  QFrame*                      createMainFrame   (QWidget*);
+
+  QLabel*                      myMeshName;
+  QGroupBox*                   myErrorGroup;
+  QTable*                      myTable;
+  QPushButton*                 myShowBtn;
+  QPushButton*                 myPublishBtn;
+
+  SMESHGUI_MeshInfosBox*       myBriefInfo;
+  SMESHGUI_MeshInfosBox*       myFullInfo;
+
+  friend class SMESHGUI_ComputeOp;
+
+};
+
+#endif
index cabea5343dad03489ef4182795dc23453e602912..92853de163be7b821527699f701950165c1e4f5a 100644 (file)
@@ -42,6 +42,8 @@
 
 #include "LightApp_UpdateFlags.h"
        
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
 //================================================================================
 /*!
  * \brief Constructor
index c4600fcc4ad0fe169140e8cfaa849d35c6b4d52b..5f3e42bebdcf928259d93f70d824639ab2b2cfc5 100644 (file)
@@ -84,6 +84,7 @@
 // IDL Headers
 #include "SALOMEconfig.h"
 #include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
 
 using namespace std;
 
index 6736a589047c3828d81d51da5aef5b2780d7758e..8c2c87db65a3ff73027025603f93901e6fe042f2 100644 (file)
@@ -111,7 +111,7 @@ int SMESHGUI_Dialog::prefix( const QString& name )
 // name    : resourceMgr
 // Purpose : Gets resource manager
 //=======================================================================
-SUIT_ResourceMgr* resourceMgr()
+SUIT_ResourceMgr* SMESHGUI_Dialog::resourceMgr()
 {
   return SUIT_Session::session()->resourceMgr();
 }
index d19484cf54ce567e210d11cb6bc86a1f764be95d..1fa802bc1a3ccbbfa1ad2e2491a180e4f5995033 100644 (file)
 #include "SMESHGUI.h"
 #include "SMESHGUI_Utils.h"
 #include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_SpinBox.h"
 
+#include "SMESH_Actor.h"
 #include "SMESH_TypeFilter.hxx"
+#include "SMESH_LogicalFilter.hxx"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMDS_Mesh.hxx"
 
-#include "SUIT_Desktop.h"
+#include "GEOMBase.h"
+
+#include "SUIT_ResourceMgr.h"
 #include "SUIT_Session.h"
 #include "SUIT_MessageBox.h"
 
 #include "LightApp_Application.h"
 
+#include "SVTK_ViewModel.h"
+#include "SVTK_ViewWindow.h"
+#include "SVTK_Selector.h"
+#include "SVTK_Selection.h"
 #include "SALOME_ListIO.hxx"
 
 #include "utilities.h"
 
+// OCCT Includes
+#include <gp_XYZ.hxx>
+#include <TColStd_MapOfInteger.hxx>
+#include <TColStd_MapIteratorOfMapOfInteger.hxx>
+
+//IDL Headers
+#include CORBA_SERVER_HEADER(SMESH_Group)
+
+// VTK Includes
+#include <vtkUnstructuredGrid.h>
+#include <vtkRenderer.h>
+#include <vtkActor2D.h>
+#include <vtkPoints.h>
+#include <vtkDataSetMapper.h>
+#include <vtkMaskPoints.h>
+#include <vtkSelectVisiblePoints.h>
+#include <vtkLabeledDataMapper.h>
+#include <vtkTextProperty.h>
+#include <vtkIntArray.h>
+#include <vtkPolyData.h>
+#include <vtkProperty2D.h>
+#include <vtkPointData.h>
+
 // QT Includes
 #include <qapplication.h>
 #include <qbuttongroup.h>
 #include <qgroupbox.h>
 #include <qlabel.h>
 #include <qlineedit.h>
+#include <qlistbox.h>
+#include <qlistview.h>
 #include <qpushbutton.h>
 #include <qradiobutton.h>
+#include <qcheckbox.h>
 #include <qlayout.h>
 #include <qpixmap.h>
+#include <qheader.h>
+
+using namespace std;
+
+namespace SMESH {
+  class TIdPreview { // to display in the viewer IDs of the selected elements
+    SVTK_ViewWindow* myViewWindow;
+
+    vtkUnstructuredGrid* myIdGrid;
+    SALOME_Actor* myIdActor;
+
+    vtkUnstructuredGrid* myPointsNumDataSet;
+    vtkMaskPoints* myPtsMaskPoints;
+    vtkSelectVisiblePoints* myPtsSelectVisiblePoints;
+    vtkLabeledDataMapper* myPtsLabeledDataMapper;
+    vtkTextProperty* aPtsTextProp;
+    bool myIsPointsLabeled;
+    vtkActor2D* myPointLabels;
+
+    vector<int> myIDs;
+
+  public:
+    TIdPreview(SVTK_ViewWindow* theViewWindow):
+      myViewWindow(theViewWindow)
+    {
+      myIdGrid = vtkUnstructuredGrid::New();
+
+      // Create and display actor
+      vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
+      aMapper->SetInput( myIdGrid );
+
+      myIdActor = SALOME_Actor::New();
+      myIdActor->SetInfinitive(true);
+      myIdActor->VisibilityOff();
+      myIdActor->PickableOff();
+
+      myIdActor->SetMapper( aMapper );
+      aMapper->Delete();
+
+      myViewWindow->AddActor(myIdActor);
+
+      //Definition of points numbering pipeline
+      myPointsNumDataSet = vtkUnstructuredGrid::New();
+
+      myPtsMaskPoints = vtkMaskPoints::New();
+      myPtsMaskPoints->SetInput(myPointsNumDataSet);
+      myPtsMaskPoints->SetOnRatio(1);
+
+      myPtsSelectVisiblePoints = vtkSelectVisiblePoints::New();
+      myPtsSelectVisiblePoints->SetInput(myPtsMaskPoints->GetOutput());
+      myPtsSelectVisiblePoints->SelectInvisibleOff();
+      myPtsSelectVisiblePoints->SetTolerance(0.1);
+    
+      myPtsLabeledDataMapper = vtkLabeledDataMapper::New();
+      myPtsLabeledDataMapper->SetInput(myPtsSelectVisiblePoints->GetOutput());
+      myPtsLabeledDataMapper->SetLabelFormat("%g");
+      myPtsLabeledDataMapper->SetLabelModeToLabelScalars();
+    
+      vtkTextProperty* aPtsTextProp = vtkTextProperty::New();
+      aPtsTextProp->SetFontFamilyToTimes();
+      static int aPointsFontSize = 12;
+      aPtsTextProp->SetFontSize(aPointsFontSize);
+      aPtsTextProp->SetBold(1);
+      aPtsTextProp->SetItalic(0);
+      aPtsTextProp->SetShadow(0);
+      myPtsLabeledDataMapper->SetLabelTextProperty(aPtsTextProp);
+      aPtsTextProp->Delete();
+  
+      myIsPointsLabeled = false;
+
+      myPointLabels = vtkActor2D::New();
+      myPointLabels->SetMapper(myPtsLabeledDataMapper);
+      myPointLabels->GetProperty()->SetColor(1,1,1);
+      myPointLabels->SetVisibility(myIsPointsLabeled);
+
+      AddToRender(myViewWindow->getRenderer());
+    }
+
+    void SetPointsData ( SMDS_Mesh* theMesh, 
+                        TColStd_MapOfInteger & theNodesIdMap )
+    {
+      vtkPoints* aPoints = vtkPoints::New();
+      aPoints->SetNumberOfPoints(theNodesIdMap.Extent());
+      myIDs.clear();
+      
+      TColStd_MapIteratorOfMapOfInteger idIter( theNodesIdMap );
+      for( int i = 0; idIter.More(); idIter.Next(), i++ ) {
+       const SMDS_MeshNode* aNode = theMesh->FindNode(idIter.Key());
+       aPoints->SetPoint( i, aNode->X(), aNode->Y(), aNode->Z() );
+       myIDs.push_back(idIter.Key());
+      }
+
+      myIdGrid->SetPoints(aPoints);
+
+      aPoints->Delete();
+
+      myIdActor->GetMapper()->Update();
+    }
+
+    void SetElemsData( TColStd_MapOfInteger & theElemsIdMap, 
+                      list<gp_XYZ> & aGrCentersXYZ )
+    {
+      vtkPoints* aPoints = vtkPoints::New();
+      aPoints->SetNumberOfPoints(theElemsIdMap.Extent());
+      myIDs.clear();
+      
+      TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap );
+      for( ; idIter.More(); idIter.Next() ) {
+       myIDs.push_back(idIter.Key());
+      }
+
+      gp_XYZ aXYZ;
+      list<gp_XYZ>::iterator coordIt = aGrCentersXYZ.begin();
+      for( int i = 0; coordIt != aGrCentersXYZ.end(); coordIt++, i++ ) {
+       aXYZ = *coordIt;
+       aPoints->SetPoint( i, aXYZ.X(), aXYZ.Y(), aXYZ.Z() );
+      }
+      myIdGrid->SetPoints(aPoints);
+      aPoints->Delete();
+      
+      myIdActor->GetMapper()->Update();
+    }
+
+    void AddToRender(vtkRenderer* theRenderer)
+    {
+      myIdActor->AddToRender(theRenderer);
+
+      myPtsSelectVisiblePoints->SetRenderer(theRenderer);
+      theRenderer->AddActor2D(myPointLabels);
+    }
+
+    void RemoveFromRender(vtkRenderer* theRenderer)
+    {
+      myIdActor->RemoveFromRender(theRenderer);
+
+      myPtsSelectVisiblePoints->SetRenderer(theRenderer);
+      theRenderer->RemoveActor(myPointLabels);
+    }
+
+    void SetPointsLabeled( bool theIsPointsLabeled, bool theIsActorVisible = true )
+    {
+      myIsPointsLabeled = theIsPointsLabeled && myIdGrid->GetNumberOfPoints();
+      
+      if ( myIsPointsLabeled ) {
+       myPointsNumDataSet->ShallowCopy(myIdGrid);
+       vtkDataSet *aDataSet = myPointsNumDataSet;
+       int aNbElem = myIDs.size();
+       vtkIntArray *anArray = vtkIntArray::New();
+       anArray->SetNumberOfValues( aNbElem );
+       for ( int i = 0; i < aNbElem; i++ )
+         anArray->SetValue( i, myIDs[i] );
+       aDataSet->GetPointData()->SetScalars( anArray );
+       anArray->Delete();
+       myPtsMaskPoints->SetInput( aDataSet );
+       myPointLabels->SetVisibility( theIsActorVisible );
+      }
+      else {
+       myPointLabels->SetVisibility( false );
+      }
+    }
+    
+    ~TIdPreview()
+    {
+      RemoveFromRender(myViewWindow->getRenderer());
+
+      myIdGrid->Delete();
+
+      myViewWindow->RemoveActor(myIdActor);
+      myIdActor->Delete();
+
+      //Deleting of points numbering pipeline
+      //---------------------------------------
+      myPointsNumDataSet->Delete();
+      
+      myPtsLabeledDataMapper->RemoveAllInputs();
+      myPtsLabeledDataMapper->Delete();
+
+      myPtsSelectVisiblePoints->UnRegisterAllOutputs();
+      myPtsSelectVisiblePoints->Delete();
+
+      myPtsMaskPoints->UnRegisterAllOutputs();
+      myPtsMaskPoints->Delete();
+
+      myPointLabels->Delete();
+
+//       myTimeStamp->Delete();
+    }
+  };
+}
+
+static const char * IconFirst[] = {
+"18 10 2 1",
+"      g None",
+".     g #000000",
+"         .     .  ",
+"  ..    ..    ..  ",
+"  ..   ...   ...  ",
+"  ..  ....  ....  ",
+"  .. ..... .....  ",
+"  .. ..... .....  ",
+"  ..  ....  ....  ",
+"  ..   ...   ...  ",
+"  ..    ..    ..  ",
+"         .     .  "};
 
 //=================================================================================
 // class    : SMESHGUI_EditMeshDlg()
 // purpose  :
 //=================================================================================
-SMESHGUI_EditMeshDlg::SMESHGUI_EditMeshDlg (SMESHGUI* theModule,
-                                            const char* title, const char* icon,
-                                            int theAction)
+SMESHGUI_EditMeshDlg::SMESHGUI_EditMeshDlg (SMESHGUI* theModule, 
+                                           int theAction)
   : QDialog(SMESH::GetDesktop(theModule), "SMESHGUI_EditMeshDlg", false, WStyle_Customize |
             WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | Qt::WDestructiveClose),
     mySMESHGUI(theModule),
     mySelectionMgr(SMESH::GetSelectionMgr(theModule)),
     myAction(theAction)
 {
-  resize(303, 185);
-  setCaption(tr(title));
+  setCaption(tr("SMESH_MERGE_NODES"));
 
-  SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
-  QPixmap image0 (aResMgr->loadPixmap("SMESH", tr(icon)));
-  QPixmap image1 (aResMgr->loadPixmap("SMESH", tr("ICON_SELECT")));
+  myIdPreview = new SMESH::TIdPreview(SMESH::GetViewWindow( mySMESHGUI ));
+
+  SUIT_ResourceMgr* aResMgr = SMESH::GetResourceMgr( mySMESHGUI );
+  QPixmap IconMergeNodes (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_MERGE_NODES")));
+  QPixmap IconMergeElems (aResMgr->loadPixmap("SMESH", tr("ICON_DLG_MERGE_ELEMENTS")));
+  QPixmap IconSelect     (aResMgr->loadPixmap("SMESH", tr("ICON_SELECT")));
+  QPixmap IconAdd        (aResMgr->loadPixmap("SMESH", tr("ICON_APPEND")));
+  QPixmap IconRemove     (aResMgr->loadPixmap("SMESH", tr("ICON_REMOVE")));
 
   setSizeGripEnabled(TRUE);
   DlgLayout = new QGridLayout (this);
@@ -74,35 +319,29 @@ SMESHGUI_EditMeshDlg::SMESHGUI_EditMeshDlg (SMESHGUI* theModule,
 
   /***************************************************************/
   GroupConstructors = new QButtonGroup (this, "GroupConstructors");
+  GroupConstructors->setTitle(tr("SMESH_MERGE_NODES"));
   GroupConstructors->setExclusive(TRUE);
   GroupConstructors->setColumnLayout(0, Qt::Vertical);
   GroupConstructors->layout()->setSpacing(0);
   GroupConstructors->layout()->setMargin(0);
-  GroupConstructorsLayout = new QGridLayout (GroupConstructors->layout());
+  GroupConstructorsLayout = new QGridLayout(GroupConstructors->layout());
   GroupConstructorsLayout->setAlignment(Qt::AlignTop);
   GroupConstructorsLayout->setSpacing(6);
   GroupConstructorsLayout->setMargin(11);
-  Constructor1 = new QRadioButton (GroupConstructors, "Constructor1");
-  Constructor1->setText(tr(""));
-  Constructor1->setPixmap(image0);
-  Constructor1->setChecked(TRUE);
-  Constructor1->setSizePolicy(QSizePolicy((QSizePolicy::SizeType)1,
-                                          (QSizePolicy::SizeType)0,
-                                          Constructor1->sizePolicy().hasHeightForWidth()));
-  Constructor1->setMinimumSize(QSize(50, 0));
-  GroupConstructorsLayout->addWidget(Constructor1, 0, 0);
-  QSpacerItem* spacer = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
-  GroupConstructorsLayout->addItem(spacer, 0, 1);
+  RadioButton = new QRadioButton(GroupConstructors, "RadioButton");
+  RadioButton->setPixmap(IconMergeNodes);
+  if (myAction == 1) RadioButton->setPixmap(IconMergeElems);
+  RadioButton->setChecked(TRUE);
+  GroupConstructorsLayout->addWidget(RadioButton, 0, 0);
   DlgLayout->addWidget(GroupConstructors, 0, 0);
 
   /***************************************************************/
   GroupButtons = new QGroupBox (this, "GroupButtons");
-  GroupButtons->setGeometry(QRect(10, 10, 281, 48));
   GroupButtons->setTitle(tr("" ));
   GroupButtons->setColumnLayout(0, Qt::Vertical);
   GroupButtons->layout()->setSpacing(0);
   GroupButtons->layout()->setMargin(0);
-  GroupButtonsLayout = new QGridLayout (GroupButtons->layout());
+  GroupButtonsLayout = new QGridLayout(GroupButtons->layout());
   GroupButtonsLayout->setAlignment(Qt::AlignTop);
   GroupButtonsLayout->setSpacing(6);
   GroupButtonsLayout->setMargin(11);
@@ -110,53 +349,138 @@ SMESHGUI_EditMeshDlg::SMESHGUI_EditMeshDlg (SMESHGUI* theModule,
   buttonHelp->setText(tr("SMESH_BUT_HELP" ));
   buttonHelp->setAutoDefault(TRUE);
   GroupButtonsLayout->addWidget(buttonHelp, 0, 4);
-  buttonCancel = new QPushButton (GroupButtons, "buttonCancel");
+  buttonCancel = new QPushButton(GroupButtons, "buttonCancel");
   buttonCancel->setText(tr("SMESH_BUT_CLOSE" ));
   buttonCancel->setAutoDefault(TRUE);
   GroupButtonsLayout->addWidget(buttonCancel, 0, 3);
-  buttonApply = new QPushButton (GroupButtons, "buttonApply");
+  buttonApply = new QPushButton(GroupButtons, "buttonApply");
   buttonApply->setText(tr("SMESH_BUT_APPLY" ));
   buttonApply->setAutoDefault(TRUE);
   GroupButtonsLayout->addWidget(buttonApply, 0, 1);
-  QSpacerItem* spacer_9 = new QSpacerItem (20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
-  GroupButtonsLayout->addItem(spacer_9, 0, 2);
-  buttonOk = new QPushButton (GroupButtons, "buttonOk");
+  QSpacerItem* spacer3 = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
+  GroupButtonsLayout->addItem(spacer3, 0, 2);
+  buttonOk = new QPushButton(GroupButtons, "buttonOk");
   buttonOk->setText(tr("SMESH_BUT_OK" ));
   buttonOk->setAutoDefault(TRUE);
   buttonOk->setDefault(TRUE);
   GroupButtonsLayout->addWidget(buttonOk, 0, 0);
-  DlgLayout->addWidget(GroupButtons, 2, 0);
+  DlgLayout->addWidget(GroupButtons, 4, 0);
 
   /***************************************************************/
-  GroupMesh = new QGroupBox (this, "GroupMesh");
-  GroupMesh->setTitle(tr("SMESH_MESH" ));
-  GroupMesh->setMinimumSize(QSize(0, 0));
-  GroupMesh->setFrameShape(QGroupBox::Box);
-  GroupMesh->setFrameShadow(QGroupBox::Sunken);
+
+  // Controls for mesh defining
+  GroupMesh = new QGroupBox(this, "GroupMesh");
+  GroupMesh->setTitle(tr("SMESH_SELECT_WHOLE_MESH"));
   GroupMesh->setColumnLayout(0, Qt::Vertical);
   GroupMesh->layout()->setSpacing(0);
   GroupMesh->layout()->setMargin(0);
-  GroupMeshLayout = new QGridLayout (GroupMesh->layout());
+  GroupMeshLayout = new QGridLayout(GroupMesh->layout());
   GroupMeshLayout->setAlignment(Qt::AlignTop);
   GroupMeshLayout->setSpacing(6);
   GroupMeshLayout->setMargin(11);
-  TextLabelMesh = new QLabel (GroupMesh, "TextLabelMesh");
-  TextLabelMesh->setText(tr("SMESH_MESH"));
-  TextLabelMesh->setMinimumSize(QSize(50, 0));
-  TextLabelMesh->setFrameShape(QLabel::NoFrame);
-  TextLabelMesh->setFrameShadow(QLabel::Plain);
-  GroupMeshLayout->addWidget(TextLabelMesh, 0, 0);
-  SelectButton = new QPushButton (GroupMesh, "SelectButton");
-  SelectButton->setText(tr(""));
-  SelectButton->setPixmap(image1);
-  SelectButton->setToggleButton(FALSE);
-  GroupMeshLayout->addWidget(SelectButton, 0, 1);
-  LineEditMesh = new QLineEdit (GroupMesh, "LineEditMesh");
+
+  TextLabelName = new QLabel(GroupMesh, "TextLabelName");
+  TextLabelName->setText(tr("SMESH_NAME"));
+  GroupMeshLayout->addWidget(TextLabelName, 0, 0);
+
+  SelectMeshButton = new QPushButton(GroupMesh, "SelectMeshButton");
+  SelectMeshButton->setPixmap(IconSelect);
+  GroupMeshLayout->addWidget(SelectMeshButton, 0, 1);
+
+  LineEditMesh = new QLineEdit(GroupMesh, "LineEditMesh");
   LineEditMesh->setReadOnly(true);
   GroupMeshLayout->addWidget(LineEditMesh, 0, 2);
+
   DlgLayout->addWidget(GroupMesh, 1, 0);
 
-  myHelpFileName = "merge_elements.htm";
+  /***************************************************************/
+
+  // Controls for coincident elements detecting
+  GroupCoincident = new QGroupBox(this, "GroupCoincident");
+  GroupCoincident->setTitle(tr("COINCIDENT_NODES"));
+  GroupCoincident->setColumnLayout(0, Qt::Vertical);
+  GroupCoincident->layout()->setSpacing(0);
+  GroupCoincident->layout()->setMargin(0);
+  GroupCoincidentLayout = new QGridLayout(GroupCoincident->layout());
+  GroupCoincidentLayout->setAlignment(Qt::AlignTop);
+  GroupCoincidentLayout->setSpacing(6);
+  GroupCoincidentLayout->setMargin(11);
+  
+  if (myAction == 0) { // case merge nodes
+    TextLabelTolerance = new QLabel(GroupCoincident, "TextLabelTolerance");
+    TextLabelTolerance->setText(tr("SMESH_TOLERANCE"));
+    TextLabelTolerance->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred));
+    GroupCoincidentLayout->addWidget(TextLabelTolerance, 0, 0);
+
+    SpinBoxTolerance = new SMESHGUI_SpinBox(GroupCoincident, "SpinBoxTolerance");
+    GroupCoincidentLayout->addWidget(SpinBoxTolerance, 0, 1);
+  }
+
+  DetectButton = new QPushButton(GroupCoincident, "DetectButton");
+  DetectButton->setText(tr("DETECT"));
+  DetectButton->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum));
+  GroupCoincidentLayout->addWidget(DetectButton, 0, 2);
+
+  ListCoincident = new QListBox(GroupCoincident, "ListCoincident");
+  ListCoincident->setSelectionMode(QListBox::Extended);
+  if (myAction == 0) // case merge nodes
+    GroupCoincidentLayout->addMultiCellWidget(ListCoincident, 1, 3, 0, 1);
+  else // case merge elements
+    GroupCoincidentLayout->addMultiCellWidget(ListCoincident, 0, 3, 0, 1);
+
+  QSpacerItem* spacer1 = new QSpacerItem(20, 21, QSizePolicy::Minimum, QSizePolicy::Expanding);
+  GroupCoincidentLayout->addItem(spacer1, 1, 2);
+
+  AddGroupButton = new QPushButton(GroupCoincident, "AddGroupButton");
+  AddGroupButton->setText(tr("SMESH_BUT_ADD"));
+  GroupCoincidentLayout->addWidget(AddGroupButton, 2, 2);
+
+  RemoveGroupButton = new QPushButton(GroupCoincident, "RemoveGroupButton");
+  RemoveGroupButton->setText(tr("SMESH_BUT_REMOVE"));
+  GroupCoincidentLayout->addWidget(RemoveGroupButton, 3, 2);
+
+  SelectAllCB = new QCheckBox(GroupCoincident, "SelectAllCB");
+  SelectAllCB->setText(tr("SELECT_ALL"));
+  GroupCoincidentLayout->addWidget(SelectAllCB, 4, 0);
+
+  DlgLayout->addWidget(GroupCoincident, 2, 0);
+
+  /***************************************************************/
+
+  // Controls for editing the selected group
+  GroupEdit = new QGroupBox(this, "GroupEdit");
+  GroupEdit->setTitle(tr("EDIT_SELECTED_GROUP"));
+  GroupEdit->setColumnLayout(0, Qt::Vertical);
+  GroupEdit->layout()->setSpacing(0);
+  GroupEdit->layout()->setMargin(0);
+  GroupEditLayout = new QGridLayout(GroupEdit->layout());
+  GroupEditLayout->setAlignment(Qt::AlignTop);
+  GroupEditLayout->setSpacing(6);
+  GroupEditLayout->setMargin(11);
+
+  ListEdit = new QListBox(GroupEdit, "ListEdit");
+  ListEdit->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred));
+  ListEdit->setRowMode(QListBox::FixedNumber);
+  ListEdit->setMinimumHeight(ListEdit->sizeHint().height());
+  ListEdit->setHScrollBarMode(QScrollView::AlwaysOn);
+  ListEdit->setVScrollBarMode(QScrollView::AlwaysOff);
+  ListEdit->setSelectionMode(QListBox::Extended);
+  GroupEditLayout->addMultiCellWidget(ListEdit, 0, 1, 0, 0);
+
+  AddElemButton = new QPushButton(GroupEdit, "AddElemButton");
+  AddElemButton->setPixmap(IconAdd);
+  GroupEditLayout->addWidget(AddElemButton, 0, 1);
+
+  RemoveElemButton = new QPushButton(GroupEdit, "RemoveElemButton");
+  RemoveElemButton->setPixmap(IconRemove);
+  GroupEditLayout->addWidget(RemoveElemButton, 0, 2);
+
+  SetFirstButton = new QPushButton(GroupEdit, "SetFirstButton");
+  SetFirstButton->setIconSet(QPixmap(IconFirst));
+  SetFirstButton->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed));
+  GroupEditLayout->addMultiCellWidget(SetFirstButton, 1, 1, 1, 2);
+
+  DlgLayout->addWidget(GroupEdit, 3, 0);
 
   Init(); // Initialisations
 }
@@ -168,6 +492,7 @@ SMESHGUI_EditMeshDlg::SMESHGUI_EditMeshDlg (SMESHGUI* theModule,
 SMESHGUI_EditMeshDlg::~SMESHGUI_EditMeshDlg()
 {
   // no need to delete child widgets, Qt does it all for us
+  delete myIdPreview;
 }
 
 //=================================================================================
@@ -176,57 +501,156 @@ SMESHGUI_EditMeshDlg::~SMESHGUI_EditMeshDlg()
 //=================================================================================
 void SMESHGUI_EditMeshDlg::Init()
 {
-  GroupMesh->show();
-  mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+  if (myAction == 0) {
+    SpinBoxTolerance->RangeStepAndValidator(0.0, COORD_MAX, 0.1, 3);
+    SpinBoxTolerance->SetValue(1e-05);
+  }
+
+  RadioButton->setChecked(TRUE);
+
+  myEditCurrentArgument = (QWidget*)LineEditMesh; 
 
-  myMesh = SMESH::SMESH_Mesh::_nil();
+  myActor = 0;
+  mySubMeshOrGroup = SMESH::SMESH_subMesh::_nil();
 
-  myMeshFilter = new SMESH_TypeFilter (MESH);
+  mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
+
+  mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+  myIsBusy = false;
+  
+  // Costruction of the logical filter
+  SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH);
+  SMESH_TypeFilter* aSmeshGroupFilter    = new SMESH_TypeFilter (GROUP);
+  
+  QPtrList<SUIT_SelectionFilter> aListOfFilters;
+  if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter);
+  if (aSmeshGroupFilter)    aListOfFilters.append(aSmeshGroupFilter);
 
-  // signals and slots connections
-  connect(buttonOk    , SIGNAL(clicked()), this, SLOT(ClickOnOk()));
+  myMeshOrSubMeshOrGroupFilter =
+    new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR);
+  
+  /* signals and slots connections */
+  connect(buttonOk,     SIGNAL(clicked()), this, SLOT(ClickOnOk()));
   connect(buttonCancel, SIGNAL(clicked()), this, SLOT(ClickOnCancel()));
-  connect(buttonApply , SIGNAL(clicked()), this, SLOT(ClickOnApply()));
+  connect(buttonApply SIGNAL(clicked()), this, SLOT(ClickOnApply()));
   connect(buttonHelp,   SIGNAL(clicked()), this, SLOT(ClickOnHelp()));
 
-  connect(SelectButton, SIGNAL(clicked()), this, SLOT(SelectionIntoArgument()));
+  connect(SelectMeshButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument()));
+  connect(DetectButton, SIGNAL (clicked()), this, SLOT(onDetect()));
+  connect(ListCoincident, SIGNAL (selectionChanged()), this, SLOT(onSelectGroup()));
+  connect(AddGroupButton, SIGNAL (clicked()), this, SLOT(onAddGroup()));
+  connect(RemoveGroupButton, SIGNAL (clicked()), this, SLOT(onRemoveGroup()));
+  connect(SelectAllCB, SIGNAL(toggled(bool)), this, SLOT(onSelectAll(bool)));
+  connect(ListEdit, SIGNAL (selectionChanged()), this, SLOT(onSelectElementFromGroup()));
+  connect(AddElemButton, SIGNAL (clicked()), this, SLOT(onAddElement()));
+  connect(RemoveElemButton, SIGNAL (clicked()), this, SLOT(onRemoveElement()));
+  connect(SetFirstButton, SIGNAL( clicked() ), this, SLOT( onSetFirst() ) );
 
+  connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
   connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+  /* to close dialog if study change */
+  connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel()));
 
-  connect(mySMESHGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
-  connect(mySMESHGUI, SIGNAL(SignalCloseAllDialogs())       , this, SLOT(ClickOnCancel()));
+  this->show(); /* displays Dialog */
+  
+  SetFirstButton->setEnabled(false);
+  buttonOk->setEnabled(false);
+  buttonApply->setEnabled(false);
 
-  this->show(); // displays Dialog
+  // Init Mesh field from selection
+  SelectionIntoArgument();
 
-  LineEditMesh->setFocus();
-  mySelectionMgr->clearFilters();
-  mySelectionMgr->installFilter(myMeshFilter);
+  // dialog customization
+  if (myAction == 1) {
+    setCaption(tr("SMESH_MERGE_ELEMENTS"));
+    GroupConstructors->setTitle(tr("SMESH_MERGE_ELEMENTS"));
+    GroupCoincident->setTitle(tr("COINCIDENT_ELEMENTS"));
+  }
+    
+  myHelpFileName = "merge_elements.htm";
+}
 
-  SelectionIntoArgument();
+//=================================================================================
+// function : FindGravityCenter()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::FindGravityCenter(TColStd_MapOfInteger & theElemsIdMap, 
+                                            list< gp_XYZ > & theGrCentersXYZ)
+{
+  if (!myActor)
+    return;
+
+  SMDS_Mesh* aMesh = 0;
+  aMesh = myActor->GetObject()->GetMesh();
+  if (!aMesh)
+    return;
+
+  int nbNodes;
+
+  TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap );
+  for( ; idIter.More(); idIter.Next() ) {
+    const SMDS_MeshElement* anElem = aMesh->FindElement(idIter.Key());
+    if ( !anElem )
+      continue;
+
+    gp_XYZ anXYZ(0., 0., 0.);
+    SMDS_ElemIteratorPtr nodeIt = anElem->nodesIterator();
+    for ( nbNodes = 0; nodeIt->more(); nbNodes++ ) {
+      const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+      anXYZ.Add( gp_XYZ( node->X(), node->Y(), node->Z() ) );
+    }
+    anXYZ.Divide( nbNodes );
+    
+    theGrCentersXYZ.push_back( anXYZ );
+  }
 }
 
 //=================================================================================
 // function : ClickOnApply()
 // purpose  :
 //=================================================================================
-void SMESHGUI_EditMeshDlg::ClickOnApply()
+bool SMESHGUI_EditMeshDlg::ClickOnApply()
 {
-  if (!myMesh->_is_nil()) {
-    try        {
-      QApplication::setOverrideCursor(Qt::waitCursor);
+  if (mySMESHGUI->isActiveStudyLocked() || myMesh->_is_nil())
+    return false;
 
-      if (myAction == 1) {
-        SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
-        aMeshEditor->MergeEqualElements();
-      }
+  try {
+    SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
+
+    QApplication::setOverrideCursor(Qt::waitCursor);
+
+    SMESH::long_array_var anIds = new SMESH::long_array;
+    SMESH::array_of_long_array_var aGroupsOfElements = new SMESH::array_of_long_array;
 
-      QApplication::restoreOverrideCursor();
-    } catch(...) {
+    aGroupsOfElements->length(ListCoincident->count());
+    QListBoxItem* item = ListCoincident->firstItem();
+
+    int anArrayNum = 0;
+    while (item) {
+      QStringList aListIds = QStringList("");
+      aListIds = QStringList::split(" ", item->text(), false);
+
+      anIds->length(aListIds.count());
+      for (int i = 0; i < aListIds.count(); i++)
+        anIds[i] = aListIds[i].toInt();
+
+      aGroupsOfElements[anArrayNum++] = anIds.inout();
+      item = item->next();
     }
 
-    //mySelectionMgr->clearSelected();
-    SMESH::UpdateView();
+    if( myAction == 0 )
+      aMeshEditor->MergeNodes (aGroupsOfElements.inout());
+    else
+      aMeshEditor->MergeElements (aGroupsOfElements.inout());
+
+    QApplication::restoreOverrideCursor();
+  } catch(...) {
   }
+  
+  SMESH::UpdateView();
+
+  onDetect();
+  return true;
 }
 
 //=================================================================================
@@ -235,8 +659,8 @@ void SMESHGUI_EditMeshDlg::ClickOnApply()
 //=================================================================================
 void SMESHGUI_EditMeshDlg::ClickOnOk()
 {
-  ClickOnApply();
-  ClickOnCancel();
+  if (ClickOnApply())
+    ClickOnCancel();
 }
 
 //=================================================================================
@@ -245,8 +669,12 @@ void SMESHGUI_EditMeshDlg::ClickOnOk()
 //=================================================================================
 void SMESHGUI_EditMeshDlg::ClickOnCancel()
 {
-  //mySelectionMgr->clearSelected();
+  myIdPreview->SetPointsLabeled(false);
   mySelectionMgr->clearFilters();
+  //mySelectionMgr->clearSelected();
+  SMESH::SetPointRepresentation(false);
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+    aViewWindow->SetSelectionMode(ActorSelection);
   disconnect(mySelectionMgr, 0, this, 0);
   mySMESHGUI->ResetState();
   reject();
@@ -276,36 +704,396 @@ void SMESHGUI_EditMeshDlg::ClickOnHelp()
 }
 
 //=================================================================================
-// function : SelectionIntoArgument()
-// purpose  : Called when selection as changed or other case
+// function : onEditGroup()
+// purpose  :
 //=================================================================================
-void SMESHGUI_EditMeshDlg::SelectionIntoArgument()
+void SMESHGUI_EditMeshDlg::onEditGroup()
+{
+  int nbSel = 0;
+  for (int i = 0; i < ListCoincident->count(); i++) {
+    if (ListCoincident->isSelected(i))
+      nbSel++;
+    if (nbSel > 1) {
+      ListEdit->clear();
+      return;
+    }
+  }
+  if (nbSel == 0) {
+    ListEdit->clear();
+    return;
+  }
+
+  QString aNewIds = "";
+
+  QListBoxItem* anItem;
+  for (anItem = ListEdit->firstItem(); anItem != 0; anItem = anItem->next())
+    aNewIds+=QString(" %1").arg(anItem->text());
+
+  ListCoincident->changeItem(aNewIds, ListCoincident->currentItem());
+  ListCoincident->setSelected(ListCoincident->currentItem(), true);
+  
+}
+
+//=================================================================================
+// function : updateControls()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::updateControls()
 {
-  if (!GroupButtons->isEnabled()) // inactive
+  if (ListEdit->count() == 0)
+    SetFirstButton->setEnabled(false);
+  bool enable = !(myMesh->_is_nil()) && ListCoincident->count();
+  buttonOk->setEnabled(enable);
+  buttonApply->setEnabled(enable);
+}
+
+//=================================================================================
+// function : onDetect()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onDetect()
+{
+  if ( myMesh->_is_nil() || LineEditMesh->text().isEmpty() )
     return;
 
-  QString aString = "";
+  try {
+    SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
+
+    QApplication::setOverrideCursor(Qt::waitCursor);
+    ListCoincident->clear();
+    ListEdit->clear();
+
+    SMESH::array_of_long_array_var aGroupsArray;
+
+    switch (myAction) {
+    case 0 :
+      if(!mySubMeshOrGroup->_is_nil())
+       aMeshEditor->FindCoincidentNodesOnPart(mySubMeshOrGroup, SpinBoxTolerance->GetValue(), aGroupsArray);
+      else
+       aMeshEditor->FindCoincidentNodes(SpinBoxTolerance->GetValue(), aGroupsArray);
+      break;
+    case 1 :
+      if(!mySubMeshOrGroup->_is_nil())
+       aMeshEditor->FindEqualElements(mySubMeshOrGroup, aGroupsArray);
+      else
+       aMeshEditor->FindEqualElements(myMesh, aGroupsArray);
+      break;
+    }
+    
+    QListBoxItem* anItem = 0;
+    for (int i = 0; i < aGroupsArray->length(); i++) {
+      SMESH::long_array& aGroup = aGroupsArray[i];
+
+      QString anIDs;
+      for (int j = 0; j < aGroup.length(); j++)
+        anIDs+=QString(" %1").arg(aGroup[j]);
+
+      anItem = new QListBoxText(anIDs);
+      ListCoincident->insertItem(anItem);
+    }
+    QApplication::restoreOverrideCursor();
+  } catch(...) {
+  }
+
+  ListCoincident->selectAll(true);
+  updateControls();
+}
+
+//=================================================================================
+// function : onSelectGroup()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onSelectGroup()
+{
+  if (myIsBusy || !myActor)
+    return;
+  myEditCurrentArgument = (QWidget*)ListCoincident;
 
+  ListEdit->clear();
+  
+  TColStd_MapOfInteger anIndices;
+  QListBoxItem* anItem;
+  int NbOfSelected = 0;
+  for (anItem = ListCoincident->firstItem(); anItem != 0; anItem = anItem->next()) {
+    if (anItem->isSelected()) {
+      QStringList aListIds = QStringList("");
+      aListIds = QStringList::split(" ", anItem->text(), false);
+      for (int i = 0; i < aListIds.count(); i++)
+       anIndices.Add(aListIds[i].toInt());
+      NbOfSelected++;
+      ListEdit->clear();
+      if (NbOfSelected == 1) {
+       ListEdit->insertStringList(aListIds);
+       ListEdit->selectAll(true);
+      }
+    }
+  }
+  mySelector->AddOrRemoveIndex(myActor->getIO(), anIndices, false);
   SALOME_ListIO aList;
-  mySelectionMgr->selectedObjects(aList);
-  int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
-
-  // mesh
-  if (nbSel != 1) {
-    myMesh = SMESH::SMESH_Mesh::_nil();
-    aString = "";
-  } else {
-    Handle(SALOME_InteractiveObject) IO = aList.First();
-    myMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO);
-    if (myMesh->_is_nil())
-      aString = "";
+  aList.Append(myActor->getIO());
+  mySelectionMgr->setSelectedObjects(aList,false);
+  
+  if (myAction == 0) {
+    myIdPreview->SetPointsData(myActor->GetObject()->GetMesh(), anIndices);
+    myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
+  }
+  else {
+    list< gp_XYZ > aGrCentersXYZ;
+    FindGravityCenter(anIndices, aGrCentersXYZ);
+    myIdPreview->SetElemsData( anIndices, aGrCentersXYZ);
+    myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
+  }
+
+  updateControls();
+}
+
+//=================================================================================
+// function : onSelectAll()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onSelectAll (bool isToggled)
+{
+  ListCoincident->selectAll(isToggled);
+}
+
+//=================================================================================
+// function : onSelectElementFromGroup()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onSelectElementFromGroup()
+{
+  if (myIsBusy || !myActor)
+    return;
+
+  int nbSel = 0;
+  TColStd_MapOfInteger anIndices;
+  QListBoxItem* anItem;
+  for (anItem = ListEdit->firstItem(); anItem != 0; anItem = anItem->next()) {
+    if (anItem->isSelected()) {
+      int anId = anItem->text().toInt();
+      anIndices.Add(anId);
+      nbSel++;
+      if (nbSel == 1)
+       SetFirstButton->setEnabled(true);
+    }
+  }
+  if (nbSel == 0 || nbSel > 1)
+    SetFirstButton->setEnabled(false);
+
+  mySelector->AddOrRemoveIndex(myActor->getIO(), anIndices, false);
+  SALOME_ListIO aList;
+  aList.Append(myActor->getIO());
+  mySelectionMgr->setSelectedObjects(aList);
+
+  if (myAction == 0) {
+    myIdPreview->SetPointsData(myActor->GetObject()->GetMesh(), anIndices);
+    myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
+  }
+  else {
+    list< gp_XYZ > aGrCentersXYZ;
+    FindGravityCenter(anIndices, aGrCentersXYZ);
+    myIdPreview->SetElemsData(anIndices, aGrCentersXYZ);
+    myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility());
+  }
+}
+
+//=================================================================================
+// function : onAddGroup()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onAddGroup()
+{
+  if ( myMesh->_is_nil() || LineEditMesh->text().isEmpty() )
+    return;
+
+  QString anIDs = "";
+  SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), anIDs);
+  
+  ListCoincident->clearSelection();
+  QListBoxItem* anItem = new QListBoxText(anIDs);
+  ListCoincident->insertItem(anItem);
+  int nbGroups = ListCoincident->count();
+  if (nbGroups) {
+    ListCoincident->setCurrentItem(nbGroups-1);
+    ListCoincident->setSelected(nbGroups-1, true);
+  }
+  else {
+    ListCoincident->setCurrentItem(0);
+    ListCoincident->setSelected(0, true);
+  }
+
+  updateControls();
+}
+
+//=================================================================================
+// function : onRemoveGroup()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onRemoveGroup()
+{
+  if (myEditCurrentArgument != (QWidget*)ListCoincident)
+    return;
+  myIsBusy = true;
+
+  for (int i = ListCoincident->count(); i > 0; i--)
+    if (ListCoincident->isSelected(i-1))
+      ListCoincident->removeItem(i-1);
+
+  ListEdit->clear();
+  updateControls();
+
+  myIsBusy = false;
+}
+
+//=================================================================================
+// function : onAddElement()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onAddElement()
+{
+  if (!myActor)
+    return;
+  myIsBusy = true;
+
+  QString aListStr = "";
+  int aNbNnodes = 0;
+
+  aNbNnodes = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aListStr);
+  if (aNbNnodes < 1)
+    return;
+
+  QStringList aNodes = QStringList::split(" ", aListStr);
+  QListBoxItem* anItem = 0;
+
+  for (QStringList::iterator it = aNodes.begin(); it != aNodes.end(); ++it) {
+    anItem = ListEdit->findItem(*it, Qt::ExactMatch);
+    if (!anItem) {
+      anItem = new QListBoxText(*it);
+      ListEdit->insertItem(anItem);
+    }
+    ListEdit->setSelected(anItem, true);
+  }
+
+  myIsBusy = false;
+  onEditGroup();
+}
+
+//=================================================================================
+// function : onRemoveElement()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onRemoveElement()
+{
+  if (myEditCurrentArgument != (QWidget*)ListCoincident)
+    return;
+  myIsBusy = true;
+
+  for (int i = ListEdit->count(); i > 0; i--)
+    if (ListEdit->isSelected(i-1))
+      ListEdit->removeItem(i-1);
+
+  myIsBusy = false;
+  onEditGroup();
+}
+
+//=================================================================================
+// function : onSetFirst()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::onSetFirst()
+{
+  if (myEditCurrentArgument != (QWidget*)ListCoincident)
+    return;
+  myIsBusy = true;
+  
+  QListBoxItem* anItem;
+  for (anItem = ListEdit->firstItem(); anItem != 0; anItem = anItem->next()) {
+    if (anItem->isSelected()) {
+      ListEdit->takeItem(anItem);
+      ListEdit->insertItem(anItem, 0);
+    }
+  }
+
+  myIsBusy = false;
+  onEditGroup();
+}
+
+//=================================================================================
+// function : SetEditCurrentArgument()
+// purpose  :
+//=================================================================================
+void SMESHGUI_EditMeshDlg::SetEditCurrentArgument()
+{
+  QPushButton* send = (QPushButton*)sender();
+
+  disconnect(mySelectionMgr, 0, this, 0);
+  mySelectionMgr->clearSelected();
+  mySelectionMgr->clearFilters();
+
+  if (send == SelectMeshButton) {
+    myEditCurrentArgument = (QWidget*)LineEditMesh;
+    SMESH::SetPointRepresentation(false);
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->SetSelectionMode(ActorSelection);
+    mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
   }
 
-  LineEditMesh->setText(aString);
+  myEditCurrentArgument->setFocus();
+  connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
+  SelectionIntoArgument();
+}
 
-  bool isEnabled = (!myMesh->_is_nil());
-  buttonOk->setEnabled(isEnabled);
-  buttonApply->setEnabled(isEnabled);
+//=================================================================================
+// function : SelectionIntoArgument()
+// purpose  : Called when selection as changed or other case
+//=================================================================================
+void SMESHGUI_EditMeshDlg::SelectionIntoArgument()
+{
+  if (myEditCurrentArgument == (QWidget*)LineEditMesh) {
+    QString aString = "";
+    LineEditMesh->setText(aString);
+    
+    ListCoincident->clear();
+    ListEdit->clear();
+    myActor = 0;
+    
+    int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
+    if (nbSel != 1)
+      return;
+
+    SALOME_ListIO aList;
+    mySelectionMgr->selectedObjects(aList, SVTK_Viewer::Type());
+    
+    Handle(SALOME_InteractiveObject) IO = aList.First();
+    myMesh = SMESH::GetMeshByIO(IO);
+    
+    if (myMesh->_is_nil())
+      return;
+    
+    myActor = SMESH::FindActorByEntry(IO->getEntry());
+    if (!myActor)
+      myActor = SMESH::FindActorByObject(myMesh);
+    if(!myActor)
+      return;
+    
+    mySubMeshOrGroup = SMESH::SMESH_IDSource::_nil();
+    
+    if ((!SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(IO)->_is_nil() || //SUBMESH OR GROUP
+         !SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(IO)->_is_nil()) &&
+        !SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO)->_is_nil())
+      mySubMeshOrGroup = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO);
+     
+    LineEditMesh->setText(aString);
+
+    if (myAction == 0) {
+      SMESH::SetPointRepresentation(true);
+      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+       aViewWindow->SetSelectionMode(NodeSelection);
+    }
+    else
+      if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+       aViewWindow->SetSelectionMode(CellSelection);
+  }
 }
 
 //=================================================================================
@@ -317,6 +1105,8 @@ void SMESHGUI_EditMeshDlg::DeactivateActiveDialog()
   if (GroupConstructors->isEnabled()) {
     GroupConstructors->setEnabled(false);
     GroupMesh->setEnabled(false);
+    GroupCoincident->setEnabled(false);
+    GroupEdit->setEnabled(false);
     GroupButtons->setEnabled(false);
     mySMESHGUI->ResetState();
     mySMESHGUI->SetActiveDialogBox(0);
@@ -333,6 +1123,8 @@ void SMESHGUI_EditMeshDlg::ActivateThisDialog()
   mySMESHGUI->EmitSignalDeactivateDialog();
   GroupConstructors->setEnabled(true);
   GroupMesh->setEnabled(true);
+  GroupCoincident->setEnabled(true);
+  GroupEdit->setEnabled(true);
   GroupButtons->setEnabled(true);
 
   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
@@ -343,18 +1135,17 @@ void SMESHGUI_EditMeshDlg::ActivateThisDialog()
 // function : enterEvent()
 // purpose  :
 //=================================================================================
-void SMESHGUI_EditMeshDlg::enterEvent(QEvent* e)
+void SMESHGUI_EditMeshDlg::enterEvent(QEvent*)
 {
-  if (GroupConstructors->isEnabled())
-    return;
-  ActivateThisDialog();
+  if (!GroupConstructors->isEnabled())
+    ActivateThisDialog();
 }
 
 //=================================================================================
 // function : closeEvent()
 // purpose  :
 //=================================================================================
-void SMESHGUI_EditMeshDlg::closeEvent(QCloseEvent* e)
+void SMESHGUI_EditMeshDlg::closeEvent(QCloseEvent*)
 {
   /* same than click on cancel button */
   this->ClickOnCancel();
@@ -364,18 +1155,17 @@ void SMESHGUI_EditMeshDlg::closeEvent(QCloseEvent* e)
 //function : hideEvent
 //purpose  : caused by ESC key
 //=======================================================================
-void SMESHGUI_EditMeshDlg::hideEvent (QHideEvent * e)
+void SMESHGUI_EditMeshDlg::hideEvent (QHideEvent *)
 {
   if (!isMinimized())
     ClickOnCancel();
 }
 
-
 //=================================================================================
 // function : keyPressEvent()
 // purpose  :
 //=================================================================================
-void SMESHGUI_EditMeshDlg::keyPressEvent( QKeyEvent* e )
+void SMESHGUI_EditMeshDlg::keyPressEvent( QKeyEvent* e)
 {
   QDialog::keyPressEvent( e );
   if ( e->isAccepted() )
index 71a11b74342c28a6e46259c0bbd938e9879ec64b..f511b049f6d864f089242d888f816f3f7ec6d7e5 100644 (file)
@@ -18,8 +18,8 @@
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
-#ifndef DIALOGBOX_GETMESH_H
-#define DIALOGBOX_GETMESH_H
+#ifndef SMESHGUI_EditMeshDlg_H
+#define SMESHGUI_EditMeshDlg_H
 
 #include "SMESH_SMESHGUI.hxx"
 
@@ -30,6 +30,7 @@
 #include <qdialog.h>
 
 // Open CASCADE Includes
+#include <gp_XYZ.hxx>
 
 class QGridLayout;
 class QButtonGroup;
@@ -38,11 +39,22 @@ class QLabel;
 class QLineEdit;
 class QPushButton;
 class QRadioButton;
+class QCheckBox;
+class QListBox;
 class SMESHGUI;
+class SMESHGUI_SpinBox;
+class SMESH_Actor;
+class SALOME_Actor;
+class SVTK_ViewWindow;
+class SVTK_Selector;
+
+namespace SMESH{
+  struct TIdPreview;
+}
 
 // IDL Headers
 #include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
 
 //=================================================================================
 // class    : SMESHGUI_EditMeshDlg
@@ -54,8 +66,6 @@ class SMESHGUI_EXPORT SMESHGUI_EditMeshDlg : public QDialog
 
  public:
   SMESHGUI_EditMeshDlg (SMESHGUI  * theModule,
-                       const char* title,
-                       const char* icon,
                        int         theAction);
   ~SMESHGUI_EditMeshDlg();
 
@@ -65,47 +75,89 @@ class SMESHGUI_EXPORT SMESHGUI_EditMeshDlg : public QDialog
   void enterEvent (QEvent*);              /* mouse enter the QWidget */
   void hideEvent  (QHideEvent*);          /* ESC key */
   void keyPressEvent(QKeyEvent*);
+  void onEditGroup();
+
+  void FindGravityCenter(TColStd_MapOfInteger & ElemsIdMap, 
+                        list< gp_XYZ > & GrCentersXYZ);
+  // add the centers of gravity of ElemsIdMap elements to the GrCentersXYZ list
 
  private:
   SMESHGUI*               mySMESHGUI;     /* Current SMESHGUI object */
   LightApp_SelectionMgr*  mySelectionMgr; /* User shape selection */
+  SVTK_Selector*          mySelector;
+  
+  QWidget*                myEditCurrentArgument;
 
-  SMESH::SMESH_Mesh_var   myMesh;
-  SUIT_SelectionFilter*   myMeshFilter;
+  SMESH::SMESH_Mesh_var     myMesh;
+  SMESH::SMESH_IDSource_var mySubMeshOrGroup;
+  SMESH_Actor*              myActor;
+  SUIT_SelectionFilter*     myMeshOrSubMeshOrGroupFilter;
+
+  SMESH::TIdPreview*        myIdPreview;
 
   int myAction;
+  bool myIsBusy;
 
   // Widgets
-  QButtonGroup* GroupConstructors;
-  QRadioButton* Constructor1;
-
-  QGroupBox* GroupButtons;
-  QPushButton* buttonOk;
-  QPushButton* buttonCancel;
-  QPushButton* buttonApply;
-  QPushButton* buttonHelp;
-
-  QGroupBox* GroupMesh;
-  QLabel* TextLabelMesh;
-  QPushButton* SelectButton;
-  QLineEdit* LineEditMesh;
-
+  QButtonGroup*     GroupConstructors;
+  QRadioButton*     RadioButton;
+
+  QGroupBox*        GroupButtons;
+  QPushButton*      buttonOk;
+  QPushButton*      buttonCancel;
+  QPushButton*      buttonApply;
+  QPushButton*      buttonHelp;
+
+  QGroupBox*        GroupMesh;
+  QLabel*           TextLabelName;
+  QPushButton*      SelectMeshButton;
+  QLineEdit*        LineEditMesh;
+
+  QGroupBox*        GroupCoincident;
+  QLabel*           TextLabelTolerance;
+  SMESHGUI_SpinBox* SpinBoxTolerance;
+  QPushButton*      DetectButton;
+  QListBox*         ListCoincident;
+  QPushButton*      AddGroupButton;
+  QPushButton*      RemoveGroupButton;
+  QCheckBox*        SelectAllCB;
+
+  QGroupBox*        GroupEdit;
+  QListBox*         ListEdit;
+  QPushButton*      AddElemButton;
+  QPushButton*      RemoveElemButton;
+  QPushButton*      SetFirstButton;
+    
   //protected:
   QGridLayout* DlgLayout;
   QGridLayout* GroupConstructorsLayout;
   QGridLayout* GroupButtonsLayout;
   QGridLayout* GroupMeshLayout;
+  QGridLayout* GroupCoincidentLayout;
+  QGridLayout* GroupEditLayout;
 
   QString myHelpFileName;
 
  private slots:
   void ClickOnOk();
   void ClickOnCancel();
-  void ClickOnApply();
+  bool ClickOnApply();
   void ClickOnHelp();
-  void SelectionIntoArgument();
-  void DeactivateActiveDialog();
-  void ActivateThisDialog();
+  void updateControls();
+  void onDetect();
+  void onAddGroup();
+  void onRemoveGroup();
+  void onSelectGroup();
+  void onSelectAll(bool isToggled);
+  void onSelectElementFromGroup();
+  void onAddElement();
+  void onRemoveElement();
+  void onSetFirst();
+  void SetEditCurrentArgument();
+  void SelectionIntoArgument() ;
+  void DeactivateActiveDialog() ;
+  void ActivateThisDialog() ;
+
 };
 
-#endif // DIALOGBOX_GETMESH_H
+#endif // SMESHGUI_EditMeshDlg_H
index 2ee720b872b1acd6b6ab5c6e8b150427c5e0fa01..da79f4aca580cfa286658768c00db9f18d15419c 100644 (file)
@@ -88,6 +88,7 @@
 // IDL Headers
 #include "SALOMEconfig.h"
 #include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
 
 using namespace std;
 
@@ -219,10 +220,13 @@ SMESHGUI_ExtrusionAlongPathDlg::SMESHGUI_ExtrusionAlongPathDlg( SMESHGUI* theMod
   SelectBasePointButton->setPixmap(selectImage);
 
   XLab  = new QLabel(tr("SMESH_X"), BasePointGrp);
+  XLab->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   XSpin = new SMESHGUI_SpinBox(BasePointGrp);
   YLab  = new QLabel(tr("SMESH_Y"), BasePointGrp);
+  YLab->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   YSpin = new SMESHGUI_SpinBox(BasePointGrp);
   ZLab  = new QLabel(tr("SMESH_Z"), BasePointGrp);
+  ZLab->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   ZSpin = new SMESHGUI_SpinBox(BasePointGrp);
 
   // layouting
@@ -839,7 +843,7 @@ void SMESHGUI_ExtrusionAlongPathDlg::SelectionIntoArgument()
       // try to get selected elements IDs
       QString aString;
       //int aNbUnits = SMESH::GetNameOfSelectedElements(mySelectionMgr, aString);
-      SMESH::GetNameOfSelectedElements(mySelector, myMeshActor->getIO(), aString);
+      SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
       ElementsLineEdit->setText(aString);
     }
   } else if (myEditCurrentArgument == PathMeshLineEdit) {
index d29f6f7f7a58fa73cdb8fd8a6d911590fb27a899..6f0ca271b868d866239b7e6f54339abfbf0cd537 100644 (file)
@@ -125,6 +125,7 @@ private:
   QLabel*           StartPointLab;
   QToolButton*      SelectStartPointButton;
   QLineEdit*        StartPointLineEdit;
+  QCheckBox*        LinearAnglesCheck;
   QCheckBox*        AnglesCheck;
   QGroupBox*        AnglesGrp;
   QListBox*         AnglesList;
index 5bf8c555822fcaf62072c39b0ac2394342084221..aa7779d0f248a43b9b1f90b22ae2111eb3a7f640 100644 (file)
@@ -79,6 +79,7 @@
 // IDL Headers
 #include "SALOMEconfig.h"
 #include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
 
 using namespace std;
 
@@ -624,7 +625,7 @@ void SMESHGUI_ExtrusionDlg::SelectionIntoArgument()
         aNbElements = anElementsIds->length();
       }
     } else {
-      aNbElements = SMESH::GetNameOfSelectedElements(mySelector, myActor->getIO(), aString);
+      aNbElements = SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
       myElementsId = aString;
     }
 
index 9fdc3f71996e087995d068a33c65490e6d332f07..2b75ac0c4025963d4d22d59957684bd1c5d35c79 100755 (executable)
@@ -676,6 +676,7 @@ bool SMESHGUI_FilterTable::IsValid (const bool theMess, const int theEntityType)
          aCriterion == FT_BelongToGeom ||
          aCriterion == FT_BelongToPlane ||
          aCriterion == FT_BelongToCylinder ||
+         aCriterion == FT_BelongToGenSurface ||
          aCriterion == FT_LyingOnGeom) {
       if (aTable->text(i, 2).isEmpty()) {
         if (theMess)
@@ -786,6 +787,7 @@ void SMESHGUI_FilterTable::GetCriterion (const int                 theRow,
        aCriterionType != FT_BelongToGeom &&
        aCriterionType != FT_BelongToPlane &&
        aCriterionType != FT_BelongToCylinder &&
+       aCriterionType != FT_BelongToGenSurface &&
        aCriterionType != FT_LyingOnGeom)
   {
     theCriterion.Compare = ((ComboItem*)aTable->item(theRow, 1))->GetValue();
@@ -836,6 +838,7 @@ void SMESHGUI_FilterTable::SetCriterion (const int                       theRow,
       theCriterion.Type != FT_BelongToGeom &&
       theCriterion.Type != FT_BelongToPlane &&
       theCriterion.Type != FT_BelongToCylinder &&
+      theCriterion.Type != FT_BelongToGenSurface &&
       theCriterion.Type != FT_LyingOnGeom &&
       theCriterion.Type != FT_FreeBorders &&
       theCriterion.Type != FT_FreeEdges &&
@@ -850,7 +853,8 @@ void SMESHGUI_FilterTable::SetCriterion (const int                       theRow,
 
   if (theCriterion.Compare == FT_EqualTo ||
        theCriterion.Type    == FT_BelongToPlane ||
-       theCriterion.Type    == FT_BelongToCylinder)
+       theCriterion.Type    == FT_BelongToCylinder ||
+       theCriterion.Type    == FT_BelongToGenSurface)
   {
     QTableItem* anItem = aTable->item(theRow, 0);
     if (!myAddWidgets.contains(anItem))
@@ -1081,6 +1085,7 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con
            aCriterionType == SMESH::FT_BelongToGeom ||
            aCriterionType == SMESH::FT_BelongToPlane ||
            aCriterionType == SMESH::FT_BelongToCylinder ||
+           aCriterionType == SMESH::FT_BelongToGenSurface ||
            aCriterionType == SMESH::FT_LyingOnGeom)
   {
     QMap<int, QString> aMap;
@@ -1275,6 +1280,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
       aCriteria[ SMESH::FT_BelongToGeom     ] = tr("BELONG_TO_GEOM");
       aCriteria[ SMESH::FT_BelongToPlane    ] = tr("BELONG_TO_PLANE");
       aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER");
+      aCriteria[ SMESH::FT_BelongToGenSurface]= tr("BELONG_TO_GENSURFACE");
       aCriteria[ SMESH::FT_LyingOnGeom      ] = tr("LYING_ON_GEOM");
     }
     return aCriteria;
@@ -1291,6 +1297,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
       aCriteria[ SMESH::FT_BelongToGeom     ] = tr("BELONG_TO_GEOM");
       aCriteria[ SMESH::FT_BelongToPlane    ] = tr("BELONG_TO_PLANE");
       aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER");
+      aCriteria[ SMESH::FT_BelongToGenSurface]= tr("BELONG_TO_GENSURFACE");
       aCriteria[ SMESH::FT_LyingOnGeom      ] = tr("LYING_ON_GEOM");
     }
     return aCriteria;
@@ -1311,6 +1318,7 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
       aCriteria[ SMESH::FT_BelongToGeom     ] = tr("BELONG_TO_GEOM");
       aCriteria[ SMESH::FT_BelongToPlane    ] = tr("BELONG_TO_PLANE");
       aCriteria[ SMESH::FT_BelongToCylinder ] = tr("BELONG_TO_CYLINDER");
+      aCriteria[ SMESH::FT_BelongToGenSurface]= tr("BELONG_TO_GENSURFACE");
       aCriteria[ SMESH::FT_LyingOnGeom      ] = tr("LYING_ON_GEOM");
       aCriteria[ SMESH::FT_Length2D         ] = tr("LENGTH2D");
       aCriteria[ SMESH::FT_MultiConnection2D] = tr("MULTI2D_BORDERS");
@@ -2112,6 +2120,7 @@ bool SMESHGUI_FilterDlg::isValid() const
     if (aType == FT_BelongToGeom ||
         aType == FT_BelongToPlane ||
         aType == FT_BelongToCylinder ||
+        aType == FT_BelongToGenSurface ||
         aType == FT_LyingOnGeom) {
       QString aName;
       myTable->GetThreshold(i, aName);
@@ -2124,7 +2133,9 @@ bool SMESHGUI_FilterDlg::isValid() const
         return false;
       }
 
-      if (aType == FT_BelongToCylinder || aType == FT_BelongToPlane) {
+      if (aType == FT_BelongToCylinder ||
+          aType == FT_BelongToPlane    ||
+          aType == FT_BelongToGenSurface ) {
         CORBA::Object_var anObject = SMESH::SObjectToObject(aList[ 0 ]);
         //GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(aList[ 0 ]->GetObject());
         GEOM::GEOM_Object_var aGeomObj = GEOM::GEOM_Object::_narrow(anObject);
@@ -2520,6 +2531,7 @@ void SMESHGUI_FilterDlg::onSelectionDone()
       myTable->GetCriterionType(aRow) != FT_BelongToGeom &&
       myTable->GetCriterionType(aRow) != FT_BelongToPlane &&
       myTable->GetCriterionType(aRow) != FT_BelongToCylinder &&
+      myTable->GetCriterionType(aRow) != FT_BelongToGenSurface &&
       myTable->GetCriterionType(aRow) != FT_LyingOnGeom)
     return;
 
@@ -2575,9 +2587,11 @@ void SMESHGUI_FilterDlg::updateSelection()
       (myTable->GetCriterionType(aRow) == FT_BelongToGeom ||
        myTable->GetCriterionType(aRow) == FT_BelongToPlane ||
        myTable->GetCriterionType(aRow) == FT_BelongToCylinder ||
+       myTable->GetCriterionType(aRow) == FT_BelongToGenSurface ||
        myTable->GetCriterionType(aRow) == FT_LyingOnGeom)) {
 
     if (myTable->GetCriterionType(aRow) == FT_BelongToGeom ||
+        myTable->GetCriterionType(aRow) == FT_BelongToGenSurface ||
         myTable->GetCriterionType(aRow) == FT_LyingOnGeom) {
 
       mySelectionMgr->installFilter(new GEOM_SelectionFilter( aStudy, true ));
index 52049930119cde5a5b2d086c20359b389a25c746..2537452c659e9214694ab256cd31c9c8e78a553b 100644 (file)
@@ -92,4 +92,18 @@ namespace SMESH {
     }
     return GEOM::GEOM_Object::_nil();
   }
+
+  GEOM::GEOM_Object_ptr GetSubShape (GEOM::GEOM_Object_ptr theMainShape,
+                                     long                  theID)
+  {
+    GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
+    _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
+    if (!aStudy || geomGen->_is_nil())
+      return GEOM::GEOM_Object::_nil();
+    GEOM::GEOM_IShapesOperations_var aShapesOp = geomGen->GetIShapesOperations(aStudy->StudyId());
+    if (aShapesOp->_is_nil())
+      return GEOM::GEOM_Object::_nil();
+    GEOM::GEOM_Object_var subShape = aShapesOp->GetSubShape (theMainShape,theID);
+    return subShape._retn();
+  }
 }
index 9e0762d13356c2f4f8ce82e313d3fc7223a002f2..32a7526ead6d42d571aa66551e7ac115994102c8 100644 (file)
@@ -36,6 +36,9 @@ namespace SMESH
   SMESHGUI_EXPORT GEOM::GEOM_Object_var GetShapeOnMeshOrSubMesh (_PTR(SObject) theSObject);
 
   SMESHGUI_EXPORT GEOM::GEOM_Object_ptr GetGeom (_PTR(SObject) theSO);
+
+  SMESHGUI_EXPORT GEOM::GEOM_Object_ptr GetSubShape (GEOM::GEOM_Object_ptr theMainShape,
+                                     long                  theID);
 }
 
 #endif
index c43cf1335367f078edb1c8a330a28aabda39e851..8968d907c014f6b78973747d980b7e6f0b09b180 100644 (file)
@@ -553,15 +553,18 @@ void SMESHGUI_GroupDlg::init (SMESH::SMESH_GroupBase_ptr theGroup)
 //=================================================================================
 void SMESHGUI_GroupDlg::updateButtons()
 {
-  bool enable;
+  bool enable = !myName->text().stripWhiteSpace().isEmpty();
 
-  if (myGrpTypeId == 0)
-    enable = !myName->text().stripWhiteSpace().isEmpty() && myElements->count() > 0;
-  else if (myGrpTypeId == 1)
-    {
-      bool isEditMode = !CORBA::is_nil( myGroupOnGeom );
-      enable = !myName->text().stripWhiteSpace().isEmpty() && (myGeomObjects->length() > 0 || isEditMode);
+  if (myGrpTypeId == 0) {
+    enable = enable && myElements->count() > 0;
+    enable = enable && (!myGroup->_is_nil() || !myMesh->_is_nil());
+  }
+  else if (myGrpTypeId == 1) {
+    if (CORBA::is_nil(myGroupOnGeom)) { // creation mode
+      enable = enable && myGeomObjects->length() > 0 && !myMesh->_is_nil();
     }
+  }
+
   QPushButton* aBtn;
   aBtn = (QPushButton*) child("ok", "QPushButton");
   if (aBtn) aBtn->setEnabled(enable);
@@ -678,18 +681,27 @@ bool SMESHGUI_GroupDlg::onApply()
   if (mySMESHGUI->isActiveStudyLocked())
     return false;
 
-  if (myGrpTypeId == 0 &&
-      !myName->text().stripWhiteSpace().isEmpty() &&
-      myElements->count() > 0) {
+  if (myName->text().stripWhiteSpace().isEmpty())
+    return false;
+
+  if (myGrpTypeId == 0) { // on mesh elements
+    if (!myElements->count())
+      return false;
+
     mySelectionMgr->clearSelected();
-    if (myGroup->_is_nil()) {
+
+    if (myGroup->_is_nil()) { // creation
+      if (myMesh->_is_nil())
+        return false;
+
       SMESH::ElementType aType = SMESH::ALL;
-      switch(myTypeId) {
+      switch (myTypeId) {
       case 0: aType = SMESH::NODE; break;
       case 1: aType = SMESH::EDGE; break;
       case 2: aType = SMESH::FACE; break;
       case 3: aType = SMESH::VOLUME; break;
       }
+
       SMESH::long_array_var anIdList = new SMESH::long_array;
       int i, k = myElements->count();
       anIdList->length(k);
@@ -700,23 +712,22 @@ bool SMESHGUI_GroupDlg::onApply()
 
       myGroup = SMESH::AddGroup(myMesh, aType, myName->text());
       myGroup->Add(anIdList.inout());
-      
+
       int aColorNumber = myColorSpinBox->value();
       myGroup->SetColorNumber(aColorNumber);
-      
+
       _PTR(SObject) aMeshGroupSO = SMESH::FindSObject(myGroup);
 
       SMESH::setFileName ( aMeshGroupSO, QString::number(myColorSpinBox->value()) );
-      
-      SMESH::setFileType ( aMeshGroupSO,"COULEURGROUP" );
-      
+      SMESH::setFileType ( aMeshGroupSO, "COULEURGROUP" );
+
       /* init for next operation */
       myName->setText("");
       myColorSpinBox->setValue(0);
       myElements->clear();
       myGroup = SMESH::SMESH_Group::_nil();
 
-    } else {
+    } else { // edition
       myGroup->SetName(myName->text());
         
       int aColorNumber = myColorSpinBox->value();
@@ -759,11 +770,12 @@ bool SMESHGUI_GroupDlg::onApply()
     SMESH::UpdateView(); // asv: fix of BUG PAL5515
     mySelectionMgr->clearSelected();
     return true;
-  } else if (myGrpTypeId == 1 &&
-             !myName->text().stripWhiteSpace().isEmpty() &&
-             (myGeomObjects->length() > 0 || !CORBA::is_nil(myGroupOnGeom)))
-  {
-    if (myGroupOnGeom->_is_nil()) {
+  }
+  else if (myGrpTypeId == 1) { // on geom object
+    if (CORBA::is_nil(myGroupOnGeom)) { // creation
+      if (myMesh->_is_nil() || !myGeomObjects->length())
+        return false;
+
       SMESH::ElementType aType = SMESH::ALL;
       switch (myTypeId) {
       case 0: aType = SMESH::NODE; break;
@@ -771,88 +783,85 @@ bool SMESHGUI_GroupDlg::onApply()
       case 2: aType = SMESH::FACE; break;
       case 3: aType = SMESH::VOLUME; break;
       }
-      
+
       _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
       GEOM::GEOM_IGroupOperations_var aGroupOp =
        SMESH::GetGEOMGen()->GetIGroupOperations(aStudy->StudyId());
-      
-      if (myGeomObjects->length() == 1)
+
+      if (myGeomObjects->length() == 1) {
        myGroupOnGeom = myMesh->CreateGroupFromGEOM(aType, myName->text(),myGeomObjects[0]);
-      else
-       {
-         SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen();
-         if ( aSMESHGen->_is_nil() )
-           return false;
+      }
+      else {
+        SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen();
+        if ( aSMESHGen->_is_nil() )
+          return false;
+
+        // create a geometry group
+        GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
+        _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
+
+        if (geomGen->_is_nil() || !aStudy)
+          return false;
+
+        GEOM::GEOM_IGroupOperations_var op =
+          geomGen->GetIGroupOperations(aStudy->StudyId());
+        if (op->_is_nil())
+          return false;
+
+        // check and add all selected GEOM objects: they must be
+        // a sub-shapes of the main GEOM and must be of one type
+        TopAbs_ShapeEnum aGroupType = TopAbs_SHAPE;
+        for ( int i =0; i < myGeomObjects->length(); i++) {
+          TopAbs_ShapeEnum aSubShapeType = (TopAbs_ShapeEnum)myGeomObjects[i]->GetShapeType();
+          if (i == 0)
+            aGroupType = aSubShapeType;
+          else if (aSubShapeType != aGroupType) {
+            aGroupType = TopAbs_SHAPE;
+            break;
+          }
+        }
 
-         // create a geometry group
-         GEOM::GEOM_Gen_var geomGen = SMESH::GetGEOMGen();
-         _PTR(Study) aStudy = SMESH::GetActiveStudyDocument();
+        GEOM::GEOM_Object_var aMeshShape = myMesh->GetShapeToMesh();
+        GEOM::GEOM_Object_var aGroupVar = op->CreateGroup(aMeshShape, aGroupType);
+        op->UnionList(aGroupVar, myGeomObjects);
+
+        if (op->IsDone()) {
+          // publish the GEOM group in study
+          QString aNewGeomGroupName ("Auto_group_for_");
+          aNewGeomGroupName += myName->text();
+          SALOMEDS::SObject_var aNewGroupSO =
+            geomGen->AddInStudy(aSMESHGen->GetCurrentStudy(), aGroupVar, aNewGeomGroupName, aMeshShape);
+        }
+
+        myGroupOnGeom = myMesh->CreateGroupFromGEOM(aType, myName->text(), aGroupVar);
+      }
 
-         if (geomGen->_is_nil() || !aStudy)
-           return false;
-
-         GEOM::GEOM_IGroupOperations_var op =
-           geomGen->GetIGroupOperations(aStudy->StudyId());
-         if (op->_is_nil())
-           return false;
-           
-         // check and add all selected GEOM objects: they must be
-         // a sub-shapes of the main GEOM and must be of one type
-         TopAbs_ShapeEnum aGroupType = TopAbs_SHAPE;
-         for ( int i =0; i < myGeomObjects->length(); i++)
-           {
-             TopAbs_ShapeEnum aSubShapeType = (TopAbs_ShapeEnum)myGeomObjects[i]->GetShapeType();
-             if (i == 0)
-               aGroupType = aSubShapeType;
-             else if (aSubShapeType != aGroupType)
-               {
-                 aGroupType = TopAbs_SHAPE;
-                 break;
-               }
-           }
-           
-         GEOM::GEOM_Object_var aMeshShape = myMesh->GetShapeToMesh();
-         GEOM::GEOM_Object_var aGroupVar = op->CreateGroup(aMeshShape, aGroupType);
-         op->UnionList(aGroupVar, myGeomObjects);
-
-         if (op->IsDone()) {
-           // publish the GEOM group in study
-           QString aNewGeomGroupName ("Auto_group_for_");
-           aNewGeomGroupName += myName->text();
-           SALOMEDS::SObject_var aNewGroupSO =
-             geomGen->AddInStudy(aSMESHGen->GetCurrentStudy(), aGroupVar, aNewGeomGroupName, aMeshShape);
-         }
-         
-         myGroupOnGeom = myMesh->CreateGroupFromGEOM(aType, myName->text(), aGroupVar);
-               }
-      
       int aColorNumber = myColorSpinBox->value();
       myGroupOnGeom->SetColorNumber(aColorNumber);
-      
+
       _PTR(SObject) aMeshGroupSO = SMESH::FindSObject(myGroupOnGeom);
-      
+
       SMESH::setFileName ( aMeshGroupSO, QString::number(myColorSpinBox->value()) );
-      
+
       SMESH::setFileType ( aMeshGroupSO,"COULEURGROUP" );
-      
+
       /* init for next operation */
       myName->setText("");
       myColorSpinBox->setValue(0);
       myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil();
     }
-    else
-      {
-       myGroupOnGeom->SetName(myName->text());
-        
-       int aColorNumber = myColorSpinBox->value();
-       myGroupOnGeom->SetColorNumber(aColorNumber);
-      }
-    
+    else { // edition
+      myGroupOnGeom->SetName(myName->text());
+
+      int aColorNumber = myColorSpinBox->value();
+      myGroupOnGeom->SetColorNumber(aColorNumber);
+    }
+
     mySMESHGUI->updateObjBrowser(true);
     mySelectionMgr->clearSelected();
     return true;
   }
-  
+
   return false;
 }
 
@@ -924,6 +933,9 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged()
       myGeomGroupBtn->setEnabled(false);
       myGeomGroupLine->setEnabled(false);
       myGeomGroupLine->setText("");
+      myGeomObjects = new GEOM::ListOfGO();
+      myGeomObjects->length(0);
+
       if (myGeomGroupBtn->isOn())
        myGeomGroupBtn->setOn(false);
       if (!myCreate)
@@ -936,6 +948,7 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged()
        myGroupOnGeom = SMESH::SMESH_GroupOnGeom::_nil(); 
         myMesh = SMESH::SMESH_Mesh::_nil();
        updateGeomPopup();
+        updateButtons();
         myIsBusy = false;
         return;
       }
@@ -946,6 +959,7 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged()
        updateGeomPopup();
         if (myMesh->_is_nil())
        {
+          updateButtons();
          myIsBusy = false;
          return;
        }
@@ -1001,19 +1015,20 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged()
       return;
 
     } else if (myCurrentLineEdit == myGeomGroupLine) {
-      
+
       myGeomObjects = new GEOM::ListOfGO();
-      
+
       // The mesh SObject
       _PTR(SObject) aMeshSO = SMESH::FindSObject(myMesh);
-      
+
       if (aNbSel == 0 || !aMeshSO)
        {
          myGeomObjects->length(0);
+          updateButtons();
          myIsBusy = false;
          return;
        }
-      
+
       myGeomObjects->length(aNbSel);
 
       GEOM::GEOM_Object_var aGeomGroup;
index c58be37f57b8ed4eb0bc1df6acbd8b2158df64b7..e94a8a99394c281a4a9b1af76c3039f9d1ede6fc 100644 (file)
@@ -119,7 +119,7 @@ void SMESHGUI_GenericHypothesisCreator::edit( SMESH::SMESH_Hypothesis_ptr h, QWi
       if( !aSubMesh->_is_nil() )
        aMesh = aSubMesh->GetFather();
       _PTR(SObject) meshSO = SMESH::FindSObject( aMesh );
-      SMESH::ModifiedMesh( meshSO, false);
+      SMESH::ModifiedMesh( meshSO, false, aMesh->NbNodes()==0);
     }
   SMESHGUI::GetSMESHGUI()->updateObjBrowser( true, 0 );
 }
index ebb1ca33341cb34caad8ffcff5f6acd561930ffd..114b8dbc3c274ed9a550d96443f255fc38391fd0 100644 (file)
@@ -433,7 +433,7 @@ namespace SMESH{
        if (res < SMESH::HYP_UNKNOWN_FATAL) {
          _PTR(SObject) aSH = SMESH::FindSObject(aHyp);
          if (SM && aSH) {
-           SMESH::ModifiedMesh(SM, false);
+           SMESH::ModifiedMesh(SM, false, aMesh->NbNodes()==0);
          }
        }
        if (res > SMESH::HYP_OK) {
@@ -468,7 +468,7 @@ namespace SMESH{
          if (res < SMESH::HYP_UNKNOWN_FATAL)  {
             _PTR(SObject) meshSO = SMESH::FindSObject(aMesh);
             if (meshSO)
-              SMESH::ModifiedMesh(meshSO, false);
+              SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0);
          }
          if (res > SMESH::HYP_OK) {
            wc.suspend();
@@ -554,7 +554,7 @@ namespace SMESH{
            if (res < SMESH::HYP_UNKNOWN_FATAL) {
               _PTR(SObject) meshSO = SMESH::FindSObject(aMesh);
               if (meshSO)
-                SMESH::ModifiedMesh(meshSO, false);
+                SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0);
             }
            if (res > SMESH::HYP_OK) {
              wc.suspend();
@@ -606,25 +606,28 @@ namespace SMESH{
     return listSOmesh;
   }
 
-#define CASE2MESSAGE(enum) case SMESH::enum: msg = QObject::tr( #enum ); break;
+#define CASE2MESSAGE(enum) case SMESH::enum: msg = QObject::tr( "STATE_" #enum ); break;
   QString GetMessageOnAlgoStateErrors(const algo_error_array& errors)
   {
     QString resMsg = QObject::tr("SMESH_WRN_MISSING_PARAMETERS") + ":\n";
     for ( int i = 0; i < errors.length(); ++i ) {
       const SMESH::AlgoStateError & error = errors[ i ];
+      const bool hasAlgo = ( strlen( error.algoName ) != 0 );
       QString msg;
-      switch( error.name ) {
-        CASE2MESSAGE( MISSING_ALGO );
-        CASE2MESSAGE( MISSING_HYPO );
-        CASE2MESSAGE( NOT_CONFORM_MESH );
-        CASE2MESSAGE( BAD_PARAM_VALUE );
-      default: continue;
-      }
+      if ( !hasAlgo )
+        msg = QObject::tr( "STATE_ALGO_MISSING" );
+      else 
+        switch( error.state ) {
+          CASE2MESSAGE( HYP_MISSING );
+          CASE2MESSAGE( HYP_NOTCONFORM );
+          CASE2MESSAGE( HYP_BAD_PARAMETER );
+        default: continue;
+        }
       // apply args to message:
       // %1 - algo name
-      if ( error.algoName.in() != 0 )
+      if ( hasAlgo )
         msg = msg.arg( error.algoName.in() );
-      // %2 - dimention
+      // %2 - dimension
       msg = msg.arg( error.algoDim );
       // %3 - global/local
       msg = msg.arg( QObject::tr( error.isGlobalAlgo ? "GLOBAL_ALGO" : "LOCAL_ALGO" ));
diff --git a/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx b/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx
new file mode 100644 (file)
index 0000000..b21ad32
--- /dev/null
@@ -0,0 +1,630 @@
+//  SMESH SMESHGUI : GUI for SMESH component
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : SMESHGUI_MakeNodeAtPointDlg.cxx
+//  Author : Edward AGAPOV
+//  Module : SMESH
+
+#include "SMESHGUI_MakeNodeAtPointDlg.h"
+
+#include "SMESHGUI.h"
+#include "SMESHGUI_GEOMGenUtils.h"
+#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_SpinBox.h"
+#include "SMESHGUI_MeshEditPreview.h"
+
+#include "SMDS_Mesh.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMESH_Actor.h"
+#include "SMESH_ActorUtils.h"
+#include "SMESH_NumberFilter.hxx"
+#include "SMESH_LogicalFilter.hxx"
+
+#include "GEOMBase.h"
+#include "GeometryGUI.h"
+
+#include "LightApp_DataOwner.h"
+#include "LightApp_SelectionMgr.h"
+#include "SALOMEDSClient_SObject.hxx"
+#include "SALOME_ListIO.hxx"
+#include "SUIT_Desktop.h"
+#include "SVTK_Selector.h"
+#include "SVTK_ViewWindow.h"
+#include "SVTK_ViewModel.h"
+#include "SalomeApp_Tools.h"
+#include "SalomeApp_TypeFilter.h"
+#include "SUIT_ResourceMgr.h"
+#include "SUIT_OverrideCursor.h"
+#include "SUIT_MessageBox.h"
+
+// OCCT Includes
+#include <TColStd_MapOfInteger.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <BRep_Tool.hxx>
+
+// QT Includes
+#include <qframe.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qlabel.h>
+#include <qradiobutton.h>
+#include <qbuttongroup.h>
+#include <qapplication.h>
+#include <qstringlist.h>
+#include <qcheckbox.h>
+#include <qmessagebox.h>
+
+#include <vtkProperty.h>
+
+// IDL Headers
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
+#define SPACING 5
+#define MARGIN  10
+
+/*!
+ * \brief Dialog to publish a sub-shape of the mesh main shape
+ *        by selecting mesh elements
+ */
+SMESHGUI_MakeNodeAtPointDlg::SMESHGUI_MakeNodeAtPointDlg()
+  : SMESHGUI_Dialog( 0, false, true )
+{
+  setCaption(tr("CAPTION"));
+
+  QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame(), MARGIN, SPACING);
+
+  QFrame* aMainFrame = createMainFrame  (mainFrame());
+
+  aDlgLay->addWidget(aMainFrame);
+
+  aDlgLay->setStretchFactor(aMainFrame, 1);
+}
+
+//=======================================================================
+// function : createMainFrame()
+// purpose  : Create frame containing dialog's input fields
+//=======================================================================
+QFrame* SMESHGUI_MakeNodeAtPointDlg::createMainFrame (QWidget* theParent)
+{
+  QFrame* aFrame = new QFrame(theParent);
+
+  SUIT_ResourceMgr* rm = SMESH::GetResourceMgr( SMESHGUI::GetSMESHGUI() );
+  QPixmap iconMoveNode (rm->loadPixmap("SMESH", tr("ICON_DLG_MOVE_NODE")));
+  QPixmap iconSelect   (rm->loadPixmap("SMESH", tr("ICON_SELECT")));
+
+  // constructor
+
+  QButtonGroup* aPixGrp = new QButtonGroup(1, Qt::Vertical, tr("MESH_PASS_THROUGH_POINT"), aFrame);
+  aPixGrp->setExclusive(TRUE);
+  QRadioButton* aRBut = new QRadioButton(aPixGrp);
+  aRBut->setPixmap(iconMoveNode);
+  aRBut->setChecked(TRUE);
+
+  // coordinates
+
+  QGroupBox* aCoordGrp = new QGroupBox(1, Qt::Vertical, tr("SMESH_COORDINATES"), aFrame);
+  myCoordBtn = new QPushButton(aCoordGrp);
+  myCoordBtn->setPixmap(iconSelect);
+  myCoordBtn->setToggleButton(TRUE);
+
+  QLabel* aXLabel = new QLabel(tr("SMESH_X"), aCoordGrp);
+  aXLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
+  myX = new SMESHGUI_SpinBox(aCoordGrp);
+
+  QLabel* aYLabel = new QLabel(tr("SMESH_Y"), aCoordGrp);
+  aYLabel->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
+  myY = new SMESHGUI_SpinBox(aCoordGrp);
+
+  QLabel* aZLabel = new QLabel(tr("SMESH_Z"), aCoordGrp);
+  aZLabel->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
+  myZ = new SMESHGUI_SpinBox(aCoordGrp);
+
+  myX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
+  myY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
+  myZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, 3);
+
+  // Method selection
+
+  QButtonGroup* aMethodGrp = new QButtonGroup(1, Qt::Vertical, tr("METHOD"), aFrame);
+  aMethodGrp->setExclusive(TRUE);
+  myMoveRBtn = new QRadioButton(tr("MOVE_EXISTING_METHOD"), aMethodGrp);
+  myCreateRBtn = new QRadioButton(tr("CREATE_NEW_METHOD"), aMethodGrp);
+
+  // node ID
+
+  myNodeToMoveGrp = new QGroupBox(tr("NODE_2MOVE"), aFrame, "anIdGrp");
+
+  QLabel* idLabel = new QLabel(tr("NODE_2MOVE_ID"), myNodeToMoveGrp, "idLabel");
+  myIdBtn = new QPushButton(myNodeToMoveGrp);
+  myIdBtn->setPixmap(iconSelect);
+  myIdBtn->setToggleButton(TRUE);
+  myId = new QLineEdit(myNodeToMoveGrp,"myId");
+  myId->setValidator(new SMESHGUI_IdValidator(this, "validator", 1));
+  myAutoSearchChkBox = new QCheckBox( tr("AUTO_SEARCH"), myNodeToMoveGrp, "myAutoSearchChkBox");
+  myPreviewChkBox = new QCheckBox( tr("PREVIEW"), myNodeToMoveGrp, "myPreviewChkBox");
+
+  myNodeToMoveGrp->setColumnLayout(0, Qt::Vertical);
+  myNodeToMoveGrp->layout()->setSpacing(0);
+  myNodeToMoveGrp->layout()->setMargin(0);
+  QGridLayout* myNodeToMoveGrpLayout = new QGridLayout(myNodeToMoveGrp->layout());
+  myNodeToMoveGrpLayout->setAlignment(Qt::AlignTop);
+  myNodeToMoveGrpLayout->setSpacing(SPACING);
+  myNodeToMoveGrpLayout->setMargin(MARGIN);
+  myNodeToMoveGrpLayout->addWidget( idLabel, 0, 0 );
+  myNodeToMoveGrpLayout->addWidget( myIdBtn, 0, 1 );
+  myNodeToMoveGrpLayout->addWidget( myId,    0, 2 );
+  myNodeToMoveGrpLayout->addMultiCellWidget( myAutoSearchChkBox, 1, 1, 0, 2 );
+  myNodeToMoveGrpLayout->addMultiCellWidget( myPreviewChkBox,    2, 2, 0, 2 );
+
+  QVBoxLayout* aLay = new QVBoxLayout(aFrame);
+  aLay->addWidget(aPixGrp);
+  aLay->addWidget(aCoordGrp);
+  aLay->addWidget(aMethodGrp);
+  aLay->addWidget(myNodeToMoveGrp);
+
+  connect(myCoordBtn,         SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool)));
+  connect(myMoveRBtn,         SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool)));
+  connect(myCreateRBtn,       SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool)));
+  connect(myIdBtn,            SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool)));
+  connect(myAutoSearchChkBox, SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool)));
+
+  myMoveRBtn->setChecked(TRUE);
+  myIdBtn->setOn(TRUE);
+  myAutoSearchChkBox->setChecked(TRUE);
+
+  return aFrame;
+}
+
+//================================================================================
+/*!
+ * \brief SLOT called when any button is toggled
+  * \param bool - on or off
+ */
+//================================================================================
+
+void SMESHGUI_MakeNodeAtPointDlg::ButtonToggled (bool on)
+{
+  const QObject* aSender = sender();
+  if ( on ) {
+    if ( aSender == myCoordBtn ) // button to set coord by node selection
+    {
+      if ( myIdBtn->isEnabled() )
+        myIdBtn->setOn( !on );
+    }
+    else if ( aSender == myIdBtn ) // button to select a node to move
+    {
+      myCoordBtn->setOn( !on );
+    }
+    else if ( aSender == myMoveRBtn ) // move node method
+    {
+      myNodeToMoveGrp->setEnabled( TRUE );
+    }
+    else if ( aSender == myCreateRBtn ) // create node method
+    {
+      myNodeToMoveGrp->setEnabled( FALSE );
+      myCoordBtn->setOn( TRUE ); 
+    }
+  }      
+  if ( aSender == myAutoSearchChkBox ) // automatic node search
+  {
+    if ( on ) {
+      myId->setText("");
+      myId->setReadOnly ( TRUE );
+      myIdBtn->setOn( FALSE );
+      myIdBtn->setEnabled( FALSE );
+      myCoordBtn->setOn( TRUE );
+    }
+    else {
+      myId->setReadOnly ( FALSE );
+      myIdBtn->setEnabled( TRUE );
+    }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Constructor
+*/
+//================================================================================
+
+SMESHGUI_MakeNodeAtPointOp::SMESHGUI_MakeNodeAtPointOp()
+{
+  mySimulation = 0;
+  myDlg = new SMESHGUI_MakeNodeAtPointDlg;
+  myFilter = 0;
+
+  // connect signals and slots
+  connect(myDlg->myX, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
+  connect(myDlg->myY, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
+  connect(myDlg->myZ, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
+  connect(myDlg->myId,SIGNAL (textChanged(const QString&)),SLOT(redisplayPreview()));
+  connect(myDlg->myPreviewChkBox,   SIGNAL (toggled(bool)),SLOT(redisplayPreview()));
+  connect(myDlg->myAutoSearchChkBox,SIGNAL (toggled(bool)),SLOT(redisplayPreview()));
+  connect(myDlg->myMoveRBtn,        SIGNAL (toggled(bool)),SLOT(redisplayPreview()));
+  connect(myDlg->myCreateRBtn,      SIGNAL (toggled(bool)),SLOT(redisplayPreview()));
+}
+
+//=======================================================================
+// function : startOperation()
+// purpose  : Init dialog fields, connect signals and slots, show dialog
+//=======================================================================
+void SMESHGUI_MakeNodeAtPointOp::startOperation()
+{
+  myNoPreview = false;
+  myMeshActor = 0;
+
+  // init simulation with a current View
+  if ( mySimulation ) delete mySimulation;
+  mySimulation = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow( getSMESHGUI() ));
+  vtkProperty* aProp = vtkProperty::New();
+  aProp->SetRepresentationToWireframe();
+  aProp->SetColor(250, 0, 250);
+  aProp->SetPointSize(5);
+  aProp->SetLineWidth( SMESH::GetFloat("SMESH:element_width",1) + 1);
+  mySimulation->GetActor()->SetProperty(aProp);
+  aProp->Delete();
+
+  SMESHGUI_SelectionOp::startOperation();
+
+  // SalomeApp_TypeFilter depends on a current study
+  if ( myFilter ) delete myFilter;
+  QPtrList<SUIT_SelectionFilter> filters;
+  filters.append( new SalomeApp_TypeFilter((SalomeApp_Study*)study(), "SMESH" ));
+  TColStd_MapOfInteger vertexType;
+  vertexType.Add( TopAbs_VERTEX );
+  filters.append( new SMESH_NumberFilter("GEOM", TopAbs_VERTEX, 1, vertexType ));
+  myFilter = new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR );
+  
+  activateSelection(); // set filters
+
+  myDlg->myX->SetValue(0);
+  myDlg->myY->SetValue(0);
+  myDlg->myZ->SetValue(0);
+  myDlg->myId->setText("");
+  myDlg->show();
+
+  onSelectionDone(); // init myMeshActor
+
+  if ( myMeshActor ) {
+//     myMeshOldDisplayMode = myMeshActor->GetRepresentation();
+//     myMeshActor->SetRepresentation( VTK_WIREFRAME );
+    myMeshActor->SetPointRepresentation(true);
+    SMESH::RepaintCurrentView();
+    redisplayPreview();
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Stops operation
+ */
+//================================================================================
+
+void SMESHGUI_MakeNodeAtPointOp::stopOperation()
+{
+  myNoPreview = true;
+  mySimulation->SetVisibility(false);
+  if ( myMeshActor ) {
+//     myMeshActor->SetRepresentation( myMeshOldDisplayMode );
+    myMeshActor->SetPointRepresentation(false);
+    SMESH::RepaintCurrentView();
+    myMeshActor = 0;
+  }
+  selectionMgr()->removeFilter( myFilter );
+  SMESHGUI_SelectionOp::stopOperation();
+}
+
+//================================================================================
+/*!
+ * \brief perform it's intention action: move or create a node
+ */
+//================================================================================
+
+bool SMESHGUI_MakeNodeAtPointOp::onApply()
+{
+  if( isStudyLocked() )
+    return false;
+
+  if ( !myMeshActor ) {
+    SUIT_MessageBox::warn1( dlg(), tr( "SMESH_WRN_WARNING" ),
+                            tr("INVALID_MESH"), tr( "SMESH_BUT_OK" ) );
+    dlg()->show();
+    return false;
+  }
+
+  if ( !isValid() ) { // node id is invalid
+    SUIT_MessageBox::warn1( dlg(), tr( "SMESH_WRN_WARNING" ),
+                            tr("INVALID_ID"), tr( "SMESH_BUT_OK" ) );
+    dlg()->show();
+    return false;
+  }
+
+
+  try {
+    SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(myMeshActor->getIO());
+    if (aMesh->_is_nil()) {
+      QMessageBox::information(SMESHGUI::desktop(), tr("SMESH_ERROR"),
+                               tr("SMESHG_NO_MESH"), QMessageBox::Ok);
+      return true;
+    }
+    SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
+    if (aMeshEditor->_is_nil())
+      return true;
+
+    int aResult = 0;
+    if ( myDlg->myCreateRBtn->isOn() )
+    {
+      aResult = aMeshEditor->AddNode(myDlg->myX->GetValue(),
+                                     myDlg->myY->GetValue(),
+                                     myDlg->myZ->GetValue());
+    }
+    else
+    {
+      int anId = myDlg->myId->text().toInt();
+      aResult = aMeshEditor->MoveClosestNodeToPoint(myDlg->myX->GetValue(),
+                                                    myDlg->myY->GetValue(),
+                                                    myDlg->myZ->GetValue(),
+                                                    anId);
+    }
+    if (aResult)
+    {
+      myDlg->myId->setText("");
+
+      SALOME_ListIO aList;
+      selectionMgr()->setSelectedObjects(aList,false);
+      aList.Append(myMeshActor->getIO());
+      selectionMgr()->setSelectedObjects(aList,false);
+      SMESH::UpdateView();
+    }
+  }
+  catch (const SALOME::SALOME_Exception& S_ex) {
+    SalomeApp_Tools::QtCatchCorbaException(S_ex);
+  }
+  catch (...) {
+  }
+
+  return true;
+}
+
+//================================================================================
+/*!
+ * \brief Check selected node id validity
+ */
+//================================================================================
+
+bool SMESHGUI_MakeNodeAtPointOp::isValid()
+{
+  bool ok = true;
+
+  if ( myMeshActor &&
+       myDlg->myMoveRBtn->isOn() &&
+       !myDlg->myAutoSearchChkBox->isChecked() )
+  {
+    ok = false;
+    int id = myDlg->myId->text().toInt();
+    if ( id > 0 )
+      if (SMDS_Mesh* aMesh = myMeshActor->GetObject()->GetMesh())
+        ok = aMesh->FindNode( id );
+  }
+  return ok;
+}
+
+//================================================================================
+/*!
+ * \brief SLOT called when selection changed
+ */
+//================================================================================
+
+void SMESHGUI_MakeNodeAtPointOp::onSelectionDone()
+{
+  if ( !myDlg->isShown() || !myDlg->isEnabled() )
+    return;
+  try {
+    SALOME_ListIO aList;
+    selectionMgr()->selectedObjects(aList, SVTK_Viewer::Type());
+    if (aList.Extent() != 1)
+      return;
+    Handle(SALOME_InteractiveObject) anIO = aList.First();
+    SMESH_Actor* aMeshActor = SMESH::FindActorByEntry(anIO->getEntry());
+
+    if (!aMeshActor) { // coord by geom
+      if ( myDlg->myCoordBtn->isOn() ) {
+        GEOM::GEOM_Object_var geom = SMESH::IObjectToInterface<GEOM::GEOM_Object>(anIO);
+        if ( !geom->_is_nil() ) {
+          TopoDS_Vertex aShape;
+          if ( GEOMBase::GetShape(geom, aShape) &&
+               aShape.ShapeType() == TopAbs_VERTEX ) {
+            gp_Pnt P = BRep_Tool::Pnt(aShape);
+            myNoPreview = true;
+            myDlg->myX->SetValue(P.X());
+            myDlg->myY->SetValue(P.Y());
+            myDlg->myZ->SetValue(P.Z());
+            myNoPreview = false;
+            redisplayPreview();
+          }
+        }
+        return;
+      }
+    }
+
+    if ( !myMeshActor )
+      myMeshActor = aMeshActor;
+
+    QString aString;
+    int nbElems = SMESH::GetNameOfSelectedElements(selector(),anIO, aString);
+    if (nbElems == 1) {
+      if (SMDS_Mesh* aMesh = aMeshActor->GetObject()->GetMesh()) {
+        if (const SMDS_MeshNode* aNode = aMesh->FindNode(aString.toInt())) {
+          myNoPreview = true;
+          if ( myDlg->myCoordBtn->isOn() ) { // set coord
+            myDlg->myX->SetValue(aNode->X());
+            myDlg->myY->SetValue(aNode->Y());
+            myDlg->myZ->SetValue(aNode->Z());
+            myNoPreview = false;
+            redisplayPreview();
+          }
+          else if ( myDlg->myIdBtn->isOn() &&
+                    myDlg->myIdBtn->isEnabled() ) { // set node to move
+            myDlg->myId->setText(aString);
+            myNoPreview = false;
+            redisplayPreview();
+          }
+        }
+      }
+    }
+  } catch (...) {
+  }
+}
+
+//================================================================================
+/*!
+ * \brief update preview
+ */
+//================================================================================
+
+void SMESHGUI_MakeNodeAtPointOp::redisplayPreview()
+{
+  if ( myNoPreview )
+    return;
+  myNoPreview = true;
+
+  SMESH::MeshPreviewStruct_var aMeshPreviewStruct;
+
+  bool moveShown = false;
+  if ( myDlg->myMoveRBtn->isOn() && // Move method
+       myMeshActor)
+  {
+    const bool autoSearch = myDlg->myAutoSearchChkBox->isChecked();
+    const bool preview    = myDlg->myPreviewChkBox->isChecked();
+    if ( autoSearch )
+      myDlg->myId->setText("");
+    if ( preview && ( autoSearch || isValid() ))
+    {
+      try {
+        SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(myMeshActor->getIO());
+        if (!aMesh->_is_nil()) {
+          SMESH::SMESH_MeshEditor_var aPreviewer = aMesh->GetMeshEditPreviewer();
+          if (!aPreviewer->_is_nil())
+          {
+            SUIT_OverrideCursor aWaitCursor;
+
+            // find id and/or just compute preview
+            int anId = aPreviewer->MoveClosestNodeToPoint(myDlg->myX->GetValue(),
+                                                          myDlg->myY->GetValue(),
+                                                          myDlg->myZ->GetValue(),
+                                                          myDlg->myId->text().toInt());
+            if ( autoSearch ) { // set found id
+              QString idTxt("%1");
+              if ( anId > 0 )
+                idTxt = idTxt.arg( anId );
+              else
+                idTxt = "";
+              myDlg->myId->setText( idTxt );
+            }
+            if ( preview ) { // fill preview data
+              aMeshPreviewStruct = aPreviewer->GetPreviewData();
+              moveShown = ( anId > 0 );
+            }
+          }
+        }
+      }catch (...) {
+      }
+    }
+  }
+
+  if ( !moveShown )
+  {
+    aMeshPreviewStruct = new SMESH::MeshPreviewStruct();
+
+    aMeshPreviewStruct->nodesXYZ.length(1);
+    aMeshPreviewStruct->nodesXYZ[0].x = myDlg->myX->GetValue();
+    aMeshPreviewStruct->nodesXYZ[0].y = myDlg->myY->GetValue();
+    aMeshPreviewStruct->nodesXYZ[0].z = myDlg->myZ->GetValue();
+
+    aMeshPreviewStruct->elementTypes.length(1);
+    aMeshPreviewStruct->elementTypes[0].SMDS_ElementType = SMESH::NODE;
+    aMeshPreviewStruct->elementTypes[0].isPoly = false;
+    aMeshPreviewStruct->elementTypes[0].nbNodesInElement = 1;
+
+    aMeshPreviewStruct->elementConnectivities.length(1);
+    aMeshPreviewStruct->elementConnectivities[0] = 0;
+  }
+
+  // display data
+  if ( aMeshPreviewStruct.operator->() )
+  {
+    mySimulation->SetData(aMeshPreviewStruct._retn());
+  }
+  else
+{
+    mySimulation->SetVisibility(false);
+  }
+
+  myNoPreview = false;
+}
+
+//================================================================================
+/*!
+ * \brief Activate Node selection
+ */
+//================================================================================
+
+void SMESHGUI_MakeNodeAtPointOp::activateSelection()
+{
+  selectionMgr()->clearFilters();
+  SMESH::SetPointRepresentation(false);
+  selectionMgr()->installFilter( myFilter );
+  setSelectionMode( NodeSelection );
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+*/
+//================================================================================
+
+SMESHGUI_MakeNodeAtPointOp::~SMESHGUI_MakeNodeAtPointOp()
+{
+  if ( myDlg )        delete myDlg;
+  if ( mySimulation ) delete mySimulation;
+  if ( myFilter )     delete myFilter;
+}
+
+//================================================================================
+/*!
+ * \brief Gets dialog of this operation
+ * \retval LightApp_Dialog* - pointer to dialog of this operation
+ */
+//================================================================================
+
+LightApp_Dialog* SMESHGUI_MakeNodeAtPointOp::dlg() const
+{
+  return myDlg;
+}
+
diff --git a/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.h b/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.h
new file mode 100644 (file)
index 0000000..6751b6f
--- /dev/null
@@ -0,0 +1,124 @@
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : SMESHGUI_MakeNodeAtPointDlg.h
+//  Author : Edward AGAPOV
+//  Module : SMESH
+
+
+#ifndef SMESHGUI_MakeNodeAtPointDlg_H
+#define SMESHGUI_MakeNodeAtPointDlg_H
+
+#include "SMESHGUI_Dialog.h"
+#include "SMESHGUI_SelectionOp.h"
+
+#include "VTKViewer.h"
+
+class QFrame;
+class QLineEdit;
+class QPushButton;
+class LightApp_SelectionMgr;
+class SVTK_ViewWindow;
+class QButtonGroup;
+class SMESHGUI;
+class QCheckBox;
+class QRadioButton;
+class SMESHGUI_SpinBox;
+class SALOME_Actor;
+class SMESHGUI_MeshEditPreview;
+class SMESHGUI_MakeNodeAtPointDlg;
+
+/*!
+ * \brief Operation to make a mesh pass through a point
+ */
+class SMESHGUI_MakeNodeAtPointOp: public SMESHGUI_SelectionOp
+{
+  Q_OBJECT
+
+public:
+  SMESHGUI_MakeNodeAtPointOp();
+  virtual ~SMESHGUI_MakeNodeAtPointOp();
+
+  virtual LightApp_Dialog*       dlg() const;  
+
+protected:
+
+  virtual void                   startOperation();
+  virtual void                   stopOperation();
+
+  virtual void                   activateSelection();
+
+  bool                           isValid();
+
+protected slots:
+  virtual bool                   onApply();
+
+private slots:
+
+  void                           onSelectionDone();
+  void                           redisplayPreview();
+
+private:
+
+  SMESHGUI_MakeNodeAtPointDlg*  myDlg;
+
+  SUIT_SelectionFilter*         myFilter;
+  int                           myMeshOldDisplayMode;
+  SMESHGUI_MeshEditPreview*     mySimulation;
+  SMESH_Actor*                  myMeshActor;
+  bool                          myNoPreview;
+
+};
+
+/*!
+ * \brief Dialog to make a mesh pass through a point
+ */
+
+class SMESHGUI_MakeNodeAtPointDlg : public SMESHGUI_Dialog
+{
+  Q_OBJECT
+
+public:
+                                 SMESHGUI_MakeNodeAtPointDlg();
+
+private:
+
+  QFrame*                        createMainFrame   (QWidget*);
+
+  QPushButton*                 myCoordBtn;
+  SMESHGUI_SpinBox             *myX, *myY, *myZ;
+  QRadioButton                 *myMoveRBtn, *myCreateRBtn;
+  QGroupBox*                   myNodeToMoveGrp;
+  QPushButton*                 myIdBtn;
+  QLineEdit*                   myId;
+  QCheckBox*                   myAutoSearchChkBox;
+  QCheckBox*                   myPreviewChkBox;
+
+  QString                      myHelpFileName;
+
+  friend class SMESHGUI_MakeNodeAtPointOp;
+
+private slots:
+
+  void                           ButtonToggled (bool);
+};
+
+#endif
index 475f2161cf58776c9d4543ab1702d87fff9244d9..1fadd352b62e19e376af870247f1133dcc4d6d94 100644 (file)
@@ -36,6 +36,8 @@
 
 #include "SMESH_Actor.h"
 #include "SMESH_TypeFilter.hxx"
+#include "SMESH_LogicalFilter.hxx"
+#include "SMESHGUI_MeshUtils.h"
 #include "SMDS_Mesh.hxx"
 
 #include "GEOMBase.h"
@@ -72,6 +74,9 @@
 #include <qpixmap.h>
 #include <qheader.h>
 
+//IDL Headers
+#include CORBA_SERVER_HEADER(SMESH_Group)
+
 using namespace std;
 
 //=================================================================================
@@ -158,7 +163,7 @@ SMESHGUI_MergeNodesDlg::SMESHGUI_MergeNodesDlg( SMESHGUI* theModule, const char*
 
   // Controls for mesh defining
   GroupMesh = new QGroupBox(this, "GroupMesh");
-  GroupMesh->setTitle(tr("SMESH_MESH"));
+  GroupMesh->setTitle(tr("SMESH_SELECT_WHOLE_MESH"));
   GroupMesh->setColumnLayout(0, Qt::Vertical);
   GroupMesh->layout()->setSpacing(0);
   GroupMesh->layout()->setMargin(0);
@@ -254,12 +259,24 @@ SMESHGUI_MergeNodesDlg::SMESHGUI_MergeNodesDlg( SMESHGUI* theModule, const char*
   myEditCurrentArgument = (QWidget*)LineEditMesh; 
 
   myActor = 0;
+  mySubMeshOrGroup = SMESH::SMESH_subMesh::_nil();
 
   mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
 
   mySMESHGUI->SetActiveDialogBox((QDialog*)this);
-
-  myMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH);
+  
+  // Costruction of the logical filter
+  SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH);
+  SMESH_TypeFilter* aSmeshGroupFilter    = new SMESH_TypeFilter (GROUP);
+  
+  QPtrList<SUIT_SelectionFilter> aListOfFilters;
+  if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter);
+  if (aSmeshGroupFilter)    aListOfFilters.append(aSmeshGroupFilter);
+
+  myMeshOrSubMeshOrGroupFilter =
+    new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR);
+  
+  //myMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH);
 
   /* signals and slots connections */
   connect(buttonOk, SIGNAL(clicked()),     this, SLOT(ClickOnOk()));
@@ -468,7 +485,10 @@ void SMESHGUI_MergeNodesDlg::onDetect()
     ListEdit->clear();
 
     SMESH::array_of_long_array_var aNodeGroups;
-    aMeshEditor->FindCoincidentNodes(SpinBoxTolerance->GetValue(), aNodeGroups);
+    if(!mySubMeshOrGroup->_is_nil())
+      aMeshEditor->FindCoincidentNodesOnPart(mySubMeshOrGroup, SpinBoxTolerance->GetValue(), aNodeGroups);
+    else
+      aMeshEditor->FindCoincidentNodes(SpinBoxTolerance->GetValue(), aNodeGroups);
 
     for (int i = 0; i < aNodeGroups->length(); i++) {
       SMESH::long_array& aGroup = aNodeGroups[i];
@@ -630,7 +650,7 @@ void SMESHGUI_MergeNodesDlg::SetEditCurrentArgument()
     SMESH::SetPointRepresentation(false);
     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
       aViewWindow->SetSelectionMode(ActorSelection);
-    mySelectionMgr->installFilter(myMeshOrSubMeshFilter);
+    mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter);
   }
 
   myEditCurrentArgument->setFocus();
@@ -647,23 +667,37 @@ void SMESHGUI_MergeNodesDlg::SelectionIntoArgument()
   if (myEditCurrentArgument == (QWidget*)LineEditMesh) {
     QString aString = "";
     LineEditMesh->setText(aString);
-
+    
     ListCoincident->clear();
     ListEdit->clear();
-
+    myActor = 0;
+    
     int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString);
     if (nbSel != 1)
       return;
 
     SALOME_ListIO aList;
     mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
-
+    
     Handle(SALOME_InteractiveObject) IO = aList.First();
-    myMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO);
-    myActor = SMESH::FindActorByEntry(aList.First()->getEntry());
-    if (myMesh->_is_nil() || !myActor)
+    myMesh = SMESH::GetMeshByIO(IO);
+    
+    if (myMesh->_is_nil())
       return;
-
+    
+    myActor = SMESH::FindActorByEntry(IO->getEntry());
+    if (!myActor)
+      myActor = SMESH::FindActorByObject(myMesh);
+    if(!myActor)
+      return;
+    
+    mySubMeshOrGroup = SMESH::SMESH_IDSource::_nil();
+    
+    if ((!SMESH::IObjectToInterface<SMESH::SMESH_subMesh>(IO)->_is_nil() || //SUBMESH OR GROUP
+         !SMESH::IObjectToInterface<SMESH::SMESH_GroupBase>(IO)->_is_nil()) &&
+        !SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO)->_is_nil())
+      mySubMeshOrGroup = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(IO);
+     
     LineEditMesh->setText(aString);
   }
 }
index 174f87290035fe8dca56ee3215344826ed28e153..65ca3cde331285aee2e4d7d7a492cda954e96a6e 100644 (file)
@@ -58,7 +58,7 @@ class SVTK_Selector;
 
 // IDL Headers
 #include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
 
 
 //=================================================================================
@@ -91,9 +91,10 @@ private:
     QWidget*                      myEditCurrentArgument;
 
     SMESH::SMESH_Mesh_var         myMesh;
+    SMESH::SMESH_IDSource_var     mySubMeshOrGroup;
     SMESH_Actor*                  myActor;
     //Handle(SMESH_TypeFilter)      myMeshOrSubMeshFilter;
-    SUIT_SelectionFilter*         myMeshOrSubMeshFilter;
+    SUIT_SelectionFilter*         myMeshOrSubMeshOrGroupFilter;
 
     QButtonGroup*     GroupConstructors;
     QRadioButton*     RadioButton1;
index 3d19a12786e10dc628e0355fd2cbeef28038e226..33d2e6485f6eaf4c13943600fc337944b0c99615 100644 (file)
@@ -391,12 +391,14 @@ SMESHGUI_MeshDlg::SMESHGUI_MeshDlg( const bool theToCreate, const bool theIsMesh
   // Create tab widget
   
   myTabWg = new QTabWidget( mainFrame() );
+  myTabs[ Dim0D ] = new SMESHGUI_MeshTab( myTabWg );
   myTabs[ Dim1D ] = new SMESHGUI_MeshTab( myTabWg );
   myTabs[ Dim2D ] = new SMESHGUI_MeshTab( myTabWg );
   myTabs[ Dim3D ] = new SMESHGUI_MeshTab( myTabWg );
   myTabWg->addTab( myTabs[ Dim3D ], tr( "DIM_3D" ) );
   myTabWg->addTab( myTabs[ Dim2D ], tr( "DIM_2D" ) );
   myTabWg->addTab( myTabs[ Dim1D ], tr( "DIM_1D" ) );
+  myTabWg->addTab( myTabs[ Dim0D ], tr( "DIM_0D" ) );
 
   // Hypotheses Sets
   myHypoSetPopup = new QPopupMenu();
@@ -454,7 +456,7 @@ SMESHGUI_MeshDlg::~SMESHGUI_MeshDlg()
 //================================================================================
 SMESHGUI_MeshTab* SMESHGUI_MeshDlg::tab( const int theId ) const
 {
-  return ( theId >= Dim1D && theId <= Dim3D ? myTabs[ theId ] : 0 );
+  return ( theId >= Dim0D && theId <= Dim3D ? myTabs[ theId ] : 0 );
 }
 
 //================================================================================
@@ -465,6 +467,7 @@ SMESHGUI_MeshTab* SMESHGUI_MeshDlg::tab( const int theId ) const
 void SMESHGUI_MeshDlg::reset()
 {
   clearSelection();
+  myTabs[ Dim0D ]->reset();
   myTabs[ Dim1D ]->reset();
   myTabs[ Dim2D ]->reset();
   myTabs[ Dim3D ]->reset();
@@ -489,8 +492,8 @@ void SMESHGUI_MeshDlg::setCurrentTab( const int theId  )
 
 void SMESHGUI_MeshDlg::setMaxHypoDim( const int maxDim )
 {
-  const int DIM = maxDim - 1;
-  for ( int dim = Dim1D; dim <= Dim3D; ++dim ) {
+  const int DIM = maxDim;
+  for ( int dim = Dim0D; dim <= Dim3D; ++dim ) {
     bool enable = ( dim <= DIM );
     if ( !enable )
       myTabs[ dim ]->reset();
index 0429403a446da59039a5d9d42c75992156b86f88..33f1b2d573dd05abcd22f9771f4d6e162fb5b1ae 100644 (file)
@@ -62,7 +62,7 @@ public:
   enum Controls { Obj, Mesh, Geom };
   
   /*! Describes dimensions */
-  enum Dimensions { Dim1D = 0, Dim2D, Dim3D };      
+  enum Dimensions { Dim0D = 0, Dim1D, Dim2D, Dim3D };      
   
 public:
   SMESHGUI_MeshDlg( const bool theToCreate, const bool theIsMesh );
diff --git a/src/SMESHGUI/SMESHGUI_MeshEditPreview.cxx b/src/SMESHGUI/SMESHGUI_MeshEditPreview.cxx
new file mode 100644 (file)
index 0000000..6190024
--- /dev/null
@@ -0,0 +1,245 @@
+//  SMESH SMESHGUI : GUI for SMESH component
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : SMESHGUI_MeshEditPreview.cxx
+//  Module : SMESH
+//  $Header:
+
+#include "SMESHGUI_MeshEditPreview.h"
+
+#include "VTKViewer_CellLocationsArray.h"
+#include "SVTK_ViewWindow.h"
+
+#include "SMESH_Actor.h"
+#include "SMESH_ActorUtils.h"
+#include "SMESHGUI_VTKUtils.h"
+
+// VTK Includes
+#include <vtkPoints.h>
+#include <vtkIdList.h>
+#include <vtkCellArray.h>
+#include <vtkUnsignedCharArray.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkUnstructuredGridWriter.h>
+#include <vtkDataSetMapper.h>
+#include <vtkProperty.h>
+
+// QT Includes
+#include <qcolor.h>
+
+// IDL Headers
+#include "SALOMEconfig.h"
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
+using namespace SMESH;
+
+//================================================================================
+/*!
+ * \brief Constructor
+ */
+//================================================================================
+
+SMESHGUI_MeshEditPreview::SMESHGUI_MeshEditPreview(SVTK_ViewWindow* theViewWindow):
+  myViewWindow(theViewWindow)
+{
+  myGrid = vtkUnstructuredGrid::New();
+
+  // Create and display actor
+  vtkDataSetMapper* aMapper = vtkDataSetMapper::New();
+  aMapper->SetInput( myGrid );
+
+  myPreviewActor = SALOME_Actor::New();
+  myPreviewActor->SetInfinitive(true);
+  myPreviewActor->VisibilityOn();
+  myPreviewActor->PickableOff();
+
+  vtkFloatingPointType anRGB[3];
+  GetColor( "SMESH", "selection_element_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) );
+  SetColor( anRGB[0], anRGB[1], anRGB[2] );
+
+  myPreviewActor->SetMapper( aMapper );
+  aMapper->Delete();
+
+  myViewWindow->AddActor(myPreviewActor);
+
+}
+
+//================================================================================
+/*!
+ * \brief Destroy
+ */
+//================================================================================
+
+SMESHGUI_MeshEditPreview::~SMESHGUI_MeshEditPreview()
+{
+  myGrid->Delete();
+
+  myViewWindow->RemoveActor(myPreviewActor);
+  myPreviewActor->Delete();
+
+}
+
+//================================================================================
+/*!
+ * \brief Returns vtk cell type
+ */
+//================================================================================
+
+vtkIdType getCellType( const SMDSAbs_ElementType theType,
+                       const bool thePoly,
+                       const int theNbNodes )
+{
+  switch( theType ) 
+  {
+  case SMDSAbs_Node:              return VTK_VERTEX;
+  case SMDSAbs_Edge: 
+    if( theNbNodes == 2 )         return VTK_LINE;
+    else if ( theNbNodes == 3 )   return VTK_QUADRATIC_EDGE;
+    else return VTK_EMPTY_CELL;
+
+  case SMDSAbs_Face  :
+    if (thePoly && theNbNodes>2 ) return VTK_POLYGON;
+    else if ( theNbNodes == 3 )   return VTK_TRIANGLE;
+    else if ( theNbNodes == 4 )   return VTK_QUAD;
+    else if ( theNbNodes == 6 )   return VTK_QUADRATIC_TRIANGLE;
+    else if ( theNbNodes == 8 )   return VTK_QUADRATIC_QUAD;
+    else return VTK_EMPTY_CELL;
+
+  case SMDSAbs_Volume:
+    if (thePoly && theNbNodes>3 ) return VTK_CONVEX_POINT_SET;
+    else if ( theNbNodes == 4 )   return VTK_TETRA;
+    else if ( theNbNodes == 5 )   return VTK_PYRAMID;
+    else if ( theNbNodes == 6 )   return VTK_WEDGE;
+    else if ( theNbNodes == 8 )   return VTK_HEXAHEDRON;
+    else if ( theNbNodes == 10 )  {
+      return VTK_QUADRATIC_TETRA;
+    }
+    else if ( theNbNodes == 20 )  {
+      return VTK_QUADRATIC_HEXAHEDRON;
+    }
+    else if ( theNbNodes==13 || theNbNodes==15 )  {
+      return VTK_CONVEX_POINT_SET;
+    }
+    else return VTK_EMPTY_CELL;
+
+  default: return VTK_EMPTY_CELL;
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Set preview data
+ */
+//================================================================================
+
+void SMESHGUI_MeshEditPreview::SetData (const SMESH::MeshPreviewStruct* previewData)
+{
+  // Create points
+  const SMESH::nodes_array& aNodesXYZ = previewData->nodesXYZ;
+  vtkPoints* aPoints = vtkPoints::New();
+  aPoints->SetNumberOfPoints(aNodesXYZ.length());
+
+  for ( int i = 0; i < aNodesXYZ.length(); i++ ) {
+    aPoints->SetPoint( i, aNodesXYZ[i].x, aNodesXYZ[i].y, aNodesXYZ[i].z );
+  }
+  myGrid->SetPoints(aPoints);
+
+  aPoints->Delete();
+
+  // Create cells
+  const SMESH::long_array&  anElemConnectivity = previewData->elementConnectivities;
+  const SMESH::types_array& anElemTypes = previewData->elementTypes;
+
+  vtkIdType aCellsSize = anElemConnectivity.length() + anElemTypes.length();
+  vtkIdType aNbCells = anElemTypes.length();
+
+  vtkCellArray* aConnectivity = vtkCellArray::New();
+  aConnectivity->Allocate( aCellsSize, 0 );
+
+  vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New();
+  aCellTypesArray->SetNumberOfComponents( 1 );
+  aCellTypesArray->Allocate( aNbCells * aCellTypesArray->GetNumberOfComponents() );
+
+  vtkIdList *anIdList = vtkIdList::New();
+  int aNodePos = 0;
+
+  for ( int i = 0; i < anElemTypes.length(); i++ ) {
+    const ElementSubType& anElementSubType = anElemTypes[i];
+    SMDSAbs_ElementType aType = SMDSAbs_ElementType(anElementSubType.SMDS_ElementType);
+    vtkIdType aNbNodes = anElementSubType.nbNodesInElement;
+    anIdList->SetNumberOfIds( aNbNodes );
+
+    for ( vtkIdType aNodeId = 0; aNodeId < aNbNodes; aNodeId++ ){
+      anIdList->SetId( aNodeId, anElemConnectivity[aNodePos] );
+      aNodePos++;
+    }
+
+    aConnectivity->InsertNextCell( anIdList );
+    aCellTypesArray->InsertNextValue( getCellType( aType,
+                                                   anElemTypes[i].isPoly, 
+                                                   aNbNodes ) );
+  }
+  anIdList->Delete();
+
+  // Insert cells in grid
+  VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New();
+  aCellLocationsArray->SetNumberOfComponents( 1 );
+  aCellLocationsArray->SetNumberOfTuples( aNbCells );
+
+  aConnectivity->InitTraversal();
+  for( vtkIdType idType = 0, *pts, npts; aConnectivity->GetNextCell( npts, pts ); idType++ )
+    aCellLocationsArray->SetValue( idType, aConnectivity->GetTraversalLocation( npts ) );
+
+  myGrid->SetCells( aCellTypesArray, aCellLocationsArray, aConnectivity );
+
+  myPreviewActor->GetMapper()->Update();
+
+  aCellTypesArray->Delete();
+  aCellLocationsArray->Delete();
+  aConnectivity->Delete();
+
+  SetVisibility(true);
+}
+
+//================================================================================
+/*!
+ * \brief Set visibility
+ */
+//================================================================================
+
+void SMESHGUI_MeshEditPreview::SetVisibility (bool theVisibility)
+{
+  myPreviewActor->SetVisibility(theVisibility);
+  RepaintCurrentView();
+}
+
+//================================================================================
+/*!
+ * \brief Set preview color
+ */
+//================================================================================
+
+void SMESHGUI_MeshEditPreview::SetColor(double R, double G, double B)
+{
+  myPreviewActor->SetColor( R, G, B );
+}
diff --git a/src/SMESHGUI/SMESHGUI_MeshEditPreview.h b/src/SMESHGUI/SMESHGUI_MeshEditPreview.h
new file mode 100644 (file)
index 0000000..7e20125
--- /dev/null
@@ -0,0 +1,62 @@
+//  SMESH SMESHGUI : GUI for SMESH component
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : SMESHGUI_MeshEditPreview.cxx
+//  Module : SMESH
+//  $Header:
+
+#ifndef SMESHGUI_MESHEDITPREVIEW_H
+#define SMESHGUI_MESHEDITPREVIEW_H
+
+class SVTK_ViewWindow;
+class vtkUnstructuredGrid;
+class SALOME_Actor;
+namespace SMESH {
+  class MeshPreviewStruct;
+}
+
+/*!
+ * \brief Displayer of the mesh edition preview
+ */
+class SMESHGUI_MeshEditPreview {
+  SVTK_ViewWindow* myViewWindow;
+
+  vtkUnstructuredGrid* myGrid;
+  SALOME_Actor* myPreviewActor;
+
+public:
+
+  SMESHGUI_MeshEditPreview(SVTK_ViewWindow* theViewWindow);
+  ~SMESHGUI_MeshEditPreview();
+
+  void SetData (const SMESH::MeshPreviewStruct* theMeshPreviewStruct);
+
+  void SetVisibility (bool theVisibility);
+
+  void SetColor(double R, double G, double B);
+
+  SALOME_Actor* GetActor() { return myPreviewActor; }
+
+};
+
+#endif
index 0e13c26e5196cfb172bb4452c2f612fececde5b1..9aa469e68ccf909ef99a60a3f68957f6ebad73ae 100644 (file)
@@ -76,6 +76,7 @@ enum { GLOBAL_ALGO_TAG        =3,
        GLOBAL_HYPO_TAG        =2,
        LOCAL_ALGO_TAG         =2,
        LOCAL_HYPO_TAG         =1,
+       SUBMESH_ON_VERTEX_TAG  =4,
        SUBMESH_ON_EDGE_TAG    =5,
        SUBMESH_ON_WIRE_TAG    =6,
        SUBMESH_ON_FACE_TAG    =7,
@@ -201,7 +202,7 @@ void SMESHGUI_MeshOp::startOperation()
   if( !myDlg )
   {
     myDlg = new SMESHGUI_MeshDlg( myToCreate, myIsMesh );
-    for ( int i = SMESH::DIM_1D; i <= SMESH::DIM_3D; i++ )
+    for ( int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++ )
     {
       connect( myDlg->tab( i ), SIGNAL( createHyp( const int, const int ) ),
               this, SLOT( onCreateHyp( const int, const int ) ) );
@@ -220,10 +221,9 @@ void SMESHGUI_MeshOp::startOperation()
   }
   SMESHGUI_SelectionOp::startOperation();
 
-  // iterate through dimensions and get available algoritms,
-  // set them to the dialog
+  // iterate through dimensions and get available algoritms, set them to the dialog
   _PTR(SComponent) aFather = SMESH::GetActiveStudyDocument()->FindComponent( "SMESH" );
-  for ( int i = SMESH::DIM_1D; i <= SMESH::DIM_3D; i++ )
+  for ( int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++ )
   {
     SMESHGUI_MeshTab* aTab = myDlg->tab( i );
     QStringList hypList;
@@ -331,11 +331,19 @@ bool SMESHGUI_MeshOp::isSubshapeOk() const
         GEOM::GEOM_Object::_narrow(_CAST(SObject,pSubGeom)->GetObject());
       if (aSubGeomVar->_is_nil()) return false;
 
+      // skl for NPAL14695 - implementation of searching of mainObj
       GEOM::GEOM_Object_var mainObj = op->GetMainShape(aSubGeomVar);
-      if (mainObj->_is_nil() ||
-          string(mainObj->GetEntry()) != string(mainGeom->GetEntry())) return false;
+      //if (mainObj->_is_nil() ||
+      //    string(mainObj->GetEntry()) != string(mainGeom->GetEntry())) return false;
+      while(1) {
+       if(mainObj->_is_nil())
+         return false;
+       if( string(mainObj->GetEntry()) == string(mainGeom->GetEntry()) )
+         return true;
+       mainObj = op->GetMainShape(mainObj);
+      }
     }
-    return true;
+    //return true;
   }
 
   return false;
@@ -359,6 +367,7 @@ _PTR(SObject) SMESHGUI_MeshOp::getSubmeshByGeom() const
     if ( !geom->_is_nil() ) {
       int tag = -1;
       switch ( geom->GetShapeType() ) {
+      case GEOM::VERTEX:   tag = SUBMESH_ON_VERTEX_TAG  ; break;
       case GEOM::EDGE:     tag = SUBMESH_ON_EDGE_TAG    ; break;
       case GEOM::WIRE:     tag = SUBMESH_ON_WIRE_TAG    ; break;
       case GEOM::FACE:     tag = SUBMESH_ON_FACE_TAG    ; break;
@@ -834,7 +843,7 @@ SMESHGUI_MeshOp::getInitParamsHypothesis( const QString& aHypType,
 static int getTabDim (const QObject* tab, SMESHGUI_MeshDlg* dlg )
 {
   int aDim = -1;
-  for (int i = SMESH::DIM_1D; i <= SMESH::DIM_3D; i++)
+  for (int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++)
     if (tab == dlg->tab(i))
       aDim = i;
   return aDim;
@@ -970,7 +979,7 @@ HypothesisData* SMESHGUI_MeshOp::hypData( const int theDim,
                                           const int theHypType,
                                           const int theIndex)
 {
-  if ( theDim     > -1 && theDim     < 3 &&
+  if ( theDim     > -1 && theDim    <= SMESH::DIM_3D &&
        theHypType > -1 && theHypType < NbHypTypes &&
        theIndex   > -1 && theIndex   < myAvailableHypData[ theDim ][ theHypType ].count() )
     return myAvailableHypData[ theDim ][ theHypType ][ theIndex ];
@@ -996,7 +1005,7 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
 
   // find highest available dimension, all algos of this dimension are available for choice
   int aTopDim = -1;
-  for (int i = SMESH::DIM_1D; i <= SMESH::DIM_3D; i++)
+  for (int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++)
     if (isAccessibleDim( i ))
       aTopDim = i;
   if (aTopDim == -1)
@@ -1005,7 +1014,7 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
   const bool isSubmesh = ( myToCreate ? !myIsMesh : myDlg->isObjectShown( SMESHGUI_MeshDlg::Mesh ));
 
   HypothesisData* algoData = hypData( aDim, Algo, theIndex );
-  HypothesisData* algoByDim[3];
+  HypothesisData* algoByDim[4];
   algoByDim[ aDim ] = algoData;
 
   QStringList anAvailable;
@@ -1022,7 +1031,7 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
   {
     int dim = aDim + 1, lastDim = SMESH::DIM_3D, dir = 1;
     if ( !forward ) {
-      dim = aDim - 1; lastDim = SMESH::DIM_1D; dir = -1;
+      dim = aDim - 1; lastDim = SMESH::DIM_0D; dir = -1;
     }
     HypothesisData* prevAlgo = algoData;
     bool noCompatible = false;
@@ -1056,7 +1065,7 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
 
       // restore previously selected algo
       algoIndex = myAvailableHypData[dim][Algo].findIndex( curAlgo );
-      if ( !isSubmesh && algoIndex < 0 && soleCompatible && !forward )
+      if ( !isSubmesh && algoIndex < 0 && soleCompatible && !forward && dim != SMESH::DIM_0D)
         // select the sole compatible algo
         algoIndex = myAvailableHypData[dim][Algo].findIndex( soleCompatible );
       setCurrentHyp( dim, Algo, algoIndex );
@@ -1070,7 +1079,7 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
 
   _PTR(SObject) pObj = SMESH::GetActiveStudyDocument()->FindComponent("SMESH");
 
-  for ( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ )
+  for ( int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++ )
   {
     if ( !isAccessibleDim( dim ))
       continue;
@@ -1151,7 +1160,7 @@ void SMESHGUI_MeshOp::onHypoSet( const QString& theSetName )
   if (!aHypoSet) return;
 
   // clear all hyps
-  for (int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++) {
+  for (int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++) {
     setCurrentHyp(dim, Algo, -1);
     setCurrentHyp(dim, AddHyp, -1);
     setCurrentHyp(dim, MainHyp, -1);
@@ -1235,7 +1244,7 @@ bool SMESHGUI_MeshOp::createMesh( QString& theMess )
     if ( aMeshSO )
       SMESH::SetName( aMeshSO, myDlg->objectText( SMESHGUI_MeshDlg::Obj ).latin1() );
 
-    for ( int aDim = SMESH::DIM_1D; aDim <= SMESH::DIM_3D; aDim++ ) {
+    for ( int aDim = SMESH::DIM_0D; aDim <= SMESH::DIM_3D; aDim++ ) {
       if ( !isAccessibleDim( aDim )) continue;
 
       // assign hypotheses
@@ -1355,7 +1364,7 @@ bool SMESHGUI_MeshOp::createSubMesh( QString& theMess )
   // create sub-mesh
   SMESH::SMESH_subMesh_var aSubMeshVar = aMeshVar->GetSubMesh( aGeomVar, aName.latin1() );
 
-  for ( int aDim = SMESH::DIM_1D; aDim <= SMESH::DIM_3D; aDim++ )
+  for ( int aDim = SMESH::DIM_0D; aDim <= SMESH::DIM_3D; aDim++ )
   {
     if ( !isAccessibleDim( aDim )) continue;
 
@@ -1377,8 +1386,8 @@ bool SMESHGUI_MeshOp::createSubMesh( QString& theMess )
     }
   }
 
-  // deselect geometry: next submesh sould be created on other subshape
-  myDlg->selectObject( "", SMESHGUI_MeshDlg::Geom, "" );
+  // deselect geometry: next submesh should be created on other subshape
+  myDlg->clearSelection( SMESHGUI_MeshDlg::Geom );
   selectObject( _PTR(SObject)() );
   selectionDone();
 
@@ -1573,7 +1582,7 @@ void SMESHGUI_MeshOp::readMesh()
 
   // Get hypotheses and algorithms assigned to the mesh/sub-mesh
   QStringList anExisting;
-  for ( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ )
+  for ( int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++ )
   {
     // get algorithm
     existingHyps( dim, Algo, pObj, anExisting, myObjHyps[ dim ][ Algo ] );
@@ -1598,7 +1607,7 @@ void SMESHGUI_MeshOp::readMesh()
 
   // get hypotheses
   bool hypWithoutAlgo = false;
-  for ( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ )
+  for ( int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++ )
   {
     for ( int hypType = MainHyp; hypType <= AddHyp; hypType++ )
     {
@@ -1711,37 +1720,35 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess )
   // Set new name
   SMESH::SetName( pObj, myDlg->objectText( SMESHGUI_MeshDlg::Obj ).latin1() );
 
-  // Assign new hypotheses and algorithms
-  for ( int dim = SMESH::DIM_1D; dim <= SMESH::DIM_3D; dim++ )
+  // First, remove old algos in order to avoid messages on algorithm hiding
+  for ( int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++ )
+  {
+    if ( isAccessibleDim( dim ) && myObjHyps[ dim ][ Algo ].count() > 0 )
+    {
+      SMESH::SMESH_Hypothesis_var anOldAlgo = myObjHyps[ dim ][ Algo ].first();
+      SMESH::SMESH_Hypothesis_var anAlgoVar = getAlgo( dim );
+      if ( anAlgoVar->_is_nil() || // no new algo selected or
+           strcmp(anOldAlgo->GetName(), anAlgoVar->GetName()) ) // algo change
+      {
+        // remove old algorithm
+        SMESH::RemoveHypothesisOrAlgorithmOnMesh ( pObj, myObjHyps[ dim ][ Algo ].first() );
+        myObjHyps[ dim ][ Algo ].clear();
+      }
+    }
+  }
+
+  // Assign new algorithms and hypotheses
+  for ( int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++ )
   {
     if ( !isAccessibleDim( dim )) continue;
 
     // find or create algorithm
-    bool toDelete = false, toAdd = true;
     SMESH::SMESH_Hypothesis_var anAlgoVar = getAlgo( dim );
-    if ( anAlgoVar->_is_nil() ) {
-      toAdd = false;
-    }
-    if ( myObjHyps[ dim ][ Algo ].count() > 0 ) {
-      SMESH::SMESH_Hypothesis_var anOldAlgo = myObjHyps[ dim ][ Algo ].first();
-      if ( toAdd ) {
-        if ( strcmp(anOldAlgo->GetName(), anAlgoVar->GetName()) == 0 ) {
-          toAdd = false;
-        } else {
-          toDelete = true;
-        }
-      } else {
-        toDelete = true;
-      }
-    }
-    // remove old algorithm
-    if ( toDelete ) {
-      SMESH::RemoveHypothesisOrAlgorithmOnMesh ( pObj, myObjHyps[ dim ][ Algo ].first() );
-      myObjHyps[ dim ][ Algo ].clear();
-    }
 
     // assign new algorithm
-    if ( toAdd ) {
+    if ( !anAlgoVar->_is_nil() && // some algo selected and
+         myObjHyps[ dim ][ Algo ].count() == 0 ) // no algo assigned
+    {
       SMESH::SMESH_Mesh_var aMeshVar =
         SMESH::SMESH_Mesh::_narrow( _CAST(SObject,pObj)->GetObject() );
       bool isMesh = !aMeshVar->_is_nil();
index 3155a52cc61974adb80d3d9ddf4f5120a4a6f2c7..190c386dd77a33232e7722b9206f916a33a09f63 100644 (file)
@@ -136,7 +136,7 @@ private:
                                                  //   edited mesh/sub-mesh
 
   // hypdata corresponding to hypotheses present in myDlg
-  THypDataList                   myAvailableHypData[3][NbHypTypes];
+  THypDataList                   myAvailableHypData[4][NbHypTypes];
 
   bool                           myIgnoreAlgoSelection;
 };
index 46c575dd2b0962290f06507cdcf9115797d7c633..8eb5e67cece16eaef81766b254d58472d5776c12 100644 (file)
@@ -82,6 +82,7 @@
 // IDL Headers
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
 
 #define MARGIN  10
 #define SPACING 5
@@ -178,11 +179,16 @@ QFrame* SMESHGUI_MoveNodesDlg::createMainFrame (QWidget* theParent)
   myId->setValidator(new SMESHGUI_IdValidator(this, "validator", 1));
 
   QGroupBox* aCoordGrp = new QGroupBox(1, Qt::Vertical, tr("SMESH_COORDINATES"), aFrame);
-  new QLabel(tr("SMESH_X"), aCoordGrp);
+  QLabel* aXLabel = new QLabel(tr("SMESH_X"), aCoordGrp);
+  aXLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
   myX = new SMESHGUI_SpinBox(aCoordGrp);
-  new QLabel(tr("SMESH_Y"), aCoordGrp);
+
+  QLabel* aYLabel = new QLabel(tr("SMESH_Y"), aCoordGrp);
+  aYLabel->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   myY = new SMESHGUI_SpinBox(aCoordGrp);
-  new QLabel(tr("SMESH_Z"), aCoordGrp);
+
+  QLabel* aZLabel = new QLabel(tr("SMESH_Z"), aCoordGrp);
+  aZLabel->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   myZ = new SMESHGUI_SpinBox(aCoordGrp);
 
   myX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 25.0, 3);
index 4842e4c7b5215edc5dd688e3b0c859eaa9a5022d..6a58a84890e742805ea2c45bbab0de7c64f0343b 100755 (executable)
@@ -38,6 +38,7 @@
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
 #include CORBA_SERVER_HEADER(SMESH_Filter)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
 
 class SMESHGUI;
 class SMESHGUI_FilterDlg;
index c76153065a1c4dcc7a00620dc9b52d49159d99a5..b89009898cd88a49bd08ff2f08c09a682757b83f 100644 (file)
@@ -89,6 +89,8 @@
 #include <qvalidator.h>
 #include <qevent.h>
 
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
 using namespace std;
 
 
@@ -309,13 +311,16 @@ SMESHGUI_NodesDlg::SMESHGUI_NodesDlg (SMESHGUI* theModule,
   GroupCoordinatesLayout->setSpacing(6);
   GroupCoordinatesLayout->setMargin(11);
   TextLabel_X = new QLabel(GroupCoordinates, "TextLabel_X");
+  TextLabel_X->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
   TextLabel_X->setText(tr("SMESH_X" ));
   GroupCoordinatesLayout->addWidget(TextLabel_X, 0, 0);
   TextLabel_Y = new QLabel(GroupCoordinates, "TextLabel_Y");
+  TextLabel_Y->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   TextLabel_Y->setText(tr("SMESH_Y" ));
   GroupCoordinatesLayout->addWidget(TextLabel_Y, 0, 2);
 
   TextLabel_Z = new QLabel(GroupCoordinates, "TextLabel_Z");
+  TextLabel_Z->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   TextLabel_Z->setText(tr("SMESH_Z" ));
   GroupCoordinatesLayout->addWidget(TextLabel_Z, 0, 4);
 
index a54ac738dac876fd5caf566c587929ac1c766ea2..d4636f4f2b62dcbc607951b4951ab101437e461a 100644 (file)
@@ -71,6 +71,8 @@
 
 using namespace std;
 
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
 //=================================================================================
 // class    : SMESHGUI_RemoveElementsDlg()
 // purpose  :
index c34fed723d1e8a3965c77855a47ea7f9532b138c..329d5db3bdc0851af610b6556393440a88364ccc 100644 (file)
@@ -71,6 +71,8 @@
 
 using namespace std;
 
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
 //=================================================================================
 // class    : SMESHGUI_RemoveNodesDlg()
 // purpose  :
index cc8c5013cb8ce7f339feda54c15247b8eab5fb01..17fe6f6a84d944589de4b59bcea2a72858d744cc 100644 (file)
@@ -59,6 +59,8 @@
 
 using namespace std;
 
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
 //=================================================================================
 // class    : SMESHGUI_RenumberingDlg()
 // purpose  :
index 53af86b9c955402dcee705fd1741e02aefb7a370..90b699a7fc228f0b4ad1cfec1c5287656c2a0548 100644 (file)
@@ -75,6 +75,7 @@
 // IDL Headers
 #include "SALOMEconfig.h"
 #include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
 
 using namespace std;
 
@@ -208,6 +209,7 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule, const char*
   GroupAxisLayout->addWidget(SelectPointButton, 0, 1);
 
   TextLabelX = new QLabel(GroupAxis, "TextLabelX");
+  TextLabelX->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   TextLabelX->setText(tr("SMESH_X"));
   GroupAxisLayout->addWidget(TextLabelX, 0, 2);
 
@@ -215,6 +217,7 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule, const char*
   GroupAxisLayout->addWidget(SpinBox_X, 0, 3);
 
   TextLabelY = new QLabel(GroupAxis, "TextLabelY");
+  TextLabelY->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   TextLabelY->setText(tr("SMESH_Y"));
   GroupAxisLayout->addWidget(TextLabelY, 0, 4);
 
@@ -222,6 +225,7 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule, const char*
   GroupAxisLayout->addWidget(SpinBox_Y, 0, 5);
 
   TextLabelZ = new QLabel(GroupAxis, "TextLabelZ");
+  TextLabelZ->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   TextLabelZ->setText(tr("SMESH_Z"));
   GroupAxisLayout->addWidget(TextLabelZ, 0, 6);
 
@@ -237,6 +241,7 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule, const char*
   GroupAxisLayout->addWidget(SelectVectorButton, 1, 1);
 
   TextLabelDX = new QLabel(GroupAxis, "TextLabelDX");
+  TextLabelDX->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   TextLabelDX->setText(tr("SMESH_DX"));
   GroupAxisLayout->addWidget(TextLabelDX, 1, 2);
 
@@ -244,6 +249,7 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule, const char*
   GroupAxisLayout->addWidget(SpinBox_DX, 1, 3);
 
   TextLabelDY = new QLabel(GroupAxis, "TextLabelDY");
+  TextLabelDY->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   TextLabelDY->setText(tr("SMESH_DY"));
   GroupAxisLayout->addWidget(TextLabelDY, 1, 4);
 
@@ -251,6 +257,7 @@ SMESHGUI_RevolutionDlg::SMESHGUI_RevolutionDlg( SMESHGUI* theModule, const char*
   GroupAxisLayout->addWidget(SpinBox_DY, 1, 5);
 
   TextLabelDZ = new QLabel(GroupAxis, "TextLabelDZ");
+  TextLabelDZ->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   TextLabelDZ->setText(tr("SMESH_DZ"));
   GroupAxisLayout->addWidget(TextLabelDZ, 1, 6);
 
@@ -698,7 +705,7 @@ void SMESHGUI_RevolutionDlg::SelectionIntoArgument()
         aNbUnits = anElementsIds->length();
       }
     } else {
-      aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, myActor->getIO(), aString);
+      aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
       myElementsId = aString;
     }
 
@@ -707,7 +714,7 @@ void SMESHGUI_RevolutionDlg::SelectionIntoArgument()
 
     myNbOkElements = true;
   } else {
-    aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aString);
+    aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
     if (aNbUnits != 1)
       return;
 
index 50fc56bcebdd5364063de41e86e9ad3149cb6454..e4f4a1d5bff18e638a79c044cf51ddabb5884927 100644 (file)
@@ -73,6 +73,7 @@
 // IDL Headers
 #include "SALOMEconfig.h"
 #include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
 
 using namespace std;
 
@@ -212,6 +213,7 @@ SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule, const char* nam
   GroupAxisLayout->addWidget(SelectPointButton, 0, 1);
 
   TextLabelX = new QLabel(GroupAxis, "TextLabelX");
+  TextLabelX->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   TextLabelX->setText(tr("SMESH_X"));
   GroupAxisLayout->addWidget(TextLabelX, 0, 2);
 
@@ -219,6 +221,7 @@ SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule, const char* nam
   GroupAxisLayout->addWidget(SpinBox_X, 0, 3);
 
   TextLabelY = new QLabel(GroupAxis, "TextLabelY");
+  TextLabelY->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   TextLabelY->setText(tr("SMESH_Y"));
   GroupAxisLayout->addWidget(TextLabelY, 0, 4);
 
@@ -226,6 +229,7 @@ SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule, const char* nam
   GroupAxisLayout->addWidget(SpinBox_Y, 0, 5);
 
   TextLabelZ = new QLabel(GroupAxis, "TextLabelZ");
+  TextLabelZ->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   TextLabelZ->setText(tr("SMESH_Z"));
   GroupAxisLayout->addWidget(TextLabelZ, 0, 6);
 
@@ -241,6 +245,7 @@ SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule, const char* nam
   GroupAxisLayout->addWidget(SelectVectorButton, 1, 1);
 
   TextLabelDX = new QLabel(GroupAxis, "TextLabelDX");
+  TextLabelDX->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   TextLabelDX->setText(tr("SMESH_DX"));
   GroupAxisLayout->addWidget(TextLabelDX, 1, 2);
 
@@ -248,6 +253,7 @@ SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule, const char* nam
   GroupAxisLayout->addWidget(SpinBox_DX, 1, 3);
 
   TextLabelDY = new QLabel(GroupAxis, "TextLabelDY");
+  TextLabelDY->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   TextLabelDY->setText(tr("SMESH_DY"));
   GroupAxisLayout->addWidget(TextLabelDY, 1, 4);
 
@@ -255,6 +261,7 @@ SMESHGUI_RotationDlg::SMESHGUI_RotationDlg( SMESHGUI* theModule, const char* nam
   GroupAxisLayout->addWidget(SpinBox_DY, 1, 5);
 
   TextLabelDZ = new QLabel(GroupAxis, "TextLabelDZ");
+  TextLabelDZ->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   TextLabelDZ->setText(tr("SMESH_DZ"));
   GroupAxisLayout->addWidget(TextLabelDZ, 1, 6);
 
@@ -628,7 +635,7 @@ void SMESHGUI_RotationDlg::SelectionIntoArgument()
         aNbUnits = anElementsIds->length();
       }
     } else {
-      aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, myActor->getIO(), aString);
+      aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
       myElementsId = aString;
     }
 
@@ -637,7 +644,7 @@ void SMESHGUI_RotationDlg::SelectionIntoArgument()
 
     myNbOkElements = true;
   } else {
-    aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aString);
+    aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
     if (aNbUnits != 1)
       return;
 
index db218de9a1c8ba528986fb756f2f25293ca58901..238e88a41d2a41676d34fdf7882ad19af95d4c3a 100644 (file)
@@ -31,6 +31,7 @@
 #include "SMESHGUI.h"
 #include "SMESHGUI_Utils.h"
 #include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_MeshUtils.h"
 #include "SMESHGUI_IdValidator.h"
 
 #include "SMESH_Actor.h"
 #include <qlayout.h>
 #include <qpixmap.h>
 
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
 using namespace std;
 
+
 //=================================================================================
 // class    : SMESHGUI_SewingDlg()
 // purpose  :
@@ -777,7 +781,7 @@ void SMESHGUI_SewingDlg::SelectionIntoArgument (bool isSelectionChanged)
     return;
 
   Handle(SALOME_InteractiveObject) IO = aList.First();
-  myMesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO);
+  myMesh = SMESH::GetMeshByIO(IO); //@ SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(IO);
   myActor = SMESH::FindActorByEntry(aList.First()->getEntry());
 
   if (myMesh->_is_nil() || !myActor)
@@ -788,11 +792,11 @@ void SMESHGUI_SewingDlg::SelectionIntoArgument (bool isSelectionChanged)
 
   if (GetConstructorId() != 3 ||
       (myEditCurrentArgument != LineEdit1 && myEditCurrentArgument != LineEdit4)) {
-    aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aString);
+    aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
     if (aNbUnits != 1)
       return;
   } else {
-    aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, myActor->getIO(), aString);
+    aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
     if (aNbUnits < 1)
       return;
   }
index bc0f7877965b48d3bb341789130d8dd9ac789729..51881af4282140a591d5109dd4ba967b1a5632c1 100644 (file)
@@ -146,10 +146,6 @@ SMESHGUI_ShapeByMeshDlg::~SMESHGUI_ShapeByMeshDlg()
 //================================================================================
 /*!
  * \brief Constructor
-  * \param theToCreate - if this parameter is true then operation is used for creation,
-  * for editing otherwise
- *
- * Initialize operation
 */
 //================================================================================
 SMESHGUI_ShapeByMeshOp::SMESHGUI_ShapeByMeshOp(bool isMultipleAllowed):
index 69d8dafc080ef8bd1725a96c9e032ccefe2955f8..222a38bbaafca611d8b3ee33ccd869d2895db0a5 100644 (file)
@@ -61,35 +61,22 @@ public:
 
 private:
 
-//   void                     closeEvent (QCloseEvent* e);
-//   void                     enterEvent (QEvent*);
-
-private:
-
-  //QFrame*                  createButtonFrame (QWidget*);
   QFrame*                  createMainFrame   (QWidget*);
-  //void                     displayPreview();
-  //void                     erasePreview();
-private:
 
   QButtonGroup*            myElemTypeGroup;
   QLineEdit*               myElementId;
   QLineEdit*               myGeomName;
 
-private:
   bool                     myIsMultipleAllowed;
   void                     setMultipleAllowed(bool isAllowed) {myIsMultipleAllowed = isAllowed;};
 
-//   QPushButton*             myOkBtn;
-//   QPushButton*             myCloseBtn;
-
-//   SMESHGUI*                mySMESHGUI;
-//   LightApp_SelectionMgr*   mySelectionMgr;
-//   SVTK_ViewWindow*         myViewWindow;
-
   friend class SMESHGUI_ShapeByMeshOp;
 };
 
+/*!
+ * \brief Operation to publish a sub-shape of the mesh main shape
+ *        by selecting mesh elements
+ */
 class SMESHGUI_ShapeByMeshOp: public SMESHGUI_SelectionOp
 {
   Q_OBJECT
@@ -109,35 +96,16 @@ protected:
 
   virtual void                   commitOperation();
   virtual void                   startOperation();
-  //virtual void                   selectionDone();
-  //virtual SUIT_SelectionFilter*  createFilter( const int ) const;
-  //virtual bool                   isValid( SUIT_Operation* ) const;
 
   void                     activateSelection();
   void                     setElementID(const QString&);
 
-/* signals: */
-
-/*   void                     PublishShape(); */
-/*   void                     Close(); */
-
 protected slots:
 
   virtual bool                   onApply() { return true; }
-/*   void                           onCreateHyp( const int theHypType, const int theIndex ); */
-/*   void                           onEditHyp( const int theHypType, const int theIndex ); */
-/*   void                           onHypoSet( const QString& theSetName ); */
-/*   void                           onGeomSelectionByMesh( bool ); */
-/*   void                           onPublishShapeByMeshDlg(); */
-/*   void                           onCloseShapeByMeshDlg(); */
 
 private slots:
 
-//   void                     onOk();
-//   void                     onClose();
-
-//   void                     onDeactivate();
-
   void                     onSelectionDone();
   void                     onTypeChanged (int);
   void                     onElemIdChanged (const QString&);
index 6fa5058ad44daa1fbf9329c77ef740f39289b25f..1faf1416cd3637fa7ab5dd122f757646f6b1de63 100755 (executable)
@@ -33,6 +33,7 @@
 
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
 
 class QCloseEvent;
 class QFrame;
index 6f5dc5fdc8695501f9f6054c9e1d56fe35048b7d..231dba97f7e98b4f1bfbdf1d6e3103c24e2a5c5f 100644 (file)
@@ -80,6 +80,7 @@
 // IDL Headers
 #include "SALOMEconfig.h"
 #include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
 
 using namespace std;
 
@@ -616,12 +617,12 @@ void SMESHGUI_SmoothingDlg::SelectionIntoArgument()
         aNbUnits = anElementsIds->length();
       }
     } else {
-      aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, myActor->getIO(), aString);
+      aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString);
       myElementsId = aString;
     }
   } else if (myEditCurrentArgument == LineEditNodes && !myMesh->_is_nil() && myActor) {
     myNbOkNodes = 0;
-    aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aString);
+    aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
   } else {
   }
 
index c1912cab2ad4e4c9c0a5c93c4f57cb85c63c1b40..fec084979966469eae52d41301a8133ccc11c300 100644 (file)
@@ -633,20 +633,23 @@ SMESH_Swig::SetName(const char* theEntry,
 //================================================================================
 
 void SMESH_Swig::SetMeshIcon(const char* theMeshEntry, 
-                            const bool theIsComputed)
+                            const bool theIsComputed,
+                             const bool isEmpty)
 {
   class TEvent: public SALOME_Event
   {
     SALOMEDS::Study_var myStudy;
     std::string myMeshEntry;
-    bool myIsComputed;
+    bool myIsComputed, myIsEmpty;
   public:
     TEvent(const SALOMEDS::Study_var& theStudy,
           const std::string& theMeshEntry,
-          const bool theIsComputed):
+          const bool theIsComputed,
+           const bool isEmpty):
       myStudy(theStudy),
       myMeshEntry(theMeshEntry),
-      myIsComputed(theIsComputed)
+      myIsComputed(theIsComputed),
+      myIsEmpty(isEmpty)
     {}
 
     virtual
@@ -656,11 +659,12 @@ void SMESH_Swig::SetMeshIcon(const char* theMeshEntry,
       SALOMEDS::SObject_var aMeshSO = myStudy->FindObjectID(myMeshEntry.c_str());
       if(!aMeshSO->_is_nil())
        if(_PTR(SObject) aMesh = ClientFactory::SObject(aMeshSO))
-         SMESH::ModifiedMesh(aMesh,myIsComputed);
+         SMESH::ModifiedMesh(aMesh,myIsComputed,myIsEmpty);
     }
   };
 
   ProcessVoidEvent(new TEvent(myStudy,
                              theMeshEntry,
-                             theIsComputed));
+                             theIsComputed,
+                              isEmpty));
 }
index 3b7e69e73859b3623809b41dbe0e73d382bdb8db..073f6902a03cf2450847972c2f57340958e05042 100644 (file)
@@ -68,7 +68,7 @@ public:
     * \param Mesh_Entry - entry of a mesh
     * \param isComputed - is mesh computed or not
    */
-  void SetMeshIcon(const char* Mesh_Entry, const bool isComputed);
+  void SetMeshIcon(const char* Mesh_Entry, const bool isComputed, const bool isEmpty);
 
 private:
   SALOMEDS::Study_var        myStudy;
index 1a7c393fa91fc7b6c2f2ca4621261ddefb878c87..67c00c06eab264369a824f6c0b9be41721141cd3 100644 (file)
@@ -73,7 +73,7 @@ class SMESH_Swig
 
   void SetName(const char* Entry, const char* Name);
 
-  void SetMeshIcon(const char* Mesh_Entry, const bool isComputed);
+  void SetMeshIcon(const char* Mesh_Entry, const bool isComputed, const bool isEmpty);
 
   void CreateAndDisplayActor( const char* Mesh_Entry );
 };
index 920fb06a9e3abd4d0ed93535d67a9f651089694e..357eb8f41384485bb14ad9f7637b3e5428122f4f 100644 (file)
@@ -74,6 +74,7 @@
 // IDL Headers
 #include "SALOMEconfig.h"
 #include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
 
 using namespace std;
 
@@ -218,6 +219,7 @@ SMESHGUI_SymmetryDlg::SMESHGUI_SymmetryDlg( SMESHGUI* theModule, const char* nam
   GroupMirrorLayout->addWidget(SelectPointButton, 0, 1);
 
   TextLabelX = new QLabel(GroupMirror, "TextLabelX");
+  TextLabelX->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   TextLabelX->setText(tr("SMESH_X"));
   GroupMirrorLayout->addWidget(TextLabelX, 0, 2);
 
@@ -225,6 +227,7 @@ SMESHGUI_SymmetryDlg::SMESHGUI_SymmetryDlg( SMESHGUI* theModule, const char* nam
   GroupMirrorLayout->addWidget(SpinBox_X, 0, 3);
 
   TextLabelY = new QLabel(GroupMirror, "TextLabelY");
+  TextLabelY->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   TextLabelY->setText(tr("SMESH_Y"));
   GroupMirrorLayout->addWidget(TextLabelY, 0, 4);
 
@@ -232,6 +235,7 @@ SMESHGUI_SymmetryDlg::SMESHGUI_SymmetryDlg( SMESHGUI* theModule, const char* nam
   GroupMirrorLayout->addWidget(SpinBox_Y, 0, 5);
 
   TextLabelZ = new QLabel(GroupMirror, "TextLabelZ");
+  TextLabelZ->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   TextLabelZ->setText(tr("SMESH_Z"));
   GroupMirrorLayout->addWidget(TextLabelZ, 0, 6);
 
@@ -693,7 +697,7 @@ void SMESHGUI_SymmetryDlg::SelectionIntoArgument()
         aNbUnits = anElementsIds->length();
       }
     } else {
-      aNbUnits = SMESH::GetNameOfSelectedElements( mySelector, myActor->getIO(), aString);
+      aNbUnits = SMESH::GetNameOfSelectedElements( mySelector, IO, aString);
       myElementsId = aString;
     }
 
@@ -702,7 +706,7 @@ void SMESHGUI_SymmetryDlg::SelectionIntoArgument()
 
     myNbOkElements = true;
   } else {
-    aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aString);
+    aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
     if (aNbUnits != 1)
       return;
 
index efaaa78fbff5ce17f982c540f2ddcda6230c1646..bf4fd6d9861277f742fa1606829a27d6dfa2e10e 100644 (file)
@@ -75,6 +75,7 @@
 // IDL Headers
 #include "SALOMEconfig.h"
 #include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
 
 using namespace std;
 
@@ -200,18 +201,21 @@ SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule, const cha
   GroupArgumentsLayout->addWidget(SelectButton1, 2, 1);
 
   TextLabel1_1 = new QLabel(GroupArguments, "TextLabel1_1");
+  TextLabel1_1->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   GroupArgumentsLayout->addWidget(TextLabel1_1, 2, 2);
 
   SpinBox1_1 = new SMESHGUI_SpinBox(GroupArguments, "SpinBox1_1");
   GroupArgumentsLayout->addWidget(SpinBox1_1, 2, 3);
 
   TextLabel1_2 = new QLabel(GroupArguments, "TextLabel1_2");
+  TextLabel1_2->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   GroupArgumentsLayout->addWidget(TextLabel1_2, 2, 4);
 
   SpinBox1_2 = new SMESHGUI_SpinBox(GroupArguments, "SpinBox1_2");
   GroupArgumentsLayout->addWidget(SpinBox1_2, 2, 5);
 
   TextLabel1_3 = new QLabel(GroupArguments, "TextLabel1_3");
+  TextLabel1_3->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   GroupArgumentsLayout->addWidget(TextLabel1_3, 2, 6);
 
   SpinBox1_3 = new SMESHGUI_SpinBox(GroupArguments, "SpinBox1_3");
@@ -228,6 +232,7 @@ SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule, const cha
   GroupArgumentsLayout->addWidget(SelectButton2, 3, 1);
 
   TextLabel2_1 = new QLabel(GroupArguments, "TextLabel2_1");
+  TextLabel2_1->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   TextLabel2_1->setText(tr("SMESH_X" ));
   GroupArgumentsLayout->addWidget(TextLabel2_1, 3, 2);
 
@@ -235,6 +240,7 @@ SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule, const cha
   GroupArgumentsLayout->addWidget(SpinBox2_1, 3, 3);
 
   TextLabel2_2 = new QLabel(GroupArguments, "TextLabel2_2");
+  TextLabel2_2->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   TextLabel2_2->setText(tr("SMESH_Y" ));
   GroupArgumentsLayout->addWidget(TextLabel2_2, 3, 4);
 
@@ -242,6 +248,7 @@ SMESHGUI_TranslationDlg::SMESHGUI_TranslationDlg( SMESHGUI* theModule, const cha
   GroupArgumentsLayout->addWidget(SpinBox2_2, 3, 5);
 
   TextLabel2_3 = new QLabel(GroupArguments, "TextLabel2_3");
+  TextLabel2_3->setAlignment( Qt::AlignRight | Qt::AlignVCenter | Qt::ExpandTabs );
   TextLabel2_3->setText(tr("SMESH_Z"));
   GroupArgumentsLayout->addWidget(TextLabel2_3, 3, 6);
 
@@ -664,7 +671,7 @@ void SMESHGUI_TranslationDlg::SelectionIntoArgument()
 
     myNbOkElements = true;
   } else {
-    aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aString);
+    aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString);
     if (aNbUnits != 1)
       return;
 
index 04ae86959a4fb1ccd5b536edd617dbd8cfea792b..6ef3fddaba7a997dc382efafca8821f0239269cd 100644 (file)
 #include <qstring.h>
 
 #include "SMESHGUI_Utils.h"
+#include "SMESHGUI.h"
 
 #include "OB_Browser.h"
 
 #include "SUIT_Desktop.h"
 #include "SUIT_Application.h"
 #include "SUIT_Session.h"
+#include "SUIT_MessageBox.h"
 
 #include "LightApp_SelectionMgr.h"
 #include "SalomeApp_Application.h"
@@ -252,7 +254,7 @@ namespace SMESH{
     return theSObject->GetFather();
   }
 
-  void ModifiedMesh (_PTR(SObject) theSObject, bool theIsRight)
+  void ModifiedMesh (_PTR(SObject) theSObject, bool theIsNotModif, bool isEmptyMesh)
   {
     _PTR(Study) aStudy = GetActiveStudyDocument();
     if (aStudy->GetProperties()->IsLocked())
@@ -262,10 +264,12 @@ namespace SMESH{
     _PTR(GenericAttribute) anAttr =
       aBuilder->FindOrCreateAttribute(theSObject,"AttributePixMap");
     _PTR(AttributePixMap) aPixmap = anAttr;
-    if (theIsRight) {
+    if (theIsNotModif) {
       aPixmap->SetPixMap("ICON_SMESH_TREE_MESH");
-    } else {
+    } else if ( isEmptyMesh ) {
       aPixmap->SetPixMap("ICON_SMESH_TREE_MESH_WARN");
+    } else {
+      aPixmap->SetPixMap("ICON_SMESH_TREE_MESH_PARTIAL");
     }
 
     _PTR(ChildIterator) anIter = aStudy->NewChildIterator(theSObject);
@@ -277,16 +281,34 @@ namespace SMESH{
          _PTR(SObject) aSObj1 = anIter1->Value();
          anAttr = aBuilder->FindOrCreateAttribute(aSObj1, "AttributePixMap");
          aPixmap = anAttr;
-         if (theIsRight) {
-           aPixmap->SetPixMap("ICON_SMESH_TREE_MESH");
-         } else {
-           aPixmap->SetPixMap("ICON_SMESH_TREE_MESH_WARN");
-         }
+          if (theIsNotModif) {
+            aPixmap->SetPixMap("ICON_SMESH_TREE_MESH");
+          } else if ( isEmptyMesh ) {
+            aPixmap->SetPixMap("ICON_SMESH_TREE_MESH_WARN");
+          } else {
+            aPixmap->SetPixMap("ICON_SMESH_TREE_MESH_PARTIAL");
+          }
        }
       }
     }
   }
 
+  void ShowHelpFile (QString theHelpFileName)
+  {
+    LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
+    if (app) {
+      SMESHGUI* gui = SMESHGUI::GetSMESHGUI();
+      app->onHelpContextModule(gui ? app->moduleName(gui->moduleName()) : QString(""),
+                               theHelpFileName);
+    }
+    else {
+      SUIT_MessageBox::warn1(0, QObject::tr("WRN_WARNING"),
+                             QObject::tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser", "application")).arg(theHelpFileName),
+                             QObject::tr("BUT_OK"));
+      }
+  }
+
 //  void UpdateObjBrowser (bool)
 //  {
 //    //SMESHGUI::activeStudy()->updateObjBrowser(true);
index d4c973f146edb80eb6f058b1ed5b16fe908f775d..690cd26335c6c4ce2ea3b6d7ee1330013984dc05 100644 (file)
@@ -146,9 +146,10 @@ SMESHGUI_EXPORT
   _PTR(SObject) GetMeshOrSubmesh (_PTR(SObject) theSObject);
 
 SMESHGUI_EXPORT
-  void ModifiedMesh (_PTR(SObject) theSObject, bool theIsRight);
+  void ModifiedMesh (_PTR(SObject) theSObject, bool theIsNot, bool isEmptyMesh=false);
 
-//  void UpdateObjBrowser (bool);
+SMESHGUI_EXPORT
+  void ShowHelpFile (QString theHelpFileName);
 }
 
 #endif
index 16eecc6966c619b774b44d4767a6d63af6624940..f924d19b77327e32f797d380dbc4123e81236f63 100644 (file)
 //  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
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 
 
 #include "SMESHGUI_VTKUtils.h"
 #include "SMESHGUI_Utils.h"
 #include "SMESHGUI_Filter.h"
 
-#include <vtkRenderer.h>
-#include <vtkActorCollection.h>
-
-#include <TColStd_IndexedMapOfInteger.hxx>
+#include "SMESHGUI.h"
+#include "SMESH_Actor.h"
+#include "SMESH_ObjectDef.h"
 
 #include <SUIT_Desktop.h>
 #include <SUIT_Session.h>
 #include <SUIT_Study.h>
 
-#include "LightApp_SelectionMgr.h"
+#include <SALOME_ListIO.hxx>
+#include <SALOME_ListIteratorOfListIO.hxx>
 
-#include "SVTK_Selector.h"
-#include "SVTK_ViewModel.h"
-#include "SVTK_ViewWindow.h"
+#include <SVTK_Selector.h>
+#include <SVTK_ViewModel.h>
+#include <SVTK_ViewWindow.h>
 
-#include "utilities.h"
+#include <LightApp_SelectionMgr.h>
+#include <SalomeApp_Application.h>
+#include <SalomeApp_Study.h>
+
+#include <utilities.h>
 
-#include "SALOMEconfig.h"
+#include <SALOMEconfig.h>
 #include CORBA_CLIENT_HEADER(SMESH_Gen)
 #include CORBA_CLIENT_HEADER(SMESH_Mesh)
 #include CORBA_CLIENT_HEADER(SMESH_Group)
 #include CORBA_CLIENT_HEADER(SMESH_Hypothesis)
 
-#include "SMESHGUI.h"
-#include "SMESH_Actor.h"
-#include "SMESH_ObjectDef.h"
-
-#include <SalomeApp_Application.h>
-#include <LightApp_SelectionMgr.h>
-#include <SalomeApp_Study.h>
-
 #include <SALOMEDSClient_Study.hxx>
 #include <SALOMEDSClient_SObject.hxx>
 
-#include <SALOME_ListIO.hxx>
-#include <SALOME_ListIteratorOfListIO.hxx>
+// VTK
+#include <vtkRenderer.h>
+#include <vtkActorCollection.h>
 
+// OCCT
+#include <TColStd_IndexedMapOfInteger.hxx>
+
+// STL
 #include <set>
 using namespace std;
 
-namespace SMESH{
+
+namespace SMESH {
 
   typedef map<TKeyOfVisualObj,TVisualObjPtr> TVisualObjCont;
   static TVisualObjCont VISUAL_OBJ_CONT;
@@ -75,7 +77,8 @@ namespace SMESH{
       if(anIter != VISUAL_OBJ_CONT.end()){
        aVisualObj = anIter->second;
       }else{
-        SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SMESHGUI::activeStudy()->application() );
+        SalomeApp_Application* app =
+          dynamic_cast<SalomeApp_Application*>( SMESHGUI::activeStudy()->application() );
        _PTR(Study) aStudy = SMESHGUI::activeStudy()->studyDS();
        _PTR(SObject) aSObj = aStudy->FindObjectID(theEntry);
        if(aSObj){
@@ -139,16 +142,41 @@ namespace SMESH{
   }
 
 
-  SVTK_ViewWindow*
-  GetViewWindow(const SalomeApp_Module* theModule)
+  /*! Return active view window, if it instantiates SVTK_ViewWindow class,
+   *  overwise find or create corresponding view window, make it active and return it.
+   *  \note Active VVTK_ViewWindow can be returned, because it inherits SVTK_ViewWindow.
+   */
+  SVTK_ViewWindow* GetViewWindow (const SalomeApp_Module* theModule,
+                                  bool createIfNotFound)
   {
-    if (SalomeApp_Application* anApp = theModule->getApp())
-      return dynamic_cast<SVTK_ViewWindow*>(anApp->desktop()->activeWindow());
+    SalomeApp_Application* anApp;
+    if (theModule)
+      anApp = theModule->getApp();
+    else
+      anApp = dynamic_cast<SalomeApp_Application*>
+        (SUIT_Session::session()->activeApplication());
+
+    if (anApp) {
+      if (SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(anApp->desktop()->activeWindow()))
+       return aView;
+
+      SUIT_ViewManager* aViewManager =
+        anApp->getViewManager(SVTK_Viewer::Type(), createIfNotFound);
+      if (aViewManager) {
+        if (SUIT_ViewWindow* aViewWindow = aViewManager->getActiveView()) {
+          if (SVTK_ViewWindow* aView = dynamic_cast<SVTK_ViewWindow*>(aViewWindow)) {
+            aViewWindow->raise();
+            aViewWindow->setFocus();
+            return aView;
+          }
+        }
+      }
+    }
     return NULL;
   }
 
-  SVTK_ViewWindow* FindVtkViewWindowSUIT_ViewManager* theMgr,
-                                          SUIT_ViewWindow* theWindow )
+  SVTK_ViewWindow* FindVtkViewWindow (SUIT_ViewManager* theMgr,
+                                      SUIT_ViewWindow * theWindow)
   {
     if( !theMgr )
       return NULL;
@@ -160,12 +188,10 @@ namespace SMESH{
       return NULL;
   }
 
-
   SVTK_ViewWindow* GetVtkViewWindow(SUIT_ViewWindow* theWindow){
     return dynamic_cast<SVTK_ViewWindow*>(theWindow);
   }
 
-
 /*  SUIT_ViewWindow* GetActiveWindow()
   {
     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
@@ -182,8 +208,19 @@ namespace SMESH{
     return GetVtkViewWindow( GetActiveWindow() );
   }
 
+
+  void RepaintCurrentView()
+  {
+    if (SVTK_ViewWindow* wnd = GetCurrentVtkView())
+      {
+       wnd->getRenderer()->Render();
+       wnd->Repaint(false);
+      }
+  }
+
   void RepaintViewWindow(SVTK_ViewWindow* theWindow)
   {
+    theWindow->getRenderer()->Render();
     theWindow->Repaint();
   }
 
@@ -193,6 +230,14 @@ namespace SMESH{
     theWindow->Repaint();
   }
 
+  void FitAll(){
+    if(SVTK_ViewWindow* wnd = GetCurrentVtkView() ){
+      wnd->onFitAll();
+      wnd->Repaint();
+    }
+  }
+
+
   SMESH_Actor* FindActorByEntry(SUIT_ViewWindow *theWindow,
                                const char* theEntry)
   {
@@ -286,27 +331,6 @@ namespace SMESH{
   }
 
 
-  void FitAll(){
-    if(SVTK_ViewWindow* wnd = GetCurrentVtkView() ){
-      wnd->onFitAll();
-      wnd->Repaint();
-    }
-  }
-
-  vtkRenderer* GetCurrentRenderer(){
-    if(SVTK_ViewWindow* wnd = GetCurrentVtkView() )
-      return wnd->getRenderer();
-    return NULL;
-  }
-
-  void RepaintCurrentView(){
-    if(SVTK_ViewWindow* wnd = GetCurrentVtkView() )
-      {
-       wnd->getRenderer()->Render();
-       wnd->Repaint(false);
-      }
-  }
-
   void UpdateView(SUIT_ViewWindow *theWnd, EDisplaing theAction, const char* theEntry)
   {
     if(SVTK_ViewWindow* aViewWnd = GetVtkViewWindow(theWnd)){
@@ -450,17 +474,17 @@ namespace SMESH{
       // update VTK viewer properties
       if(SVTK_ViewWindow* aVtkView = GetVtkViewWindow( views[i] )){
        // mesh element selection
-       aVtkView->SetSelectionProp(aSelColor.red()/255., 
+       aVtkView->SetSelectionProp(aSelColor.red()/255.,
                                   aSelColor.green()/255.,
-                                  aSelColor.blue()/255., 
+                                  aSelColor.blue()/255.,
                                   SW );
        // tolerances
        aVtkView->SetSelectionTolerance(SP1, SP2);
 
        // pre-selection
-       aVtkView->SetPreselectionProp(aPreColor.red()/255., 
+       aVtkView->SetPreselectionProp(aPreColor.red()/255.,
                                      aPreColor.green()/255.,
-                                     aPreColor.blue()/255., 
+                                     aPreColor.blue()/255.,
                                      PW);
        // update actors
        vtkRenderer* aRenderer = aVtkView->getRenderer();
@@ -468,10 +492,10 @@ namespace SMESH{
        aCollection->InitTraversal();
        while(vtkActor *anAct = aCollection->GetNextActor()){
          if(SMESH_Actor *anActor = dynamic_cast<SMESH_Actor*>(anAct)){
-           anActor->SetHighlightColor(aHiColor.red()/255., 
+           anActor->SetHighlightColor(aHiColor.red()/255.,
                                       aHiColor.green()/255.,
                                       aHiColor.blue()/255.);
-           anActor->SetPreHighlightColor(aPreColor.red()/255., 
+           anActor->SetPreHighlightColor(aPreColor.red()/255.,
                                          aPreColor.green()/255.,
                                          aPreColor.blue()/255.);
          }
@@ -482,7 +506,7 @@ namespace SMESH{
 
 
   //----------------------------------------------------------------------------
-  SVTK_Selector* 
+  SVTK_Selector*
   GetSelector(SUIT_ViewWindow *theWindow)
   {
     if(SVTK_ViewWindow* aWnd = GetVtkViewWindow(theWindow))
index 74b383c71683079e89c5b74d55ee51c0d2cd7228..b46c3f19d2090b10a55cbe096e5f2815e292f31f 100644 (file)
 //  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
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 
 #ifndef SMESHGUI_VTKUtils_HeaderFile
 #define SMESHGUI_VTKUtils_HeaderFile
 
 #include "SMESH_SMESHGUI.hxx"
 
-class QString;
-class vtkRenderer;
-class TColStd_IndexedMapOfInteger;
-
 #include "SALOMEDSClient_definitions.hxx"
 #include "SALOME_InteractiveObject.hxx"
 #include "VTKViewer_Filter.h"
 
+#include "SMESH_Object.h"
+#include "SMESHGUI_Utils.h"
+
+#include <CORBA.h>
+
+#include "SALOMEconfig.h"
+#include CORBA_CLIENT_HEADER(SALOMEDS)
+
+#include <boost/shared_ptr.hpp>
+
+class QString;
+
+class TColStd_IndexedMapOfInteger;
+
 class SALOMEDSClient_Study;
 
 class SUIT_Study;
@@ -40,22 +50,13 @@ class SVTK_ViewWindow;
 class SVTK_Selector;
 
 class LightApp_SelectionMgr;
-class SMESHGUI;
-
-#include <omniORB4/CORBA.h>
-
-#include "SALOMEconfig.h"
-#include CORBA_CLIENT_HEADER(SALOMEDS)
-
-#include <boost/shared_ptr.hpp>
-#include "SMESH_Object.h"
+class SalomeApp_Module;
 
+class SMESHGUI;
 class SMESH_Actor;
 class SALOME_Actor;
-class SVTK_ViewWindow;
-class SalomeApp_Module;
 
-namespace SMESH{
+namespace SMESH {
 
   //----------------------------------------------------------------------------
   typedef pair<int,string> TKeyOfVisualObj;
@@ -66,25 +67,25 @@ SMESHGUI_EXPORT
 
   //----------------------------------------------------------------------------
 SMESHGUI_EXPORT
-  SVTK_ViewWindow* GetViewWindow(const SalomeApp_Module* theModule);
-
-SMESHGUI_EXPORT
-  SUIT_ViewWindow* GetActiveWindow();
-
+  SVTK_ViewWindow* GetViewWindow(const SalomeApp_Module* theModule = NULL,
+                                bool createIfNotFound = false);
 SMESHGUI_EXPORT
-  SVTK_ViewWindow* FindVtkViewWindow( SUIT_ViewManager*,
-                                     SUIT_ViewWindow* );
-
+  SVTK_ViewWindow* FindVtkViewWindow(SUIT_ViewManager*, SUIT_ViewWindow*);
 SMESHGUI_EXPORT
-  SVTK_ViewWindow* GetVtkViewWindow( SUIT_ViewWindow* );
+  SVTK_ViewWindow* GetVtkViewWindow(SUIT_ViewWindow*);
 
 SMESHGUI_EXPORT
   SVTK_ViewWindow* GetCurrentVtkView();
 
+  //----------------------------------------------------------------------------
+SMESHGUI_EXPORT
+  void RepaintCurrentView();
 SMESHGUI_EXPORT
   void RepaintViewWindow(SVTK_ViewWindow*);
 SMESHGUI_EXPORT
   void RenderViewWindow(SVTK_ViewWindow*);
+SMESHGUI_EXPORT
+  void FitAll();
 
   //----------------------------------------------------------------------------
 SMESHGUI_EXPORT
@@ -106,11 +107,11 @@ SMESHGUI_EXPORT
   //----------------------------------------------------------------------------
   enum EDisplaing {eDisplayAll, eDisplay, eDisplayOnly, eErase, eEraseAll};
 SMESHGUI_EXPORT
-  void UpdateView (SUIT_ViewWindow*, 
-                  EDisplaing theAction, 
-                  const char* theEntry = "");
-SMESHGUI_EXPORT
-  void UpdateView (EDisplaing theAction, 
+  void UpdateView (SUIT_ViewWindow*,
+                  EDisplaing theAction,
+                  const char* theEntry = "" );
+SMESHGUI_EXPORT                   
+  void UpdateView (EDisplaing theAction,
                   const char* theEntry = "");
 
 SMESHGUI_EXPORT
@@ -122,18 +123,7 @@ SMESHGUI_EXPORT
 
 
   //----------------------------------------------------------------------------
-SMESHGUI_EXPORT
-  void FitAll();
-
-SMESHGUI_EXPORT
-  void RepaintCurrentView();
-
-SMESHGUI_EXPORT
-  vtkRenderer* GetCurrentRenderer();
-
-
-  //----------------------------------------------------------------------------
-SMESHGUI_EXPORT
+SMESHGUI_EXPORT  
   void SetPointRepresentation(bool theIsVisible);
 
 SMESHGUI_EXPORT
@@ -145,24 +135,17 @@ SMESHGUI_EXPORT
 
   //----------------------------------------------------------------------------
 SMESHGUI_EXPORT
-  SVTK_Selector* 
-    GetSelector(SUIT_ViewWindow* = GetActiveWindow());
+  SVTK_Selector* GetSelector (SUIT_ViewWindow* = GetActiveWindow());
 
 SMESHGUI_EXPORT
   void SetFilter (const Handle(VTKViewer_Filter)& theFilter,
                  SVTK_Selector* theSelector = GetSelector());
-
 SMESHGUI_EXPORT
-  Handle(VTKViewer_Filter) 
-    GetFilter (int theId, SVTK_Selector* theSelector = GetSelector());
-
+  Handle(VTKViewer_Filter) GetFilter (int theId, SVTK_Selector* theSelector = GetSelector());
 SMESHGUI_EXPORT
-  bool IsFilterPresent (int theId, 
-                       SVTK_Selector* theSelector = GetSelector());
-
+  bool IsFilterPresent (int theId, SVTK_Selector* theSelector = GetSelector());
 SMESHGUI_EXPORT
-  void RemoveFilter (int theId, 
-                    SVTK_Selector* theSelector = GetSelector());
+  void RemoveFilter (int theId, SVTK_Selector* theSelector = GetSelector());
 
 SMESHGUI_EXPORT
   void RemoveFilters (SVTK_Selector* theSelector = GetSelector());
@@ -172,44 +155,38 @@ SMESHGUI_EXPORT
                SVTK_Selector* theSelector = GetSelector());
 
   //----------------------------------------------------------------------------
-SMESHGUI_EXPORT
-  int GetNameOfSelectedNodes(SVTK_Selector* theSelector, 
-                            const Handle(SALOME_InteractiveObject)& theIO, 
+SMESHGUI_EXPORT  
+  int GetNameOfSelectedNodes(SVTK_Selector* theSelector,
+                            const Handle(SALOME_InteractiveObject)& theIO,
                             QString& theName);
-  
 SMESHGUI_EXPORT
-  int GetNameOfSelectedElements(SVTK_Selector* theSelector, 
-                               const Handle(SALOME_InteractiveObject)& theIO, 
+  int GetNameOfSelectedElements(SVTK_Selector* theSelector,
+                               const Handle(SALOME_InteractiveObject)& theIO,
                                QString& theName);
-  
 SMESHGUI_EXPORT
-  int GetEdgeNodes(SVTK_Selector* theSelector, 
+  int GetEdgeNodes(SVTK_Selector* theSelector,
                   const TVisualObjPtr& theVisualObj,
-                  int& theId1, 
+                  int& theId1,
                   int& theId2);
 
   //----------------------------------------------------------------------------
-SMESHGUI_EXPORT
-  int GetNameOfSelectedNodes (LightApp_SelectionMgr*, 
-                             const Handle(SALOME_InteractiveObject)& theIO, 
+SMESHGUI_EXPORT  
+  int GetNameOfSelectedNodes (LightApp_SelectionMgr*,
+                             const Handle(SALOME_InteractiveObject)& theIO,
                              QString& theName);
-
 SMESHGUI_EXPORT
-  int GetNameOfSelectedNodes (LightApp_SelectionMgr*, 
+  int GetNameOfSelectedNodes (LightApp_SelectionMgr*,
                              QString& aName);
-
 SMESHGUI_EXPORT
-  int GetNameOfSelectedElements (LightApp_SelectionMgr*, 
-                                const Handle(SALOME_InteractiveObject)& theIO, 
+  int GetNameOfSelectedElements (LightApp_SelectionMgr*,
+                                const Handle(SALOME_InteractiveObject)& theIO,
                                 QString& theName);
-
 SMESHGUI_EXPORT
-  int GetNameOfSelectedElements (LightApp_SelectionMgr*, 
+  int GetNameOfSelectedElements (LightApp_SelectionMgr*,
                                 QString& aName);
-
 SMESHGUI_EXPORT
-  int GetSelected (LightApp_SelectionMgr*, 
-                  TColStd_IndexedMapOfInteger& theMap, 
+  int GetSelected (LightApp_SelectionMgr*,
+                  TColStd_IndexedMapOfInteger& theMap,
                   const bool theIsElement = true );
 
 SMESHGUI_EXPORT
index 2c6065cee7b7d1bfebd53d9bdedf179a7d378f03..e1ade098004bfed4432e9938997cbf2dd44c2cb1 100644 (file)
@@ -141,7 +141,7 @@ bool SMESHGUI_XmlHandler::startElement (const QString&, const QString&,
       {
         int aVal = (*anIter).toInt( &isOk );
         if ( isOk )
-          aDim.append( aVal - 1 );
+          aDim.append( aVal );
       }
 
       // for algo
@@ -156,18 +156,18 @@ bool SMESHGUI_XmlHandler::startElement (const QString&, const QString&,
         }
       }
       
-      HypothesisData* aHypLibNames =
+      HypothesisData* aHypData =
         new HypothesisData (aHypAlType, myPluginName, myServerLib, myClientLib,
                             aLabel, anIcon, aDim, isAux,
                             attr[ HYPOS ], attr[ OPT_HYPOS ], attr[ INPUT ], attr[ OUTPUT ]);
 
       if (qName == "algorithm")
       {
-        myAlgorithmsMap[(char*)aHypAlType.latin1()] = aHypLibNames;
+        myAlgorithmsMap[(char*)aHypAlType.latin1()] = aHypData;
       }
       else
       {
-        myHypothesesMap[(char*)aHypAlType.latin1()] = aHypLibNames;
+        myHypothesesMap[(char*)aHypAlType.latin1()] = aHypData;
       }
     }
   }
index 19f58fbecd273a2e6f734617e1892528a96cf43f..a9980d0cf8ca87ee2a35c31764aa67fbac45a362 100644 (file)
@@ -53,6 +53,10 @@ msgstr "mesh_add_sub.png"
 msgid "ICON_DLG_MOVE_NODE"
 msgstr "mesh_move_node.png"
 
+#Mesh to pass through point
+msgid "ICON_DLG_MESH_THROU_POINT"
+msgstr "mesh_node_to_point.png"
+
 #Remove Node
 msgid "ICON_DLG_REM_NODE"
 msgstr "mesh_rem_node.png"
@@ -133,6 +137,10 @@ msgstr "mesh_merge_nodes.png"
 msgid "ICON_DLG_MERGE_ELEMENTS"
 msgstr "mesh_merge_elements.png"
 
+#Build compound
+msgid "ICON_DLG_BUILD_COMPOUND_MESH"
+msgstr "mesh_build_compound.png"
+
 #-----------------------------------------------------------
 # Hypothesis
 #-----------------------------------------------------------
@@ -226,6 +234,10 @@ msgstr "mesh_quad_hexahedron.png"
 msgid "ICON_SMESH_TREE_MESH"
 msgstr "mesh_tree_mesh.png"    
 
+#mesh_tree_mesh
+msgid "ICON_SMESH_TREE_MESH_PARTIAL"
+msgstr "mesh_tree_mesh_partial.png"    
+
 #mesh_tree_group
 msgid "ICON_SMESH_TREE_GROUP"
 msgstr "mesh_tree_group.png"   
@@ -289,6 +301,9 @@ msgstr "delete.png"
 msgid "ICON_COMPUTE"
 msgstr "mesh_compute.png"
 
+msgid "ICON_BUILD_COMPOUND"
+msgstr "mesh_build_compound.png"
+
 msgid "ICON_UNION"
 msgstr "mesh_unionGroups.png"
 
@@ -389,4 +404,4 @@ msgid "ICON_FILE_OPEN"
 msgstr "open.png"
 
 msgid "ICON_CONV_TO_QUAD"
-msgstr "mesh_conv_to_quad.png"
\ No newline at end of file
+msgstr "mesh_conv_to_quad.png"
index 8aecfe085737dd88cd1699b2ddb558003f0735b9..4ef2f345a78f1c6e4d7311b9e588756ef87e8935 100644 (file)
@@ -1,3 +1,18 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Free Software Foundation, Inc.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"PO-Revision-Date: 2007-01-19 10:44+0300\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
 #  Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 #  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 #
@@ -23,7 +38,7 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
-"PO-Revision-Date: 2006-01-13 13:50+0300\n"
+"PO-Revision-Date: 2006-12-28 12:10+0300\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
 "MIME-Version: 1.0\n"
@@ -145,6 +160,10 @@ msgstr "Missing parameters"
 msgid "SMESH_WRN_COMPUTE_FAILED"
 msgstr "Mesh computation failed"
 
+#Compute failed
+msgid "SMESH_COMPUTE_SUCCEED"
+msgstr "Mesh computation succeed"
+
 #Study frame with VTK Viewer must be activated
 msgid "SMESH_WRN_VIEWER_VTK"
 msgstr "Study frame with VTK Viewer must be activated"
@@ -756,7 +775,7 @@ msgid "SMESH_MERGE_NODES"
 msgstr "Merge nodes"
 
 #Merge elements
-msgid "SMESH_MERGE_ELEMENTS_TITLE"
+msgid "SMESH_MERGE_ELEMENTS"
 msgstr "Merge elements"
 
 #Extrusion
@@ -775,6 +794,10 @@ msgstr "Create a copy"
 msgid "SMESH_ROTATION"
 msgstr "Rotation"
 
+#Build compound
+msgid "SMESH_BUILD_COMPOUND_TITLE"
+msgstr "Create a Compound"
+
 # -------------- Mesh Infos --------------
 
 #Mesh Infos
@@ -1139,6 +1162,9 @@ msgstr "Belong to Plane"
 msgid "SMESHGUI_FilterTable::BELONG_TO_CYLINDER"
 msgstr "Belong to Cylinder"
 
+msgid "SMESHGUI_FilterTable::BELONG_TO_GENSURFACE"
+msgstr "Belong to Surface"
+
 msgid "SMESHGUI_FilterTable::LYING_ON_GEOM"
 msgstr "Lying on Geom"
 
@@ -1246,6 +1272,8 @@ msgstr "Can not unassign \"%1\":\n"
 msgid "SMESH_RM_HYP_WRN"
 msgstr "\"%1\" unassigned but:\n"
 
+# Hypothesis_Status:
+
 msgid "SMESH_HYP_1"
 msgstr "Algorithm misses a hypothesis"
 
@@ -1256,36 +1284,48 @@ msgid "SMESH_HYP_3"
 msgstr "Hypothesis has a bad parameter value"
 
 msgid "SMESH_HYP_4"
-msgstr "Unknown fatal error at hypothesis definition"
+msgstr "Algorithm is hidden by an algorithm of upper dimension generating all-dimensions elements"
 
 msgid "SMESH_HYP_5"
-msgstr "Hypothesis is not suitable in the current context"
+msgstr "Algorithm hides algorithm(s) of lower dimension by generating all-dimensions elements"
 
 msgid "SMESH_HYP_6"
-msgstr "Non-conform mesh is produced using applied hypotheses"
+msgstr "Unknown fatal error at hypothesis definition"
 
 msgid "SMESH_HYP_7"
-msgstr "Such dimention hypothesis is already assigned to the shape"
+msgstr "Hypothesis is not suitable in the current context"
 
 msgid "SMESH_HYP_8"
-msgstr "Hypothesis and submesh dimensions mismatch"
+msgstr "Non-conform mesh is produced using applied hypotheses"
 
 msgid "SMESH_HYP_9"
-msgstr "Shape is neither the main one, nor its subshape, nor a valid group"
+msgstr "Such dimention hypothesis is already assigned to the shape"
 
 msgid "SMESH_HYP_10"
+msgstr "Hypothesis and submesh dimensions mismatch"
+
+msgid "SMESH_HYP_11"
+msgstr "Shape is neither the main one, nor its subshape, nor a valid group"
+
+msgid "SMESH_HYP_12"
 msgstr "Geomerty mismatches algorithm's expectation"
 
-msgid "MISSING_ALGO"
+# SMESHGUI_HypothesesUtils::GetMessageOnAlgoStateErrors()
+# %1 - algo name
+# %2 - dimension
+# %3 - global/local
+# %4 - hypothesis dim == algoDim
+
+msgid "STATE_ALGO_MISSING"
 msgstr "%3 %2D algorithm is missing"
 
-msgid "MISSING_HYPO"
+msgid "STATE_HYP_MISSING"
 msgstr "%3 %2D algorithm \"%1\" misses %4D hypothesis"
 
-msgid "BAD_PARAM_VALUE"
+msgid "STATE_HYP_BAD_PARAMETER"
 msgstr "Hypothesis of %3 %2D algorithm \"%1\" has a bad parameter value"
 
-msgid "NOT_CONFORM_MESH"
+msgid "STATE_HYP_NOTCONFORM"
 msgstr "%3 %2D algorithm \"%1\" would produce not conform mesh: global \"Not Conform Mesh Allowed\" hypotesis is missing"
 
 msgid "GLOBAL_ALGO"
@@ -1317,6 +1357,13 @@ msgid "SMESH_EXPORT_UNV"
 msgstr "During export mesh with name - \"%1\" to UNV\n"
        "       pyramid's elements will be missed"
 
+msgid "SMESH_EXPORT_STL1"
+msgstr "Mesh  - \"%1\" does not contain triangles"
+
+msgid "SMESH_EXPORT_STL2"
+msgstr "Mesh  - \"%1\" contains another than triangles elements,"
+       "     they are ignored during writing to STL"
+
 msgid "SMESH_EXPORT_MED_DUPLICATED_GRP"
 msgstr "There are duplicated group names in mesh \"%1\".\n"
        "You can cancel exporting and rename them,\n"
@@ -1483,7 +1530,7 @@ msgstr "Maximum bending angle"
 msgid "SMESHGUI_CuttingOfQuadsDlg::CAPTION"
 msgstr "Cutting of quadrangles"
 
-msgid "SMESHGUI_CuttingOfQuadsDlg::PREVIEW"
+msgid "PREVIEW"
 msgstr "Preview"
 
 #----------------------------------------------------
@@ -1491,7 +1538,7 @@ msgstr "Preview"
 msgid "SMESHGUI_MoveNodesDlg::CAPTION"
 msgstr "Move node"
 
-msgid "SMESHGUI_MoveNodesDlg::NODE_ID"
+msgid "NODE_ID"
 msgstr "Node ID"
 
 msgid "SMESHGUI_MoveNodesDlg::NODE_ID_IS_NOT_DEFINED"
@@ -1499,6 +1546,38 @@ msgstr "Node ID is not defined"
 
 #----------------------------------------------------
 
+msgid "SMESHGUI_MakeNodeAtPointDlg::CAPTION"
+msgstr "Mesh to pass through a point"
+
+msgid "SMESHGUI_MakeNodeAtPointDlg::MESH_PASS_THROUGH_POINT"
+msgstr "Make a node at point"
+
+msgid "SMESHGUI_MakeNodeAtPointDlg::METHOD"
+msgstr "Method"
+
+msgid "SMESHGUI_MakeNodeAtPointDlg::MOVE_EXISTING_METHOD"
+msgstr "Move a node"
+
+msgid "SMESHGUI_MakeNodeAtPointDlg::CREATE_NEW_METHOD"
+msgstr "Create a node"
+
+msgid "SMESHGUI_MakeNodeAtPointDlg::NODE_2MOVE"
+msgstr "Node to move"
+
+msgid "SMESHGUI_MakeNodeAtPointDlg::NODE_2MOVE_ID"
+msgstr "ID"
+
+msgid "SMESHGUI_MakeNodeAtPointDlg::AUTO_SEARCH"
+msgstr "Automatic search"
+
+msgid "SMESHGUI_MakeNodeAtPointOp::INVALID_ID"
+msgstr "Node ID is invalid"
+
+msgid "SMESHGUI_MakeNodeAtPointOp::INVALID_MESH"
+msgstr "Mesh to modify not selected"
+
+#----------------------------------------------------
+
 msgid "SMESHGUI_DeleteGroupDlg::CAPTION"
 msgstr "Delete groups with contents"
 
@@ -1696,6 +1775,9 @@ msgstr "Start node"
 msgid "SMESHGUI_ExtrusionAlongPathDlg::SMESH_USE_ANGLES"
 msgstr "Use Angles"
 
+msgid "SMESHGUI_ExtrusionAlongPathDlg::LINEAR_ANGLES"
+msgstr "Linear variation of the angles"
+
 msgid "SMESHGUI_ExtrusionAlongPathDlg::SMESH_ANGLES"
 msgstr "Rotation Angles"
 
@@ -1734,23 +1816,36 @@ msgstr "Revolution of 1D elements"
 msgid "SMESHGUI_RevolutionDlg::REVOLUTION_2D"
 msgstr "Revolution of 2D elements"
 
+msgid "SMESHGUI_RevolutionDlg::ANGLE_BY_STEP"
+msgstr "Use Angle by Step"
+
+msgid "SMESHGUI_RevolutionDlg::TOTAL_ANGLE"
+msgstr "Use Total Angle"
+
+msgid "SMESHGUI_RevolutionDlg::PREVIEW"
+msgstr "Preview"
+
 #----------------------------------------------------
 
 #Coincident nodes
-msgid "SMESHGUI_MergeNodesDlg::COINCIDENT_NODES"
+msgid "SMESHGUI_EditMeshDlg::COINCIDENT_NODES"
 msgstr "Coincident nodes"
 
+#Coincident elements
+msgid "SMESHGUI_EditMeshDlg::COINCIDENT_ELEMENTS"
+msgstr "Coincident elements"
+
 #Detect
-msgid "SMESHGUI_MergeNodesDlg::DETECT"
+msgid "SMESHGUI_EditMeshDlg::DETECT"
 msgstr "Detect"
 
 #Select all
-msgid "SMESHGUI_MergeNodesDlg::SELECT_ALL"
+msgid "SMESHGUI_EditMeshDlg::SELECT_ALL"
 msgstr "Select all"
 
-# Edit group of nodes
-msgid "SMESHGUI_MergeNodesDlg::EDIT_GROUP_OF_NODES"
-msgstr "Edit group of nodes"
+# Edit selected group
+msgid "SMESHGUI_EditMeshDlg::EDIT_SELECTED_GROUP"
+msgstr "Edit selected group"
 
 #----------------------------------------------------
 
@@ -2033,6 +2128,9 @@ msgstr "UNV file"
 msgid "MEN_MED"
 msgstr "MED file"
 
+msgid "MEN_STL"
+msgstr "STL file"
+
 msgid "MEN_EXPORT_DAT"
 msgstr "Export to DAT file"
 
@@ -2042,6 +2140,9 @@ msgstr "Export to UNV file"
 msgid "MEN_EXPORT_MED"
 msgstr "Export to MED file"
 
+msgid "MEN_EXPORT_STL"
+msgstr "Export to STL file"
+
 msgid "MEN_DELETE"
 msgstr "Delete"
 
@@ -2060,6 +2161,9 @@ msgstr "Compute"
 msgid "MEN_CREATE_SUBMESH"
 msgstr "Create Sub-mesh"
 
+msgid "MEN_BUILD_COMPOUND"
+msgstr "Build Compound"
+
 msgid "MEN_GLOBAL_HYPO"
 msgstr "Global Hypothesis"
 
@@ -2219,6 +2323,9 @@ msgstr "Merge elements"
 msgid "MEN_MOVE"
 msgstr "Move Node"
 
+msgid "MEN_MESH_THROU_POINT"
+msgstr "Mesh to pass through a point"
+
 msgid "MEN_INV"
 msgstr "Diagonal Inversion"
 
@@ -2398,6 +2505,9 @@ msgstr "Export to UNV file"
 msgid "TOP_EXPORT_MED"
 msgstr "Export to MED file"
 
+msgid "TOP_EXPORT_STL"
+msgstr "Export to STL file"
+
 msgid "TOP_DELETE"
 msgstr "Delete"
 
@@ -2416,6 +2526,9 @@ msgstr "Compute"
 msgid "TOP_CREATE_SUBMESH"
 msgstr "Create Sub-mesh"
 
+msgid "TOP_BUILD_COMPOUND"
+msgstr "Build Compound Mesh"
+
 msgid "TOP_GLOBAL_HYPO"
 msgstr "Global Hypothesis"
 
@@ -2572,6 +2685,9 @@ msgstr "Merge elements"
 msgid "TOP_MOVE"
 msgstr "Move Node"
 
+msgid "TOP_MESH_THROU_POINT"
+msgstr "Mesh to pass through a point"
+
 msgid "TOP_INV"
 msgstr "Diagonal Inversion"
 
@@ -2702,6 +2818,9 @@ msgstr "Export to UNV file"
 msgid "STB_EXPORT_MED"
 msgstr "Export to MED file"
 
+msgid "STB_EXPORT_STL"
+msgstr "Export to STL file"
+
 msgid "STB_DELETE"
 msgstr "Delete"
 
@@ -2720,6 +2839,9 @@ msgstr "Compute"
 msgid "STB_CREATE_SUBMESH"
 msgstr "Create Sub-mesh"
 
+msgid "STB_BUILD_COMPOUND"
+msgstr "Build Compound Mesh"
+
 msgid "STB_GLOBAL_HYPO"
 msgstr "Global Hypothesis"
 
@@ -2876,6 +2998,9 @@ msgstr "Merge elements"
 msgid "STB_MOVE"
 msgstr "Move Node"
 
+msgid "STB_MESH_THROU_POINT"
+msgstr "Mesh to pass through a point"
+
 msgid "STB_INV"
 msgstr "Diagonal Inversion"
 
@@ -3103,8 +3228,14 @@ msgstr "Display mode"
 msgid "SMESHGUI::PREF_AUTO_GROUPS"
 msgstr "Automatically create groups for MED export"
 
+msgid "SMESHGUI::PREF_RENUMBER" 
+msgstr "Automatic renumbering"
+
 #-----------------------------------------------------------
 
+msgid "SMESHGUI_MeshDlg::DIM_0D"
+msgstr "0D"
+
 msgid "SMESHGUI_MeshDlg::DIM_1D"
 msgstr "1D"
 
@@ -3134,6 +3265,31 @@ msgstr "Edit mesh/sub-mesh"
 
 msgid "SMESHGUI_MeshDlg::HYPOTHESES_SETS"
 msgstr "Assign a set of hypotheses"
+#-----------------------------------------------------------
+
+msgid "SMESHGUI_BuildCompoundDlg::COMPOUND"
+msgstr "Compound"
+
+msgid "SMESHGUI_BuildCompoundDlg::RESULT_NAME"
+msgstr "Result name"
+
+msgid "SMESHGUI_BuildCompoundDlg::COMPOUND_MESH"
+msgstr "Compound_Mesh"
+
+msgid "SMESHGUI_BuildCompoundDlg::MESHES"
+msgstr "Meshes"
+
+msgid "SMESHGUI_BuildCompoundDlg::PROCESSING_IDENTICAL_GROUPS"
+msgstr "Processing identical groups"
+
+msgid "SMESHGUI_BuildCompoundDlg::UNITE"
+msgstr "Unite"
+
+msgid "SMESHGUI_BuildCompoundDlg::RENAME"
+msgstr "Rename"
+
+msgid "SMESHGUI_BuildCompoundDlg::MERGE_NODES_AND_ELEMENTS"
+msgstr "Merge coincident nodes and elements"
 
 #-----------------------------------------------------------
 
@@ -3233,3 +3389,59 @@ msgstr "Mesh is not selected\nPlease specify it and try again"
 
 msgid "SMESHGUI_ConvToQuadOp::REF_IS_NULL"
 msgstr "No valid mesh object selected"
+
+#-----------------------------------------------------------
+
+msgid "SMESHGUI_ComputeDlg::CAPTION"
+msgstr "Compute mesh failed"
+
+msgid "SMESHGUI_ComputeDlg::CONSTRUCTOR"
+msgstr "Compute mesh"
+
+msgid "SMESHGUI_ComputeDlg::ERRORS"
+msgstr "Errors"
+
+msgid "SMESHGUI_ComputeDlg::SHOW_SHAPE"
+msgstr "Show SubShape"
+
+msgid "SMESHGUI_ComputeDlg::PUBLISH_SHAPE"
+msgstr "Publish SubShape"
+
+msgid "COMPERR_OK"
+msgstr "No errors"
+
+msgid "COMPERR_BAD_INPUT_MESH"
+msgstr "Invalid input mesh"
+
+msgid "COMPERR_STD_EXCEPTION"
+msgstr "std::exception"
+
+msgid "COMPERR_OCC_EXCEPTION"
+msgstr "OCC exception"
+
+msgid "COMPERR_SLM_EXCEPTION"
+msgstr "SALOME exception"
+
+msgid "COMPERR_EXCEPTION"
+msgstr "Unknown exception"
+
+msgid "COMPERR_MEMORY_PB"
+msgstr "Memory allocation problem"
+
+msgid "COMPERR_ALGO_FAILED"
+msgstr "Algorithm failed"
+
+msgid "COMPERR_BAD_SHAPE"
+msgstr "Unexpected geometry"
+
+msgid "COL_ALGO_HEADER"
+msgstr "Algorithm"
+
+msgid "COL_SHAPE_HEADER"
+msgstr "SubShape"
+
+msgid "COL_ERROR_HEADER"
+msgstr "Error"
+
+#-----------------------------------------------------------
+
index b306f5916292dad2e5d83b0370d4bff7436aae32..7b4e0550c76b8e91706ab0c3cd6210c0abcecc0e 100644 (file)
@@ -33,7 +33,8 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am
 salomeinclude_HEADERS = \
        SMESH_Gen_i.hxx \
        SMESH_Algo_i.hxx \
-       SMESH_1D_Algo_i.hxx \
+       SMESH_0D_Algo_i.hxx \
+       SMESH_1D_Algo_i.hxx \   
        SMESH_2D_Algo_i.hxx \
        SMESH_3D_Algo_i.hxx \
        SMESH_subMesh_i.hxx \
@@ -62,6 +63,7 @@ dist_libSMESHEngine_la_SOURCES = \
        SMESH_MeshEditor_i.cxx \
        SMESH_Hypothesis_i.cxx \
        SMESH_Algo_i.cxx \
+       SMESH_0D_Algo_i.cxx \
        SMESH_1D_Algo_i.cxx \
        SMESH_2D_Algo_i.cxx \
        SMESH_3D_Algo_i.cxx \
diff --git a/src/SMESH_I/SMESH_0D_Algo_i.cxx b/src/SMESH_I/SMESH_0D_Algo_i.cxx
new file mode 100644 (file)
index 0000000..44de806
--- /dev/null
@@ -0,0 +1,84 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : SMESH_0D_Algo_i.cxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+#include "SMESH_0D_Algo_i.hxx"
+
+//=============================================================================
+/*!
+ *  SMESH_0D_Algo_i::SMESH_0D_Algo_i
+ * 
+ *  Constructor
+ */
+//=============================================================================
+
+SMESH_0D_Algo_i::SMESH_0D_Algo_i( PortableServer::POA_ptr thePOA )
+     : SALOME::GenericObj_i( thePOA ), 
+       SMESH_Hypothesis_i( thePOA ), 
+       SMESH_Algo_i( thePOA )
+{
+}
+
+//=============================================================================
+/*!
+ *  SMESH_0D_Algo_i::~SMESH_0D_Algo_i
+ * 
+ *  Destructor
+ */
+//=============================================================================
+
+SMESH_0D_Algo_i::~SMESH_0D_Algo_i()
+{
+}
+
+//================================================================================
+/*!
+ * \brief Verify whether algorithm supports given entity type 
+  * \param type - dimension (see SMESH::Dimension enumeration)
+  * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise
+ * 
+ * Verify whether algorithm supports given entity type (see SMESH::Dimension enumeration)
+ */
+//================================================================================
+CORBA::Boolean SMESH_0D_Algo_i::IsDimSupported( SMESH::Dimension type )
+{
+  return type == SMESH::DIM_0D;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/SMESH_I/SMESH_0D_Algo_i.hxx b/src/SMESH_I/SMESH_0D_Algo_i.hxx
new file mode 100644 (file)
index 0000000..2be0029
--- /dev/null
@@ -0,0 +1,55 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : SMESH_0D_Algo_i.hxx
+//  Module : SMESH
+//  $Header$
+
+#ifndef _SMESH_0D_ALGO_I_HXX_
+#define _SMESH_0D_ALGO_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Hypothesis)
+
+#include "SMESH_Algo_i.hxx"
+
+// ======================================================
+// Generic 0D algorithm
+// ======================================================
+class SMESH_0D_Algo_i:
+  public virtual POA_SMESH::SMESH_0D_Algo,
+  public virtual SMESH_Algo_i
+{
+protected:
+  // Constructor : placed in protected section to prohibit creation of generic class instance
+  SMESH_0D_Algo_i( PortableServer::POA_ptr thePOA );
+
+public:
+  // Destructor
+  virtual ~SMESH_0D_Algo_i();
+  
+  // Verify whether algorithm supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+};
+
+#endif
index ccf63624030fd6a96767b3a0ce79b74a4c8c0c9a..3cd0dd18a0724af4a3bf934667954765c05a38a3 100644 (file)
@@ -60,6 +60,7 @@ IMPLEMENT_STANDARD_RTTIEXT(_pyAlgorithm       ,_pyHypothesis);
 IMPLEMENT_STANDARD_RTTIEXT(_pyComplexParamHypo,_pyHypothesis);
 IMPLEMENT_STANDARD_RTTIEXT(_pyNumberOfSegmentsHyp,_pyHypothesis);
 IMPLEMENT_STANDARD_RTTIEXT(_pyLayerDistributionHypo,_pyHypothesis);
+IMPLEMENT_STANDARD_RTTIEXT(_pySegmentLengthAroundVertexHyp,_pyHypothesis);
 
 using namespace std;
 using SMESH::TPythonDump;
@@ -158,7 +159,7 @@ _pyGen::_pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod
  */
 //================================================================================
 
-void _pyGen::AddCommand( const TCollection_AsciiString& theCommand)
+Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand)
 {
   // store theCommand in the sequence
   myCommands.push_back( new _pyCommand( theCommand, ++myNbCommands ));
@@ -171,32 +172,32 @@ void _pyGen::AddCommand( const TCollection_AsciiString& theCommand)
   _pyID objID = aCommand->GetObject();
 
   if ( objID.IsEmpty() )
-    return;
+    return aCommand;
 
   // SMESH_Gen method?
   if ( objID == this->GetID() ) {
     this->Process( aCommand );
-    return;
+    return aCommand;
   }
   // SMESH_Mesh method?
   map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( objID );
   if ( id_mesh != myMeshes.end() ) {
     id_mesh->second->Process( aCommand );
-    return;
+    return aCommand;
   }
   // SMESH_Hypothesis method?
   list< Handle(_pyHypothesis) >::iterator hyp = myHypos.begin();
   for ( ; hyp != myHypos.end(); ++hyp )
     if ( !(*hyp)->IsAlgo() && objID == (*hyp)->GetID() ) {
       (*hyp)->Process( aCommand );
-      return;
+      return aCommand;
     }
 
   // Add access to a wrapped mesh
   AddMeshAccessorMethod( aCommand );
 
   // Add access to a wrapped algorithm
-  AddAlgoAccessorMethod( aCommand );
+  AddAlgoAccessorMethod( aCommand ); // ??? what if algo won't be wrapped at all ???
 
   // PAL12227. PythonDump was not updated at proper time; result is
   //     aCriteria.append(SMESH.Filter.Criterion(17,26,0,'L1',26,25,1e-07,SMESH.EDGE,-1))
@@ -216,6 +217,7 @@ void _pyGen::AddCommand( const TCollection_AsciiString& theCommand)
       aCommand->GetString() += tmpCmd.GetString();
     }
   }
+  return aCommand;
 }
 
 //================================================================================
@@ -229,10 +231,12 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
 {
   // there are methods to convert:
   // CreateMesh( shape )
+  // Concatenate( [mesh1, ...], ... )
   // CreateHypothesis( theHypType, theLibName )
   // Compute( mesh, geom )
 
-  if ( theCommand->GetMethod() == "CreateMesh" )
+  if ( theCommand->GetMethod() == "CreateMesh" ||
+       theCommand->GetMethod() == "CreateEmptyMesh" )
   {
     Handle(_pyMesh) mesh = new _pyMesh( theCommand );
     myMeshes.insert( make_pair( mesh->GetID(), mesh ));
@@ -270,6 +274,12 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
 
   // smeshgen.Method() --> smesh.smesh.Method()
   theCommand->SetObject( SMESH_2smeshpy::GenName() );
+
+  // Concatenate( [mesh1, ...], ... )
+  if ( theCommand->GetMethod() == "Concatenate" )
+  {
+    AddMeshAccessorMethod( theCommand );
+  }
 }
 
 //================================================================================
@@ -297,7 +307,7 @@ void _pyGen::Flush()
 
 //================================================================================
 /*!
- * \brief Add access method to mesh that is object or arg
+ * \brief Add access method to mesh that is an object or an argument
   * \param theCmd - command to add access method
   * \retval bool - true if added
  */
@@ -305,17 +315,18 @@ void _pyGen::Flush()
 
 bool _pyGen::AddMeshAccessorMethod( Handle(_pyCommand) theCmd ) const
 {
+  bool added = false;
   map< _pyID, Handle(_pyMesh) >::const_iterator id_mesh = myMeshes.begin();
   for ( ; id_mesh != myMeshes.end(); ++id_mesh ) {
     if ( theCmd->AddAccessorMethod( id_mesh->first, id_mesh->second->AccessorMethod() ))
-      return true;
+      added = true;
   }
-  return false;
+  return added;
 }
 
 //================================================================================
 /*!
- * \brief Add access method to algo that is object or arg
+ * \brief Add access method to algo that is an object or an argument
   * \param theCmd - command to add access method
   * \retval bool - true if added
  */
@@ -323,13 +334,14 @@ bool _pyGen::AddMeshAccessorMethod( Handle(_pyCommand) theCmd ) const
 
 bool _pyGen::AddAlgoAccessorMethod( Handle(_pyCommand) theCmd ) const
 {
+  bool added = false;
   list< Handle(_pyHypothesis) >::const_iterator hyp = myHypos.begin();
   for ( ; hyp != myHypos.end(); ++hyp ) {
-    if ( (*hyp)->IsAlgo() &&
+    if ( (*hyp)->IsAlgo() && /*(*hyp)->IsWrapped() &&*/
          theCmd->AddAccessorMethod( (*hyp)->GetID(), (*hyp)->AccessorMethod() ))
-      return true;
+      added = true;
   }
-  return false;
+  return added;
 }
 
 //================================================================================
@@ -408,7 +420,9 @@ void _pyGen::ExchangeCommands( Handle(_pyCommand) theCmd1, Handle(_pyCommand) th
 
 void _pyGen::SetCommandAfter( Handle(_pyCommand) theCmd, Handle(_pyCommand) theAfterCmd )
 {
-//   cout << "SET\t" << theCmd->GetString() << endl << "AFTER\t" << theAfterCmd->GetString() << endl << endl;
+#ifdef _DEBUG_
+//cout << "SET\t" << theAfterCmd->GetString() << endl << "BEFORE\t" << theCmd->GetString() << endl<<endl;
+#endif
   list< Handle(_pyCommand) >::iterator pos;
   pos = find( myCommands.begin(), myCommands.end(), theCmd );
   myCommands.erase( pos );
@@ -622,6 +636,37 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand )
   }
 }
 
+namespace {
+
+  //================================================================================
+  /*!
+   * \brief add addition result treatement command
+    * \param addCmd - hypothesis addition command
+   */
+  //================================================================================
+
+  void addErrorTreatmentCmd( Handle(_pyCommand) & addCmd,
+                             const bool           isAlgo)
+  {
+    return; // TO DEBUD - TreatHypoStatus() is not placed right after addCmd
+    // addCmd: status = mesh.AddHypothesis( geom, hypo )
+    // treatement command:
+    //    def TreatHypoStatus(status, hypName, geomName, isAlgo):
+    TCollection_AsciiString status = addCmd->GetResultValue();
+    if ( !status.IsEmpty() ) {
+      const _pyID& geomID = addCmd->GetArg( 1 );
+      const _pyID& hypoID = addCmd->GetArg( 2 );
+      TCollection_AsciiString cmdStr = addCmd->GetIndentation() +
+        SMESH_2smeshpy::SmeshpyName() + ".TreatHypoStatus( " + status + ", " +
+        SMESH_2smeshpy::SmeshpyName() + ".GetName(" + hypoID + "), " +
+        SMESH_2smeshpy::SmeshpyName() + ".GetName(" + geomID + "), " +
+        (char*)( isAlgo ? "True" : "False" ) + " )";
+      Handle(_pyCommand) cmd = theGen->AddCommand( cmdStr );
+      addCmd->AddDependantCmd( cmd, true );
+    }
+  }
+}
+
 //================================================================================
 /*!
  * \brief Convert creation and addition of all algos and hypos
@@ -671,6 +716,8 @@ void _pyMesh::Flush()
       // mesh.GetMesh().AddHypothesis(geom, ALGO ) ->
       // mesh.GetMesh().AddHypothesis(geom, ALGO.GetAlgorithm() )
       addCmd->SetArg( 2, addCmd->GetArg( 2 ) + ".GetAlgorithm()" );
+      // add addition result treatement cmd
+      addErrorTreatmentCmd( addCmd, true );
     }
   }
 
@@ -683,18 +730,11 @@ void _pyMesh::Flush()
     Handle(_pyHypothesis) hyp = theGen->FindHyp( hypID );
     if ( hyp.IsNull() || hyp->IsAlgo() )
       continue;
-    const _pyID& geom = addCmd->GetArg( 1 );
-    // find algo created on <geom> for this mesh
-    Handle(_pyHypothesis) algo = theGen->FindAlgo( geom, this->GetID(), hyp->GetType() );
-    //_pyID algoID = algo.IsNull() ? "" : algo->GetID();
-    if ( !algo.IsNull() && hyp->Addition2Creation( addCmd, this->GetID() )) // OK
-    {
-      addCmd->SetObject( algo->GetID() );
-      algo->GetCreationCmd()->AddDependantCmd( addCmd );
-    }
-    else
+    if ( !hyp->Addition2Creation( addCmd, this->GetID() ))
     {
       AddMeshAccess( addCmd );
+      // add addition result treatement cmd
+      addErrorTreatmentCmd( addCmd, false );
     }
   }
 
@@ -723,7 +763,7 @@ void _pyMesh::Flush()
 _pyHypothesis::_pyHypothesis(const Handle(_pyCommand)& theCreationCmd):
   _pyObject( theCreationCmd )
 {
-  myDim = myIsAlgo = /*myIsLocal = */myIsWrapped = myIsConverted = false;
+  myIsAlgo = myIsWrapped = /*myIsConverted = myIsLocal = myDim = */false;
 }
 
 //================================================================================
@@ -754,131 +794,145 @@ Handle(_pyHypothesis) _pyHypothesis::NewHypothesis( const Handle(_pyCommand)& th
 
   // 1D Regular_1D ----------
   if ( hypType == "Regular_1D" ) {
-    algo->SetDimMethodType( 1, "Segment");
+    // set mesh's method creating algo,
+    // i.e. convertion result will be "regular1d = Mesh.Segment()",
+    // and set hypType by which algo creating a hypothesis is searched for
+    algo->SetConvMethodAndType("Segment", hypType.ToCString());
+  }
+  else if ( hypType == "CompositeSegment_1D" ) {
+    algo->SetConvMethodAndType("Segment", "Regular_1D");
+    algo->myArgs.Append( "algo=smesh.COMPOSITE");
   }
   else if ( hypType == "LocalLength" ) {
-    hyp->SetDimMethodType( 1, "LocalLength", "Regular_1D");
+    // set algo's method creating hyp, and algo type
+    hyp->SetConvMethodAndType( "LocalLength", "Regular_1D");
+    // set method whose 1 arg will become the 1-st arg of hyp creation command
+    // i.e. convertion result will be "locallength = regular1d.LocalLength(<arg of SetLength()>)"
     hyp->AddArgMethod( "SetLength" );
   }
   else if ( hypType == "NumberOfSegments" ) {
     hyp = new _pyNumberOfSegmentsHyp( theCreationCmd );
-    hyp->SetDimMethodType( 1, "NumberOfSegments", "Regular_1D");
+    hyp->SetConvMethodAndType( "NumberOfSegments", "Regular_1D");
+    // arg of SetNumberOfSegments() will become the 1-st arg of hyp creation command
     hyp->AddArgMethod( "SetNumberOfSegments" );
+    // arg of SetScaleFactor() will become the 2-nd arg of hyp creation command
     hyp->AddArgMethod( "SetScaleFactor" );
   }
   else if ( hypType == "Arithmetic1D" ) {
     hyp = new _pyComplexParamHypo( theCreationCmd );
-    hyp->SetDimMethodType( 1, "Arithmetic1D", "Regular_1D");
+    hyp->SetConvMethodAndType( "Arithmetic1D", "Regular_1D");
   }
   else if ( hypType == "StartEndLength" ) {
     hyp = new _pyComplexParamHypo( theCreationCmd );
-    hyp->SetDimMethodType( 1, "StartEndLength", "Regular_1D");
+    hyp->SetConvMethodAndType( "StartEndLength", "Regular_1D");
   }
   else if ( hypType == "Deflection1D" ) {
-    hyp->SetDimMethodType( 1, "Deflection1D", "Regular_1D");
+    hyp->SetConvMethodAndType( "Deflection1D", "Regular_1D");
     hyp->AddArgMethod( "SetDeflection" );
   }
   else if ( hypType == "Propagation" ) {
-    hyp->SetDimMethodType( 1, "Propagation", "Regular_1D");
+    hyp->SetConvMethodAndType( "Propagation", "Regular_1D");
   }
   else if ( hypType == "QuadraticMesh" ) {
-    hyp->SetDimMethodType( 1, "QuadraticMesh", "Regular_1D");
+    hyp->SetConvMethodAndType( "QuadraticMesh", "Regular_1D");
   }
   else if ( hypType == "AutomaticLength" ) {
-    hyp->SetDimMethodType( 1, "AutomaticLength", "Regular_1D");
+    hyp->SetConvMethodAndType( "AutomaticLength", "Regular_1D");
     hyp->AddArgMethod( "SetFineness");
   }
+  else if ( hypType == "SegmentLengthAroundVertex" ) {
+    hyp = new _pySegmentLengthAroundVertexHyp( theCreationCmd );
+    hyp->SetConvMethodAndType( "LengthNearVertex", "Regular_1D" );
+    hyp->AddArgMethod( "SetLength" );
+  }
   // 1D Python_1D ----------
   else if ( hypType == "Python_1D" ) {
-    algo->SetDimMethodType( 1, "Segment");
+    algo->SetConvMethodAndType( "Segment", hypType.ToCString());
     algo->myArgs.Append( "algo=smesh.PYTHON");
   }
   else if ( hypType == "PythonSplit1D" ) {
-    hyp->SetDimMethodType( 1, "PythonSplit1D", "Python_1D");
+    hyp->SetConvMethodAndType( "PythonSplit1D", "Python_1D");
     hyp->AddArgMethod( "SetNumberOfSegments");
     hyp->AddArgMethod( "SetPythonLog10RatioFunction");
   }
   // 2D ----------
   else if ( hypType == "MEFISTO_2D" ) {
-    algo->SetDimMethodType( 2, "Triangle");
+    algo->SetConvMethodAndType( "Triangle", hypType.ToCString());
   }
   else if ( hypType == "MaxElementArea" ) {
-    hyp->SetDimMethodType( 2, "MaxElementArea", "MEFISTO_2D");
+    hyp->SetConvMethodAndType( "MaxElementArea", "MEFISTO_2D");
     hyp->AddArgMethod( "SetMaxElementArea");
   }
   else if ( hypType == "LengthFromEdges" ) {
-    hyp->SetDimMethodType( 2, "LengthFromEdges", "MEFISTO_2D");
+    hyp->SetConvMethodAndType( "LengthFromEdges", "MEFISTO_2D");
   }
   else if ( hypType == "Quadrangle_2D" ) {
-    algo->SetDimMethodType( 2, "Quadrangle" );
+    algo->SetConvMethodAndType( "Quadrangle" , hypType.ToCString());
   }
   else if ( hypType == "QuadranglePreference" ) {
-    hyp->SetDimMethodType( 2, "QuadranglePreference", "Quadrangle_2D");
+    hyp->SetConvMethodAndType( "QuadranglePreference", "Quadrangle_2D");
   }
   // 3D ----------
   else if ( hypType == "NETGEN_3D") {
-    algo->SetDimMethodType( 3, "Tetrahedron" );
+    algo->SetConvMethodAndType( "Tetrahedron" , hypType.ToCString());
     algo->myArgs.Append( "algo=smesh.NETGEN" );
   }
   else if ( hypType == "MaxElementVolume") {
-    hyp->SetDimMethodType( 3, "MaxElementVolume", "NETGEN_3D");
+    hyp->SetConvMethodAndType( "MaxElementVolume", "NETGEN_3D");
     hyp->AddArgMethod( "SetMaxElementVolume" );
   }
   else if ( hypType == "GHS3D_3D" ) {
-    algo->SetDimMethodType( 3, "Tetrahedron");
+    algo->SetConvMethodAndType( "Tetrahedron", hypType.ToCString());
     algo->myArgs.Append( "algo=smesh.GHS3D" );
   }
   else if ( hypType == "Hexa_3D" ) {
-    algo->SetDimMethodType( 3, "Hexahedron");
+    algo->SetConvMethodAndType( "Hexahedron", hypType.ToCString());
   }
   // Repetitive ---------
   else if ( hypType == "Projection_1D" ) {
-    algo->SetDimMethodType( 1, "Projection1D");
+    algo->SetConvMethodAndType( "Projection1D", hypType.ToCString());
   }
   else if ( hypType == "ProjectionSource1D" ) {
-    hyp->SetDimMethodType( 1, "SourceEdge", "Projection_1D");
+    hyp->SetConvMethodAndType( "SourceEdge", "Projection_1D");
     hyp->AddArgMethod( "SetSourceEdge");
     hyp->AddArgMethod( "SetSourceMesh");
+    // 2 args of SetVertexAssociation() will become the 3-th and 4-th args of hyp creation command
     hyp->AddArgMethod( "SetVertexAssociation", 2 );
   }
   else if ( hypType == "Projection_2D" ) {
-    algo->SetDimMethodType( 2, "Projection2D");
+    algo->SetConvMethodAndType( "Projection2D", hypType.ToCString());
   }
   else if ( hypType == "ProjectionSource2D" ) {
-    hyp->SetDimMethodType( 2, "SourceFace", "Projection_2D");
+    hyp->SetConvMethodAndType( "SourceFace", "Projection_2D");
     hyp->AddArgMethod( "SetSourceFace");
     hyp->AddArgMethod( "SetSourceMesh");
     hyp->AddArgMethod( "SetVertexAssociation", 4 );
   }
   else if ( hypType == "Projection_3D" ) {
-    algo->SetDimMethodType( 3, "Projection3D");
+    algo->SetConvMethodAndType( "Projection3D", hypType.ToCString());
   }
   else if ( hypType == "ProjectionSource3D" ) {
-    hyp->SetDimMethodType( 3, "SourceShape3D", "Projection_3D");
+    hyp->SetConvMethodAndType( "SourceShape3D", "Projection_3D");
     hyp->AddArgMethod( "SetSource3DShape");
     hyp->AddArgMethod( "SetSourceMesh");
     hyp->AddArgMethod( "SetVertexAssociation", 4 );
   }
   else if ( hypType == "Prism_3D" ) {
-    algo->SetDimMethodType( 3, "Prism");
+    algo->SetConvMethodAndType( "Prism", hypType.ToCString());
   }
   else if ( hypType == "RadialPrism_3D" ) {
-    algo->SetDimMethodType( 3, "Prism");
+    algo->SetConvMethodAndType( "Prism", hypType.ToCString());
   }
   else if ( hypType == "NumberOfLayers" ) {
-    hyp->SetDimMethodType( 3, "NumberOfLayers", "RadialPrism_3D");
+    hyp->SetConvMethodAndType( "NumberOfLayers", "RadialPrism_3D");
     hyp->AddArgMethod( "SetNumberOfLayers" );
   }
   else if ( hypType == "LayerDistribution" ) {
     hyp = new _pyLayerDistributionHypo( theCreationCmd );
-    hyp->SetDimMethodType( 3, "LayerDistribution", "RadialPrism_3D");
-//     hyp->AddArgMethod( "SetSource3DShape");
-//     hyp->AddArgMethod( "SetSourceMesh");
-//     hyp->AddArgMethod( "SetVertexAssociation", 4 );
+    hyp->SetConvMethodAndType( "LayerDistribution", "RadialPrism_3D");
   }
 
-  if ( algo->GetDim() ) {
-    algo->myType = hypType;
+  if ( !algo->GetCreationMethod().IsEmpty() ) {
     return algo;
   }
   return hyp;
@@ -901,39 +955,38 @@ bool _pyHypothesis::Addition2Creation( const Handle(_pyCommand)& theCmd,
   if ( !IsWrappable( theMesh ))
     return false;
 
-  myIsWrapped = true;
+  myGeom = theCmd->GetArg( 1 );
 
-  if ( myIsWrapped )
-  {
-    // mesh.AddHypothesis(geom,hyp) --> hyp = theMesh.myCreationMethod(args)
-    theCmd->SetResultValue( GetID() );
-    theCmd->SetObject( theMesh );
-    theCmd->SetMethod( myCreationMethod );
-    // set args
-    theCmd->RemoveArgs();
-    for ( int i = 1; i <= myArgs.Length(); ++i ) {
-      if ( !myArgs( i ).IsEmpty() )
-        theCmd->SetArg( i, myArgs( i ));
-      else
-        theCmd->SetArg( i, "[]");
-    }
-    // set a new creation command
-    GetCreationCmd()->Clear();
-    SetCreationCmd( theCmd );
-
-    // clear commands setting arg values
-    list < Handle(_pyCommand) >::iterator argCmd = myArgCommands.begin();
-    for ( ; argCmd != myArgCommands.end(); ++argCmd )
-      (*argCmd)->Clear();
+  Handle(_pyHypothesis) algo;
+  if ( !IsAlgo() ) {
+    // find algo created on myGeom in theMesh
+    algo = theGen->FindAlgo( myGeom, theMesh, GetType() );
+    if ( algo.IsNull() )
+      return false;
+    algo->GetCreationCmd()->AddDependantCmd( theCmd );
   }
-  else
-  {
-//     // set arg commands after hypo creation
-//     list<Handle(_pyCommand)>::iterator argCmd = myArgCommands.begin();
-//     for ( ; argCmd != myArgCommands.end(); ++argCmd )
-//       if ( !(*argCmd)->IsEmpty() && GetCommandNb() > (*argCmd)->GetOrderNb() )
-//         theGen->ExchangeCommands( GetCreationCmd(), *argCmd );
+  myIsWrapped = true;
+
+  // mesh.AddHypothesis(geom,hyp) --> hyp = <theMesh or algo>.myCreationMethod(args)
+  theCmd->SetResultValue( GetID() );
+  theCmd->SetObject( IsAlgo() ? theMesh : algo->GetID());
+  theCmd->SetMethod( myCreationMethod );
+  // set args
+  theCmd->RemoveArgs();
+  for ( int i = 1; i <= myArgs.Length(); ++i ) {
+    if ( !myArgs( i ).IsEmpty() )
+      theCmd->SetArg( i, myArgs( i ));
+    else
+      theCmd->SetArg( i, "[]");
   }
+  // set a new creation command
+  GetCreationCmd()->Clear();
+  SetCreationCmd( theCmd );
+
+  // clear commands setting arg values
+  list < Handle(_pyCommand) >::iterator argCmd = myArgCommands.begin();
+  for ( ; argCmd != myArgCommands.end(); ++argCmd )
+    (*argCmd)->Clear();
 
   // set unknown arg commands after hypo creation
   Handle(_pyCommand) afterCmd = myIsWrapped ? theCmd : GetCreationCmd();
@@ -1228,6 +1281,49 @@ void _pyNumberOfSegmentsHyp::Flush()
   }
 }
 
+//================================================================================
+/*!
+ * \brief Convert the command adding "SegmentLengthAroundVertex" to mesh
+ * into regular1D.LengthNearVertex( length, vertex )
+  * \param theCmd - The command like mesh.AddHypothesis( vertex, SegmentLengthAroundVertex )
+  * \param theMesh - The mesh needing this hypo
+  * \retval bool - false if the command cant be converted
+ */
+//================================================================================
+  
+bool _pySegmentLengthAroundVertexHyp::Addition2Creation( const Handle(_pyCommand)& theCmd,
+                                                         const _pyID&              theMeshID)
+{
+  if ( IsWrappable( theMeshID )) {
+
+    _pyID vertex = theCmd->GetArg( 1 );
+
+    // the problem here is that segment algo will not be found
+    // by pyHypothesis::Addition2Creation() for <vertex>, so we try to find
+    // geometry where segment algorithm is assigned
+    Handle(_pyHypothesis) algo;
+    _pyID geom = vertex;
+    while ( algo.IsNull() && !geom.IsEmpty()) {
+      // try to find geom as a father of <vertex>
+      geom = FatherID( geom );
+      algo = theGen->FindAlgo( geom, theMeshID, GetType() );
+    }
+    if ( algo.IsNull() )
+      return false; // also possible to find geom as brother of veretex...
+    // set geom instead of vertex
+    theCmd->SetArg( 1, geom );
+
+    // set vertex as a second arg
+    if ( myArgs.Length() < 1) myArgs.Append( "1" ); // :(
+    myArgs.Append( vertex );
+
+    // mesh.AddHypothesis(vertex, SegmentLengthAroundVertex) -->
+    // theMeshID.LengthNearVertex( length, vertex )
+    return _pyHypothesis::Addition2Creation( theCmd, theMeshID );
+  }
+  return false;
+}
+
 //================================================================================
 /*!
  * \brief _pyAlgorithm constructor
@@ -1253,15 +1349,10 @@ _pyAlgorithm::_pyAlgorithm(const Handle(_pyCommand)& theCreationCmd)
 bool _pyAlgorithm::Addition2Creation( const Handle(_pyCommand)& theCmd,
                                       const _pyID&              theMeshID)
 {
-  if ( IsWrappable( theMeshID )) {
-
-    myGeom = theCmd->GetArg( 1 );
-
-    // mesh.AddHypothesis(geom,algo) --> theMeshID.myCreationMethod()
-    if ( _pyHypothesis::Addition2Creation( theCmd, theMeshID )) {
-      theGen->SetAccessorMethod( GetID(), "GetAlgorithm()" );
-      return true;
-    }
+  // mesh.AddHypothesis(geom,algo) --> theMeshID.myCreationMethod()
+  if ( _pyHypothesis::Addition2Creation( theCmd, theMeshID )) {
+    theGen->SetAccessorMethod( GetID(), "GetAlgorithm()" );
+    return true;
   }
   return false;
 }
@@ -1298,6 +1389,23 @@ void _pyCommand::SetBegPos( int thePartIndex, int thePosition )
   myBegPos( thePartIndex ) = thePosition;
 }
 
+//================================================================================
+/*!
+ * \brief Returns whitespace symbols at the line beginning
+  * \retval TCollection_AsciiString - result
+ */
+//================================================================================
+
+TCollection_AsciiString _pyCommand::GetIndentation()
+{
+  int end = 1;
+  if ( GetBegPos( RESULT_IND ) == UNKNOWN )
+    GetWord( myString, end, true );
+  else
+    end = GetBegPos( RESULT_IND );
+  return myString.SubString( 1, end - 1 );
+}
+
 //================================================================================
 /*!
  * \brief Return substring of python command looking like ResultValue = Obj.Meth()
@@ -1624,27 +1732,32 @@ bool _pyCommand::AddAccessorMethod( _pyID theObjectID, const char* theAcsMethod
   int beg = GetBegPos( OBJECT_IND );
   if ( beg < 1 || beg > Length() )
     return false;
+  bool added = false;
   while (( beg = myString.Location( theObjectID, beg, Length() )))
   {
     // check that theObjectID is not just a part of a longer ID
     int afterEnd = beg + theObjectID.Length();
     Standard_Character c = myString.Value( afterEnd );
     if ( !isalnum( c ) && c != ':' ) {
-      // insertion
-      int oldLen = Length();
-      myString.Insert( afterEnd, (char*) theAcsMethod );
-      myString.Insert( afterEnd, "." );
-      // update starting positions of the parts following the modified one
-      int posDelta = Length() - oldLen;
-      for ( int i = 1; i <= myBegPos.Length(); ++i ) {
-        if ( myBegPos( i ) > afterEnd )
-          myBegPos( i ) += posDelta;
+      // check if accessor method already present
+      if ( c != '.' ||
+           myString.Location( (char*) theAcsMethod, afterEnd, Length() ) != afterEnd+1) {
+        // insertion
+        int oldLen = Length();
+        myString.Insert( afterEnd, (char*) theAcsMethod );
+        myString.Insert( afterEnd, "." );
+        // update starting positions of the parts following the modified one
+        int posDelta = Length() - oldLen;
+        for ( int i = 1; i <= myBegPos.Length(); ++i ) {
+          if ( myBegPos( i ) > afterEnd )
+            myBegPos( i ) += posDelta;
+        }
+        added = true;
       }
-      return true;
     }
     beg = afterEnd; // is a part - next search
   }
-  return false;
+  return added;
 }
 
 //================================================================================
@@ -1658,3 +1771,16 @@ const char* _pyObject::AccessorMethod() const
 {
   return 0;
 }
+//================================================================================
+/*!
+ * \brief Return ID of a father
+ */
+//================================================================================
+
+_pyID _pyObject::FatherID(const _pyID & childID)
+{
+  int colPos = childID.SearchFromEnd(':');
+  if ( colPos > 0 )
+    return childID.SubString( 1, colPos-1 );
+  return "";
+}
index f5717cd2a386538862b3c5e4d42572d33de00829..2f1bc027c5abed7015147b8c1b17f7433ea06565 100644 (file)
@@ -131,6 +131,7 @@ public:
   int Length() { return myString.Length(); }
   void Clear() { myString.Clear(); myBegPos.Clear(); }
   bool IsEmpty() const { return myString.IsEmpty(); }
+  TCollection_AsciiString GetIndentation();
   const TCollection_AsciiString & GetResultValue();
   const TCollection_AsciiString & GetObject();
   const TCollection_AsciiString & GetMethod();
@@ -149,8 +150,8 @@ public:
   static TCollection_AsciiString GetWord( const TCollection_AsciiString & theSring,
                                           int & theStartPos, const bool theForward,
                                           const bool dotIsWord = false);
-  void AddDependantCmd( Handle(_pyCommand) cmd)
-  { return myDependentCmds.push_back( cmd ); }
+  void AddDependantCmd( Handle(_pyCommand) cmd, bool prepend = false)
+  { if (prepend) myDependentCmds.push_front( cmd ); else myDependentCmds.push_back( cmd ); }
   bool SetDependentCmdsAfter() const;
 
   bool AddAccessorMethod( _pyID theObjectID, const char* theAcsMethod );
@@ -170,6 +171,7 @@ class _pyObject: public Standard_Transient
 public:
   _pyObject(const Handle(_pyCommand)& theCreationCmd): myCreationCmd(theCreationCmd) {}
   const _pyID& GetID() { return myCreationCmd->GetResultValue(); }
+  static _pyID FatherID(const _pyID & childID);
   const Handle(_pyCommand)& GetCreationCmd() { return myCreationCmd; }
   void  SetCreationCmd( Handle(_pyCommand) cmd ) { myCreationCmd = cmd; }
   int GetCommandNb() { return myCreationCmd->GetOrderNb(); }
@@ -191,7 +193,7 @@ class _pyGen: public _pyObject
 public:
   _pyGen(Resource_DataMapOfAsciiStringAsciiString& theEntry2AccessorMethod);
   //~_pyGen();
-  void AddCommand( const TCollection_AsciiString& theCommand );
+  Handle(_pyCommand) AddCommand( const TCollection_AsciiString& theCommand );
   void Process( const Handle(_pyCommand)& theCommand );
   void Flush();
   Handle(_pyHypothesis) FindHyp( const _pyID& theHypID );
@@ -262,8 +264,8 @@ private:
 class _pyHypothesis: public _pyObject
 {
 protected:
-  bool    myIsAlgo, /*myIsLocal, */myIsWrapped, myIsConverted;
-  int     myDim/*, myAdditionCmdNb*/;
+  bool    myIsAlgo, myIsWrapped; //myIsLocal, myIsConverted;
+  //int     myDim/*, myAdditionCmdNb*/;
   _pyID    myGeom, myMesh;
   TCollection_AsciiString       myCreationMethod, myType;
   TColStd_SequenceOfAsciiString myArgs;
@@ -273,8 +275,10 @@ protected:
   std::list<Handle(_pyCommand)>  myUnknownCommands;
 public:
   _pyHypothesis(const Handle(_pyCommand)& theCreationCmd);
-  void SetDimMethodType(const int dim, const char* creationMethod, const char* type=0)
-  { myDim = dim; myCreationMethod = (char*)creationMethod; if ( type ) myType = (char*)type; }
+  void SetConvMethodAndType(const char* creationMethod, const char* type=0)
+  { myCreationMethod = (char*)creationMethod; if ( type ) myType = (char*)type; }
+//   void SetDimMethodType(const int dim, const char* creationMethod, const char* type=0)
+//   { myDim = dim; myCreationMethod = (char*)creationMethod; if ( type ) myType = (char*)type; }
   void AddArgMethod(const char* method, const int nbArgs = 1)
   { myArgMethods.Append( (char*)method ); myNbArgsByMethod.Append( nbArgs ); }
   const TColStd_SequenceOfAsciiString& GetArgs() const { return myArgs; }
@@ -283,8 +287,8 @@ public:
   void ClearAllCommands();
   virtual bool IsAlgo() const { return myIsAlgo; }
   bool IsWrapped() const { return myIsWrapped; }
-  bool & IsConverted() { return myIsConverted; }
-  int GetDim() const { return myDim; }
+  //bool & IsConverted() { return myIsConverted; }
+  //int GetDim() const { return myDim; }
   const _pyID & GetGeom() const { return myGeom; }
   void SetMesh( const _pyID& theMeshId) { if ( myMesh.IsEmpty() ) myMesh = theMeshId; }
   const _pyID & GetMesh() const { return myMesh; }
@@ -301,6 +305,22 @@ public:
   DEFINE_STANDARD_RTTI (_pyHypothesis)
 };
 
+// -------------------------------------------------------------------------------------
+/*!
+ * \brief Class representing smesh.Mesh_Algorithm
+ */
+// -------------------------------------------------------------------------------------
+class _pyAlgorithm: public _pyHypothesis
+{
+public:
+  _pyAlgorithm(const Handle(_pyCommand)& theCreationCmd);
+  virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
+                                  const _pyID&              theMesh);
+  const char* AccessorMethod() const { return "GetAlgorithm()"; }
+
+  DEFINE_STANDARD_RTTI (_pyAlgorithm)
+};
+
 // -------------------------------------------------------------------------------------
 /*!
  * \brief Class for hypotheses having several parameters modified by one method
@@ -336,7 +356,6 @@ public:
 };
 DEFINE_STANDARD_HANDLE (_pyLayerDistributionHypo, _pyHypothesis);
 
-
 // -------------------------------------------------------------------------------------
 /*!
  * \brief Class representing NumberOfSegments hypothesis
@@ -356,18 +375,17 @@ DEFINE_STANDARD_HANDLE (_pyNumberOfSegmentsHyp, _pyHypothesis);
 
 // -------------------------------------------------------------------------------------
 /*!
- * \brief Class representing smesh.Mesh_Algorithm
+ * \brief Class representing SegmentLengthAroundVertex hypothesis
  */
 // -------------------------------------------------------------------------------------
-class _pyAlgorithm: public _pyHypothesis
+class _pySegmentLengthAroundVertexHyp: public _pyHypothesis
 {
 public:
-  _pyAlgorithm(const Handle(_pyCommand)& theCreationCmd);
+  _pySegmentLengthAroundVertexHyp(const Handle(_pyCommand)& theCrCmd): _pyHypothesis(theCrCmd) {}
   virtual bool Addition2Creation( const Handle(_pyCommand)& theAdditionCmd,
                                   const _pyID&              theMesh);
-  const char* AccessorMethod() const { return "GetAlgorithm()"; }
-
-  DEFINE_STANDARD_RTTI (_pyAlgorithm)
+  DEFINE_STANDARD_RTTI (_pySegmentLengthAroundVertexHyp)
 };
+DEFINE_STANDARD_HANDLE (_pySegmentLengthAroundVertexHyp, _pyHypothesis);
 
 #endif
index e0ecf8fcd0cd328d320d187da17eded84f4f9e9e..e1079ebc7c43c54594303b4afef3a6e8923d8e9b 100644 (file)
@@ -231,6 +231,7 @@ namespace SMESH
       case FT_BelongToGeom:     myStream<< "aBelongToGeom";     break;
       case FT_BelongToPlane:    myStream<< "aBelongToPlane";    break;
       case FT_BelongToCylinder: myStream<< "aBelongToCylinder"; break;
+      case FT_BelongToGenSurface:myStream<<"aBelongToGenSurface";break;
       case FT_LyingOnGeom:      myStream<< "aLyingOnGeom";      break;
       case FT_RangeOfIds:       myStream<< "aRangeOfIds";       break;
       case FT_BadOrientedVolume:myStream<< "aBadOrientedVolume";break;
index e653aa172e1b01e9c4584a29fb66e362169698ae..d9c221ad70cc049c25b5d660099881a9056ec0a1 100644 (file)
@@ -886,7 +886,6 @@ void BelongToSurface_i::SetSurface( GEOM::GEOM_Object_ptr theGeom, ElementType t
   }
 
   myElementsOnSurfacePtr->SetSurface( TopoDS_Shape(), (SMDSAbs_ElementType)theType );
-  TPythonDump()<<this<<".SetSurface("<<theGeom<<",'"<<theType<<"')";
 }
 
 void BelongToSurface_i::SetShapeName( const char* theName, ElementType theType )
@@ -934,6 +933,18 @@ CORBA::Double BelongToSurface_i::GetTolerance()
   return myElementsOnSurfacePtr->GetTolerance();
 }
 
+void BelongToSurface_i::SetUseBoundaries( CORBA::Boolean theUseBndRestrictions )
+{
+  myElementsOnSurfacePtr->SetUseBoundaries( theUseBndRestrictions );
+  TPythonDump()<<this<<".SetUseBoundaries( " << theUseBndRestrictions << " )";
+}
+
+CORBA::Boolean BelongToSurface_i::GetUseBoundaries()
+{
+  return myElementsOnSurfacePtr->GetUseBoundaries();
+}
+
+
 /*
   Class       : BelongToPlane_i
   Description : Verify whether mesh element lie in pointed Geom planar object
@@ -976,6 +987,33 @@ FunctorType BelongToCylinder_i::GetFunctorType()
   return FT_BelongToCylinder;
 }
 
+/*
+  Class       : BelongToGenSurface_i
+  Description : Verify whether mesh element lie in pointed Geom planar object
+*/
+
+BelongToGenSurface_i::BelongToGenSurface_i()
+: BelongToSurface_i( STANDARD_TYPE( Geom_CylindricalSurface ) )
+{
+}
+
+void BelongToGenSurface_i::SetSurface( GEOM::GEOM_Object_ptr theGeom, ElementType theType )
+{
+  if ( theGeom->_is_nil() )
+    return;
+  TopoDS_Shape aLocShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theGeom );
+  if ( !aLocShape.IsNull() && aLocShape.ShapeType() != TopAbs_FACE )
+    aLocShape.Nullify();
+  
+  BelongToSurface_i::myElementsOnSurfacePtr->SetSurface( aLocShape, (SMDSAbs_ElementType)theType );
+  TPythonDump()<<this<<".SetGenSurface("<<theGeom<<","<<theType<<")";
+}
+
+FunctorType BelongToGenSurface_i::GetFunctorType()
+{
+  return FT_BelongToGenSurface;
+}
+
 /*
   Class       : LyingOnGeom_i
   Description : Predicate for selection on geometrical support
@@ -1558,6 +1596,14 @@ BelongToCylinder_ptr FilterManager_i::CreateBelongToCylinder()
   return anObj._retn();
 }
 
+BelongToGenSurface_ptr FilterManager_i::CreateBelongToGenSurface()
+{
+  SMESH::BelongToGenSurface_i* aServant = new SMESH::BelongToGenSurface_i();
+  SMESH::BelongToGenSurface_var anObj = aServant->_this();
+  TPythonDump()<<aServant<<" = "<<this<<".CreateBelongToGenSurface()";
+  return anObj._retn();
+}
+
 LyingOnGeom_ptr FilterManager_i::CreateLyingOnGeom()
 {
   SMESH::LyingOnGeom_i* aServant = new SMESH::LyingOnGeom_i();
@@ -1858,6 +1904,7 @@ static inline bool getCriteria( Predicate_i*                thePred,
     }
   case FT_BelongToPlane:
   case FT_BelongToCylinder:
+  case FT_BelongToGenSurface:
     {
       BelongToSurface_i* aPred = dynamic_cast<BelongToSurface_i*>( thePred );
 
@@ -2010,7 +2057,7 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria
     ElementType aTypeOfElem   = theCriteria[ i ].TypeOfElement;
     long        aPrecision    = theCriteria[ i ].Precision;
 
-    TPythonDump()<<"aCriteria.append(SMESH.Filter.Criterion("<<
+    TPythonDump()<<"aCriterion = SMESH.Filter.Criterion("<<
       aCriterion<<","<<aCompare<<","<<aThreshold<<",'"<<aThresholdStr<<"','"<<aThresholdID<<"',"<<
       aUnary<<","<<aBinary<<","<<aTolerance<<","<<aTypeOfElem<<","<<aPrecision<<"))";
 
@@ -2076,13 +2123,17 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria
         break;
       case SMESH::FT_BelongToPlane:
       case SMESH::FT_BelongToCylinder:
+      case SMESH::FT_BelongToGenSurface:
         {
-         SMESH::BelongToSurface_ptr tmpPred;
-          if ( aCriterion == SMESH::FT_BelongToPlane )
-            tmpPred = aFilterMgr->CreateBelongToPlane();
-          else
-            tmpPred = aFilterMgr->CreateBelongToCylinder();
-
+          SMESH::BelongToSurface_ptr tmpPred;
+          switch ( aCriterion ) {
+          case SMESH::FT_BelongToPlane:
+            tmpPred = aFilterMgr->CreateBelongToPlane(); break;
+          case SMESH::FT_BelongToCylinder:
+            tmpPred = aFilterMgr->CreateBelongToCylinder(); break;
+          default:
+            tmpPred = aFilterMgr->CreateBelongToGenSurface();
+          }
           tmpPred->SetShape( aThresholdID, aThresholdStr, aTypeOfElem );
           tmpPred->SetTolerance( aTolerance );
           aPredicate = tmpPred;
@@ -2153,6 +2204,7 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria
     // logical op
     aPredicates.push_back( aPredicate );
     aBinaries.push_back( aBinary );
+    TPythonDump()<<"aCriteria.append(aCriterion)";
 
   } // end of for
   TPythonDump()<<this<<".SetCriteria(aCriteria)";
@@ -2313,6 +2365,7 @@ static inline LDOMString toString( CORBA::Long theType )
     case FT_BelongToGeom    : return "Belong to Geom";
     case FT_BelongToPlane   : return "Belong to Plane";
     case FT_BelongToCylinder: return "Belong to Cylinder";
+    case FT_BelongToGenSurface: return "Belong to Generic Surface";
     case FT_LyingOnGeom     : return "Lying on Geom";
     case FT_BadOrientedVolume: return "Bad Oriented Volume";
     case FT_RangeOfIds      : return "Range of IDs";
@@ -2349,6 +2402,7 @@ static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr )
   else if ( theStr.equals( "Belong to Geom"               ) ) return FT_BelongToGeom;
   else if ( theStr.equals( "Belong to Plane"              ) ) return FT_BelongToPlane;
   else if ( theStr.equals( "Belong to Cylinder"           ) ) return FT_BelongToCylinder;
+  else if ( theStr.equals( "Belong to Generic Surface"    ) ) return FT_BelongToGenSurface;
   else if ( theStr.equals( "Lying on Geom"                ) ) return FT_LyingOnGeom;
   else if ( theStr.equals( "Free borders"                 ) ) return FT_FreeBorders;
   else if ( theStr.equals( "Free edges"                   ) ) return FT_FreeEdges;
index 524ab3ca4fa2719e59818d7aa054f8d6f6103630..f52f44785576cad94c188e95451002989408d503 100644 (file)
@@ -392,6 +392,9 @@ namespace SMESH
 
     void                            SetTolerance( CORBA::Double );
     CORBA::Double                   GetTolerance();
+    
+    void                            SetUseBoundaries( CORBA::Boolean theUseBndRestrictions );
+    CORBA::Boolean                  GetUseBoundaries();
 
   protected:
     Controls::ElementsOnSurfacePtr  myElementsOnSurfacePtr;
@@ -426,6 +429,19 @@ namespace SMESH
     FunctorType                     GetFunctorType();
   };
 
+  /*
+    Class       : BelongToGenSurface_i
+    Description : Verify whether mesh element lie on pointed Geom surfasic object
+  */
+  class BelongToGenSurface_i: public virtual POA_SMESH::BelongToGenSurface,
+                              public virtual BelongToSurface_i
+  {
+  public:
+    BelongToGenSurface_i();
+    void                            SetSurface( GEOM::GEOM_Object_ptr theGeom, ElementType theType );
+    FunctorType                     GetFunctorType();
+  };
+  
   /*
     Class       : LyingOnGeom_i
     Description : Predicate for selection on geometrical support(lying or partially lying)
@@ -772,6 +788,7 @@ namespace SMESH
     BelongToGeom_ptr          CreateBelongToGeom();
     BelongToPlane_ptr         CreateBelongToPlane();
     BelongToCylinder_ptr      CreateBelongToCylinder();
+    BelongToGenSurface_ptr    CreateBelongToGenSurface();
     
     LyingOnGeom_ptr           CreateLyingOnGeom();
     
index f43941bce4d43c0238b467c184f68f8b8a528e8d..e3b8630d84d1f51fa358c810e84e6ebdf11bc0f1 100644 (file)
@@ -93,6 +93,7 @@
 #include "SMDS_FacePosition.hxx"
 #include "SMDS_VertexPosition.hxx"
 #include "SMDS_SpacePosition.hxx"
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
 
 #include CORBA_SERVER_HEADER(SMESH_Group)
 #include CORBA_SERVER_HEADER(SMESH_Filter)
@@ -255,7 +256,7 @@ SMESH_Gen_i::SMESH_Gen_i( CORBA::ORB_ptr            orb,
                           const char*               interfaceName )
      : Engines_Component_i( orb, poa, contId, instanceName, interfaceName )
 {
-  INFOS( "SMESH_Gen_i::SMESH_Gen_i : standard constructor" );
+  MESSAGE( "SMESH_Gen_i::SMESH_Gen_i : standard constructor" );
 
   myOrb = CORBA::ORB::_duplicate(orb);
   myPoa = PortableServer::POA::_duplicate(poa);
@@ -956,6 +957,105 @@ CORBA::Boolean SMESH_Gen_i::IsReadyToCompute( SMESH::SMESH_Mesh_ptr theMesh,
   return false;
 }
 
+//================================================================================
+/*!
+ * \brief  Find SObject for an algo
+ */
+//================================================================================
+
+SALOMEDS::SObject_ptr SMESH_Gen_i::GetAlgoSO(const ::SMESH_Algo* algo)
+{
+  if ( algo ) {
+    if ( !myCurrentStudy->_is_nil() ) {
+      // find algo in the study
+      SALOMEDS::SComponent_var father = SALOMEDS::SComponent::_narrow
+        ( myCurrentStudy->FindComponent( ComponentDataType() ) );
+      if ( !father->_is_nil() ) {
+        SALOMEDS::ChildIterator_var itBig = myCurrentStudy->NewChildIterator( father );
+        for ( ; itBig->More(); itBig->Next() ) {
+          SALOMEDS::SObject_var gotBranch = itBig->Value();
+          if ( gotBranch->Tag() == GetAlgorithmsRootTag() ) {
+            SALOMEDS::ChildIterator_var algoIt = myCurrentStudy->NewChildIterator( gotBranch );
+            for ( ; algoIt->More(); algoIt->Next() ) {
+              SALOMEDS::SObject_var algoSO = algoIt->Value();
+              CORBA::Object_var     algoIOR = SObjectToObject( algoSO );
+              if ( !CORBA::is_nil( algoIOR )) {
+                SMESH_Hypothesis_i* impl = SMESH::DownCast<SMESH_Hypothesis_i*>( algoIOR );
+                if ( impl && impl->GetImpl() == algo )
+                  return algoSO._retn();
+              }
+            } // loop on algo SO's
+            break;
+          } // if algo tag
+        } // SMESH component iterator
+      }
+    }
+  }
+  return SALOMEDS::SObject::_nil();
+}
+
+//================================================================================
+/*!
+ * \brief Return errors of mesh computation
+ */
+//================================================================================
+
+SMESH::compute_error_array* SMESH_Gen_i::GetComputeErrors( SMESH::SMESH_Mesh_ptr theMesh, 
+                                                           GEOM::GEOM_Object_ptr theSubObject )
+  throw ( SALOME::SALOME_Exception )
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  if(MYDEBUG) MESSAGE( "SMESH_Gen_i::GetComputeErrors()" );
+
+  if ( CORBA::is_nil( theSubObject ) )
+    THROW_SALOME_CORBA_EXCEPTION( "bad shape object reference", SALOME::BAD_PARAM );
+
+  if ( CORBA::is_nil( theMesh ) )
+    THROW_SALOME_CORBA_EXCEPTION( "bad Mesh reference",SALOME::BAD_PARAM );
+
+  SMESH::compute_error_array_var error_array = new SMESH::compute_error_array;
+  try {
+    if ( SMESH_Mesh_i* meshServant = SMESH::DownCast<SMESH_Mesh_i*>( theMesh ))
+    {
+      TopoDS_Shape shape = GeomObjectToShape( theSubObject );
+      ::SMESH_Mesh& mesh = meshServant->GetImpl();
+
+      error_array->length( mesh.GetMeshDS()->MaxShapeIndex() );
+      int nbErr = 0;
+
+      SMESH_subMesh *sm = mesh.GetSubMesh(shape);
+      const bool includeSelf = true, complexShapeFirst = true;
+      SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(includeSelf,
+                                                               complexShapeFirst);
+      while ( smIt->more() )
+      {
+        sm = smIt->next();
+        if ( sm->GetSubShape().ShapeType() == TopAbs_VERTEX )
+          break;
+        SMESH_ComputeErrorPtr error = sm->GetComputeError();
+        if ( error && !error->IsOK() && error->myAlgo )
+        {
+          SMESH::ComputeError & errStruct = error_array[ nbErr++ ];
+          errStruct.code       = -( error->myName < 0 ? error->myName + 1: error->myName ); // -1 -> 0
+          errStruct.comment    = error->myComment.c_str();
+          errStruct.subShapeID = sm->GetId();
+          SALOMEDS::SObject_var algoSO = GetAlgoSO( error->myAlgo );
+          if ( !algoSO->_is_nil() )
+            errStruct.algoName   = algoSO->GetName();
+          else
+            errStruct.algoName   = error->myAlgo->GetName();
+        }
+      }
+      error_array->length( nbErr );
+    }
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    INFOS( "catch exception "<< S_ex.what() );
+  }
+
+  return error_array._retn();
+}
+
 //================================================================================
 /*!
  * \brief Returns errors of hypotheses definintion
@@ -993,55 +1093,15 @@ SMESH::algo_error_array* SMESH_Gen_i::GetAlgoState( SMESH::SMESH_Mesh_ptr theMes
       int i = 0;
       for ( error = error_list.begin(); error != error_list.end(); ++error )
       {
-        // error name
-        SMESH::AlgoStateErrorName errName;
-        switch ( error->_name ) {
-        case ::SMESH_Gen::MISSING_ALGO:     errName = SMESH::MISSING_ALGO; break;
-        case ::SMESH_Gen::MISSING_HYPO:     errName = SMESH::MISSING_HYPO; break;
-        case ::SMESH_Gen::NOT_CONFORM_MESH: errName = SMESH::NOT_CONFORM_MESH; break;
-        case ::SMESH_Gen::BAD_PARAM_VALUE:  errName = SMESH::BAD_PARAM_VALUE; break;
-        default:
-          THROW_SALOME_CORBA_EXCEPTION( "bad error name",SALOME::BAD_PARAM );
-        }
-        // algo name
-        CORBA::String_var algoName;
-        if ( error->_algo ) {
-          if ( !myCurrentStudy->_is_nil() ) {
-            // find algo in the study
-            SALOMEDS::SComponent_var father = SALOMEDS::SComponent::_narrow
-              ( myCurrentStudy->FindComponent( ComponentDataType() ) );
-            if ( !father->_is_nil() ) {
-              SALOMEDS::ChildIterator_var itBig = myCurrentStudy->NewChildIterator( father );
-              for ( ; itBig->More(); itBig->Next() ) {
-                SALOMEDS::SObject_var gotBranch = itBig->Value();
-                if ( gotBranch->Tag() == GetAlgorithmsRootTag() ) {
-                  SALOMEDS::ChildIterator_var algoIt = myCurrentStudy->NewChildIterator( gotBranch );
-                  for ( ; algoIt->More(); algoIt->Next() ) {
-                    SALOMEDS::SObject_var algoSO = algoIt->Value();
-                    CORBA::Object_var    algoIOR = SObjectToObject( algoSO );
-                    if ( !CORBA::is_nil( algoIOR )) {
-                      SMESH_Hypothesis_i* myImpl = SMESH::DownCast<SMESH_Hypothesis_i*>( algoIOR );
-                      if ( myImpl && myImpl->GetImpl() == error->_algo ) {
-                        algoName = algoSO->GetName();
-                        break;
-                      }
-                    }
-                  } // loop on algo SO's
-                  break;
-                } // if algo tag
-              } // SMESH component iterator
-            }
-          }
-          if ( algoName.in() == 0 )
-            // use algo type name
-            algoName = CORBA::string_dup( error->_algo->GetName() );
-        }
         // fill AlgoStateError structure
         SMESH::AlgoStateError & errStruct = error_array[ i++ ];
-        errStruct.name         = errName;
-        errStruct.algoName     = algoName;
+        errStruct.state        = SMESH_Mesh_i::ConvertHypothesisStatus( error->_name );
         errStruct.algoDim      = error->_algoDim;
         errStruct.isGlobalAlgo = error->_isGlobalAlgo;
+        errStruct.algoName     = "";
+        SALOMEDS::SObject_var algoSO = GetAlgoSO( error->_algo );
+        if ( !algoSO->_is_nil() )
+          errStruct.algoName   = algoSO->GetName();
       }
     }
   }
@@ -1203,11 +1263,34 @@ SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
     GEOM::GEOM_Gen_var    geomGen   = GetGeomEngine();
 
     // try to find the corresponding SObject
-    GeomObjectToShape( geom ); // geom client remembers the found shape
     SALOMEDS::SObject_var SObj = ObjectToSObject( myCurrentStudy, geom.in() );
-    if ( SObj->_is_nil() )
-      // publish a new subshape
+    if ( SObj->_is_nil() ) // submesh can be not found even if published
+    {
+      // try to find published submesh
+      GEOM::ListOfLong_var list = geom->GetSubShapeIndices();
+      if ( !geom->IsMainShape() && list->length() == 1 ) {
+        SALOMEDS::SObject_var mainSO = ObjectToSObject( myCurrentStudy, mainShape );
+        SALOMEDS::ChildIterator_var it;
+        if ( !mainSO->_is_nil() )
+          it = myCurrentStudy->NewChildIterator( mainSO );
+        if ( !it->_is_nil() ) {
+          for ( it->InitEx(true); SObj->_is_nil() && it->More(); it->Next() ) {
+            GEOM::GEOM_Object_var subGeom =
+              GEOM::GEOM_Object::_narrow( SObjectToObject( it->Value() ));
+            if ( !subGeom->_is_nil() ) {
+              GEOM::ListOfLong_var subList = subGeom->GetSubShapeIndices();
+              if ( subList->length() == 1 && list[0] == subList[0] ) {
+                SObj = it->Value();
+                geom = subGeom;
+              }
+            }
+          }
+        }
+      }
+    }
+    if ( SObj->_is_nil() ) // publish a new subshape
       SObj = geomGen->AddInStudy( myCurrentStudy, geom, theGeomName, mainShape );
+
     // return only published geometry
     if ( !SObj->_is_nil() )
       return geom._retn();
@@ -1215,7 +1298,6 @@ SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
   return GEOM::GEOM_Object::_nil();
 }
 
-
 //================================================================================
 /*!
  * \brief Return geometrical object the given element is built on.
@@ -1227,7 +1309,7 @@ SMESH_Gen_i::GetGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
 
 GEOM::GEOM_Object_ptr
 SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
-                                   CORBA::Long            theElementID)
+                                        CORBA::Long            theElementID)
   throw ( SALOME::SALOME_Exception )
 {
   Unexpect aCatch(SALOME_SalomeException);
@@ -1255,13 +1337,203 @@ SMESH_Gen_i::FindGeometryByMeshElement( SMESH::SMESH_Mesh_ptr  theMesh,
           if ( !op->_is_nil() )
             geom = op->GetSubShape( mainShape, shapeID );
         }
-        if ( !geom->_is_nil() )
+        if ( !geom->_is_nil() ) {
+          GeomObjectToShape( geom ); // let geom client remember the found shape
          return geom._retn();
+        }
       }
   }
   return GEOM::GEOM_Object::_nil();
 }
 
+//================================================================================
+/*!
+ *  SMESH_Gen_i::Concatenate
+ *
+ *  Concatenate the given meshes into one mesh
+ */
+//================================================================================
+
+SMESH::SMESH_Mesh_ptr SMESH_Gen_i::Concatenate(const SMESH::mesh_array& theMeshesArray,
+                                              CORBA::Boolean           theUniteIdenticalGroups, 
+                                              CORBA::Boolean           theMergeNodesAndElements, 
+                                              CORBA::Double            theMergeTolerance)
+  throw ( SALOME::SALOME_Exception )
+{
+  typedef map<int, int> TIDsMap;
+  typedef list<SMESH::SMESH_Group_var> TListOfNewGroups;
+  typedef map< pair<string, SMESH::ElementType>, TListOfNewGroups > TGroupsMap;
+  typedef std::set<SMESHDS_GroupBase*> TGroups;
+
+  TPythonDump aPythonDump; // prevent dump of called methods
+
+  // create mesh
+  SMESH::SMESH_Mesh_var aNewMesh = CreateEmptyMesh();
+  
+  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();
+
+      TGroupsMap aGroupsMap;
+      TListOfNewGroups aListOfNewGroups;
+      SMESH_MeshEditor aNewEditor = ::SMESH_MeshEditor(&aLocMesh);
+      SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
+
+      // loop on meshes
+      for ( int i = 0; i < theMeshesArray.length(); i++) {
+       SMESH::SMESH_Mesh_var anInitMesh = theMeshesArray[i];
+       if ( !anInitMesh->_is_nil() ) {
+         SMESH_Mesh_i* anInitImpl = dynamic_cast<SMESH_Mesh_i*>( GetServant( anInitMesh ).in() );
+         if ( anInitImpl ) {
+           ::SMESH_Mesh& aInitLocMesh = anInitImpl->GetImpl();
+           SMESHDS_Mesh* anInitMeshDS = aInitLocMesh.GetMeshDS();
+
+           TIDsMap nodesMap;
+           TIDsMap elemsMap;
+
+           // loop on elements of mesh
+           SMDS_ElemIteratorPtr itElems = anInitMeshDS->elementsIterator();
+           const SMDS_MeshElement* anElem = 0;
+           const SMDS_MeshElement* aNewElem = 0;
+           int anElemNbNodes = 0;
+
+           for ( int j = 0; itElems->more(); j++) {
+             anElem = itElems->next();
+             SMDSAbs_ElementType anElemType = anElem->GetType();
+             anElemNbNodes = anElem->NbNodes();
+             std::vector<const SMDS_MeshNode*> aNodesArray (anElemNbNodes);
+
+             // loop on nodes of element
+             const SMDS_MeshNode* aNode = 0;
+             const SMDS_MeshNode* aNewNode = 0;
+             SMDS_ElemIteratorPtr itNodes = anElem->nodesIterator();
+
+             for ( int k = 0; itNodes->more(); k++) {
+               aNode = static_cast<const SMDS_MeshNode*>(itNodes->next());
+               if ( nodesMap.find(aNode->GetID()) == nodesMap.end() ) {
+                 aNewNode = aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z());
+                 nodesMap.insert( make_pair(aNode->GetID(), aNewNode->GetID()) );
+               }
+               else
+                 aNewNode = aNewMeshDS->FindNode( nodesMap.find(aNode->GetID())->second );
+               aNodesArray[k] = aNewNode;
+             }//nodes loop
+
+             // 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);
+                 if ( aVolume ) {
+                   aNewElem = aNewMeshDS->AddPolyhedralVolume(aNodesArray, 
+                                                              aVolume->GetQuanities());
+                   elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
+                 }
+               }
+             else {
+               
+               aNewElem = aNewEditor.AddElement(aNodesArray,
+                                                anElemType,
+                                                anElem->IsPoly());
+               elemsMap.insert(make_pair(anElem->GetID(), aNewElem->GetID()));
+             } 
+           }//elems loop
+           
+           aListOfGroups = anInitImpl->GetGroups();
+           SMESH::SMESH_GroupBase_ptr aGroup;
+
+           // loop on groups of mesh
+           SMESH::long_array_var anInitIDs = new SMESH::long_array();
+           SMESH::long_array_var anNewIDs = new SMESH::long_array();
+           SMESH::SMESH_Group_var aNewGroup;
+           for (int i = 0; i < aListOfGroups->length(); i++) {
+             aGroup = aListOfGroups[i];
+             aListOfNewGroups.clear();
+             SMESH::ElementType aGroupType = aGroup->GetType();
+             CORBA::String_var aGroupName = aGroup->GetName();
+             
+             TGroupsMap::iterator anIter = aGroupsMap.find(make_pair(aGroupName, aGroupType));
+
+             // convert a list of IDs
+             anInitIDs = aGroup->GetListOfID();
+             anNewIDs->length(anInitIDs->length());
+             if ( aGroupType == SMESH::NODE )
+               for (int j = 0; j < anInitIDs->length(); j++) {
+                 anNewIDs[j] = nodesMap.find(anInitIDs[j])->second;
+               }
+             else
+               for (int j = 0; j < anInitIDs->length(); j++) {
+                 anNewIDs[j] = elemsMap.find(anInitIDs[j])->second;
+               }
+             
+             // check that current group name and type don't have identical ones in union mesh
+             if ( anIter == aGroupsMap.end() ) {
+               // add a new group in the mesh
+               aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
+               // add elements into new group
+               aNewGroup->Add( anNewIDs );
+               
+               aListOfNewGroups.push_back(aNewGroup);
+               aGroupsMap.insert(make_pair( make_pair(aGroupName, aGroupType), aListOfNewGroups ));
+             }
+
+             else if ( theUniteIdenticalGroups ) {
+               // unite identical groups
+               TListOfNewGroups& aNewGroups = anIter->second;
+               aNewGroups.front()->Add( anNewIDs );
+             }
+
+             else {
+               // rename identical groups
+               aNewGroup = aNewImpl->CreateGroup(aGroupType, aGroupName);
+               aNewGroup->Add( anNewIDs );
+               
+               TListOfNewGroups& aNewGroups = anIter->second;
+               string aNewGroupName;
+               if (aNewGroups.size() == 1) {
+                 aNewGroupName = string(aGroupName) + "_1";
+                 aNewGroups.front()->SetName(aNewGroupName.c_str());
+               }
+               char aGroupNum[128];
+               sprintf(aGroupNum, "%u", aNewGroups.size()+1);
+               aNewGroupName = string(aGroupName) + "_" + string(aGroupNum);
+               aNewGroup->SetName(aNewGroupName.c_str());
+               aNewGroups.push_back(aNewGroup);
+             }
+           }//groups loop
+         }
+       }
+      }//meshes loop
+
+      if (theMergeNodesAndElements) {
+       // merge nodes
+       set<const SMDS_MeshNode*> aMeshNodes; // no input nodes
+       SMESH_MeshEditor::TListOfListOfNodes aGroupsOfNodes;
+       aNewEditor.FindCoincidentNodes( aMeshNodes, theMergeTolerance, aGroupsOfNodes );
+       aNewEditor.MergeNodes( aGroupsOfNodes );
+       // merge elements
+       aNewEditor.MergeEqualElements();
+      }
+    }
+  }
+  
+  // Update Python script
+  aPythonDump << aNewMesh << " = " << this << ".Concatenate(";
+  aPythonDump << "[";
+  for ( int i = 0; i < theMeshesArray.length(); i++) {
+    if (i > 0) aPythonDump << ", ";
+    aPythonDump << theMeshesArray[i];
+  }
+  aPythonDump << "], ";
+  aPythonDump << theUniteIdenticalGroups << ", "
+              << theMergeNodesAndElements << ", "
+              << theMergeTolerance << ")";
+
+  return aNewMesh._retn();
+}
+
 //=============================================================================
 /*!
  *  SMESH_Gen_i::Save
@@ -2868,7 +3140,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
               aDataset->CloseOnDisk();
 
               // get elements sorted by ID
-              ::SMESH_MeshEditor::TIDSortedElemSet elemSet;
+              TIDSortedElemSet elemSet;
               if ( isNode )
                 while ( nIt->more() ) elemSet.insert( nIt->next() );
               else
@@ -2876,7 +3148,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
               ASSERT( elemSet.size() == nbElems );
 
               // add elements to submeshes
-              ::SMESH_MeshEditor::TIDSortedElemSet::iterator iE = elemSet.begin();
+              TIDSortedElemSet::iterator iE = elemSet.begin();
               for ( int i = 0; i < nbElems; ++i, ++iE )
               {
                 int smID = smIDs[ i ];
@@ -2900,7 +3172,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent,
                   sm->AddElement( elem );
                 }
               }
-              delete smIDs;
+              delete [] smIDs;
             }
           }
         } // end reading submeshes
index 4a1088f965c6a7d8d09bda9a54d6a60a43f284ee..e87780cf2ae6b1f87366e9cc40d48fab2b4c7b51 100644 (file)
@@ -222,7 +222,13 @@ public:
 
   // Compute mesh on a shape
   CORBA::Boolean Compute( SMESH::SMESH_Mesh_ptr theMesh,
-                          GEOM::GEOM_Object_ptr  theShapeObject )
+                          GEOM::GEOM_Object_ptr theShapeObject )
+    throw ( SALOME::SALOME_Exception );
+  /*!
+   * \brief Return errors of mesh computation
+   */
+  SMESH::compute_error_array* GetComputeErrors(SMESH::SMESH_Mesh_ptr theMesh,
+                                               GEOM::GEOM_Object_ptr  theShapeObject )
     throw ( SALOME::SALOME_Exception );
 
   // Returns true if mesh contains enough data to be computed
@@ -251,6 +257,14 @@ public:
                                                   CORBA::Long            theElementID)
     throw ( SALOME::SALOME_Exception );
 
+  // Concatenate the given meshes into one mesh
+  SMESH::SMESH_Mesh_ptr Concatenate(const SMESH::mesh_array& theMeshesArray, 
+                                   CORBA::Boolean           theUniteIdenticalGroups, 
+                                   CORBA::Boolean           theMergeNodesAndElements, 
+                                   CORBA::Double            theMergeTolerance)
+    throw ( SALOME::SALOME_Exception );
+
+
   // ****************************************************
   // Interface inherited methods (from SALOMEDS::Driver)
   // ****************************************************
@@ -428,6 +442,11 @@ public:
   // Get current study ID
   int GetCurrentStudyID()
   { return myCurrentStudy->_is_nil() ? -1 : myCurrentStudy->StudyId(); }
+
+  /*!
+   * \brief Find SObject for an algo
+   */
+  SALOMEDS::SObject_ptr GetAlgoSO(const ::SMESH_Algo* algo);
  
 private:
   // Create hypothesis of given type
index 1a87b258f72822f2040d7ae62886c749e4a17dad..ff3eed5e8eedafd07c8b472ab3b852e5fee815d4 100644 (file)
@@ -31,9 +31,9 @@
 #include "SMDS_MeshEdge.hxx"
 #include "SMDS_MeshFace.hxx"
 #include "SMDS_MeshVolume.hxx"
-
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
 #include "SMESH_MeshEditor.hxx"
-
+#include "SMESH_subMeshEventListener.hxx"
 #include "SMESH_Gen_i.hxx"
 #include "SMESH_Filter_i.hxx"
 #include "SMESH_PythonDump.hxx"
 
 #include <sstream>
 
-typedef map<const SMDS_MeshElement*,
-            list<const SMDS_MeshElement*> > TElemOfElemListMap;
+#define cast2Node(elem) static_cast<const SMDS_MeshNode*>( elem )
 
 using namespace std;
 using SMESH::TPythonDump;
 
+namespace {
+
+  //=============================================================================
+  /*!
+   * \brief Mesh to apply modifications for preview purposes
+   */
+  //=============================================================================
+
+  struct TPreviewMesh: public SMESH_Mesh
+  {
+    SMDSAbs_ElementType myPreviewType; // type to show
+    //!< Constructor
+    TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
+      _isShapeToMesh = _id =_studyId =_idDoc = 0;
+      _myMeshDS  = new SMESHDS_Mesh( _id, true );
+      myPreviewType = previewElements;
+    }
+    //!< Destructor
+    virtual ~TPreviewMesh() { delete _myMeshDS; }
+    //!< Copy a set of elements
+    void Copy(const TIDSortedElemSet & theElements,
+              TIDSortedElemSet&        theCopyElements,
+              SMDSAbs_ElementType      theSelectType = SMDSAbs_All,
+              SMDSAbs_ElementType      theAvoidType = SMDSAbs_All)
+    {
+      // loop on theIDsOfElements
+      TIDSortedElemSet::const_iterator eIt = theElements.begin();
+      for ( ; eIt != theElements.end(); ++eIt )
+      {
+        const SMDS_MeshElement* anElem = *eIt;
+        if ( !anElem ) continue;
+        SMDSAbs_ElementType type = anElem->GetType();
+        if ( type == theAvoidType ||
+             ( theSelectType != SMDSAbs_All && type != theSelectType ))
+          continue;
+
+        if ( const SMDS_MeshElement* anElemCopy = Copy( anElem ))
+          theCopyElements.insert( theCopyElements.end(), anElemCopy );
+      }
+    }
+    //!< Copy an element
+    SMDS_MeshElement* Copy( const SMDS_MeshElement* anElem )
+    {
+      // copy element nodes
+      int anElemNbNodes = anElem->NbNodes();
+      vector< int > anElemNodesID( anElemNbNodes ) ;
+      SMDS_ElemIteratorPtr itElemNodes = anElem->nodesIterator();
+      for ( int i = 0; itElemNodes->more(); i++)
+      {
+        const SMDS_MeshNode* anElemNode = cast2Node( itElemNodes->next() );
+        Copy( anElemNode );
+        anElemNodesID[i] = anElemNode->GetID();
+      }
+
+      // creates a corresponding element on copied nodes
+      SMDS_MeshElement* anElemCopy = 0;
+      if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
+      {
+        const SMDS_PolyhedralVolumeOfNodes* ph =
+          dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*> (anElem);
+        if ( ph )
+          anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
+            (anElemNodesID, ph->GetQuanities(),anElem->GetID());
+      }
+      else {
+        anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
+                                                          anElem->GetType(),
+                                                          anElem->IsPoly() );
+      }
+      return anElemCopy;
+    }
+    //!< Copy a node
+    SMDS_MeshNode* Copy( const SMDS_MeshNode* anElemNode )
+    {
+      return _myMeshDS->AddNodeWithID(anElemNode->X(), anElemNode->Y(), anElemNode->Z(), 
+                                      anElemNode->GetID());
+    }
+  };// struct TPreviewMesh
+
+  static SMESH_NodeSearcher * myNodeSearcher = 0;
+
+  //=============================================================================
+  /*!
+   * \brief Deleter of myNodeSearcher at any compute event occured
+   */
+  //=============================================================================
+
+  struct TNodeSearcherDeleter : public SMESH_subMeshEventListener
+  {
+    SMESH_Mesh* myMesh;
+    //!< Constructor
+    TNodeSearcherDeleter(): SMESH_subMeshEventListener( false ), // won't be deleted by submesh
+    myMesh(0) {}
+    //!< Delete myNodeSearcher
+    static void Delete()
+    {
+      if ( myNodeSearcher ) { delete myNodeSearcher; myNodeSearcher = 0; }
+    }
+    typedef map < int, SMESH_subMesh * > TDependsOnMap;
+    //!< The meshod called by submesh: do my main job
+    void ProcessEvent(const int, const int eventType, SMESH_subMesh* sm,
+                      SMESH_subMeshEventListenerData*,const SMESH_Hypothesis*)
+    {
+      if ( eventType == SMESH_subMesh::COMPUTE_EVENT ) {
+        Delete();
+        Unset( sm->GetFather() );
+      }
+    }
+    //!< set self on all submeshes and delete myNodeSearcher if other mesh is set
+    void Set(SMESH_Mesh* mesh)
+    {
+      if ( myMesh && myMesh != mesh ) {
+        Delete();
+        Unset( myMesh );
+      }
+      myMesh = mesh;
+      if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
+        const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
+        TDependsOnMap::const_iterator sm;
+        for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
+          sm->second->SetEventListener( this, 0, sm->second );
+      }
+    }
+    //!<  delete self from all submeshes
+    void Unset(SMESH_Mesh* mesh)
+    {
+      if ( SMESH_subMesh* myMainSubMesh = mesh->GetSubMeshContaining(1) ) {
+        const TDependsOnMap & subMeshes = myMainSubMesh->DependsOn();
+        TDependsOnMap::const_iterator sm;
+        for (sm = subMeshes.begin(); sm != subMeshes.end(); sm++)
+          sm->second->DeleteEventListener( this );
+      }
+    }
+  };
+}
+
 //=============================================================================
 /*!
  *
  */
 //=============================================================================
 
-SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh* theMesh)
+SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh* theMesh, bool isPreview)
+{
+  myMesh = theMesh;
+  myPreviewMode = isPreview;
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+ */
+//================================================================================
+
+SMESH_MeshEditor_i::~SMESH_MeshEditor_i()
 {
-       _myMesh = theMesh;
+}
+
+//================================================================================
+/*!
+ * \brief Clear members
+ */
+//================================================================================
+
+void SMESH_MeshEditor_i::initData()
+{
+  if ( myPreviewMode ) {
+    myPreviewData = new SMESH::MeshPreviewStruct();
+  }
+  else {
+    myLastCreatedElems = new SMESH::long_array();
+    myLastCreatedNodes = new SMESH::long_array();
+    TNodeSearcherDeleter::Delete();
+  }
 }
 
 //=============================================================================
@@ -85,10 +249,9 @@ SMESH_MeshEditor_i::SMESH_MeshEditor_i(SMESH_Mesh* theMesh)
 CORBA::Boolean
   SMESH_MeshEditor_i::RemoveElements(const SMESH::long_array & IDsOfElements)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
-  ::SMESH_MeshEditor anEditor( _myMesh );
+  ::SMESH_MeshEditor anEditor( myMesh );
   list< int > IdList;
 
   for (int i = 0; i < IDsOfElements.length(); i++)
@@ -111,10 +274,9 @@ CORBA::Boolean
 
 CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNodes)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
-  ::SMESH_MeshEditor anEditor( _myMesh );
+  ::SMESH_MeshEditor anEditor( myMesh );
   list< int > IdList;
   for (int i = 0; i < IDsOfNodes.length(); i++)
     IdList.push_back( IDsOfNodes[i] );
@@ -136,8 +298,7 @@ CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNo
 
 CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   int NbNodes = IDsOfNodes.length();
   SMDS_MeshElement* elem = 0;
@@ -178,8 +339,7 @@ CORBA::Long SMESH_MeshEditor_i::AddEdge(const SMESH::long_array & IDsOfNodes)
 CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
                                         CORBA::Double y, CORBA::Double z)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   const SMDS_MeshNode* N = GetMeshDS()->AddNode(x, y, z);
 
@@ -198,8 +358,7 @@ CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x,
 
 CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   int NbNodes = IDsOfNodes.length();
   if (NbNodes < 3)
@@ -244,8 +403,7 @@ CORBA::Long SMESH_MeshEditor_i::AddFace(const SMESH::long_array & IDsOfNodes)
 CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace
                                    (const SMESH::long_array & IDsOfNodes)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   int NbNodes = IDsOfNodes.length();
   std::vector<const SMDS_MeshNode*> nodes (NbNodes);
@@ -274,8 +432,7 @@ CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace
 
 CORBA::Long SMESH_MeshEditor_i::AddVolume(const SMESH::long_array & IDsOfNodes)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   int NbNodes = IDsOfNodes.length();
   vector< const SMDS_MeshNode*> n(NbNodes);
@@ -325,8 +482,7 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume
                                    (const SMESH::long_array & IDsOfNodes,
                                     const SMESH::long_array & Quantities)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   int NbNodes = IDsOfNodes.length();
   std::vector<const SMDS_MeshNode*> n (NbNodes);
@@ -361,8 +517,7 @@ CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolume
 CORBA::Long SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces
                                    (const SMESH::long_array & IdsOfFaces)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   int NbFaces = IdsOfFaces.length();
   std::vector<const SMDS_MeshNode*> poly_nodes;
@@ -404,8 +559,7 @@ CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long   NodeID,
                                             CORBA::Double y,
                                             CORBA::Double z)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   const SMDS_MeshNode * node = GetMeshDS()->FindNode( NodeID );
   if ( !node )
@@ -429,8 +583,7 @@ CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long   NodeID,
 CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
                                                CORBA::Long NodeID2)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
   const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
@@ -441,7 +594,7 @@ CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
   TPythonDump() << "isDone = " << this << ".InverseDiag( "
                 << NodeID1 << ", " << NodeID2 << " )";
 
-  ::SMESH_MeshEditor aMeshEditor( _myMesh );
+  ::SMESH_MeshEditor aMeshEditor( myMesh );
   return aMeshEditor.InverseDiag ( n1, n2 );
 }
 
@@ -454,8 +607,7 @@ CORBA::Boolean SMESH_MeshEditor_i::InverseDiag(CORBA::Long NodeID1,
 CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
                                               CORBA::Long NodeID2)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   const SMDS_MeshNode * n1 = GetMeshDS()->FindNode( NodeID1 );
   const SMDS_MeshNode * n2 = GetMeshDS()->FindNode( NodeID2 );
@@ -466,11 +618,11 @@ CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
   TPythonDump() << "isDone = " << this << ".DeleteDiag( "
                 << NodeID1 << ", " << NodeID2 <<  " )";
 
-  ::SMESH_MeshEditor aMeshEditor( _myMesh );
+  ::SMESH_MeshEditor aMeshEditor( myMesh );
 
   bool stat = aMeshEditor.DeleteDiag ( n1, n2 );
 
-  UpdateLastResult(aMeshEditor);
+  StoreResult(aMeshEditor);
 
   return stat;
 }
@@ -483,10 +635,9 @@ CORBA::Boolean SMESH_MeshEditor_i::DeleteDiag(CORBA::Long NodeID1,
 
 CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfElements)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
-  ::SMESH_MeshEditor anEditor( _myMesh );
+  ::SMESH_MeshEditor anEditor( myMesh );
   for (int i = 0; i < IDsOfElements.length(); i++)
   {
     CORBA::Long index = IDsOfElements[i];
@@ -509,8 +660,7 @@ CORBA::Boolean SMESH_MeshEditor_i::Reorient(const SMESH::long_array & IDsOfEleme
 
 CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theObject)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   CORBA::Boolean isDone = Reorient(anElementsId);
@@ -525,29 +675,32 @@ CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theO
   return isDone;
 }
 
-
-//=======================================================================
-//function : ToMap
-//purpose  : auxilary function for conversion long_array to std::map<>
-//           which is used in some methods
-//=======================================================================
-static void ToMap(const SMESH::long_array &              IDs,
-                  const SMESHDS_Mesh*                    aMesh,
-                  std::map<int,const SMDS_MeshElement*>& aMap,
-                  const SMDSAbs_ElementType              aType = SMDSAbs_All )
-{ 
-  for (int i=0; i<IDs.length(); i++) {
-    CORBA::Long ind = IDs[i];
-    std::map<int,const SMDS_MeshElement*>::iterator It = aMap.find(ind);
-    if(It==aMap.end()) {
+namespace
+{
+  //================================================================================
+  /*!
+   * \brief function for conversion long_array to TIDSortedElemSet
+    * \param IDs - array of IDs
+    * \param aMesh - mesh
+    * \param aMap - collection to fill
+    * \param aType - element type
+   */
+  //================================================================================
+
+  void ToMap(const SMESH::long_array & IDs,
+             const SMESHDS_Mesh*       aMesh,
+             TIDSortedElemSet&         aMap,
+             const SMDSAbs_ElementType aType = SMDSAbs_All )
+  { 
+    for (int i=0; i<IDs.length(); i++) {
+      CORBA::Long ind = IDs[i];
       const SMDS_MeshElement * elem = aMesh->FindElement(ind);
       if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType ))
-        aMap.insert( make_pair( elem->GetID(), elem ));
+        aMap.insert( elem );
     }
   }
 }
 
-
 //=============================================================================
 /*!
  *
@@ -557,11 +710,10 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array &   IDsOfE
                                               SMESH::NumericalFunctor_ptr Criterion,
                                               CORBA::Double               MaxAngle)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESHDS_Mesh* aMesh = GetMeshDS();
-  map<int,const SMDS_MeshElement*> faces;
+  TIDSortedElemSet faces;
   ToMap(IDsOfElements, aMesh, faces, SMDSAbs_Face);
 
   SMESH::NumericalFunctor_i* aNumericalFunctor =
@@ -579,11 +731,11 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuad (const SMESH::long_array &   IDsOfE
   TPythonDump() << "print 'TriToQuad: ', isDone";
 #endif
 
-  ::SMESH_MeshEditor anEditor( _myMesh );
+  ::SMESH_MeshEditor anEditor( myMesh );
 
   bool stat = anEditor.TriToQuad( faces, aCrit, MaxAngle );
 
-  UpdateLastResult(anEditor);
+  StoreResult(anEditor);
 
   return stat;
 }
@@ -598,8 +750,7 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr
                                                     SMESH::NumericalFunctor_ptr Criterion,
                                                     CORBA::Double               MaxAngle)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   CORBA::Boolean isDone = TriToQuad(anElementsId, Criterion, MaxAngle);
@@ -633,11 +784,10 @@ CORBA::Boolean SMESH_MeshEditor_i::TriToQuadObject (SMESH::SMESH_IDSource_ptr
 CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array &   IDsOfElements,
                                               SMESH::NumericalFunctor_ptr Criterion)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESHDS_Mesh* aMesh = GetMeshDS();
-  map<int,const SMDS_MeshElement*> faces;
+  TIDSortedElemSet faces;
   ToMap(IDsOfElements, aMesh, faces, SMDSAbs_Face);
 
   SMESH::NumericalFunctor_i* aNumericalFunctor =
@@ -655,10 +805,10 @@ CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array &   IDsOfE
   TPythonDump() << "print 'QuadToTri: ', isDone";
 #endif
 
-  ::SMESH_MeshEditor anEditor( _myMesh );
+  ::SMESH_MeshEditor anEditor( myMesh );
   CORBA::Boolean stat = anEditor.QuadToTri( faces, aCrit );
 
-  UpdateLastResult(anEditor);
+  StoreResult(anEditor);
 
   return stat;
 }
@@ -672,8 +822,7 @@ CORBA::Boolean SMESH_MeshEditor_i::QuadToTri (const SMESH::long_array &   IDsOfE
 CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr   theObject,
                                                     SMESH::NumericalFunctor_ptr Criterion)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   CORBA::Boolean isDone = QuadToTri(anElementsId, Criterion);
@@ -706,11 +855,10 @@ CORBA::Boolean SMESH_MeshEditor_i::QuadToTriObject (SMESH::SMESH_IDSource_ptr
 CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfElements,
                                               CORBA::Boolean            Diag13)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESHDS_Mesh* aMesh = GetMeshDS();
-  map<int,const SMDS_MeshElement*> faces;
+  TIDSortedElemSet faces;
   ToMap(IDsOfElements, aMesh, faces, SMDSAbs_Face);
 
   // Update Python script
@@ -720,10 +868,10 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfEle
   TPythonDump() << "print 'SplitQuad: ', isDone";
 #endif
 
-  ::SMESH_MeshEditor anEditor( _myMesh );
+  ::SMESH_MeshEditor anEditor( myMesh );
   CORBA::Boolean stat = anEditor.QuadToTri( faces, Diag13 );
 
-  UpdateLastResult(anEditor);
+  StoreResult(anEditor);
 
   return stat;
 }
@@ -737,8 +885,7 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuad (const SMESH::long_array & IDsOfEle
 CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr theObject,
                                                     CORBA::Boolean            Diag13)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   CORBA::Boolean isDone = SplitQuad(anElementsId, Diag13);
@@ -780,7 +927,7 @@ CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long                 IDOfQuad,
     else
       aCrit.reset(new SMESH::Controls::AspectRatio());
 
-    ::SMESH_MeshEditor anEditor (_myMesh);
+    ::SMESH_MeshEditor anEditor (myMesh);
     return anEditor.BestSplit(quad, aCrit);
   }
   return -1;
@@ -869,12 +1016,11 @@ CORBA::Boolean
                              SMESH::SMESH_MeshEditor::Smooth_Method Method,
                              bool                                   IsParametric)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESHDS_Mesh* aMesh = GetMeshDS();
 
-  map<int,const SMDS_MeshElement*> elements;
+  TIDSortedElemSet elements;
   ToMap(IDsOfElements, aMesh, elements, SMDSAbs_Face);
 
   set<const SMDS_MeshNode*> fixedNodes;
@@ -888,11 +1034,11 @@ CORBA::Boolean
   if ( Method != SMESH::SMESH_MeshEditor::LAPLACIAN_SMOOTH )
     method = ::SMESH_MeshEditor::CENTROIDAL;
 
-  ::SMESH_MeshEditor anEditor( _myMesh );
+  ::SMESH_MeshEditor anEditor( myMesh );
   anEditor.Smooth(elements, fixedNodes, method,
                   MaxNbOfIterations, MaxAspectRatio, IsParametric );
 
-  UpdateLastResult(anEditor);
+  StoreResult(anEditor);
 
   // Update Python script
   TPythonDump() << "isDone = " << this << "."
@@ -924,8 +1070,7 @@ SMESH_MeshEditor_i::smoothObject(SMESH::SMESH_IDSource_ptr              theObjec
                                  SMESH::SMESH_MeshEditor::Smooth_Method Method,
                                  bool                                   IsParametric)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   CORBA::Boolean isDone = smooth (anElementsId, IDsOfFixedNodes, MaxNbOfIterations,
@@ -995,31 +1140,47 @@ void SMESH_MeshEditor_i::RotationSweep(const SMESH::long_array & theIDsOfElement
                                        CORBA::Long               theNbOfSteps,
                                        CORBA::Double             theTolerance)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
-  SMESHDS_Mesh* aMesh = GetMeshDS();
+  TIDSortedElemSet inElements, copyElements;
+  ToMap(theIDsOfElements, GetMeshDS(), inElements);
 
-  map<int,const SMDS_MeshElement*> elements;
-  ToMap(theIDsOfElements, aMesh, elements);
+  TIDSortedElemSet* workElements = & inElements;
+  TPreviewMesh      tmpMesh( SMDSAbs_Face );
+  SMESH_Mesh*       mesh = 0;
+  bool              makeWalls=true;
+  if ( myPreviewMode )
+  {
+    SMDSAbs_ElementType select = SMDSAbs_All, avoid = SMDSAbs_Volume;
+    tmpMesh.Copy( inElements, copyElements, select, avoid );
+    mesh = &tmpMesh;
+    workElements = & copyElements;
+    //makeWalls = false;
+  }
+  else
+  {
+    mesh = myMesh;
+  }
 
-  gp_Ax1 Ax1 (gp_Pnt( theAxis.x, theAxis.y, theAxis.z ),
+  gp_Ax1 Ax1 (gp_Pnt( theAxis.x,  theAxis.y,  theAxis.z ),
               gp_Vec( theAxis.vx, theAxis.vy, theAxis.vz ));
 
-  ::SMESH_MeshEditor anEditor( _myMesh );
-  anEditor.RotationSweep (elements, Ax1, theAngleInRadians,
-                          theNbOfSteps, theTolerance);
+  ::SMESH_MeshEditor anEditor( mesh );
+  anEditor.RotationSweep (*workElements, Ax1, theAngleInRadians,
+                          theNbOfSteps, theTolerance, makeWalls);
 
-  UpdateLastResult(anEditor);
+  StoreResult(anEditor);
 
-  // Update Python script
-  TPythonDump() << "axis = " << theAxis;
-  TPythonDump() << this << ".RotationSweep( "
-                << theIDsOfElements
-                << ", axis, "
-                << theAngleInRadians << ", "
-                << theNbOfSteps << ", "
-                << theTolerance << " )";
+  if ( !myPreviewMode ) {
+    // Update Python script
+    TPythonDump() << "axis = " << theAxis;
+    TPythonDump() << this << ".RotationSweep( "
+                  << theIDsOfElements
+                  << ", axis, "
+                  << theAngleInRadians << ", "
+                  << theNbOfSteps << ", "
+                  << theTolerance << " )";
+  }
 }
 
 //=======================================================================
@@ -1033,8 +1194,7 @@ void SMESH_MeshEditor_i::RotationSweepObject(SMESH::SMESH_IDSource_ptr theObject
                                             CORBA::Long               theNbOfSteps,
                                             CORBA::Double             theTolerance)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   RotationSweep(anElementsId, theAxis, theAngleInRadians, theNbOfSteps, theTolerance);
@@ -1061,8 +1221,7 @@ void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElemen
                                         const SMESH::DirStruct &  theStepVector,
                                         CORBA::Long               theNbOfSteps)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
 #ifdef NO_CAS_CATCH
   try {   
@@ -1072,17 +1231,17 @@ void SMESH_MeshEditor_i::ExtrusionSweep(const SMESH::long_array & theIDsOfElemen
 #endif
     SMESHDS_Mesh* aMesh = GetMeshDS();
 
-    map<int,const SMDS_MeshElement*> elements;
+    TIDSortedElemSet elements;
     ToMap(theIDsOfElements, aMesh, elements);
 
     const SMESH::PointStruct * P = &theStepVector.PS;
     gp_Vec stepVec( P->x, P->y, P->z );
 
     TElemOfElemListMap aHystory;
-    ::SMESH_MeshEditor anEditor( _myMesh );
+    ::SMESH_MeshEditor anEditor( myMesh );
     anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory);
 
-    UpdateLastResult(anEditor);
+    StoreResult(anEditor);
 
     // Update Python script
     TPythonDump() << "stepVector = " << theStepVector;
@@ -1109,8 +1268,7 @@ void SMESH_MeshEditor_i::ExtrusionSweepObject(SMESH::SMESH_IDSource_ptr theObjec
                                              const SMESH::DirStruct &  theStepVector,
                                              CORBA::Long               theNbOfSteps)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   ExtrusionSweep(anElementsId, theStepVector, theNbOfSteps);
@@ -1133,25 +1291,24 @@ void SMESH_MeshEditor_i::ExtrusionSweepObject1D(SMESH::SMESH_IDSource_ptr theObj
                                                 const SMESH::DirStruct &  theStepVector,
                                                 CORBA::Long               theNbOfSteps)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESHDS_Mesh* aMesh = GetMeshDS();
 
   SMESH::long_array_var allElementsId = theObject->GetIDs();
 
-  map<int,const SMDS_MeshElement*> elements;
+  TIDSortedElemSet elements;
   ToMap(allElementsId, aMesh, elements);
 
   const SMESH::PointStruct * P = &theStepVector.PS;
   gp_Vec stepVec( P->x, P->y, P->z );
 
-  ::SMESH_MeshEditor anEditor( _myMesh );
+  ::SMESH_MeshEditor anEditor( myMesh );
   //anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps);
   TElemOfElemListMap aHystory;
   anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory);
 
-  UpdateLastResult(anEditor);
+  StoreResult(anEditor);
 
   // Update Python script
   TPythonDump() << "stepVector = " << theStepVector;
@@ -1168,25 +1325,24 @@ void SMESH_MeshEditor_i::ExtrusionSweepObject2D(SMESH::SMESH_IDSource_ptr theObj
                                                 const SMESH::DirStruct &  theStepVector,
                                                 CORBA::Long               theNbOfSteps)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESHDS_Mesh* aMesh = GetMeshDS();
 
   SMESH::long_array_var allElementsId = theObject->GetIDs();
 
-  map<int,const SMDS_MeshElement*> elements;
+  TIDSortedElemSet elements;
   ToMap(allElementsId, aMesh, elements);
 
   const SMESH::PointStruct * P = &theStepVector.PS;
   gp_Vec stepVec( P->x, P->y, P->z );
 
-  ::SMESH_MeshEditor anEditor( _myMesh );
+  ::SMESH_MeshEditor anEditor( myMesh );
   //anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps);
   TElemOfElemListMap aHystory;
   anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory);
 
-  UpdateLastResult(anEditor);
+  StoreResult(anEditor);
 
   // Update Python script
   TPythonDump() << "stepVector = " << theStepVector;
@@ -1206,23 +1362,22 @@ void SMESH_MeshEditor_i::AdvancedExtrusion(const SMESH::long_array & theIDsOfEle
                                           CORBA::Long               theExtrFlags,
                                           CORBA::Double             theSewTolerance)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESHDS_Mesh* aMesh = GetMeshDS();
 
-  map<int,const SMDS_MeshElement*> elements;
+  TIDSortedElemSet elements;
   ToMap(theIDsOfElements, aMesh, elements);
 
   const SMESH::PointStruct * P = &theStepVector.PS;
   gp_Vec stepVec( P->x, P->y, P->z );
 
-  ::SMESH_MeshEditor anEditor( _myMesh );
+  ::SMESH_MeshEditor anEditor( myMesh );
   TElemOfElemListMap aHystory;
   anEditor.ExtrusionSweep (elements, stepVec, theNbOfSteps, aHystory,
                           theExtrFlags, theSewTolerance);
 
-  UpdateLastResult(anEditor);
+  StoreResult(anEditor);
 
   // Update Python script
   TPythonDump() << "stepVector = " << theStepVector;
@@ -1266,8 +1421,7 @@ SMESH::SMESH_MeshEditor::Extrusion_Error
                                         CORBA::Boolean              theHasRefPoint,
                                         const SMESH::PointStruct &  theRefPoint)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESHDS_Mesh*  aMesh = GetMeshDS();
 
@@ -1285,7 +1439,7 @@ SMESH::SMESH_MeshEditor::Extrusion_Error
   if ( !nodeStart )
     return SMESH::SMESH_MeshEditor::EXTR_BAD_STARTING_NODE;
 
-  map<int,const SMDS_MeshElement*> elements;
+  TIDSortedElemSet elements;
   ToMap(theIDsOfElements, aMesh, elements);
 
   list<double> angles;
@@ -1296,26 +1450,32 @@ SMESH::SMESH_MeshEditor::Extrusion_Error
   gp_Pnt refPnt( theRefPoint.x, theRefPoint.y, theRefPoint.z );
 
   // Update Python script
-  TPythonDump() << "refPoint = SMESH.PointStruct( "
-                << refPnt.X() << ", "
-                << refPnt.Y() << ", "
-                << refPnt.Z() << " )";
+  TPythonDump() << "rotAngles = " << theAngles;
+
+  if ( theHasRefPoint )
+    TPythonDump() << "refPoint = SMESH.PointStruct( "
+                  << refPnt.X() << ", "
+                  << refPnt.Y() << ", "
+                  << refPnt.Z() << " )";
+  else
+    TPythonDump() << "refPoint = SMESH.PointStruct( 0,0,0 )";
+
   TPythonDump() << "error = " << this << ".ExtrusionAlongPath( "
                 << theIDsOfElements << ", "
-                << thePathMesh  <<  ", "
-                << thePathShape <<  ", "
-                << theNodeStart << ", "
-                << theHasAngles << ", "
-                << theAngles << ", "
-                << theHasRefPoint << ", refPoint )";
-
-  ::SMESH_MeshEditor anEditor( _myMesh );
+                << thePathMesh      << ", "
+                << thePathShape     << ", "
+                << theNodeStart     << ", "
+                << theHasAngles     << ", "
+                << "rotAngles"      << ", "
+                << theHasRefPoint   << ", refPoint )";
+
+  ::SMESH_MeshEditor anEditor( myMesh );
   SMESH::SMESH_MeshEditor::Extrusion_Error error = 
     convExtrError( anEditor.ExtrusionAlongTrack( elements, aSubMesh, nodeStart,
                                                 theHasAngles, angles,
                                                 theHasRefPoint, refPnt ) );
 
-  UpdateLastResult(anEditor);
+  StoreResult(anEditor);
 
   return error;
 }
@@ -1335,8 +1495,7 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr   theObje
                                              CORBA::Boolean              theHasRefPoint,
                                              const SMESH::PointStruct &  theRefPoint)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   SMESH::SMESH_MeshEditor::Extrusion_Error error = ExtrusionAlongPath
@@ -1348,18 +1507,39 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObject(SMESH::SMESH_IDSource_ptr   theObje
   aSMESHGen->RemoveLastFromPythonScript(aSMESHGen->GetCurrentStudyID());
 
   // Update Python script
+  TPythonDump() << "rotAngles = " << theAngles;
   TPythonDump() << "error = " << this << ".ExtrusionAlongPathObject( "
                 << theObject    << ", "
                 << thePathMesh  << ", "
                 << thePathShape << ", "
                 << theNodeStart << ", "
                 << theHasAngles << ", "
-                << theAngles << ", "
-                << theHasRefPoint << ", refPoint )";
+                << "rotAngles"     << ", "
+                << theHasRefPoint<<", refPoint )";
 
   return error;
 }
 
+//================================================================================
+/*!
+ * \brief Compute rotation angles for ExtrusionAlongPath as linear variation
+ * of given angles along path steps
+  * \param PathMesh mesh containing a 1D sub-mesh on the edge, along 
+  *                which proceeds the extrusion
+  * \param PathShape is shape(edge); as the mesh can be complex, the edge 
+  *                 is used to define the sub-mesh for the path
+ */
+//================================================================================
+
+SMESH::double_array*
+SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr       thePathMesh,
+                                          GEOM::GEOM_Object_ptr       thePathShape,
+                                          const SMESH::double_array & theAngles)
+{
+  SMESH::double_array_var aResult = new SMESH::double_array();
+  return aResult._retn();
+}
+
 //=======================================================================
 //function : Mirror
 //purpose  :
@@ -1370,12 +1550,11 @@ void SMESH_MeshEditor_i::Mirror(const SMESH::long_array &           theIDsOfElem
                                 SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
                                 CORBA::Boolean                      theCopy)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESHDS_Mesh* aMesh = GetMeshDS();
 
-  map<int,const SMDS_MeshElement*> elements;
+  TIDSortedElemSet elements;
   ToMap(theIDsOfElements, aMesh, elements);
 
   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
@@ -1404,11 +1583,11 @@ void SMESH_MeshEditor_i::Mirror(const SMESH::long_array &           theIDsOfElem
                 << typeStr           << ", "
                 << theCopy           << " )";
 
-  ::SMESH_MeshEditor anEditor( _myMesh );
+  ::SMESH_MeshEditor anEditor( myMesh );
   anEditor.Transform (elements, aTrsf, theCopy);
 
   if(theCopy) {
-    UpdateLastResult(anEditor);
+    StoreResult(anEditor);
   }
 }
 
@@ -1423,8 +1602,7 @@ void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr           theObj
                                      SMESH::SMESH_MeshEditor::MirrorType theMirrorType,
                                      CORBA::Boolean                      theCopy)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   Mirror(anElementsId, theAxis, theMirrorType, theCopy);
@@ -1462,23 +1640,22 @@ void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements,
                                    const SMESH::DirStruct &  theVector,
                                    CORBA::Boolean            theCopy)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESHDS_Mesh* aMesh = GetMeshDS();
 
-  map<int,const SMDS_MeshElement*> elements;
+  TIDSortedElemSet elements;
   ToMap(theIDsOfElements, aMesh, elements);
 
   gp_Trsf aTrsf;
   const SMESH::PointStruct * P = &theVector.PS;
   aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z ));
 
-  ::SMESH_MeshEditor anEditor( _myMesh );
+  ::SMESH_MeshEditor anEditor( myMesh );
   anEditor.Transform (elements, aTrsf, theCopy);
 
   if(theCopy) {
-    UpdateLastResult(anEditor);
+    StoreResult(anEditor);
   }
 
   // Update Python script
@@ -1498,8 +1675,7 @@ void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject,
                                         const SMESH::DirStruct &  theVector,
                                         CORBA::Boolean            theCopy)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   Translate(anElementsId, theVector, theCopy);
@@ -1525,12 +1701,11 @@ void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
                                 CORBA::Double             theAngle,
                                 CORBA::Boolean            theCopy)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESHDS_Mesh* aMesh = GetMeshDS();
 
-  map<int,const SMDS_MeshElement*> elements;
+  TIDSortedElemSet elements;
   ToMap(theIDsOfElements, aMesh, elements);
 
   gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z );
@@ -1539,11 +1714,11 @@ void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements,
   gp_Trsf aTrsf;
   aTrsf.SetRotation( gp_Ax1( P, V ), theAngle);
 
-  ::SMESH_MeshEditor anEditor( _myMesh );
+  ::SMESH_MeshEditor anEditor( myMesh );
   anEditor.Transform (elements, aTrsf, theCopy);
 
   if(theCopy) {
-    UpdateLastResult(anEditor);
+    StoreResult(anEditor);
   }
 
   // Update Python script
@@ -1565,8 +1740,7 @@ void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
                                      CORBA::Double             theAngle,
                                      CORBA::Boolean            theCopy)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESH::long_array_var anElementsId = theObject->GetIDs();
   Rotate(anElementsId, theAxis, theAngle, theCopy);
@@ -1591,11 +1765,10 @@ void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject,
 void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double                  Tolerance,
                                               SMESH::array_of_long_array_out GroupsOfNodes)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
-  ::SMESH_MeshEditor anEditor( _myMesh );
+  ::SMESH_MeshEditor anEditor( myMesh );
   set<const SMDS_MeshNode*> nodes; // no input nodes
   anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
 
@@ -1615,6 +1788,64 @@ void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double                  Tol
                 << Tolerance << " )";
 }
 
+//=======================================================================
+//function : FindCoincidentNodesOnPart
+//purpose  :
+//=======================================================================
+void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr      theObject,
+                                                   CORBA::Double                  Tolerance,
+                                                   SMESH::array_of_long_array_out GroupsOfNodes)
+{
+  initData();
+  SMESH::long_array_var aElementsId = theObject->GetIDs();
+
+  SMESHDS_Mesh* aMesh = GetMeshDS();
+  set<const SMDS_MeshNode*> nodes;
+
+  if ( !CORBA::is_nil(SMESH::SMESH_GroupBase::_narrow(theObject)) &&
+      SMESH::SMESH_GroupBase::_narrow(theObject)->GetType() == SMESH::NODE) {
+    for(int i = 0; i < aElementsId->length(); i++) {
+      CORBA::Long ind = aElementsId[i];
+      const SMDS_MeshNode * elem = aMesh->FindNode(ind);
+      if(elem)
+        nodes.insert(elem);
+    }
+  }
+  else {
+    for(int i = 0; i < aElementsId->length(); i++) {
+      CORBA::Long ind = aElementsId[i];
+      const SMDS_MeshElement * elem = aMesh->FindElement(ind);
+      if(elem) {
+        SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
+        while ( nIt->more() )
+          nodes.insert( nodes.end(),static_cast<const SMDS_MeshNode*>(nIt->next()));
+      }
+    }
+  }
+    
+  
+  ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
+  ::SMESH_MeshEditor anEditor( myMesh );
+  if(!nodes.empty())
+    anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
+  
+  GroupsOfNodes = new SMESH::array_of_long_array;
+  GroupsOfNodes->length( aListOfListOfNodes.size() );
+  ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
+  for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
+    list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
+    list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
+    SMESH::long_array& aGroup = GroupsOfNodes[ i ];
+    aGroup.length( aListOfNodes.size() );
+    for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
+      aGroup[ j ] = (*lIt)->GetID();
+  }
+  // Update Python script
+  TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
+                <<theObject<<", "
+                << Tolerance << " )";
+}
+
 //=======================================================================
 //function : MergeNodes
 //purpose  :
@@ -1622,8 +1853,7 @@ void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double                  Tol
 
 void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESHDS_Mesh* aMesh = GetMeshDS();
 
@@ -1648,13 +1878,95 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN
     if ( i > 0 ) aTPythonDump << ", ";
     aTPythonDump << aNodeGroup;
   }
-  ::SMESH_MeshEditor anEditor( _myMesh );
+  ::SMESH_MeshEditor anEditor( myMesh );
   anEditor.MergeNodes( aListOfListOfNodes );
 
   // Update Python script
   aTPythonDump <<  "])";
 }
 
+//=======================================================================
+//function : FindEqualElements
+//purpose  :
+//=======================================================================
+void SMESH_MeshEditor_i::FindEqualElements(SMESH::SMESH_IDSource_ptr      theObject,
+                                          SMESH::array_of_long_array_out GroupsOfElementsID)
+{
+  initData();
+  if ( !(!CORBA::is_nil(SMESH::SMESH_GroupBase::_narrow(theObject)) &&
+        SMESH::SMESH_GroupBase::_narrow(theObject)->GetType() == SMESH::NODE) ) {
+    typedef list<int> TListOfIDs;
+    set<const SMDS_MeshElement*> elems;
+    SMESH::long_array_var aElementsId = theObject->GetIDs();
+    SMESHDS_Mesh* aMesh = GetMeshDS();
+
+    for(int i = 0; i < aElementsId->length(); i++) {
+      CORBA::Long anID = aElementsId[i];
+      const SMDS_MeshElement * elem = aMesh->FindElement(anID);
+      if (elem) {
+       elems.insert(elem);
+      }
+    }
+
+    ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
+    ::SMESH_MeshEditor anEditor( myMesh );
+    anEditor.FindEqualElements( elems, aListOfListOfElementsID );
+
+    GroupsOfElementsID = new SMESH::array_of_long_array;
+    GroupsOfElementsID->length( aListOfListOfElementsID.size() );
+
+    ::SMESH_MeshEditor::TListOfListOfElementsID::iterator arraysIt = aListOfListOfElementsID.begin();
+    for (CORBA::Long j = 0; arraysIt != aListOfListOfElementsID.end(); ++arraysIt, ++j) {
+      SMESH::long_array& aGroup = GroupsOfElementsID[ j ];
+      TListOfIDs& listOfIDs = *arraysIt;
+      aGroup.length( listOfIDs.size() );
+      TListOfIDs::iterator idIt = listOfIDs.begin();
+      for (int k = 0; idIt != listOfIDs.end(); ++idIt, ++k ) {
+       aGroup[ k ] = *idIt;
+      }
+    }
+
+  // Update Python script
+  TPythonDump() << "equal_elements = " << this << ".FindEqualElements( "
+                <<theObject<<" )";
+  }
+}
+
+//=======================================================================
+//function : MergeElements
+//purpose  :
+//=======================================================================
+
+void SMESH_MeshEditor_i::MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID)
+{
+  initData();
+
+  TPythonDump aTPythonDump;
+  aTPythonDump << this << ".MergeElements( [";
+
+  ::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
+
+  for (int i = 0; i < GroupsOfElementsID.length(); i++) {
+    const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
+    aListOfListOfElementsID.push_back( list< int >() );
+    list< int >& aListOfElemsID = aListOfListOfElementsID.back();
+    for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
+      CORBA::Long id = anElemsIDGroup[ j ];
+      aListOfElemsID.push_back( id );
+    }
+    if ( aListOfElemsID.size() < 2 )
+      aListOfListOfElementsID.pop_back();
+    if ( i > 0 ) aTPythonDump << ", ";
+    aTPythonDump << anElemsIDGroup;
+  }
+
+  ::SMESH_MeshEditor anEditor( myMesh );
+  anEditor.MergeElements(aListOfListOfElementsID);
+
+  // Update Python script
+  aTPythonDump << "] )";
+}
+
 //=======================================================================
 //function : MergeEqualElements
 //purpose  :
@@ -1662,18 +1974,85 @@ void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfN
 
 void SMESH_MeshEditor_i::MergeEqualElements()
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
-  ::SMESH_MeshEditor anEditor( _myMesh );
+  ::SMESH_MeshEditor anEditor( myMesh );
   anEditor.MergeEqualElements();
 
   // Update Python script
   TPythonDump() << this << ".MergeEqualElements()";
 }
 
+//================================================================================
+/*!
+ * \brief If the given ID is a valid node ID (nodeID > 0), just move this node, else
+ * move the node closest to the point to point's location and return ID of the node
+ */
+//================================================================================
+
+CORBA::Long SMESH_MeshEditor_i::MoveClosestNodeToPoint(CORBA::Double x,
+                                                       CORBA::Double y,
+                                                       CORBA::Double z,
+                                                       CORBA::Long   theNodeID)
+{
+  // We keep myNodeSearcher until any mesh modification:
+  // 1) initData() deletes myNodeSearcher at any edition,
+  // 2) TNodeSearcherDeleter - at any mesh compute event and mesh change
+
+  initData();
+
+  int nodeID = theNodeID;
+  const SMDS_MeshNode* node = GetMeshDS()->FindNode( nodeID );
+  if ( !node )
+  {
+    static TNodeSearcherDeleter deleter;
+    deleter.Set( myMesh );
+    if ( !myNodeSearcher ) {
+      ::SMESH_MeshEditor anEditor( myMesh );
+      myNodeSearcher = anEditor.GetNodeSearcher();
+    }
+    gp_Pnt p( x,y,z );
+    node = myNodeSearcher->FindClosestTo( p );
+  }
+  if ( node ) {
+    nodeID = node->GetID();
+    if ( myPreviewMode ) // make preview data
+    {
+      // in a preview mesh, make edges linked to a node
+      TPreviewMesh tmpMesh;
+      TIDSortedElemSet linkedNodes;
+      ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes );
+      TIDSortedElemSet::iterator nIt = linkedNodes.begin();
+      for ( ; nIt != linkedNodes.end(); ++nIt )
+      {
+        SMDS_MeshEdge edge( node, cast2Node( *nIt ));
+        tmpMesh.Copy( &edge );
+      }
+      // move copied node
+      node = tmpMesh.GetMeshDS()->FindNode( nodeID );
+      if ( node )
+        tmpMesh.GetMeshDS()->MoveNode(node, x, y, z);
+      // fill preview data
+      ::SMESH_MeshEditor anEditor( & tmpMesh );
+      StoreResult( anEditor );
+    }
+    else
+    {
+      GetMeshDS()->MoveNode(node, x, y, z);
+    }
+  }
+
+  if ( !myPreviewMode ) {
+    // Update Python script
+    TPythonDump() << "nodeID = " << this
+                  << ".MoveClosestNodeToPoint( "<< x << ", " << y << ", " << z << " )";
+  }
+
+  return nodeID;
+}
+
 //=======================================================================
-//function : operator
+//function : convError
 //purpose  :
 //=======================================================================
 
@@ -1711,8 +2090,7 @@ SMESH::SMESH_MeshEditor::Sew_Error
                                      CORBA::Boolean CreatePolygons,
                                      CORBA::Boolean CreatePolyedrs)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESHDS_Mesh* aMesh = GetMeshDS();
 
@@ -1743,7 +2121,7 @@ SMESH::SMESH_MeshEditor::Sew_Error
                 << CreatePolygons<< ", "
                 << CreatePolyedrs<< " )";
 
-  ::SMESH_MeshEditor anEditor( _myMesh );
+  ::SMESH_MeshEditor anEditor( myMesh );
   SMESH::SMESH_MeshEditor::Sew_Error error =
     convError( anEditor.SewFreeBorder (aBorderFirstNode,
                                        aBorderSecondNode,
@@ -1755,7 +2133,7 @@ SMESH::SMESH_MeshEditor::Sew_Error
                                        CreatePolygons,
                                        CreatePolyedrs) );
 
-  UpdateLastResult(anEditor);
+  StoreResult(anEditor);
 
   return error;
 }
@@ -1773,8 +2151,7 @@ SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
                                           CORBA::Long FirstNodeID2,
                                           CORBA::Long SecondNodeID2)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESHDS_Mesh* aMesh = GetMeshDS();
 
@@ -1801,7 +2178,7 @@ SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
                 << FirstNodeID2  << ", "
                 << SecondNodeID2 << " )";
 
-  ::SMESH_MeshEditor anEditor( _myMesh );
+  ::SMESH_MeshEditor anEditor( myMesh );
   SMESH::SMESH_MeshEditor::Sew_Error error =
     convError( anEditor.SewFreeBorder (aBorderFirstNode,
                                        aBorderSecondNode,
@@ -1812,7 +2189,7 @@ SMESH_MeshEditor_i::SewConformFreeBorders(CORBA::Long FirstNodeID1,
                                        true,
                                        false, false) );
 
-  UpdateLastResult(anEditor);
+  StoreResult(anEditor);
 
   return error;
 }
@@ -1832,8 +2209,7 @@ SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
                                     CORBA::Boolean CreatePolygons,
                                     CORBA::Boolean CreatePolyedrs)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESHDS_Mesh* aMesh = GetMeshDS();
 
@@ -1862,7 +2238,7 @@ SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
                 << CreatePolygons           << ", "
                 << CreatePolyedrs           << ") ";
 
-  ::SMESH_MeshEditor anEditor( _myMesh );
+  ::SMESH_MeshEditor anEditor( myMesh );
   SMESH::SMESH_MeshEditor::Sew_Error error =
     convError( anEditor.SewFreeBorder (aBorderFirstNode,
                                        aBorderSecondNode,
@@ -1874,7 +2250,7 @@ SMESH_MeshEditor_i::SewBorderToSide(CORBA::Long FirstNodeIDOnFreeBorder,
                                        CreatePolygons,
                                        CreatePolyedrs) );
 
-  UpdateLastResult(anEditor);
+  StoreResult(anEditor);
 
   return error;
 }
@@ -1893,8 +2269,7 @@ SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
                                     CORBA::Long NodeID2OfSide1ToMerge,
                                     CORBA::Long NodeID2OfSide2ToMerge)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   SMESHDS_Mesh* aMesh = GetMeshDS();
 
@@ -1910,7 +2285,7 @@ SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
       !aSecondNode2ToMerge)
     return SMESH::SMESH_MeshEditor::SEW_BAD_SIDE2_NODES;
 
-  map<int,const SMDS_MeshElement*> aSide1Elems, aSide2Elems;
+  TIDSortedElemSet aSide1Elems, aSide2Elems;
   ToMap(IDsOfSide1Elements, aMesh, aSide1Elems);
   ToMap(IDsOfSide2Elements, aMesh, aSide2Elems);
 
@@ -1923,7 +2298,7 @@ SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
                 << NodeID2OfSide1ToMerge << ", "
                 << NodeID2OfSide2ToMerge << ")";
 
-  ::SMESH_MeshEditor anEditor( _myMesh );
+  ::SMESH_MeshEditor anEditor( myMesh );
   SMESH::SMESH_MeshEditor::Sew_Error error =
     convError( anEditor.SewSideElements (aSide1Elems, aSide2Elems,
                                          aFirstNode1ToMerge,
@@ -1931,7 +2306,7 @@ SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
                                          aSecondNode1ToMerge,
                                          aSecondNode2ToMerge));
 
-  UpdateLastResult(anEditor);
+  StoreResult(anEditor);
 
   return error;
 }
@@ -1948,8 +2323,7 @@ SMESH_MeshEditor_i::SewSideElements(const SMESH::long_array& IDsOfSide1Elements,
 CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
                                                    const SMESH::long_array& newIDs)
 {
-  myLastCreatedElems = new SMESH::long_array();
-  myLastCreatedNodes = new SMESH::long_array();
+  initData();
 
   const SMDS_MeshElement* elem = GetMeshDS()->FindElement(ide);
   if(!elem) return false;
@@ -1977,31 +2351,113 @@ CORBA::Boolean SMESH_MeshEditor_i::ChangeElemNodes(CORBA::Long ide,
   
 //================================================================================
 /*!
- * \brief Update myLastCreatedNodes and myLastCreatedElems
+ * \brief Update myLastCreated* or myPreviewData
   * \param anEditor - it contains last modification results
  */
 //================================================================================
 
-void SMESH_MeshEditor_i::UpdateLastResult(::SMESH_MeshEditor& anEditor)
+void SMESH_MeshEditor_i::StoreResult(::SMESH_MeshEditor& anEditor)
 {
-  // add new elements into myLastCreatedNodes
-  SMESH_SequenceOfElemPtr aSeq = anEditor.GetLastCreatedNodes();
-  SMESH::long_array_var aResult = new SMESH::long_array;
-  aResult->length(aSeq.Length());
-  int i=0;
-  for(; i<aSeq.Length(); i++) {
-    aResult[i] = aSeq.Value(i+1)->GetID();
+  if ( myPreviewMode ) { // --- MeshPreviewStruct filling --- 
+
+    list<int> aNodesConnectivity;
+    typedef map<int, int> TNodesMap;
+    TNodesMap nodesMap;
+
+    TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( anEditor.GetMesh() );
+    SMDSAbs_ElementType previewType = aPreviewMesh->myPreviewType;
+
+    SMESHDS_Mesh* aMeshDS = anEditor.GetMeshDS();
+    int nbEdges = aMeshDS->NbEdges();
+    int nbFaces = aMeshDS->NbFaces();
+    int nbVolum = aMeshDS->NbVolumes();
+    switch ( previewType ) {
+    case SMDSAbs_Edge  : nbFaces = nbVolum = 0; break;
+    case SMDSAbs_Face  : nbEdges = nbVolum = 0; break;
+    case SMDSAbs_Volume: nbEdges = nbFaces = 0; break;
+    default:;
+    }
+    myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
+    myPreviewData->elementTypes.length(nbEdges + nbFaces + nbVolum);
+    int i = 0, j = 0;
+    SMDS_ElemIteratorPtr itMeshElems = aMeshDS->elementsIterator();
+
+    while ( itMeshElems->more() ) {
+      const SMDS_MeshElement* aMeshElem = itMeshElems->next();
+      if ( previewType != SMDSAbs_All && aMeshElem->GetType() != previewType )
+        continue;
+
+      SMDS_ElemIteratorPtr itElemNodes = aMeshElem->nodesIterator();
+      while ( itElemNodes->more() ) {
+        const SMDS_MeshNode* aMeshNode = 
+          static_cast<const SMDS_MeshNode*>( itElemNodes->next() );
+        int aNodeID = aMeshNode->GetID();
+        TNodesMap::iterator anIter = nodesMap.find(aNodeID);
+        if ( anIter == nodesMap.end() ) {
+          // filling the nodes coordinates
+          myPreviewData->nodesXYZ[j].x = aMeshNode->X();
+          myPreviewData->nodesXYZ[j].y = aMeshNode->Y();
+          myPreviewData->nodesXYZ[j].z = aMeshNode->Z();
+          anIter = nodesMap.insert( make_pair(aNodeID, j) ).first;
+          j++;
+        }
+        aNodesConnectivity.push_back(anIter->second);
+      }
+
+      // filling the elements types
+      SMDSAbs_ElementType aType;
+      bool isPoly;
+      /*if (aMeshElem->GetType() == SMDSAbs_Volume) {
+        aType = SMDSAbs_Node;
+        isPoly = false;
+      }
+      else*/ {
+        aType = aMeshElem->GetType();
+        isPoly = aMeshElem->IsPoly();
+      }
+
+      myPreviewData->elementTypes[i].SMDS_ElementType = (SMESH::ElementType) aType;
+      myPreviewData->elementTypes[i].isPoly = isPoly;
+      myPreviewData->elementTypes[i].nbNodesInElement = aMeshElem->NbNodes();
+      i++;
+
+    }
+    myPreviewData->nodesXYZ.length( j );
+
+    // filling the elements connectivities
+    list<int>::iterator aConnIter = aNodesConnectivity.begin();
+    myPreviewData->elementConnectivities.length(aNodesConnectivity.size());
+    for( int i = 0; aConnIter != aNodesConnectivity.end(); aConnIter++, i++ )
+      myPreviewData->elementConnectivities[i] = *aConnIter;
+    
+    return;
+  }
+
+  {
+    // add new nodes into myLastCreatedNodes
+    const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedNodes();
+    myLastCreatedNodes->length(aSeq.Length());
+    for(int i=0; i<aSeq.Length(); i++)
+      myLastCreatedNodes[i] = aSeq.Value(i+1)->GetID();
   }
-  myLastCreatedNodes = aResult._retn();
-  // add new elements into myLastCreatedElems
-  aSeq = anEditor.GetLastCreatedElems();
-  aResult = new SMESH::long_array;
-  aResult->length(aSeq.Length());
-  i=0;
-  for(; i<aSeq.Length(); i++) {
-    aResult[i] = aSeq.Value(i+1)->GetID();
+  {
+    // add new elements into myLastCreatedElems
+    const SMESH_SequenceOfElemPtr& aSeq = anEditor.GetLastCreatedElems();
+    myLastCreatedElems->length(aSeq.Length());
+    for(int i=0; i<aSeq.Length(); i++)
+      myLastCreatedElems[i] = aSeq.Value(i+1)->GetID();
   }
-  myLastCreatedElems = aResult._retn();
+}
+
+//================================================================================
+/*!
+ * Return data of mesh edition preview
+ */
+//================================================================================
+
+SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
+{
+  return myPreviewData._retn();
 }
 
 //================================================================================
@@ -2013,7 +2469,7 @@ void SMESH_MeshEditor_i::UpdateLastResult(::SMESH_MeshEditor& anEditor)
 
 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
 {
-  return myLastCreatedNodes;
+  return myLastCreatedNodes._retn();
 }
 
 //================================================================================
@@ -2025,10 +2481,9 @@ SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedNodes()
 
 SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
 {
-  return myLastCreatedElems;
+  return myLastCreatedElems._retn();
 }
 
-
 //=======================================================================
 //function : ConvertToQuadratic
 //purpose  :
@@ -2036,11 +2491,10 @@ SMESH::long_array* SMESH_MeshEditor_i::GetLastCreatedElems()
 
 void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
 {
-  ::SMESH_MeshEditor anEditor( _myMesh );
+  ::SMESH_MeshEditor anEditor( myMesh );
   anEditor.ConvertToQuadratic(theForce3d);
  // Update Python script
-  TPythonDump() << this << ".ConvertToQuadratic( "
-                << theForce3d << " )";
+  TPythonDump() << this << ".ConvertToQuadratic( " << theForce3d << " )";
 }
 
 //=======================================================================
@@ -2050,7 +2504,7 @@ void SMESH_MeshEditor_i::ConvertToQuadratic(CORBA::Boolean theForce3d)
 
 CORBA::Boolean SMESH_MeshEditor_i::ConvertFromQuadratic()
 {
-  ::SMESH_MeshEditor anEditor( _myMesh );
+  ::SMESH_MeshEditor anEditor( myMesh );
   CORBA::Boolean isDone = anEditor.ConvertFromQuadratic();
   // Update Python script
   TPythonDump() << this << ".ConvertFromQuadratic()";
index 6433d9162b2783c72026ebfe7f074376255f201d..52ba2d7766592675b0dfadb2499657a995964dc5 100644 (file)
@@ -32,7 +32,7 @@
 #include "SMESH.hxx"
 
 #include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_Mesh)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
 
 #include "SMESH_Mesh.hxx"
 
@@ -41,11 +41,9 @@ class SMESH_MeshEditor;
 class SMESH_I_EXPORT SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
 {
  public:
-  SMESH_MeshEditor_i(SMESH_Mesh * theMesh);
+  SMESH_MeshEditor_i(SMESH_Mesh * theMesh, bool isPreview);
 
-  virtual ~ SMESH_MeshEditor_i()
-  {
-  };
+  virtual ~ SMESH_MeshEditor_i();
 
   // --- CORBA
   CORBA::Boolean RemoveElements(const SMESH::long_array & IDsOfElements);
@@ -179,6 +177,10 @@ class SMESH_I_EXPORT SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
                              CORBA::Boolean              HasRefPoint,
                              const SMESH::PointStruct &  RefPoint);
 
+  SMESH::double_array* LinearAnglesVariation(SMESH::SMESH_Mesh_ptr       PathMesh,
+                                             GEOM::GEOM_Object_ptr       PathShape,
+                                             const SMESH::double_array & Angles);
+
   void Mirror(const SMESH::long_array &           IDsOfElements,
               const SMESH::AxisStruct &           Axis,
               SMESH::SMESH_MeshEditor::MirrorType MirrorType,
@@ -204,8 +206,19 @@ class SMESH_I_EXPORT SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
 
   void FindCoincidentNodes (CORBA::Double                  Tolerance,
                             SMESH::array_of_long_array_out GroupsOfNodes);
+  void FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr      theObject,
+                                 CORBA::Double                  Tolerance,
+                                 SMESH::array_of_long_array_out GroupsOfNodes);
   void MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes);
+  void FindEqualElements(SMESH::SMESH_IDSource_ptr      theObject,
+                        SMESH::array_of_long_array_out GroupsOfElementsID);
+  void MergeElements(const SMESH::array_of_long_array& GroupsOfElementsID);
   void MergeEqualElements();
+  CORBA::Long MoveClosestNodeToPoint(CORBA::Double x,
+                                     CORBA::Double y,
+                                     CORBA::Double z,
+                                     CORBA::Long   nodeID);
+
 
 
   SMESH::SMESH_MeshEditor::Sew_Error
@@ -246,6 +259,11 @@ class SMESH_I_EXPORT SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
    */
   CORBA::Boolean ChangeElemNodes(CORBA::Long ide, const SMESH::long_array& newIDs);
   
+  /*!
+   * Return data of mesh edition preview
+   */
+  SMESH::MeshPreviewStruct* GetPreviewData();
+
   /*!
    * If during last operation of MeshEditor some nodes were
    * created this method returns list of it's IDs, if new nodes
@@ -265,22 +283,29 @@ class SMESH_I_EXPORT SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
   //
 
   /*!
-   * \brief Update myLastCreatedNodes and myLastCreatedElems
+   * \brief Update myLastCreated* or myPreviewData
     * \param anEditor - it contains edition results
    */
-  void UpdateLastResult(::SMESH_MeshEditor& anEditor);
+  void StoreResult(::SMESH_MeshEditor& anEditor);
 
   /*!
    * \brief Return edited mesh ID
     * \retval int - mesh ID
    */
-  int GetMeshId() const { return _myMesh->GetId(); }
+  int GetMeshId() const { return myMesh->GetId(); }
 
  private:
-  SMESHDS_Mesh * GetMeshDS() { return _myMesh->GetMeshDS(); }
-  SMESH_Mesh   *_myMesh;
-  SMESH::long_array* myLastCreatedElems;
-  SMESH::long_array* myLastCreatedNodes;
+
+  SMESHDS_Mesh * GetMeshDS() { return myMesh->GetMeshDS(); }
+  void initData();
+
+  SMESH_Mesh *          myMesh;
+
+  SMESH::long_array_var myLastCreatedElems;
+  SMESH::long_array_var myLastCreatedNodes;
+
+  SMESH::MeshPreviewStruct_var myPreviewData;
+  bool                         myPreviewMode;
 };
 
 #endif
index cdcb326bb773160a740761b52e38688de29eda33..76e5a982179c651bdd6ca5b1f42b610154bb5f60 100644 (file)
@@ -90,7 +90,7 @@ SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
                            CORBA::Long studyId )
 : SALOME::GenericObj_i( thePOA )
 {
-  INFOS("SMESH_Mesh_i");
+  MESSAGE("SMESH_Mesh_i");
   _impl = NULL;
   _gen_i = gen_i;
   _id = myIdGenerator++;
@@ -142,6 +142,26 @@ void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
   }
 }
 
+//================================================================================
+/*!
+ * \brief return true if mesh has a shape to build a shape on
+ */
+//================================================================================
+
+CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
+  throw (SALOME::SALOME_Exception)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+  bool res = false;
+  try {
+    res = _impl->HasShapeToMesh();
+  }
+  catch(SALOME_Exception & S_ex) {
+    THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
+  }
+  return res;
+}
+
 //=======================================================================
 //function : GetShapeToMesh
 //purpose  :
@@ -294,36 +314,28 @@ int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshNam
  */
 //=============================================================================
 
-static SMESH::Hypothesis_Status ConvertHypothesisStatus
+#define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
+
+SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
                          (SMESH_Hypothesis::Hypothesis_Status theStatus)
 {
-  SMESH::Hypothesis_Status res;
-  switch (theStatus)
-  {
-  case SMESH_Hypothesis::HYP_OK:
-    res = SMESH::HYP_OK; break;
-  case SMESH_Hypothesis::HYP_MISSING:
-    res = SMESH::HYP_MISSING; break;
-  case SMESH_Hypothesis::HYP_CONCURENT:
-    res = SMESH::HYP_CONCURENT; break;
-  case SMESH_Hypothesis::HYP_BAD_PARAMETER:
-    res = SMESH::HYP_BAD_PARAMETER; break;
-  case SMESH_Hypothesis::HYP_INCOMPATIBLE:
-    res = SMESH::HYP_INCOMPATIBLE; break;
-  case SMESH_Hypothesis::HYP_NOTCONFORM:
-    res = SMESH::HYP_NOTCONFORM; break;
-  case SMESH_Hypothesis::HYP_ALREADY_EXIST:
-    res = SMESH::HYP_ALREADY_EXIST; break;
-  case SMESH_Hypothesis::HYP_BAD_DIM:
-    res = SMESH::HYP_BAD_DIM; break;
-  case SMESH_Hypothesis::HYP_BAD_SUBSHAPE:
-    res = SMESH::HYP_BAD_SUBSHAPE; break;
-  case SMESH_Hypothesis::HYP_BAD_GEOMETRY:
-    res = SMESH::HYP_BAD_GEOMETRY; break;
-  default:
-    res = SMESH::HYP_UNKNOWN_FATAL;
+  switch (theStatus) {
+  RETURNCASE( HYP_OK            );
+  RETURNCASE( HYP_MISSING       );
+  RETURNCASE( HYP_CONCURENT     );
+  RETURNCASE( HYP_BAD_PARAMETER );
+  RETURNCASE( HYP_HIDDEN_ALGO   );
+  RETURNCASE( HYP_HIDING_ALGO   );
+  RETURNCASE( HYP_UNKNOWN_FATAL );
+  RETURNCASE( HYP_INCOMPATIBLE  );
+  RETURNCASE( HYP_NOTCONFORM    );
+  RETURNCASE( HYP_ALREADY_EXIST );
+  RETURNCASE( HYP_BAD_DIM       );
+  RETURNCASE( HYP_BAD_SUBSHAPE  );
+  RETURNCASE( HYP_BAD_GEOMETRY  );
+  default:;
   }
-  return res;
+  return SMESH::HYP_UNKNOWN_FATAL;
 }
 
 //=============================================================================
@@ -744,9 +756,11 @@ SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
   if (MYDEBUG) MESSAGE("GetGroups");
 
   SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
+
   // Python Dump
   TPythonDump aPythonDump;
-  aPythonDump << "[ ";
+  if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
+    aPythonDump << "[ ";
 
   try {
     aList->length( _mapGroups.size() );
@@ -766,7 +780,8 @@ SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
   }
 
   // Update Python script
-  aPythonDump << " ] = " << _this() << ".GetGroups()";
+  if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
+    aPythonDump << " ] = " << _this() << ".GetGroups()";
 
   return aList._retn();
 }
@@ -1187,17 +1202,16 @@ void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
   return *_impl;
 }
 
-
 //=============================================================================
 /*!
- *
+ * Return mesh editor
  */
 //=============================================================================
 
 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
 {
   // Create MeshEditor
-  SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( _impl );
+  SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( _impl, false );
   SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
 
   // Update Python script
@@ -1206,6 +1220,19 @@ SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
   return aMesh._retn();
 }
 
+//=============================================================================
+/*!
+ * Return mesh edition previewer
+ */
+//=============================================================================
+
+SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
+{
+  SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( _impl, true );
+  SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
+  return aMesh._retn();
+}
+
 //=============================================================================
 /*!
  *  Export in different formats
@@ -1785,9 +1812,11 @@ SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID
  */
 //=============================================================================
 
-CORBA::Long SMESH_Mesh_i::GetMeshPtr()
+CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
 {
-  return CORBA::Long(size_t(_impl));
+  CORBA::LongLong pointeur = CORBA::LongLong(_impl);
+  cerr << "CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() " << pointeur << endl;
+  return pointeur;
 }
 
 
index 92e431e4f1afc3a983d9a0db1ef598e358850714..af50b569bc6f7973efc9942aa92884915de57666 100644 (file)
@@ -67,6 +67,9 @@ public:
   void SetShape( GEOM::GEOM_Object_ptr theShapeObject )
     throw (SALOME::SALOME_Exception);
 
+  CORBA::Boolean HasShapeToMesh()
+    throw (SALOME::SALOME_Exception);
+
   GEOM::GEOM_Object_ptr GetShapeToMesh()
     throw (SALOME::SALOME_Exception);
 
@@ -127,6 +130,8 @@ public:
 
   SMESH::SMESH_MeshEditor_ptr GetMeshEditor();
 
+  SMESH::SMESH_MeshEditor_ptr GetMeshEditPreviewer();
+
   void ClearLog()
     throw (SALOME::SALOME_Exception);
 
@@ -285,6 +290,9 @@ public:
   SMESH_Hypothesis::Hypothesis_Status removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
                                                        SMESH::SMESH_Hypothesis_ptr anHyp);
   
+  static SMESH::Hypothesis_Status
+  ConvertHypothesisStatus (SMESH_Hypothesis::Hypothesis_Status theStatus);
+
   int importMEDFile( const char* theFileName, const char* theMeshName );
 
   SMESH::SMESH_subMesh_ptr createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject );
@@ -306,7 +314,7 @@ public:
 
   virtual SMESH::long_array* GetIDs();
 
-  CORBA::Long GetMeshPtr();
+  CORBA::LongLong GetMeshPtr();
 
 
   /*!
index a073dfd7a0b2c70732abcad424ef84225e9ac116..4df569cb6ba46c1461f203ee2cdb73fe8365b7ce 100644 (file)
@@ -210,12 +210,18 @@ CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all)
     for ( ; sm != smList.end(); ++sm )
     {
       SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
-      while ( eIt->more() ) {
-        const SMDS_MeshElement* anElem = eIt->next();
-        SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
+      if ( eIt->more() ) {
+        while ( eIt->more() ) {
+          const SMDS_MeshElement* anElem = eIt->next();
+          SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
+          while ( nIt->more() )
+            nodeIds.insert( nIt->next()->GetID() );
+        }
+      } else {
+        SMDS_NodeIteratorPtr nIt = (*sm)->GetNodes();
         while ( nIt->more() )
           nodeIds.insert( nIt->next()->GetID() );
-      }
+      }      
     }
     return nodeIds.size();
   }
@@ -225,15 +231,21 @@ CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all)
 
   if ( all ) { // all nodes of submesh elements
     SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
-    while ( eIt->more() ) {
-      const SMDS_MeshElement* anElem = eIt->next();
-      SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
+    if ( eIt->more() ) {
+      while ( eIt->more() ) {
+        const SMDS_MeshElement* anElem = eIt->next();
+        SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
+        while ( nIt->more() )
+          nodeIds.insert( nIt->next()->GetID() );
+      }
+    } else {
+      SMDS_NodeIteratorPtr nIt = aSubMeshDS->GetNodes();
       while ( nIt->more() )
         nodeIds.insert( nIt->next()->GetID() );
     }
     return nodeIds.size();
   }
-    
+
   return aSubMeshDS->NbNodes();
 }
 
@@ -242,7 +254,7 @@ CORBA::Long SMESH_subMesh_i::GetNumberOfNodes(CORBA::Boolean all)
  *  
  */
 //=============================================================================
-  
+
 SMESH::long_array* SMESH_subMesh_i::GetElementsId()
   throw (SALOME::SALOME_Exception)
 {
@@ -317,9 +329,15 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theEle
       if ( theElemType == SMESH::NODE )
       {
         SMDS_ElemIteratorPtr eIt = (*sm)->GetElements();
-        while ( eIt->more() ) {
-          const SMDS_MeshElement* anElem = eIt->next();
-          SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
+        if ( eIt->more() ) {
+          while ( eIt->more() ) {
+            const SMDS_MeshElement* anElem = eIt->next();
+            SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
+            while ( nIt->more() )
+              nodeIds.insert( nIt->next()->GetID() );
+          }
+        } else {
+          SMDS_NodeIteratorPtr nIt = (*sm)->GetNodes();
           while ( nIt->more() )
             nodeIds.insert( nIt->next()->GetID() );
         }
@@ -340,9 +358,15 @@ SMESH::long_array* SMESH_subMesh_i::GetElementsByType( SMESH::ElementType theEle
   if ( theElemType == SMESH::NODE && aSubMeshDS )
   {
     SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
-    while ( eIt->more() ) {
-      const SMDS_MeshElement* anElem = eIt->next();
-      SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
+    if ( eIt->more() ) {
+      while ( eIt->more() ) {
+        const SMDS_MeshElement* anElem = eIt->next();
+        SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
+        while ( nIt->more() )
+          nodeIds.insert( nIt->next()->GetID() );
+      }
+    } else {
+      SMDS_NodeIteratorPtr nIt = aSubMeshDS->GetNodes();
       while ( nIt->more() )
         nodeIds.insert( nIt->next()->GetID() );
     }
index 22c2a0de671af7da69bf7d6dd3fa7678735c4694..0d66b1b12d115fddf923c9a4386a2d05cf40ac8f 100644 (file)
@@ -25,7 +25,9 @@
 # see salome_shared_modules.py
 # (avoids incomplete import at run time)
 
-print "============== import SMESH ======================="
+from launchConfigureParser import verbose
+
+if verbose(): print "============== import SMESH ======================="
 
 import SMESH
 
index ce9b65b2bd90a099332c5c0a66ddc602486d5423..acbb31f5a064c149fe32b1a1fafba2768b4029b9 100644 (file)
@@ -34,6 +34,8 @@ from   SMESH import *
 
 import StdMeshers
 
+import SALOME
+
 # import NETGENPlugin module if possible
 noNETGENPlugin = 0
 try:
@@ -43,8 +45,9 @@ except ImportError:
     pass
     
 # Types of algo
-REGULAR = 1
-PYTHON  = 2
+REGULAR    = 1
+PYTHON     = 2
+COMPOSITE  = 3
 
 MEFISTO = 3
 NETGEN  = 4
@@ -244,11 +247,17 @@ def GetCriterion(elementType,
         
     if Compare in [FT_LessThan, FT_MoreThan, FT_EqualTo]:
         aCriterion.Compare = EnumToLong(Compare)
+    elif Compare == "=" or Compare == "==":
+        aCriterion.Compare = EnumToLong(FT_EqualTo)
+    elif Compare == "<":
+        aCriterion.Compare = EnumToLong(FT_LessThan)
+    elif Compare == ">":
+        aCriterion.Compare = EnumToLong(FT_MoreThan)
     else:
         aCriterion.Compare = EnumToLong(FT_EqualTo)
         aTreshold = Compare
 
-    if CritType in [FT_BelongToGeom,     FT_BelongToPlane,
+    if CritType in [FT_BelongToGeom,     FT_BelongToPlane, FT_BelongToGenSurface, 
                     FT_BelongToCylinder, FT_LyingOnGeom]:
         # Check treshold
         if isinstance(aTreshold, geompy.GEOM._objref_GEOM_Object):
@@ -346,6 +355,43 @@ def GetFunctor(theCriterion):
         print "Error: given parameter is not numerucal functor type."
 
 
+## Print error message if a hypothesis was not assigned.
+def TreatHypoStatus(status, hypName, geomName, isAlgo):
+    if isAlgo:
+        hypType = "algorithm"
+    else:
+        hypType = "hypothesis"
+        pass
+    if status == HYP_UNKNOWN_FATAL :
+        reason = "for unknown reason"
+    elif status == HYP_INCOMPATIBLE :
+        reason = "this hypothesis mismatches algorithm"
+    elif status == HYP_NOTCONFORM :
+        reason = "not conform mesh would be built"
+    elif status == HYP_ALREADY_EXIST :
+        reason = hypType + " of the same dimension already assigned to this shape"
+    elif status == HYP_BAD_DIM :
+        reason = hypType + " mismatches shape"
+    elif status == HYP_CONCURENT :
+        reason = "there are concurrent hypotheses on sub-shapes"
+    elif status == HYP_BAD_SUBSHAPE :
+        reason = "shape is neither the main one, nor its subshape, nor a valid group"
+    elif status == HYP_BAD_GEOMETRY:
+        reason = "geometry mismatches algorithm's expectation"
+    elif status == HYP_HIDDEN_ALGO:
+        reason = "it is hidden by an algorithm of upper dimension generating all-dimensions elements"
+    elif status == HYP_HIDING_ALGO:
+        reason = "it hides algorithm(s) of lower dimension by generating all-dimensions elements"
+    else:
+        return
+    hypName = '"' + hypName + '"'
+    geomName= '"' + geomName+ '"'
+    if status < HYP_UNKNOWN_FATAL:
+        print hypName, "was assigned to",    geomName,"but", reason
+    else:
+        print hypName, "was not assigned to",geomName,":", reason
+        pass
+
     
     
 ## Mother class to define algorithm, recommended to don't use directly.
@@ -388,38 +434,6 @@ class Mesh_Algorithm:
     def GetId(self):
         return self.algo.GetId()
     
-    ## Private method. Print error message if a hypothesis was not assigned.
-    def TreatHypoStatus(self, status, hypName, geomName, isAlgo):
-        if isAlgo:
-            hypType = "algorithm"
-        else:
-            hypType = "hypothesis"
-        if status == HYP_UNKNOWN_FATAL :
-            reason = "for unknown reason"
-        elif status == HYP_INCOMPATIBLE :
-            reason = "this hypothesis mismatches algorithm"
-        elif status == HYP_NOTCONFORM :
-            reason = "not conform mesh would be built"
-        elif status == HYP_ALREADY_EXIST :
-            reason = hypType + " of the same dimension already assigned to this shape"
-        elif status == HYP_BAD_DIM :
-            reason = hypType + " mismatches shape"
-        elif status == HYP_CONCURENT :
-            reason = "there are concurrent hypotheses on sub-shapes"
-        elif status == HYP_BAD_SUBSHAPE :
-            reason = "shape is neither the main one, nor its subshape, nor a valid group"
-        elif status == HYP_BAD_GEOMETRY:
-            reason = "geometry mismatches algorithm's expectation"
-        else:
-            return
-        hypName = '"' + hypName + '"'
-        geomName= '"' + geomName+ '"'
-        if status < HYP_UNKNOWN_FATAL:
-            print hypName, "was assigned to",    geomName,"but", reason
-        else:
-            print hypName, "was not assigned to",geomName,":", reason
-        pass
-        
     ## Private method.
     def Create(self, mesh, geom, hypo, so="libStdMeshersEngine.so"):
         if geom is None:
@@ -440,7 +454,7 @@ class Mesh_Algorithm:
         self.algo = smesh.CreateHypothesis(hypo, so)
         SetName(self.algo, name + "/" + hypo)
         status = mesh.mesh.AddHypothesis(self.geom, self.algo)
-        self.TreatHypoStatus( status, hypo, name, 1 )
+        TreatHypoStatus( status, hypo, name, 1 )
         
     ## Private method
     def Hypothesis(self, hyp, args=[], so="libStdMeshersEngine.so"):
@@ -456,7 +470,7 @@ class Mesh_Algorithm:
         name = GetName(self.geom)
         SetName(hypo, name + "/" + hyp + a)
         status = self.mesh.mesh.AddHypothesis(self.geom, hypo)
-        self.TreatHypoStatus( status, hyp, name, 0 )
+        TreatHypoStatus( status, hyp, name, 0 )
         return hypo
 
 
@@ -529,6 +543,24 @@ class Mesh_Segment(Mesh_Algorithm):
         hyp.SetFineness( fineness )
         return hyp
 
+    ## Define "SegmentLengthAroundVertex" hypothesis
+    #  @param length for the segment length
+    #  @param vertex for the length localization: vertex index [0,1] | verext object
+    def LengthNearVertex(self, length, vertex=0):
+        import types
+        store_geom = self.geom
+        if vertex:
+            if type(vertex) is types.IntType:
+                vertex = geompy.SubShapeAllSorted(self.geom,geompy.ShapeType["VERTEX"])[vertex]
+                pass
+            self.geom = vertex
+            pass
+        hyp = self.Hypothesis("SegmentAroundVertex_0D")
+        hyp = self.Hypothesis("SegmentLengthAroundVertex")
+        self.geom = store_geom
+        hyp.SetLength( length )
+        return hyp
+
     ## Define "QuadraticMesh" hypothesis, forcing construction of quadratic edges.
     #  If the 2D mesher sees that all boundary edges are quadratic ones,
     #  it generates quadratic faces, else it generates linear faces using
@@ -539,6 +571,19 @@ class Mesh_Segment(Mesh_Algorithm):
         hyp = self.Hypothesis("QuadraticMesh")
         return hyp
 
+# Public class: Mesh_CompositeSegment
+# --------------------------
+
+## Class to define a segment 1D algorithm for discretization
+#
+#  More details.
+class Mesh_CompositeSegment(Mesh_Segment):
+
+    ## Private constructor.
+    def __init__(self, mesh, geom=0):
+        self.Create(mesh, geom, "CompositeSegment_1D")
+        
+
 # Public class: Mesh_Segment_Python
 # ---------------------------------
 
@@ -977,7 +1022,7 @@ class Mesh_Projection3D(Mesh_Algorithm):
 # Public class: Mesh_Prism
 # ------------------------
 
-## Class to define a Prism 3D algorithm
+## Class to define a 3D extrusion algorithm
 #
 #  More details.
 class Mesh_Prism3D(Mesh_Algorithm):
@@ -1202,6 +1247,8 @@ class Mesh:
             return Mesh_Segment(self, geom)
         elif algo == PYTHON:
             return Mesh_Segment_Python(self, geom)
+        elif algo == COMPOSITE:
+            return Mesh_CompositeSegment(self, geom)
         else:
             return Mesh_Segment(self, geom)
         
@@ -1276,7 +1323,7 @@ class Mesh:
     def Projection3D(self, geom=0):
         return Mesh_Projection3D(self, geom)
 
-    ## Creates a Prism 3D or RadialPrism 3D algorithm for solids.
+    ## Creates a 3D extrusion (Prism 3D) or RadialPrism 3D algorithm for solids.
     #  If the optional \a geom parameter is not sets, this algorithm is global.
     #  Otherwise, this algorithm define a submesh based on \a geom subshape.
     #  @param geom If defined, subshape to be meshed
@@ -1298,7 +1345,16 @@ class Mesh:
                 return 0
             else:
                 geom = self.geom
-        ok = smesh.Compute(self.mesh, geom)
+        ok = False
+        try:
+            ok = smesh.Compute(self.mesh, geom)
+        except SALOME.SALOME_Exception, ex:
+            print "Mesh computation failed, exception cought:"
+            print "    ", ex.details.text
+        except:
+            import traceback
+            print "Mesh computation failed, exception cought:"
+            traceback.print_exc()
         if not ok:
             errors = smesh.GetAlgoState( self.mesh, geom )
             allReasons = ""
@@ -1330,14 +1386,16 @@ class Mesh:
                 allReasons += reason
                 pass
             if allReasons != "":
-                print '"' + GetName(self.mesh) + '"',"not computed:"
+                print '"' + GetName(self.mesh) + '"',"has not been computed:"
                 print allReasons
+            else:
+                print '"' + GetName(self.mesh) + '"',"has not been computed."
                 pass
             pass
         if salome.sg.hasDesktop():
             smeshgui = salome.ImportComponentGUI("SMESH")
             smeshgui.Init(salome.myStudyId)
-            smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), ok )
+            smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), ok, (self.NbNodes()==0) )
             salome.sg.updateObjBrowser(1)
             pass
         return ok
@@ -1371,6 +1429,21 @@ class Mesh:
             self.Hexahedron()            
             pass
         return self.Compute()
+
+    ## Assign hypothesis
+    #  @param hyp is a hypothesis to assign
+    #  @param geom is subhape of mesh geometry
+    def AddHypothesis(self, hyp, geom=0 ):
+        if isinstance( hyp, Mesh_Algorithm ):
+            hyp = hyp.GetAlgorithm()
+            pass
+        if not geom:
+            geom = self.geom
+            pass
+        status = self.mesh.AddHypothesis(geom, hyp)
+        isAlgo = ( hyp._narrow( SMESH.SMESH_Algo ) is not None )
+        TreatHypoStatus( status, GetName( hyp ), GetName( geom ), isAlgo )
+        return status
     
     ## Get the list of hypothesis added on a geom
     #  @param geom is subhape of mesh geometry
@@ -1926,12 +1999,29 @@ class Mesh:
     
     ## Move node with given id
     #  @param NodeID id of the node
-    #  @param x displacing along the X axis
-    #  @param y displacing along the Y axis
-    #  @param z displacing along the Z axis
+    #  @param x new X coordinate
+    #  @param y new Y coordinate
+    #  @param z new Z coordinate
     def MoveNode(self, NodeID, x, y, z):
         return self.editor.MoveNode(NodeID, x, y, z)
 
+    ## Find a node closest to a point
+    #  @param x X coordinate of a point
+    #  @param y Y coordinate of a point
+    #  @param z Z coordinate of a point
+    #  @return id of a node
+    def FindNodeClosestTo(self, x, y, z):
+        preview = self.mesh.GetMeshEditPreviewer()
+        return preview.MoveClosestNodeToPoint(x, y, z, -1)
+
+    ## Find a node closest to a point and move it to a point location
+    #  @param x X coordinate of a point
+    #  @param y Y coordinate of a point
+    #  @param z Z coordinate of a point
+    #  @return id of a moved node
+    def MeshToPassThroughAPoint(self, x, y, z):
+        return self.editor.MoveClosestNodeToPoint(x, y, z, -1)
+
     ## Replace two neighbour triangles sharing Node1-Node2 link
     #  with ones built on the same 4 nodes but having other common link.
     #  @param NodeID1 first node id
@@ -2016,6 +2106,145 @@ class Mesh:
     #          diagonal is better, 0 if error occurs.
     def BestSplit (self, IDOfQuad, theCriterion):
         return self.editor.BestSplit(IDOfQuad, GetFunctor(theCriterion))
+
+    ## Split quafrangle faces near triangular facets of volumes
+    #
+    def SplitQuadsNearTriangularFacets(self):
+        faces_array = self.GetElementsByType(SMESH.FACE)
+        for face_id in faces_array:
+            if self.GetElemNbNodes(face_id) == 4: # quadrangle
+                quad_nodes = self.mesh.GetElemNodes(face_id)
+                node1_elems = self.GetNodeInverseElements(quad_nodes[1 -1])
+                isVolumeFound = False
+                for node1_elem in node1_elems:
+                    if not isVolumeFound:
+                        if self.GetElementType(node1_elem, True) == SMESH.VOLUME:
+                            nb_nodes = self.GetElemNbNodes(node1_elem)
+                            if 3 < nb_nodes and nb_nodes < 7: # tetra or penta, or prism
+                                volume_elem = node1_elem
+                                volume_nodes = self.mesh.GetElemNodes(volume_elem)
+                                if volume_nodes.count(quad_nodes[2 -1]) > 0: # 1,2
+                                    if volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,2,4
+                                        isVolumeFound = True
+                                        if volume_nodes.count(quad_nodes[3 -1]) == 0: # 1,2,4 & !3
+                                            self.SplitQuad([face_id], False) # diagonal 2-4
+                                    elif volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,2,3 & !4
+                                        isVolumeFound = True
+                                        self.SplitQuad([face_id], True) # diagonal 1-3
+                                elif volume_nodes.count(quad_nodes[4 -1]) > 0: # 1,4 & !2
+                                    if volume_nodes.count(quad_nodes[3 -1]) > 0: # 1,4,3 & !2
+                                        isVolumeFound = True
+                                        self.SplitQuad([face_id], True) # diagonal 1-3
+
+    ## @brief Split hexahedrons into tetrahedrons.
+    #
+    #  Use pattern mapping functionality for splitting.
+    #  @param theObject object to take list of hexahedrons from; is mesh, submesh or group.
+    #  @param theNode000,theNode001 is in range [0,7]; give an orientation of the
+    #         pattern relatively each hexahedron: the (0,0,0) key-point of pattern
+    #         will be mapped into <theNode000>-th node of each volume, the (0,0,1)
+    #         key-point will be mapped into <theNode001>-th node of each volume.
+    #         The (0,0,0) key-point of used pattern corresponds to not split corner.
+    #  @param @return TRUE in case of success, FALSE otherwise.
+    def SplitHexaToTetras (self, theObject, theNode000, theNode001):
+        # Pattern:     5.---------.6
+        #              /|#*      /|
+        #             / | #*    / |
+        #            /  |  # * /  |
+        #           /   |   # /*  |
+        # (0,0,1) 4.---------.7 * |
+        #          |#*  |1   | # *|
+        #          | # *.----|---#.2
+        #          |  #/ *   |   /
+        #          |  /#  *  |  /
+        #          | /   # * | /
+        #          |/      #*|/
+        # (0,0,0) 0.---------.3
+        pattern_tetra = "!!! Nb of points: \n 8 \n\
+        !!! Points: \n\
+        0 0 0  !- 0 \n\
+        0 1 0  !- 1 \n\
+        1 1 0  !- 2 \n\
+        1 0 0  !- 3 \n\
+        0 0 1  !- 4 \n\
+        0 1 1  !- 5 \n\
+        1 1 1  !- 6 \n\
+        1 0 1  !- 7 \n\
+        !!! Indices of points of 6 tetras: \n\
+        0 3 4 1 \n\
+        7 4 3 1 \n\
+        4 7 5 1 \n\
+        6 2 5 7 \n\
+        1 5 2 7 \n\
+        2 3 1 7 \n"
+
+        pattern = GetPattern()
+        isDone  = pattern.LoadFromFile(pattern_tetra)
+        if not isDone:
+            print 'Pattern.LoadFromFile :', pattern.GetErrorCode()
+            return isDone
+
+        pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
+        isDone = pattern.MakeMesh(self.mesh, False, False)
+        if not isDone: print 'Pattern.MakeMesh :', pattern.GetErrorCode()
+
+        # split quafrangle faces near triangular facets of volumes
+        self.SplitQuadsNearTriangularFacets()
+
+        return isDone
+
+    ## @brief Split hexahedrons into prisms.
+    #
+    #  Use pattern mapping functionality for splitting.
+    #  @param theObject object to take list of hexahedrons from; is mesh, submesh or group.
+    #  @param theNode000,theNode001 is in range [0,7]; give an orientation of the
+    #         pattern relatively each hexahedron: the (0,0,0) key-point of pattern
+    #         will be mapped into <theNode000>-th node of each volume, the (0,0,1)
+    #         key-point will be mapped into <theNode001>-th node of each volume.
+    #         The edge (0,0,0)-(0,0,1) of used pattern connects two not split corners.
+    #  @param @return TRUE in case of success, FALSE otherwise.
+    def SplitHexaToPrisms (self, theObject, theNode000, theNode001):
+        # Pattern:     5.---------.6
+        #              /|#       /|
+        #             / | #     / |
+        #            /  |  #   /  |
+        #           /   |   # /   |
+        # (0,0,1) 4.---------.7   |
+        #          |    |    |    |
+        #          |   1.----|----.2
+        #          |   / *   |   /
+        #          |  /   *  |  /
+        #          | /     * | /
+        #          |/       *|/
+        # (0,0,0) 0.---------.3
+        pattern_prism = "!!! Nb of points: \n 8 \n\
+        !!! Points: \n\
+        0 0 0  !- 0 \n\
+        0 1 0  !- 1 \n\
+        1 1 0  !- 2 \n\
+        1 0 0  !- 3 \n\
+        0 0 1  !- 4 \n\
+        0 1 1  !- 5 \n\
+        1 1 1  !- 6 \n\
+        1 0 1  !- 7 \n\
+        !!! Indices of points of 2 prisms: \n\
+        0 1 3 4 5 7 \n\
+        2 3 1 6 7 5 \n"
+
+        pattern = GetPattern()
+        isDone  = pattern.LoadFromFile(pattern_prism)
+        if not isDone:
+            print 'Pattern.LoadFromFile :', pattern.GetErrorCode()
+            return isDone
+
+        pattern.ApplyToHexahedrons(self.mesh, theObject.GetIDs(), theNode000, theNode001)
+        isDone = pattern.MakeMesh(self.mesh, False, False)
+        if not isDone: print 'Pattern.MakeMesh :', pattern.GetErrorCode()
+
+        # split quafrangle faces near triangular facets of volumes
+        self.SplitQuadsNearTriangularFacets()
+
+        return isDone
     
     ## Smooth elements
     #  @param IDsOfElements list if ids of elements to smooth
@@ -2173,12 +2402,14 @@ class Mesh:
     #  @param HasRefPoint allows to use base point 
     #  @param RefPoint point around which the shape is rotated(the mass center of the shape by default).
     #         User can specify any point as the Base Point and the shape will be rotated with respect to this point.
+    #  @param LinearVariation makes compute rotation angles as linear variation of given Angles along path steps
     def ExtrusionAlongPath(self, IDsOfElements, PathMesh, PathShape, NodeStart,
-                           HasAngles, Angles, HasRefPoint, RefPoint):
+                           HasAngles, Angles, HasRefPoint, RefPoint, LinearVariation=False):
         if IDsOfElements == []:
             IDsOfElements = self.GetElementsId()
         if ( isinstance( RefPoint, geompy.GEOM._objref_GEOM_Object)):
-            RefPoint = GetPointStruct(RefPoint) 
+            RefPoint = GetPointStruct(RefPoint)
+            pass
         return self.editor.ExtrusionAlongPath(IDsOfElements, PathMesh.GetMesh(), PathShape, NodeStart,
                                               HasAngles, Angles, HasRefPoint, RefPoint)
 
@@ -2193,12 +2424,13 @@ class Mesh:
     #  @param HasRefPoint allows to use base point 
     #  @param RefPoint point around which the shape is rotated(the mass center of the shape by default).
     #         User can specify any point as the Base Point and the shape will be rotated with respect to this point.
+    #  @param LinearVariation makes compute rotation angles as linear variation of given Angles along path steps
     def ExtrusionAlongPathObject(self, theObject, PathMesh, PathShape, NodeStart,
-                                 HasAngles, Angles, HasRefPoint, RefPoint):
+                                 HasAngles, Angles, HasRefPoint, RefPoint, LinearVariation=False):
         if ( isinstance( RefPoint, geompy.GEOM._objref_GEOM_Object)):
             RefPoint = GetPointStruct(RefPoint) 
         return self.editor.ExtrusionAlongPathObject(theObject, PathMesh.GetMesh(), PathShape, NodeStart,
-                                                    HasAngles, Angles, HasRefPoint, RefPoint)
+                                                    HasAngles, Angles, HasRefPoint, RefPoint, LinearVariation)
     
     ## Symmetrical copy of mesh elements
     #  @param IDsOfElements list of elements ids
@@ -2270,11 +2502,29 @@ class Mesh:
     def FindCoincidentNodes (self, Tolerance):
         return self.editor.FindCoincidentNodes(Tolerance)
 
+    ## Find group of nodes close to each other within Tolerance.
+    #  @param Tolerance tolerance value
+    #  @param SubMeshOrGroup SubMesh or Group
+    #  @param list of group of nodes
+    def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance):
+        return self.editor.FindCoincidentNodesOnPart(SubMeshOrGroup, Tolerance)
+
     ## Merge nodes
     #  @param list of group of nodes
     def MergeNodes (self, GroupsOfNodes):
         self.editor.MergeNodes(GroupsOfNodes)
 
+    ## Find elements built on the same nodes.
+    #  @param MeshOrSubMeshOrGroup Mesh or SubMesh, or Group of elements for searching
+    #  @return a list of groups of equal elements
+    def FindEqualElements (self, MeshOrSubMeshOrGroup):
+        return self.editor.FindEqualElements(MeshOrSubMeshOrGroup)
+
+    ## Merge elements in each given group.
+    #  @param GroupsOfElementsID groups of elements for merging
+    def MergeElements(self, GroupsOfElementsID):
+        self.editor.MergeElements(GroupsOfElementsID)
+
     ## Remove all but one of elements built on the same nodes.
     def MergeEqualElements(self):
         self.editor.MergeEqualElements()
index 6fceffabf40e50d97ccde4083d73ef27fc2b3cbe..870c426feb008078b6308de809c5ae930368bc9c 100644 (file)
@@ -58,6 +58,10 @@ salomeinclude_HEADERS = \
        StdMeshers_RadialPrism_3D.hxx  \
        StdMeshers_ProjectionUtils.hxx \
        StdMeshers_LayerDistribution.hxx \
+       StdMeshers_CompositeSegment_1D.hxx \
+       StdMeshers_FaceSide.hxx \
+       StdMeshers_SegmentAroundVertex_0D.hxx \
+       StdMeshers_SegmentLengthAroundVertex_0D.hxx \
        SMESH_StdMeshers.hxx
 
 # Libraries targets
@@ -94,7 +98,11 @@ dist_libStdMeshers_la_SOURCES = \
        StdMeshers_Projection_3D.cxx \
        StdMeshers_RadialPrism_3D.cxx \
        StdMeshers_ProjectionUtils.cxx \
-       StdMeshers_LayerDistribution.cxx
+       StdMeshers_LayerDistribution.cxx \
+       StdMeshers_CompositeSegment_1D.cxx \
+       StdMeshers_FaceSide.cxx \
+       StdMeshers_SegmentAroundVertex_0D.cxx \
+       StdMeshers_SegmentLengthAroundVertex_0D.cxx
 
 # additionnal information to compil and link file
 libStdMeshers_la_CPPFLAGS = \
index a91ccebb8f9c7e086795d80b3682384d52c89847..7d234388897a2fb924cd5ffbdaa066ccb02ca601 100644 (file)
@@ -97,92 +97,133 @@ void StdMeshers_AutomaticLength::SetFineness(double theFineness)
   }
 }
 
-//================================================================================
-/*!
- * \brief Return pointer to TopoDS_TShape
-  * \param theShape - The TopoDS_Shape
-  * \retval inline const TopoDS_TShape* - result
- */
-//================================================================================
+namespace {
 
-inline const TopoDS_TShape* getTShape(const TopoDS_Shape& theShape)
-{
-  return theShape.TShape().operator->();
-}
-//================================================================================
-/*!
- * \brief Compute segment length for all edges
-  * \param theMesh - The mesh
-  * \param theTShapeToLengthMap - The map of edge to segment length
- */
-//================================================================================
-
-static void computeLengths( SMESHDS_Mesh*                       aMesh,
-                            map<const TopoDS_TShape*, double> & theTShapeToLengthMap)
-{
-  theTShapeToLengthMap.clear();
-
-  TopoDS_Shape aMainShape = aMesh->ShapeToMesh();
+  //================================================================================
+  /*!
+   * \brief Return pointer to TopoDS_TShape
+   * \param theShape - The TopoDS_Shape
+   * \retval inline const TopoDS_TShape* - result
+   */
+  //================================================================================
 
-  // Find length of longest and shortest edge
-  double Lmin = DBL_MAX, Lmax = -DBL_MAX;
-  TopTools_IndexedMapOfShape edgeMap;
-  TopExp::MapShapes( aMainShape, TopAbs_EDGE, edgeMap);
-  for ( int i = 1; i <= edgeMap.Extent(); ++i )
+  inline const TopoDS_TShape* getTShape(const TopoDS_Shape& theShape)
   {
-    TopoDS_Edge edge = TopoDS::Edge( edgeMap(i) );
-    //if ( BRep_Tool::Degenerated( edge )) continue;
-
-    Standard_Real L = SMESH_Algo::EdgeLength( edge );
-    if ( L < DBL_MIN ) continue;
-
-    if ( L > Lmax ) Lmax = L;
-    if ( L < Lmin ) Lmin = L;
-
-    // remember i-th edge length
-    theTShapeToLengthMap.insert( make_pair( getTShape( edge ), L ));
+    return theShape.TShape().operator->();
   }
 
-  // Compute S0
-
-  // image attached to PAL10237
-
-//   NbSeg
-//     ^
-//     |
-//   10|\
-//     | \
-//     |  \
-//     |   \
-//    5|    --------
-//     |
-//     +------------>
-//     1    10       Lmax/Lmin
+  //================================================================================
+  /*!
+   * \brief computes segment length by S0 and edge length
+   */
+  //================================================================================
 
-  const int NbSegMin = 5, NbSegMax = 10; //  on axis NbSeg
-  const double Lrat1 = 1., Lrat2 = 10.;  //  on axis Lmax/Lmin
+  const double a14divPI = 14. / PI;
 
-  double Lratio = Lmax/Lmin;
-  double NbSeg = NbSegMin;
-  if ( Lratio < Lrat2 )
-    NbSeg += ( Lrat2 - Lratio ) / ( Lrat2 - Lrat1 )  * ( NbSegMax - NbSegMin );
+  inline double segLength(double S0, double edgeLen, double minLen )
+  {
+    // PAL10237
+    // S = S0 * f(L/Lmin) where f(x) = 1 + (2/Pi * 7 * atan(x/5) )
+    // =>
+    // S = S0 * ( 1 + 14/PI * atan( L / ( 5 * Lmin )))
+    return S0 * ( 1. + a14divPI * atan( edgeLen / ( 5 * minLen )));
+  }
 
-  double S0 = Lmin / (int) NbSeg;
-  MESSAGE( "S0 = " << S0 << ", Lmin = " << Lmin << ", Nbseg = " << (int) NbSeg);
+  //================================================================================
+  /*!
+   * \brief Compute segment length for all edges
+   * \param theMesh - The mesh
+   * \param theTShapeToLengthMap - The map of edge to segment length
+   */
+  //================================================================================
+
+  void computeLengths( SMESHDS_Mesh*                       aMesh,
+                       map<const TopoDS_TShape*, double> & theTShapeToLengthMap,
+                       double &                            theS0,
+                       double &                            theMinLen)
+  {
+    theTShapeToLengthMap.clear();
+
+    TopoDS_Shape aMainShape = aMesh->ShapeToMesh();
+
+    // Find length of longest and shortest edge
+    double Lmin = DBL_MAX, Lmax = -DBL_MAX;
+    TopTools_IndexedMapOfShape edgeMap;
+    TopExp::MapShapes( aMainShape, TopAbs_EDGE, edgeMap);
+    for ( int i = 1; i <= edgeMap.Extent(); ++i )
+    {
+      TopoDS_Edge edge = TopoDS::Edge( edgeMap(i) );
+      //if ( BRep_Tool::Degenerated( edge )) continue;
+
+      Standard_Real L = SMESH_Algo::EdgeLength( edge );
+      if ( L < DBL_MIN ) continue;
+
+      if ( L > Lmax ) Lmax = L;
+      if ( L < Lmin ) Lmin = L;
+
+      // remember i-th edge length
+      theTShapeToLengthMap.insert( make_pair( getTShape( edge ), L ));
+    }
+
+    // Compute S0
+
+    // image attached to PAL10237
+
+    //   NbSeg
+    //     ^
+    //     |
+    //   10|\
+    //     | \
+    //     |  \
+    //     |   \
+    //    5|    --------
+    //     |
+    //     +------------>
+    //     1    10       Lmax/Lmin
+
+    const int NbSegMin = 5, NbSegMax = 10; //  on axis NbSeg
+    const double Lrat1 = 1., Lrat2 = 10.;  //  on axis Lmax/Lmin
+
+    double Lratio = Lmax/Lmin;
+    double NbSeg = NbSegMin;
+    if ( Lratio < Lrat2 )
+      NbSeg += ( Lrat2 - Lratio ) / ( Lrat2 - Lrat1 )  * ( NbSegMax - NbSegMin );
+
+    double S0 = Lmin / (int) NbSeg;
+    MESSAGE( "S0 = " << S0 << ", Lmin = " << Lmin << ", Nbseg = " << (int) NbSeg);
+
+    // Compute segments length for all edges
+    map<const TopoDS_TShape*, double>::iterator tshape_length = theTShapeToLengthMap.begin();
+    for ( ; tshape_length != theTShapeToLengthMap.end(); ++tshape_length )
+    {
+      double & L = tshape_length->second;
+      L = segLength( S0, L, Lmin );
+    }
+    theS0 = S0;
+    theMinLen = Lmin;
+  }
+}
 
-  // Compute segments length for all edges
+//=============================================================================
+/*!
+ * \brief Computes segment length for an edge of given length
+ */
+//=============================================================================
 
-  // S = S0 * f(L/Lmin) where f(x) = 1 + (2/Pi * 7 * atan(x/5) )
-  // =>
-  // S = S0 * ( 1 + 14/PI * atan( L / ( 5 * Lmin )))
+double StdMeshers_AutomaticLength::GetLength(const SMESH_Mesh* theMesh,
+                                             const double      theEdgeLength)
+  throw(SALOME_Exception)
+{
+  if ( !theMesh ) throw SALOME_Exception(LOCALIZED("NULL Mesh"));
 
-  const double a14divPI = 14. / PI, a5xLmin = 5 * Lmin;
-  map<const TopoDS_TShape*, double>::iterator tshape_length = theTShapeToLengthMap.begin();
-  for ( ; tshape_length != theTShapeToLengthMap.end(); ++tshape_length )
+  SMESHDS_Mesh* aMeshDS = const_cast< SMESH_Mesh* > ( theMesh )->GetMeshDS();
+  if ( theMesh != _mesh )
   {
-    double & L = tshape_length->second;
-    L = S0 * ( 1. + a14divPI * atan( L / a5xLmin ));
+    computeLengths( aMeshDS, _TShapeToLength, _S0, _minLen );
+    _mesh = theMesh;
   }
+  double L = segLength( _S0, theEdgeLength, _minLen );
+  return L / (theCoarseConst + theFineConst * _fineness);
 }
 
 //=============================================================================
@@ -203,7 +244,7 @@ double StdMeshers_AutomaticLength::GetLength(const SMESH_Mesh*   theMesh,
   if ( theMesh != _mesh )
   {
     SMESHDS_Mesh* aMeshDS = const_cast< SMESH_Mesh* > ( theMesh )->GetMeshDS();
-    computeLengths( aMeshDS, _TShapeToLength );
+    computeLengths( aMeshDS, _TShapeToLength, _S0, _minLen );
     _mesh = theMesh;
   }
 
index a9194dce78d041aeb4d3bef936f9b19ff6a930cf..ba7504985779ea3c5a9f7be9b675927062b4bd4c 100644 (file)
@@ -53,9 +53,18 @@ public:
   StdMeshers_AutomaticLength(int hypId, int studyId, SMESH_Gen * gen);
   virtual ~ StdMeshers_AutomaticLength();
 
+  /*!
+   * \brief Computes segment for a given edge
+   */
   double GetLength(const SMESH_Mesh* aMesh, const TopoDS_Shape& anEdge)
     throw(SALOME_Exception);
 
+  /*!
+   * \brief Computes segment length for an edge of given length
+   */
+  double GetLength(const SMESH_Mesh* aMesh, const double edgeLength)
+    throw(SALOME_Exception);
+
   /*!
    * \brief Set Fineness
     * \param theFineness - The Fineness value [0.0-1.0],
@@ -91,7 +100,7 @@ public:
 protected:
   std::map<const TopoDS_TShape*, double> _TShapeToLength;
   const SMESH_Mesh* _mesh;
-  double _fineness;
+  double _fineness, _S0, _minLen;
 };
 
 #endif
diff --git a/src/StdMeshers/StdMeshers_CompositeSegment_1D.cxx b/src/StdMeshers/StdMeshers_CompositeSegment_1D.cxx
new file mode 100644 (file)
index 0000000..7c949c5
--- /dev/null
@@ -0,0 +1,418 @@
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : StdMeshers_Regular_1D.cxx
+//           Moved here from SMESH_Regular_1D.cxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+#include "StdMeshers_CompositeSegment_1D.hxx"
+#include "StdMeshers_FaceSide.hxx"
+#include "StdMeshers_AutomaticLength.hxx"
+
+#include "SMESH_Gen.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_HypoFilter.hxx"
+#include "SMESH_subMesh.hxx"
+#include "SMESH_subMeshEventListener.hxx"
+#include "SMESH_Comment.hxx"
+
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshNode.hxx"
+
+#include "utilities.h"
+
+#include <BRepAdaptor_CompCurve.hxx>
+#include <BRep_Builder.hxx>
+#include <GCPnts_AbscissaPoint.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Wire.hxx>
+#include <gp_Pnt.hxx>
+
+#include <Standard_ErrorHandler.hxx>
+#include <Standard_Failure.hxx>
+
+typedef SMESH_Comment TComm;
+
+using namespace std;
+
+
+namespace {
+
+  //================================================================================
+  /*!
+   * \brief Search for an edge conjunct to the given one by the vertex
+   *        Return NULL if more than 2 edges share the vertex or edges
+   *        continuity is less than C1
+   */
+  //================================================================================
+
+  TopoDS_Edge nextC1Edge(const TopoDS_Edge&  edge,
+                         SMESH_Mesh &        aMesh,
+                         const bool          forward)
+  {
+    TopoDS_Edge eNext;
+    TopTools_MapOfShape edgeCounter;
+    edgeCounter.Add( edge );
+    TopoDS_Vertex v;
+    v = forward ? TopExp::LastVertex( edge,1 ) : TopExp::FirstVertex( edge,1 );
+    TopTools_ListIteratorOfListOfShape ancestIt = aMesh.GetAncestors( v );
+    for ( ; ancestIt.More(); ancestIt.Next() )
+    {
+      const TopoDS_Shape & ancestor = ancestIt.Value();
+      if ( ancestor.ShapeType() == TopAbs_EDGE && edgeCounter.Add( ancestor ))
+        eNext = TopoDS::Edge( ancestor );
+    }
+    if ( edgeCounter.Extent() < 3 && !eNext.IsNull() ) {
+      GeomAbs_Shape cont = SMESH_Algo::Continuity( edge, eNext );
+      if (cont >= GeomAbs_G1) {
+        // care of orientation
+        bool reverse;
+        if ( forward )
+          reverse = ( !v.IsSame( TopExp::FirstVertex( eNext, true )));
+        else
+          reverse = ( !v.IsSame( TopExp::LastVertex( eNext, true )));
+        if ( reverse )
+          eNext.Reverse();
+        return eNext;
+      }
+    }
+    return TopoDS_Edge();
+  }
+
+  //================================================================================
+  /*!
+   * \brief Update submeshes state for all edges and internal vertices,
+   * make them look computed even if none edge or node is set on them
+   */
+  //================================================================================
+
+  void careOfSubMeshes( StdMeshers_FaceSide& side, EventListener* eListener)
+  {
+    if ( side.NbEdges() < 2)
+      return;
+    for ( int iE = 0; iE < side.NbEdges(); ++iE )
+    {
+      // set listener and its data 
+      EventListenerData * listenerData = new EventListenerData(true);
+      const TopoDS_Edge& edge = side.Edge( iE );
+      SMESH_subMesh * sm = side.GetMesh()->GetSubMesh( edge );
+      sm->SetEventListener( eListener, listenerData, sm );
+      // add edge submesh to the data
+      sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+      if ( !sm->GetComputeState() != SMESH_subMesh::COMPUTE_OK ) {
+        sm->SetIsAlwaysComputed( true );
+        listenerData->mySubMeshes.push_back( sm );
+      }
+      // add internal vertex submesh to the data
+      if ( iE )
+      {
+        TopoDS_Vertex V = side.FirstVertex( iE );
+        sm = side.GetMesh()->GetSubMesh( V );
+        sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+        if ( !sm->GetComputeState() != SMESH_subMesh::COMPUTE_OK )
+          sm->SetIsAlwaysComputed( true );
+        listenerData->mySubMeshes.push_back( sm );
+      }
+    }
+  }
+
+  //================================================================================
+  /*!
+   * \brief Class used to restore nodes on internal vertices of a complex side
+   *  when StdMeshers_CompositeSegment_1D algorithm is removed
+   */
+  //================================================================================
+
+  struct VertexNodesRestoringListener : public SMESH_subMeshEventListener
+  {
+    VertexNodesRestoringListener():SMESH_subMeshEventListener(0) // won't be deleted by submesh
+    {}
+  /*!
+   * \brief Restore nodes on internal vertices of a complex side
+   * \param event - algo_event or compute_event itself (of SMESH_subMesh)
+   * \param eventType - ALGO_EVENT or COMPUTE_EVENT (of SMESH_subMesh)
+   * \param subMesh - the submesh where the event occures
+   * \param data - listener data stored in the subMesh
+   * \param hyp - hypothesis, if eventType is algo_event
+   */
+    void ProcessEvent(const int          event,
+                      const int          eventType,
+                      SMESH_subMesh*     subMesh,
+                      EventListenerData* data,
+                      const SMESH_Hypothesis*  /*hyp*/)
+    {
+      bool hypRemoved = ( eventType == SMESH_subMesh::ALGO_EVENT &&
+                          subMesh->GetAlgoState() != SMESH_subMesh::HYP_OK );
+      if ( hypRemoved && data )
+      {
+        list<SMESH_subMesh*>::iterator smIt = data->mySubMeshes.begin();
+        for ( ; smIt != data->mySubMeshes.end(); ++smIt )
+        {
+          if ( SMESH_subMesh* sm = *smIt ) {
+            sm->SetIsAlwaysComputed( false );
+            sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+          }
+        }
+      }
+      // at study restoration:
+      // check if edge submesh must have _alwaysComputed flag
+      else if ( event     == SMESH_subMesh::SUBMESH_RESTORED &&
+                eventType == SMESH_subMesh::COMPUTE_EVENT )
+      {
+        if ( !subMesh->GetEventListenerData( this )) { // not yet checked
+          SMESHDS_Mesh * meshDS = subMesh->GetFather()->GetMeshDS();
+          if ( meshDS->NbNodes() > 0 ) {
+            // check if there are nodes on all vertices
+            bool hasNodesOnVerext = true;
+            SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
+            while ( hasNodesOnVerext && smIt->more() ) {
+              SMESH_subMesh* sm = smIt->next();
+              hasNodesOnVerext = ( sm->GetSubMeshDS() && sm->GetSubMeshDS()->NbNodes() );
+            }
+            if ( !hasNodesOnVerext ) {
+              // check if an edge is a part of a complex side
+              TopoDS_Face face;
+              TopoDS_Edge edge = TopoDS::Edge( subMesh->GetSubShape() );
+              auto_ptr< StdMeshers_FaceSide > side
+                ( StdMeshers_CompositeSegment_1D::GetFaceSide(*subMesh->GetFather(),
+                                                              edge, face, false ));
+              if ( side->NbEdges() > 1 && side->NbSegments() )
+                careOfSubMeshes( *side, this );
+            }
+          }
+        }
+      }
+    }
+  }; // struct VertexNodesRestoringListener
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+StdMeshers_CompositeSegment_1D::StdMeshers_CompositeSegment_1D(int         hypId,
+                                                               int         studyId,
+                                                               SMESH_Gen * gen)
+  :StdMeshers_Regular_1D(hypId, studyId, gen)
+{
+  MESSAGE("StdMeshers_CompositeSegment_1D::StdMeshers_CompositeSegment_1D");
+  _name = "CompositeSegment_1D";
+  _EventListener = new VertexNodesRestoringListener();
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+StdMeshers_CompositeSegment_1D::~StdMeshers_CompositeSegment_1D()
+{
+  delete _EventListener;
+}
+
+//=============================================================================
+/*!
+ * \brief Sets event listener to submeshes if necessary
+ * \param subMesh - submesh where algo is set
+ *
+ * This method is called when a submesh gets HYP_OK algo_state.
+ * After being set, event listener is notified on each event of a submesh.
+ */
+//=============================================================================
+
+void StdMeshers_CompositeSegment_1D::SetEventListener(SMESH_subMesh* subMesh)
+{
+  subMesh->SetEventListener( _EventListener, 0, subMesh);
+  StdMeshers_Regular_1D::SetEventListener( subMesh );
+}
+
+//=============================================================================
+/*!
+ * \brief Return a face side the edge belongs to
+ */
+//=============================================================================
+
+StdMeshers_FaceSide *
+StdMeshers_CompositeSegment_1D::GetFaceSide(SMESH_Mesh&        aMesh,
+                                            const TopoDS_Edge& anEdge,
+                                            const TopoDS_Face& aFace,
+                                            const bool         ignoreMeshed)
+{
+  list< TopoDS_Edge > edges;
+  edges.push_back( anEdge );
+
+  list <const SMESHDS_Hypothesis *> hypList;
+  SMESH_Algo* theAlgo = aMesh.GetGen()->GetAlgo( aMesh, anEdge );
+  if ( theAlgo ) hypList = theAlgo->GetUsedHypothesis(aMesh, anEdge, false);
+  for ( int forward = 0; forward < 2; ++forward )
+  {
+    TopoDS_Edge eNext = nextC1Edge( anEdge, aMesh, forward );
+    while ( !eNext.IsNull() ) {
+      if ( ignoreMeshed ) {
+        // eNext must not have computed mesh
+        if ( SMESHDS_SubMesh* sm = aMesh.GetMeshDS()->MeshElements(eNext) )
+          if ( sm->NbNodes() || sm->NbElements() )
+            break;
+      }
+      // eNext must have same hypotheses
+      SMESH_Algo* algo = aMesh.GetGen()->GetAlgo( aMesh, eNext );
+      if ( !algo ||
+           string(theAlgo->GetName()) != algo->GetName() ||
+           hypList != algo->GetUsedHypothesis(aMesh, eNext, false))
+        break;
+      if ( forward )
+        edges.push_back( eNext );
+      else
+        edges.push_front( eNext );
+      eNext = nextC1Edge( eNext, aMesh, forward );
+    }
+  }
+  return new StdMeshers_FaceSide( aFace, edges, &aMesh, true, false );
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+bool StdMeshers_CompositeSegment_1D::Compute(SMESH_Mesh &         aMesh,
+                                             const TopoDS_Shape & aShape)
+{
+  TopoDS_Edge edge = TopoDS::Edge( aShape );
+  SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+
+  // Get edges to be discretized as a whole
+  TopoDS_Face nullFace;
+  auto_ptr< StdMeshers_FaceSide > side( GetFaceSide(aMesh, edge, nullFace, true ));
+  //side->dump("IN COMPOSITE SEG");
+
+  if ( side->NbEdges() < 2 )
+    return StdMeshers_Regular_1D::Compute( aMesh, aShape );
+
+  // update segment lenght computed by StdMeshers_AutomaticLength
+  const list <const SMESHDS_Hypothesis * > & hyps = GetUsedHypothesis(aMesh, aShape);
+  if ( !hyps.empty() ) {
+    StdMeshers_AutomaticLength * autoLenHyp = const_cast<StdMeshers_AutomaticLength *>
+      (dynamic_cast <const StdMeshers_AutomaticLength * >(hyps.front()));
+    if ( autoLenHyp )
+      _value[ BEG_LENGTH_IND ]= autoLenHyp->GetLength( &aMesh, side->Length() );
+  }
+
+  // Compute node parameters
+  auto_ptr< BRepAdaptor_CompCurve > C3d ( side->GetCurve3d() );
+  double f = C3d->FirstParameter(), l = C3d->LastParameter();
+  list< double > params;
+  if ( !computeInternalParameters ( *C3d, side->Length(), f, l, params, false ))
+    return false;
+
+  // Redistribute parameters near ends
+  TopoDS_Vertex VFirst = side->FirstVertex();
+  TopoDS_Vertex VLast  = side->LastVertex();
+  redistributeNearVertices( aMesh, *C3d, side->Length(), params, VFirst, VLast );
+
+  params.push_front(f);
+  params.push_back(l);
+  int nbNodes = params.size();
+
+  // Create mesh
+
+  const SMDS_MeshNode * nFirst = SMESH_Algo::VertexNode( VFirst, meshDS );
+  const SMDS_MeshNode * nLast  = SMESH_Algo::VertexNode( VLast, meshDS );
+  if (!nFirst) 
+    return error(COMPERR_BAD_INPUT_MESH, TComm("No node on vertex ")
+                 <<meshDS->ShapeToIndex(VFirst));
+  if (!nLast)
+    return error(COMPERR_BAD_INPUT_MESH, TComm("No node on vertex ")
+                 <<meshDS->ShapeToIndex(VLast));
+
+  vector<const SMDS_MeshNode*> nodes( nbNodes, (const SMDS_MeshNode*)0 );
+  nodes.front() = nFirst;
+  nodes.back()  = nLast;
+
+  // create internal nodes
+  list< double >::iterator parIt = params.begin();
+  double prevPar = *parIt;
+  Standard_Real u;
+  for ( int iN = 0; parIt != params.end(); ++iN, ++parIt)
+  {
+    if ( !nodes[ iN ] ) {
+      gp_Pnt p = C3d->Value( *parIt );
+      SMDS_MeshNode* n = meshDS->AddNode( p.X(), p.Y(), p.Z());
+      C3d->Edge( *parIt, edge, u );
+      meshDS->SetNodeOnEdge( n, edge, u );
+//       cout << "new NODE: par="<<*parIt<<" ePar="<<u<<" e="<<edge.TShape().operator->()
+//            << " " << n << endl;
+      nodes[ iN ] = n;
+    }
+    // create edges
+    if ( iN ) {
+      double mPar = ( prevPar + *parIt )/2;
+      if ( _quadraticMesh ) {
+        // create medium node
+        double segLen = GCPnts_AbscissaPoint::Length(*C3d, prevPar, *parIt);
+        GCPnts_AbscissaPoint ruler( *C3d, segLen/2., prevPar );
+        if ( ruler.IsDone() )
+          mPar = ruler.Parameter();
+        gp_Pnt p = C3d->Value( mPar );
+        SMDS_MeshNode* n = meshDS->AddNode( p.X(), p.Y(), p.Z());
+        //cout << "new NODE "<< n << endl;
+        meshDS->SetNodeOnEdge( n, edge, u );
+        SMDS_MeshEdge * seg = meshDS->AddEdge(nodes[ iN-1 ], nodes[ iN ], n);
+        meshDS->SetMeshElementOnShape(seg, edge);
+      }
+      else {
+        C3d->Edge( mPar, edge, u );
+        SMDS_MeshEdge * seg = meshDS->AddEdge(nodes[ iN-1 ], nodes[ iN ]);
+        meshDS->SetMeshElementOnShape(seg, edge);
+      }
+    }
+    prevPar = *parIt;
+  }
+
+  // remove nodes on internal vertices
+  for ( int iE = 1; iE < side->NbEdges(); ++iE )
+  {
+    TopoDS_Vertex V = side->FirstVertex( iE );
+    while ( const SMDS_MeshNode * n = SMESH_Algo::VertexNode( V, meshDS ))
+      meshDS->RemoveNode( n );
+  }
+
+  // Update submeshes state for all edges and internal vertices,
+  // make them look computed even if none edge or node is set on them
+  careOfSubMeshes( *side, _EventListener );
+
+  return true;
+}
+
diff --git a/src/StdMeshers/StdMeshers_CompositeSegment_1D.hxx b/src/StdMeshers/StdMeshers_CompositeSegment_1D.hxx
new file mode 100644 (file)
index 0000000..66b87ec
--- /dev/null
@@ -0,0 +1,68 @@
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : StdMeshers_CompositeSegment_1D.hxx
+//  Module : SMESH
+//  $Header$
+
+#ifndef _SMESH_CompositeSegment_1D_HXX_
+#define _SMESH_CompositeSegment_1D_HXX_
+
+#include "StdMeshers_Regular_1D.hxx"
+
+class SMESH_subMeshEventListener;
+class SMESH_Mesh;
+class StdMeshers_FaceSide;
+class TopoDS_Edge;
+class TopoDS_Face;
+
+class StdMeshers_CompositeSegment_1D: public StdMeshers_Regular_1D
+{
+public:
+  StdMeshers_CompositeSegment_1D(int hypId, int studyId, SMESH_Gen* gen);
+  virtual ~StdMeshers_CompositeSegment_1D();
+
+  virtual bool Compute(SMESH_Mesh&         aMesh,
+                      const TopoDS_Shape& aShape);
+  /*!
+   * \brief Sets event listener to submeshes if necessary
+    * \param subMesh - submesh where algo is set
+   *
+   * This method is called when a submesh gets HYP_OK algo_state.
+   * After being set, event listener is notified on each event of a submesh.
+   */
+  virtual void SetEventListener(SMESH_subMesh* subMesh);
+
+   /*!
+   * \brief Return a face side the edge belongs to
+   */
+  static StdMeshers_FaceSide * GetFaceSide(SMESH_Mesh&        aMesh,
+                                           const TopoDS_Edge& anEdge,
+                                           const TopoDS_Face& aFace,
+                                           const bool         ignoreMeshed);
+
+protected:
+  SMESH_subMeshEventListener* _EventListener;
+};
+
+#endif
index 6cfb7559784da6f7d36561980c09c3a634ecea29..44153632755a5836ed37d64fb58f9f8e031921d0 100644 (file)
@@ -117,6 +117,12 @@ bool FunctionTable::value( const double t, double& f ) const
   if( !findBounds( t, i1, i2 ) )
     return false;
 
+  if( i1==i2 ) {
+    f = myData[ 2*i1+1 ];
+    Function::value( t, f );
+    return true;
+  }
+      
   double
     x1 = myData[2*i1], y1 = myData[2*i1+1],
     x2 = myData[2*i2], y2 = myData[2*i2+1];
@@ -140,8 +146,10 @@ double FunctionTable::integral( const int i, const double d ) const
 {
   double f1,f2, res = 0.0;
   if( value( myData[2*i]+d, f1 ) )
-    if(!value(myData[2*i], f2))
+    if(!value(myData[2*i], f2)) {
       f2 = myData[2*i+1];
+      Function::value( 1, f2 );
+    }
   res = (f2+f1) * d / 2.0;
   return res;
 }
@@ -169,7 +177,7 @@ bool FunctionTable::findBounds( const double x, int& x_ind_1, int& x_ind_2 ) con
   }
 
   for( int i=0; i<n-1; i++ )
-    if( myData[2*i]<=x && x<=myData[2*(i+1)] )
+    if( myData[2*i]<=x && x<myData[2*(i+1)] )
     {
       x_ind_1 = i;
       x_ind_2 = i+1;
@@ -177,7 +185,7 @@ bool FunctionTable::findBounds( const double x, int& x_ind_1, int& x_ind_2 ) con
     }
   x_ind_1 = n-1;
   x_ind_2 = n-1;
-  return false;
+  return ( fabs( x - myData[2*x_ind_2] ) < 1.e-10 );
 }
 
 FunctionExpr::FunctionExpr( const char* str, const int conv )
diff --git a/src/StdMeshers/StdMeshers_FaceSide.cxx b/src/StdMeshers/StdMeshers_FaceSide.cxx
new file mode 100644 (file)
index 0000000..85057fb
--- /dev/null
@@ -0,0 +1,466 @@
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+// File      : StdMeshers_FaceSide.hxx
+// Created   : Wed Jan 31 18:41:25 2007
+// Author    : Edward AGAPOV (eap)
+// Module    : SMESH
+
+#include "StdMeshers_FaceSide.hxx"
+
+#include "SMDS_EdgePosition.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMESHDS_Mesh.hxx"
+#include "SMESHDS_SubMesh.hxx"
+#include "SMESH_Algo.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_MeshEditor.hxx"
+
+#include <Adaptor2d_Curve2d.hxx>
+#include <BRepAdaptor_CompCurve.hxx>
+#include <BRepAdaptor_Curve.hxx>
+#include <BRep_Builder.hxx>
+#include <BRep_Tool.hxx>
+#include <TopExp.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <TopoDS_Wire.hxx>
+
+#include <map>
+
+#include "utilities.h"
+
+//================================================================================
+/*!
+ * \brief Constructor of a side of one edge
+  * \param theFace - the face
+  * \param theEdge - the edge
+ */
+//================================================================================
+
+StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace,
+                                         const TopoDS_Edge& theEdge,
+                                         SMESH_Mesh*        theMesh,
+                                         const bool         theIsForward,
+                                         const bool         theIgnoreMediumNodes)
+{
+  list<TopoDS_Edge> edges(1,theEdge);
+  *this = StdMeshers_FaceSide( theFace, edges, theMesh, theIsForward, theIgnoreMediumNodes );
+}
+
+//================================================================================
+/*!
+ * \brief Constructor of a side of several edges
+  * \param theFace - the face
+  * \param theEdge - the edge
+ */
+//================================================================================
+
+StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace,
+                                         list<TopoDS_Edge>& theEdges,
+                                         SMESH_Mesh*        theMesh,
+                                         const bool         theIsForward,
+                                         const bool         theIgnoreMediumNodes)
+{
+  int nbEdges = theEdges.size();
+  myEdge.resize( nbEdges );
+  myC2d.resize( nbEdges );
+  myFirst.resize( nbEdges );
+  myLast.resize( nbEdges );
+  myNormPar.resize( nbEdges );
+  myLength = 0;
+  myNbPonits = myNbSegments = 0;
+  myMesh = theMesh;
+  myMissingVertexNodes = false;
+  myIgnoreMediumNodes = theIgnoreMediumNodes;
+  if ( nbEdges == 0 ) return;
+
+  SMESHDS_Mesh* meshDS = theMesh->GetMeshDS();
+  vector<double> len( nbEdges );
+
+  int nbDegen = 0;
+  list<TopoDS_Edge>::iterator edge = theEdges.begin();
+  for ( int index = 0; edge != theEdges.end(); ++index, ++edge )
+  {
+    int i = theIsForward ? index : nbEdges - index - 1;
+    len[i] = SMESH_Algo::EdgeLength( *edge );
+    if ( len[i] < DBL_MIN ) nbDegen++;
+    myLength += len[i];
+    myEdge[i] = *edge;
+    if ( !theIsForward ) myEdge[i].Reverse();
+
+    if ( theFace.IsNull() )
+      BRep_Tool::Range( *edge, myFirst[i], myLast[i] );
+    else
+      myC2d[i] = BRep_Tool::CurveOnSurface( *edge, theFace, myFirst[i], myLast[i] );
+    if ( myEdge[i].Orientation() == TopAbs_REVERSED )
+      std::swap( myFirst[i], myLast[i] );
+
+    if ( SMESHDS_SubMesh* sm = meshDS->MeshElements( *edge )) {
+      int nbN = sm->NbNodes();
+      if ( theIgnoreMediumNodes ) {
+        SMDS_ElemIteratorPtr elemIt = sm->GetElements();
+        if ( elemIt->more() && elemIt->next()->IsQuadratic() )
+          nbN -= sm->NbElements();
+      }
+      myNbPonits += nbN;
+      myNbSegments += sm->NbElements();
+    }
+    if ( SMESH_Algo::VertexNode( TopExp::FirstVertex( *edge, 1), meshDS ))
+      myNbPonits += 1; // for the first end
+    else
+      myMissingVertexNodes = true;
+  }
+  if ( SMESH_Algo::VertexNode( TopExp::LastVertex( theEdges.back(), 1), meshDS ))
+    myNbPonits++; // for the last end
+  else
+    myMissingVertexNodes = true;
+
+  if ( nbEdges > 1 && myLength > DBL_MIN ) {
+    const double degenNormLen = 1.e-5;
+    double totLength = myLength;
+    if ( nbDegen )
+      totLength += myLength * degenNormLen * nbDegen;
+    double prevNormPar = 0;
+    for ( int i = 0; i < nbEdges; ++i ) {
+      if ( len[ i ] < DBL_MIN )
+        len[ i ] = myLength * degenNormLen;
+      myNormPar[ i ] = prevNormPar + len[i]/totLength;
+      prevNormPar = myNormPar[ i ];
+    }
+  }
+  myNormPar[nbEdges-1] = 1.;
+  //dump();
+}
+
+//================================================================================
+/*!
+ * \brief Return info on nodes on the side
+  * \retval UVPtStruct* - array of data structures
+ */
+//================================================================================
+
+const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool   isXConst,
+                                                             double constValue) const
+{
+  if ( myPoints.empty() ) {
+
+    if ( NbEdges() == 0 ) return myPoints;
+
+    SMESHDS_Mesh* meshDS = myMesh->GetMeshDS();
+
+    // sort nodes of all edges putting them into a map
+
+    map< double, const SMDS_MeshNode*> u2node;
+    //int nbOnDegen = 0;
+    for ( int i = 0; i < myEdge.size(); ++i )
+    {
+      // put 1st vertex node
+      TopoDS_Vertex VFirst, VLast;
+      TopExp::Vertices( myEdge[i], VFirst, VLast, true);
+      const SMDS_MeshNode* node = SMESH_Algo::VertexNode( VFirst, meshDS );
+      double prevNormPar = ( i == 0 ? 0 : myNormPar[ i-1 ]); // normalized param
+      if ( node ) { // internal nodes may be missing
+        u2node.insert( make_pair( prevNormPar, node ));
+      } else if ( i == 0 ) {
+        MESSAGE(" NO NODE on VERTEX" );
+        return myPoints;
+      }
+
+      // put 2nd vertex node for a last edge
+      if ( i+1 == myEdge.size() ) {
+        node = SMESH_Algo::VertexNode( VLast, meshDS );
+        if ( !node ) {
+          MESSAGE(" NO NODE on VERTEX" );
+          return myPoints;
+        }
+        u2node.insert( make_pair( 1., node ));
+      }
+
+      // put internal nodes
+      SMESHDS_SubMesh* sm = meshDS->MeshElements( myEdge[i] );
+      if ( !sm ) continue;
+      SMDS_NodeIteratorPtr nItr = sm->GetNodes();
+      double paramSize = myLast[i] - myFirst[i], r = myNormPar[i] - prevNormPar;
+      while ( nItr->more() ) {
+        const SMDS_MeshNode* node = nItr->next();
+        if ( myIgnoreMediumNodes && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge ))
+          continue;
+        const SMDS_EdgePosition* epos =
+          static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+        double u = epos->GetUParameter();
+        // paramSize is signed so orientation is taken into account
+        double normPar = prevNormPar + r * ( u - myFirst[i] ) / paramSize;
+#ifdef _DEBUG_
+        if ( normPar > 1 || normPar < 0) {
+          dump("DEBUG");
+          cout << "WRONG normPar: "<<normPar<< " prevNormPar="<<prevNormPar
+               << " u="<<u << " myFirst[i]="<<myFirst[i]<< " myLast[i]="<<myLast[i]
+               << " paramSize="<<paramSize<<endl;
+        }
+#endif
+        u2node.insert( make_pair( normPar, node ));
+      }
+    }
+    if ( u2node.size() != myNbPonits ) {
+      MESSAGE("Wrong node parameters on edges, u2node.size():"
+              <<u2node.size()<<" !=  myNbPonits:"<<myNbPonits);
+      return myPoints;
+    }
+
+    // fill array of UVPtStruct
+
+    vector<uvPtStruct>* points = const_cast<vector<uvPtStruct>*>( &myPoints );
+    points->resize( myNbPonits );
+
+    int EdgeIndex = 0;
+    double prevNormPar = 0, paramSize = myNormPar[ EdgeIndex ];
+    map< double, const SMDS_MeshNode*>::iterator u_node = u2node.begin();
+    for (int i = 0 ; u_node != u2node.end(); ++u_node, ++i ) {
+      UVPtStruct & uvPt = (*points)[i];
+      uvPt.node = u_node->second;
+      uvPt.x = uvPt.y = uvPt.normParam = u_node->first;
+      if ( isXConst ) uvPt.x = constValue;
+      else            uvPt.y = constValue;
+      if ( myNormPar[ EdgeIndex ] < uvPt.normParam ) {
+        prevNormPar = myNormPar[ EdgeIndex ];
+        ++EdgeIndex;
+#ifdef _DEBUG_
+        if ( EdgeIndex >= myEdge.size() ) {
+          dump("DEBUG");
+          cout << "WRONg EdgeIndex " << 1+EdgeIndex
+               << " myNormPar.size()="<<myNormPar.size()
+               << " myNormPar["<< EdgeIndex<<"]="<< myNormPar[ EdgeIndex ]
+               << " uvPt.normParam="<<uvPt.normParam <<endl;
+        }
+#endif
+        paramSize = myNormPar[ EdgeIndex ] - prevNormPar;
+      }
+      const SMDS_EdgePosition* epos =
+        dynamic_cast<const SMDS_EdgePosition*>(uvPt.node->GetPosition().get());
+      if ( epos ) {
+        uvPt.param = epos->GetUParameter();
+      }
+      else {
+        double r = ( uvPt.normParam - prevNormPar )/ paramSize;
+//         uvPt.param = myFirst[EdgeIndex] * ( 1 - r ) + myLast[EdgeIndex] * r;
+        uvPt.param = ( r > 0.5 ? myLast[EdgeIndex] : myFirst[EdgeIndex] );
+      }
+      if ( !myC2d[ EdgeIndex ].IsNull() ) {
+        gp_Pnt2d p = myC2d[ EdgeIndex ]->Value( uvPt.param );
+        uvPt.u = p.X();
+        uvPt.v = p.Y();
+      }
+      else {
+        uvPt.u = uvPt.v = 1e+100;
+      }
+    }
+  }
+  return myPoints;
+}
+
+//================================================================================
+/*!
+ * \brief Falsificate info on nodes
+  * \param nbSeg - nb of segments on the side
+  * \retval UVPtStruct* - array of data structures
+ */
+//================================================================================
+
+const vector<UVPtStruct>& StdMeshers_FaceSide::SimulateUVPtStruct(int    nbSeg,
+                                                                  bool   isXConst,
+                                                                  double constValue) const
+{
+  if ( myFalsePoints.empty() ) {
+
+    if ( NbEdges() == 0 ) return myFalsePoints;
+
+    vector<uvPtStruct>* points = const_cast<vector<uvPtStruct>*>( &myFalsePoints );
+    points->resize( nbSeg+1 );
+
+    int EdgeIndex = 0;
+    double prevNormPar = 0, paramSize = myNormPar[ EdgeIndex ];
+    for (int i = 0 ; i < myFalsePoints.size(); ++i ) {
+      double normPar = double(i) / double(nbSeg);
+      UVPtStruct & uvPt = (*points)[i];
+      uvPt.node = 0;
+      uvPt.x = uvPt.y = uvPt.param = uvPt.normParam = normPar;
+      if ( isXConst ) uvPt.x = constValue;
+      else            uvPt.y = constValue;
+      if ( myNormPar[ EdgeIndex ] < normPar ) {
+        prevNormPar = myNormPar[ EdgeIndex ];
+        ++EdgeIndex;
+        paramSize = myNormPar[ EdgeIndex ] - prevNormPar;
+      }
+      double r = ( normPar - prevNormPar )/ paramSize;
+      uvPt.param = myFirst[EdgeIndex] * ( 1 - r ) + myLast[EdgeIndex] * r;
+      if ( !myC2d[ EdgeIndex ].IsNull() ) {
+        gp_Pnt2d p = myC2d[ EdgeIndex ]->Value( uvPt.param );
+        uvPt.u = p.X();
+        uvPt.v = p.Y();
+      }
+      else {
+        uvPt.u = uvPt.v = 1e+100;
+      }
+    }
+  }
+  return myFalsePoints;
+}
+// gp_Pnt StdMeshers_FaceSide::Value(double U) const
+// {
+// }
+
+//================================================================================
+/*!
+ * \brief reverse order of vector elements
+  * \param vec - vector to reverse
+ */
+//================================================================================
+
+template <typename T > void reverse(vector<T> & vec)
+{
+  for ( int f=0, r=vec.size()-1; f < r; ++f, --r )
+    std::swap( vec[f], vec[r] );
+}
+
+//================================================================================
+/*!
+ * \brief Change orientation of side geometry
+ */
+//================================================================================
+
+void StdMeshers_FaceSide::Reverse()
+{
+  int nbEdges = myEdge.size();
+  for ( int i = nbEdges-1; i >= 0; --i ) {
+    std::swap( myFirst[i], myLast[i] );
+    myEdge[i].Reverse();
+    if ( i > 0 ) // at the first loop 1. is overwritten
+      myNormPar[i] = 1 - myNormPar[i-1];
+  }
+  if ( nbEdges > 1 ) {
+    reverse( myEdge );
+    reverse( myC2d );
+    reverse( myFirst );
+    reverse( myLast );
+    reverse( myNormPar );
+  }
+  myNormPar[nbEdges-1]=1.;
+  myPoints.clear();
+  myFalsePoints.clear();
+}
+
+//================================================================================
+/*!
+ * \brief Show side features
+ */
+//================================================================================
+
+void StdMeshers_FaceSide::dump(const char* msg) const
+{
+#ifdef _DEBUG_
+  cout << endl;
+  if (msg) cout << msg <<endl;
+  cout<<"NB EDGES: "<< myEdge.size() <<endl;
+  cout << "nbPoints: "<<myNbPonits<<" vecSize: " << myPoints.size()<<" "<<myFalsePoints.size() <<endl;
+  for ( int i=0; i<myEdge.size(); ++i)
+  {
+    cout << "\t"<<i+1<<endl;
+    cout << "\tEDGE: ";
+    if (myEdge[i].IsNull())
+      cout<<"NULL"<<endl;
+    else {
+      TopAbs::Print(myEdge[i].Orientation(),cout)<<" "<<myEdge[i].TShape().operator->()<<endl;
+      cout << "\tV1: " << TopExp::FirstVertex( myEdge[i], 1).TShape().operator->()
+           << "  V2: " << TopExp::LastVertex( myEdge[i], 1).TShape().operator->() << endl;
+    }
+    cout << "\tC2d: ";
+    if (myC2d[i].IsNull()) cout<<"NULL"<<endl;
+    else cout << myC2d[i].operator->()<<endl;
+    cout << "\tF: "<<myFirst[i]<< " L: "<< myLast[i]<<endl;
+    cout << "\tnormPar: "<<myNormPar[i]<<endl;
+  }
+#endif
+}
+
+//================================================================================
+/*!
+ * \brief Creates a Adaptor2d_Curve2d to be used in SMESH_Block
+  * \retval Adaptor2d_Curve2d* - 
+ */
+//================================================================================
+
+struct Adaptor2dCurve2d : public Adaptor2d_Curve2d
+{
+  const StdMeshers_FaceSide* mySide;
+  Adaptor2dCurve2d(const StdMeshers_FaceSide* faceSide):mySide(faceSide) {}
+  gp_Pnt2d Value(const Standard_Real U) const { return mySide->Value2d( U ); }
+  Standard_Real FirstParameter() const { return 0; }
+  Standard_Real LastParameter() const { return 1; }
+};
+
+Adaptor2d_Curve2d* StdMeshers_FaceSide::GetCurve2d() const
+{
+  return new Adaptor2dCurve2d( this );
+}
+
+//================================================================================
+/*!
+ * \brief Creates a fully functional Adaptor_Curve
+ */
+//================================================================================
+
+BRepAdaptor_CompCurve* StdMeshers_FaceSide::GetCurve3d() const
+{
+  if ( myEdge.empty() )
+    return 0;
+
+//   if ( myEdge.size() == 1 )
+//     return new BRepAdaptor_Curve( myEdge[0] );
+
+  TopoDS_Wire aWire;
+  BRep_Builder aBuilder;
+  aBuilder.MakeWire(aWire);
+  for ( int i=0; i<myEdge.size(); ++i )
+    aBuilder.Add( aWire, myEdge[i] );
+  return new BRepAdaptor_CompCurve( aWire );
+}
+
+//================================================================================
+/*!
+ * \brief Return 2D point by normalized parameter
+  * \param U - normalized parameter value
+  * \retval gp_Pnt2d - point
+ */
+//================================================================================
+
+gp_Pnt2d StdMeshers_FaceSide::Value2d(double U) const
+{
+  if ( !myC2d[0].IsNull() ) {
+    int i = EdgeIndex( U );
+    double prevU = i ? myNormPar[ i-1 ] : 0;
+    double r = ( U - prevU )/ ( myNormPar[ i ] - prevU );
+    return myC2d[ i ]->Value( myFirst[i] * ( 1 - r ) + myLast[i] * r );
+  }
+  return gp_Pnt2d( 1e+100, 1e+100 );
+}
diff --git a/src/StdMeshers/StdMeshers_FaceSide.hxx b/src/StdMeshers/StdMeshers_FaceSide.hxx
new file mode 100644 (file)
index 0000000..1463d2d
--- /dev/null
@@ -0,0 +1,270 @@
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+// File      : StdMeshers_FaceSide.hxx
+// Created   : Wed Jan 31 18:41:25 2007
+// Author    : Edward AGAPOV (eap)
+// Module    : SMESH
+
+#ifndef StdMeshers_FaceSide_HeaderFile
+#define StdMeshers_FaceSide_HeaderFile
+
+#include <gp_Pnt2d.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Vertex.hxx>
+#include <Geom2d_Curve.hxx>
+#include <TopExp.hxx>
+
+#include <vector>
+#include <list>
+#include <boost/shared_ptr.hpp>
+
+class SMDS_MeshNode;
+class SMESH_Mesh;
+class Adaptor2d_Curve2d;
+class Adaptor3d_Curve;
+class BRepAdaptor_CompCurve;
+class TopoDS_Face;
+
+typedef struct uvPtStruct
+{
+  double param;
+  //int    curvIndex;
+  double normParam;
+  double u; // original 2d parameter
+  double v;
+  double x; // 2d parameter, normalized [0,1]
+  double y;
+  const SMDS_MeshNode * node;
+} UVPtStruct;
+
+class StdMeshers_FaceSide;
+typedef boost::shared_ptr< StdMeshers_FaceSide > StdMeshers_FaceSidePtr;
+typedef boost::shared_ptr< uvPtStruct > UVPtStructPtr;
+
+//================================================================================
+/*!
+ * \brief Represents a side of a quasi quadrilateral face.
+ * It can be composed of several edges. Gives access to geometry and 1D mesh of a side.
+ */
+//================================================================================
+
+class StdMeshers_FaceSide
+{
+public:
+  /*!
+   * \brief Wrap one edge
+   */
+  StdMeshers_FaceSide(const TopoDS_Face& theFace,
+                      const TopoDS_Edge& theEdge,
+                      SMESH_Mesh*        theMesh,
+                      const bool         theIsForward,
+                      const bool         theIgnoreMediumNodes);
+  /*!
+   * \brief Wrap several edges. Edges must be properly ordered and oriented.
+   */
+  StdMeshers_FaceSide(const TopoDS_Face& theFace,
+                      list<TopoDS_Edge>& theEdges,
+                      SMESH_Mesh*        theMesh,
+                      const bool         theIsForward,
+                      const bool         theIgnoreMediumNodes);
+  /*!
+   * \brief Change orientation of side geometry
+   */
+  void Reverse();
+  /*!
+   * \brief Return nb nodes on edges and vertices (+1 to be == GetUVPtStruct().size() )
+   */
+  int NbPoints() const { return myNbPonits; }
+  /*!
+   * \brief Return nb edges
+   */
+  int NbSegments() const { return myNbSegments; }
+  /*!
+   * \brief Return mesh
+   */
+  SMESH_Mesh* GetMesh() const { return myMesh; }
+  /*!
+   * \brief Return true if there vertices without nodes
+   */
+  bool MissVertexNode() const { return myMissingVertexNodes; }
+  /*!
+   * \brief Return detailed data on nodes
+    * \param isXConst - true if normalized parameter X is constant
+    * \param constValue - constant parameter value
+    *
+    * Missing nodes are allowed only on internal vertices
+   */
+  const vector<UVPtStruct>& GetUVPtStruct(bool isXConst, double constValue) const;
+  /*!
+   * \brief Simulates detailed data on nodes
+    * \param isXConst - true if normalized parameter X is constant
+    * \param constValue - constant parameter value
+   */
+  const vector<UVPtStruct>& SimulateUVPtStruct(int    nbSeg,
+                                               bool   isXConst,
+                                               double constValue) const;
+  /*!
+   * \brief Return edge and parameter on edge by normalized parameter
+   */
+  inline double Parameter(double U, TopoDS_Edge & edge) const;
+  /*!
+   * \brief Return UV by normalized parameter
+   */
+  gp_Pnt2d Value2d(double U) const;
+  /*!
+   * \brief Creates a Adaptor2d_Curve2d to be used in SMESH_Block
+   */
+  Adaptor2d_Curve2d* GetCurve2d() const;
+  /*!
+   * \brief Creates a fully functional Adaptor_Curve
+   */
+  BRepAdaptor_CompCurve* GetCurve3d() const;
+  /*!
+   * \brief Return nb of wrapped edges
+   */
+  int NbEdges() const { return myEdge.size(); }
+  /*!
+   * \brief Return i-th wrapped edge (count starts from zero)
+   */
+  const TopoDS_Edge& Edge(int i) const { return myEdge[i]; }
+  /*!
+   * \brief Return 1st vertex of the i-the edge (count starts from zero)
+   */
+  inline TopoDS_Vertex FirstVertex(int i=0) const;
+  /*!
+   * \brief Return last vertex of the i-the edge (count starts from zero)
+   */
+  inline TopoDS_Vertex LastVertex(int i=-1) const;
+  /*!
+   * \brief Return first normalized parameter of the i-the edge (count starts from zero)
+   */
+  inline double FirstParameter(int i) const;
+  /*!
+   * \brief Return ast normalized parameter of the i-the edge (count starts from zero)
+   */
+  inline double LastParameter(int i) const;
+  /*!
+   * \brief Return side length
+   */
+  double Length() const { return myLength; }
+  /*!
+   * \brief Return edge index corresponding to normalized parameter
+   */
+  inline int EdgeIndex( double U ) const;
+
+  //virtual gp_Pnt Value(double U) const;
+  
+  void dump(const char* msg=0) const;
+  
+
+protected:
+  vector<uvPtStruct>           myPoints, myFalsePoints;
+  vector<TopoDS_Edge>          myEdge;
+  vector<Handle(Geom2d_Curve)> myC2d;
+  vector<double>               myFirst, myLast;
+  vector<double>               myNormPar;
+  double                       myLength;
+  int                          myNbPonits, myNbSegments;
+  SMESH_Mesh*                  myMesh;
+  bool                         myMissingVertexNodes, myIgnoreMediumNodes;
+};
+
+
+//================================================================================
+/*!
+ * \brief Return edge index corresponding to normalized parameter
+  * \param U - the parameter
+  * \retval int - index
+ */
+//================================================================================
+
+inline int StdMeshers_FaceSide::EdgeIndex( double U ) const
+{
+  int i = myNormPar.size() - 1;
+  while ( i > 0 && U < myNormPar[ i-1 ] ) --i;
+  return i;
+}
+
+//================================================================================
+/*!
+ * \brief Return edge and parameter on edge by normalized parameter
+  * \param U - the parameter
+  * \retval double - pameter on a curve
+ */
+//================================================================================
+
+inline double StdMeshers_FaceSide::Parameter(double U, TopoDS_Edge & edge) const
+{
+  int i = EdgeIndex( U );
+  edge = myEdge[ i ];
+  double prevU = i ? myNormPar[ i-1 ] : 0;
+  double r = ( U - prevU )/ ( myNormPar[ i ] - prevU );
+  return myFirst[i] * ( 1 - r ) + myLast[i] * r;
+}
+
+//================================================================================
+/*!
+ * \brief Return 1st vertex of the i-the edge
+ */
+//================================================================================
+
+inline TopoDS_Vertex StdMeshers_FaceSide::FirstVertex(int i) const
+{
+  return i < myEdge.size() ? TopExp::FirstVertex( myEdge[i], 1 ) : TopoDS_Vertex();
+}
+
+//================================================================================
+/*!
+ * \brief Return last vertex of the i-the edge
+ */
+//================================================================================
+
+inline TopoDS_Vertex StdMeshers_FaceSide::LastVertex(int i) const
+{
+  return i<0 ? TopExp::LastVertex( myEdge.back(), 1) : i<myEdge.size() ? TopExp::LastVertex( myEdge[i], 1 ) : TopoDS_Vertex();
+}
+
+//================================================================================
+/*!
+ * \brief Return first normalized parameter of the i-the edge
+ */
+//================================================================================
+
+inline double StdMeshers_FaceSide::FirstParameter(int i) const
+{
+  return i==0 ? 0. : i<myNormPar.size() ? myNormPar[i-1] : 1.;
+}
+
+//================================================================================
+/*!
+ * \brief Return ast normalized parameter of the i-the edge
+ */
+//================================================================================
+
+inline double StdMeshers_FaceSide::LastParameter(int i) const
+{
+  return i<myNormPar.size() ? myNormPar[i] : 1;
+}
+
+#endif
index ccb6c4a5a38e37c1222921d7afb3cc68e0da00ad..80cd6caeb1973e8e309f56e9a914a13586655980 100644 (file)
 
 #include "StdMeshers_Hexa_3D.hxx"
 #include "StdMeshers_Quadrangle_2D.hxx"
+#include "StdMeshers_FaceSide.hxx"
+#include "StdMeshers_Penta_3D.hxx"
+#include "StdMeshers_Prism_3D.hxx"
+
 #include "SMESH_Gen.hxx"
 #include "SMESH_Mesh.hxx"
 #include "SMESH_subMesh.hxx"
+#include "SMESH_Comment.hxx"
 
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
 #include <TopTools_ListOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <TColStd_ListIteratorOfListOfInteger.hxx>
 #include <TColStd_MapOfInteger.hxx>
 
 #include <BRep_Tool.hxx>
 #include <Geom_Surface.hxx>
-#include <Geom_Curve.hxx>
-#include <Geom2d_Curve.hxx>
-#include <Handle_Geom2d_Curve.hxx>
-#include <Handle_Geom_Curve.hxx>
 #include <gp_Pnt2d.hxx>
 
 #include "utilities.h"
 #include "Utils_ExceptHandlers.hxx"
 
-//modified by NIZNHY-PKV Wed Nov 17 15:31:58 2004 f
-#include "StdMeshers_Penta_3D.hxx"
+typedef SMESH_Comment TComm;
 
 using namespace std;
 
-static bool ComputePentahedralMesh(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape);
-//modified by NIZNHY-PKV Wed Nov 17 15:32:00 2004 t
+static SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh &, const TopoDS_Shape &);
 
 //=============================================================================
 /*!
@@ -71,8 +69,8 @@ static bool ComputePentahedralMesh(SMESH_Mesh & aMesh,        const TopoDS_Shape & aSha
  */
 //=============================================================================
 
-StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, int studyId,
-                                       SMESH_Gen * gen):SMESH_3D_Algo(hypId, studyId, gen)
+StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, int studyId, SMESH_Gen * gen)
+  :SMESH_3D_Algo(hypId, studyId, gen)
 {
   MESSAGE("StdMeshers_Hexa_3D::StdMeshers_Hexa_3D");
   _name = "Hexa_3D";
@@ -101,7 +99,7 @@ StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D()
 bool StdMeshers_Hexa_3D::ClearAndReturn(FaceQuadStruct* theQuads[6], const bool res)
 {
   for (int i = 0; i < 6; i++) {
-    StdMeshers_Quadrangle_2D::QuadDelete(theQuads[i]);
+    delete theQuads[i];
     theQuads[i] = NULL;
   }
   return res;
@@ -115,18 +113,19 @@ bool StdMeshers_Hexa_3D::ClearAndReturn(FaceQuadStruct* theQuads[6], const bool
 //=============================================================================
 
 bool StdMeshers_Hexa_3D::CheckHypothesis
-                         (SMESH_Mesh& aMesh,
-                          const TopoDS_Shape& aShape,
+                         (SMESH_Mesh&                          aMesh,
+                          const TopoDS_Shape&                  aShape,
                           SMESH_Hypothesis::Hypothesis_Status& aStatus)
 {
-       //MESSAGE("StdMeshers_Hexa_3D::CheckHypothesis");
-
-       bool isOk = true;
-        aStatus = SMESH_Hypothesis::HYP_OK;
-
-       // nothing to check
-
-       return isOk;
+  // check nb of faces in the shape
+  aStatus = SMESH_Hypothesis::HYP_BAD_GEOMETRY;
+  int nbFaces = 0;
+  for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next())
+    if ( ++nbFaces > 6 )
+      return false;
+
+  aStatus = SMESH_Hypothesis::HYP_OK;
+  return true;
 }
 
 //=======================================================================
@@ -143,8 +142,8 @@ static bool findIJ (const SMDS_MeshNode* node, const FaceQuadStruct * quad, int&
   gp_Pnt2d uv( fpos->GetUParameter(), fpos->GetVParameter() );
 
   double minDist = DBL_MAX;
-  int nbhoriz  = Min(quad->nbPts[0], quad->nbPts[2]);
-  int nbvertic = Min(quad->nbPts[1], quad->nbPts[3]);
+  int nbhoriz  = Min(quad->side[0]->NbPoints(), quad->side[2]->NbPoints());
+  int nbvertic = Min(quad->side[1]->NbPoints(), quad->side[3]->NbPoints());
   for (int i = 1; i < nbhoriz - 1; i++) {
     for (int j = 1; j < nbvertic - 1; j++) {
       int ij = j * nbhoriz + i;
@@ -174,8 +173,8 @@ static bool findIJ (const SMDS_MeshNode* node, const FaceQuadStruct * quad, int&
  */
 //=============================================================================
 
-bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
-       const TopoDS_Shape & aShape)throw(SALOME_Exception)
+bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh &         aMesh,
+                                 const TopoDS_Shape & aShape) throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
   MESSAGE("StdMeshers_Hexa_3D::Compute");
@@ -183,7 +182,6 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
   
   // 0.  - shape and face mesh verification
   // 0.1 - shape must be a solid (or a shell) with 6 faces
-  //MESSAGE("---");
 
   vector < SMESH_subMesh * >meshFaces;
   for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
@@ -191,13 +189,10 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
     ASSERT(aSubMesh);
     meshFaces.push_back(aSubMesh);
   }
-  if (meshFaces.size() != 6) {
-    SCRUTE(meshFaces.size());
-    return false;
-  }
+  if (meshFaces.size() != 6)
+    return error(COMPERR_BAD_SHAPE, TComm(meshFaces.size())<<" instead of 6 faces in block");
 
   // 0.2 - is each face meshed with Quadrangle_2D? (so, with a wire of 4 edges)
-  //MESSAGE("---");
 
   // tool for working with quadratic elements
   SMESH_MesherHelper aTool (aMesh);
@@ -230,7 +225,8 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
   for (int i = 0; i < 6; i++)
     aQuads[i] = 0;
 
-  for (int i = 0; i < 6; i++) {
+  for (int i = 0; i < 6; i++)
+  {
     TopoDS_Shape aFace = meshFaces[i]->GetSubShape();
     SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace);
     string algoName = algo->GetName();
@@ -247,9 +243,8 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
       }
     }
     if ( ! isAllQuad ) {
-      //modified by NIZNHY-PKV Wed Nov 17 15:31:37 2004 f
-      bool bIsOk = ComputePentahedralMesh(aMesh, aShape);
-      return ClearAndReturn( aQuads, bIsOk );
+      SMESH_ComputeErrorPtr err = ComputePentahedralMesh(aMesh, aShape);
+      return ClearAndReturn( aQuads, error(err));
     }
     StdMeshers_Quadrangle_2D *quadAlgo =
       dynamic_cast < StdMeshers_Quadrangle_2D * >(algo);
@@ -258,123 +253,52 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
       aQuads[i] = quadAlgo->CheckAnd2Dcompute(aMesh, aFace, _quadraticMesh);
     }
     catch(SALOME_Exception & S_ex) {
-      return ClearAndReturn( aQuads, false );
+      return ClearAndReturn( aQuads, error(COMPERR_SLM_EXCEPTION,TComm(S_ex.what()) <<
+                                           " Raised by StdMeshers_Quadrangle_2D "
+                                           " on face #" << meshDS->ShapeToIndex( aFace )));
     }
 
     // 0.2.1 - number of points on the opposite edges must be the same
-    if (aQuads[i]->nbPts[0] != aQuads[i]->nbPts[2] ||
-        aQuads[i]->nbPts[1] != aQuads[i]->nbPts[3]) {
+    if (aQuads[i]->side[0]->NbPoints() != aQuads[i]->side[2]->NbPoints() ||
+        aQuads[i]->side[1]->NbPoints() != aQuads[i]->side[3]->NbPoints()
+        /*aQuads[i]->side[0]->NbEdges() != 1 ||
+        aQuads[i]->side[1]->NbEdges() != 1 ||
+        aQuads[i]->side[2]->NbEdges() != 1 ||
+        aQuads[i]->side[3]->NbEdges() != 1*/) {
       MESSAGE("different number of points on the opposite edges of face " << i);
-      //                  ASSERT(0);
-      // \begin{E.A.}
       // Try to go into penta algorithm 'cause it has been improved.
-      // return ClearAndReturn( aQuads, false );
-      bool bIsOk = ComputePentahedralMesh(aMesh, aShape);
-      return ClearAndReturn( aQuads, bIsOk );
-      // \end{E.A.}
+      SMESH_ComputeErrorPtr err = ComputePentahedralMesh(aMesh, aShape);
+      return ClearAndReturn( aQuads, error(err));
     }
   }
 
   // 1.  - identify faces and vertices of the "cube"
   // 1.1 - ancestor maps vertex->edges in the cube
-  //MESSAGE("---");
 
   TopTools_IndexedDataMapOfShapeListOfShape MS;
   TopExp::MapShapesAndAncestors(aShape, TopAbs_VERTEX, TopAbs_EDGE, MS);
 
   // 1.2 - first face is choosen as face Y=0 of the unit cube
-  //MESSAGE("---");
 
   const TopoDS_Shape & aFace = meshFaces[0]->GetSubShape();
   const TopoDS_Face & F = TopoDS::Face(aFace);
 
   // 1.3 - identify the 4 vertices of the face Y=0: V000, V100, V101, V001
-  //MESSAGE("---");
-
-  int i = 0;
-  TopoDS_Edge E = aQuads[0]->edge[i];  //edge will be Y=0,Z=0 on unit cube
-  double f, l;
-  Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
-  TopoDS_Vertex VFirst, VLast;
-  TopExp::Vertices(E, VFirst, VLast);  // corresponds to f and l
-  bool isForward = (((l - f) * (aQuads[0]->last[i] - aQuads[0]->first[i])) > 0);
-
-  if (isForward) {
-    aCube.V000 = VFirst;       // will be (0,0,0) on the unit cube
-    aCube.V100 = VLast;                // will be (1,0,0) on the unit cube
-  }
-  else {
-    aCube.V000 = VLast;
-    aCube.V100 = VFirst;
-  }
 
-  i = 1;
-  E = aQuads[0]->edge[i];
-  C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
-  TopExp::Vertices(E, VFirst, VLast);
-  isForward = (((l - f) * (aQuads[0]->last[i] - aQuads[0]->first[i])) > 0);
-  if (isForward)
-    aCube.V101 = VLast;                // will be (1,0,1) on the unit cube
-  else
-    aCube.V101 = VFirst;
-
-  i = 2;
-  E = aQuads[0]->edge[i];
-  C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
-  TopExp::Vertices(E, VFirst, VLast);
-  isForward = (((l - f) * (aQuads[0]->last[i] - aQuads[0]->first[i])) > 0);
-  if (isForward)
-    aCube.V001 = VLast;                // will be (0,0,1) on the unit cube
-  else
-    aCube.V001 = VFirst;
-
-  // 1.4 - find edge X=0, Z=0 (ancestor of V000 not in face Y=0)
-  //     - find edge X=1, Z=0 (ancestor of V100 not in face Y=0)
-  //     - find edge X=1, Z=1 (ancestor of V101 not in face Y=0) 
-  //     - find edge X=0, Z=1 (ancestor of V001 not in face Y=0)
-  //MESSAGE("---");
-
-  TopoDS_Edge E_0Y0 = EdgeNotInFace(aMesh, aShape, F, aCube.V000, MS);
-  ASSERT(!E_0Y0.IsNull());
-
-  TopoDS_Edge E_1Y0 = EdgeNotInFace(aMesh, aShape, F, aCube.V100, MS);
-  ASSERT(!E_1Y0.IsNull());
-
-  TopoDS_Edge E_1Y1 = EdgeNotInFace(aMesh, aShape, F, aCube.V101, MS);
-  ASSERT(!E_1Y1.IsNull());
-
-  TopoDS_Edge E_0Y1 = EdgeNotInFace(aMesh, aShape, F, aCube.V001, MS);
-  ASSERT(!E_0Y1.IsNull());
-
-  // 1.5 - identify the 4 vertices in face Y=1: V010, V110, V111, V011
-  //MESSAGE("---");
-
-  TopExp::Vertices(E_0Y0, VFirst, VLast);
-  if (VFirst.IsSame(aCube.V000))
-    aCube.V010 = VLast;
-  else
-    aCube.V010 = VFirst;
-
-  TopExp::Vertices(E_1Y0, VFirst, VLast);
-  if (VFirst.IsSame(aCube.V100))
-    aCube.V110 = VLast;
-  else
-    aCube.V110 = VFirst;
-
-  TopExp::Vertices(E_1Y1, VFirst, VLast);
-  if (VFirst.IsSame(aCube.V101))
-    aCube.V111 = VLast;
-  else
-    aCube.V111 = VFirst;
-
-  TopExp::Vertices(E_0Y1, VFirst, VLast);
-  if (VFirst.IsSame(aCube.V001))
-    aCube.V011 = VLast;
-  else
-    aCube.V011 = VFirst;
+  aCube.V000 = aQuads[0]->side[0]->FirstVertex(); // will be (0,0,0) on the unit cube
+  aCube.V100 = aQuads[0]->side[0]->LastVertex();  // will be (1,0,0) on the unit cube
+  aCube.V001 = aQuads[0]->side[2]->FirstVertex(); // will be (0,0,1) on the unit cube
+  aCube.V101 = aQuads[0]->side[2]->LastVertex();  // will be (1,0,1) on the unit cube
+
+  TopTools_IndexedMapOfShape MV0;
+  TopExp::MapShapes(F, TopAbs_VERTEX, MV0);
+
+  aCube.V010 = OppositeVertex( aCube.V000, MV0, aQuads);
+  aCube.V110 = OppositeVertex( aCube.V100, MV0, aQuads);
+  aCube.V011 = OppositeVertex( aCube.V001, MV0, aQuads);
+  aCube.V111 = OppositeVertex( aCube.V101, MV0, aQuads);
 
   // 1.6 - find remaining faces given 4 vertices
-  //MESSAGE("---");
 
   int _indY0 = 0;
   aCube.quad_Y0 = aQuads[_indY0];
@@ -399,8 +323,6 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
                             aCube.V100, aCube.V101, aCube.V110, aCube.V111);
   aCube.quad_X1 = aQuads[_indX1];
 
-  //MESSAGE("---");
-
   // 1.7 - get convertion coefs from face 2D normalized to 3D normalized
 
   Conv2DStruct cx0;                    // for face X=0
@@ -425,15 +347,14 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
 
   // 1.8 - create a 3D structure for normalized values
   
-  //MESSAGE("---");
-  int nbx = aCube.quad_Z0->nbPts[0];
-  if (cz0.a1 == 0.) nbx = aCube.quad_Z0->nbPts[1];
+  int nbx = aCube.quad_Z0->side[0]->NbPoints();
+  if (cz0.a1 == 0.) nbx = aCube.quad_Z0->side[1]->NbPoints();
  
-  int nby = aCube.quad_X0->nbPts[0];
-  if (cx0.a1 == 0.) nby = aCube.quad_X0->nbPts[1];
+  int nby = aCube.quad_X0->side[0]->NbPoints();
+  if (cx0.a1 == 0.) nby = aCube.quad_X0->side[1]->NbPoints();
  
-  int nbz = aCube.quad_Y0->nbPts[0];
-  if (cy0.a1 != 0.) nbz = aCube.quad_Y0->nbPts[1];
+  int nbz = aCube.quad_Y0->side[0]->NbPoints();
+  if (cy0.a1 != 0.) nbz = aCube.quad_Y0->side[1]->NbPoints();
 
   int i1, j1, nbxyz = nbx * nby * nbz;
   Point3DStruct *np = new Point3DStruct[nbxyz];
@@ -445,8 +366,8 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
 
     faceQuadStruct *quad = aCube.quad_X0;
     int i = 0;                         // j = x/face , k = y/face
-    int nbdown = quad->nbPts[0];
-    int nbright = quad->nbPts[1];
+    int nbdown = quad->side[0]->NbPoints();
+    int nbright = quad->side[1]->NbPoints();
 
     SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
                        
@@ -454,7 +375,8 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
       const SMDS_MeshNode * node = itf->next();
       if(aTool.IsMedium(node))
         continue;
-      findIJ( node, quad, i1, j1 );
+      if ( !findIJ( node, quad, i1, j1 ))
+        return ClearAndReturn( aQuads, false );
       int ij1 = j1 * nbdown + i1;
       quad->uv_grid[ij1].node = node;
     }
@@ -478,14 +400,15 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
 
     faceQuadStruct *quad = aCube.quad_X1;
     int i = nbx - 1;           // j = x/face , k = y/face
-    int nbdown = quad->nbPts[0];
-    int nbright = quad->nbPts[1];
+    int nbdown = quad->side[0]->NbPoints();
+    int nbright = quad->side[1]->NbPoints();
 
     while(itf->more()) {
       const SMDS_MeshNode * node = itf->next();
       if(aTool.IsMedium(node))
         continue;
-      findIJ( node, quad, i1, j1 );
+      if ( !findIJ( node, quad, i1, j1 ))
+        return ClearAndReturn( aQuads, false );
       int ij1 = j1 * nbdown + i1;
       quad->uv_grid[ij1].node = node;
     }
@@ -509,14 +432,15 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
 
     faceQuadStruct *quad = aCube.quad_Y0;
     int j = 0;                         // i = x/face , k = y/face
-    int nbdown = quad->nbPts[0];
-    int nbright = quad->nbPts[1];
+    int nbdown = quad->side[0]->NbPoints();
+    int nbright = quad->side[1]->NbPoints();
 
     while(itf->more()) {
       const SMDS_MeshNode * node = itf->next();
       if(aTool.IsMedium(node))
         continue;
-      findIJ( node, quad, i1, j1 );
+      if ( !findIJ( node, quad, i1, j1 ))
+        return ClearAndReturn( aQuads, false );
       int ij1 = j1 * nbdown + i1;
       quad->uv_grid[ij1].node = node;
     }
@@ -540,14 +464,15 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
 
     faceQuadStruct *quad = aCube.quad_Y1;
     int j = nby - 1;           // i = x/face , k = y/face
-    int nbdown = quad->nbPts[0];
-    int nbright = quad->nbPts[1];
+    int nbdown = quad->side[0]->NbPoints();
+    int nbright = quad->side[1]->NbPoints();
 
     while(itf->more()) {
       const SMDS_MeshNode * node = itf->next();
       if(aTool.IsMedium(node))
         continue;
-      findIJ( node, quad, i1, j1 );
+      if ( !findIJ( node, quad, i1, j1 ))
+        return ClearAndReturn( aQuads, false );
       int ij1 = j1 * nbdown + i1;
       quad->uv_grid[ij1].node = node;
     }
@@ -571,14 +496,15 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
 
     faceQuadStruct *quad = aCube.quad_Z0;
     int k = 0;                         // i = x/face , j = y/face
-    int nbdown = quad->nbPts[0];
-    int nbright = quad->nbPts[1];
+    int nbdown = quad->side[0]->NbPoints();
+    int nbright = quad->side[1]->NbPoints();
 
     while(itf->more()) {
       const SMDS_MeshNode * node = itf->next();
       if(aTool.IsMedium(node))
         continue;
-      findIJ( node, quad, i1, j1 );
+      if ( !findIJ( node, quad, i1, j1 ))
+        return ClearAndReturn( aQuads, false );
       int ij1 = j1 * nbdown + i1;
       quad->uv_grid[ij1].node = node;
     }
@@ -602,14 +528,15 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
 
     faceQuadStruct *quad = aCube.quad_Z1;
     int k = nbz - 1;           // i = x/face , j = y/face
-    int nbdown = quad->nbPts[0];
-    int nbright = quad->nbPts[1];
+    int nbdown = quad->side[0]->NbPoints();
+    int nbright = quad->side[1]->NbPoints();
     
     while(itf->more()) {
       const SMDS_MeshNode * node = itf->next();
       if(aTool.IsMedium(node))
         continue;
-      findIJ( node, quad, i1, j1 );
+      if ( !findIJ( node, quad, i1, j1 ))
+        return ClearAndReturn( aQuads, false );
       int ij1 = j1 * nbdown + i1;
       quad->uv_grid[ij1].node = node;
     }
@@ -746,20 +673,12 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
 
         SMDS_MeshVolume * elt;
         if ( isForw ) {
-          //elt = meshDS->AddVolume(np[n1].node, np[n2].node,
-          //                        np[n3].node, np[n4].node,
-          //                        np[n5].node, np[n6].node,
-          //                        np[n7].node, np[n8].node);
           elt = aTool.AddVolume(np[n1].node, np[n2].node,
                                 np[n3].node, np[n4].node,
                                 np[n5].node, np[n6].node,
                                 np[n7].node, np[n8].node);
         }
         else {
-          //elt = meshDS->AddVolume(np[n1].node, np[n4].node,
-          //                        np[n3].node, np[n2].node,
-          //                        np[n5].node, np[n8].node,
-          //                        np[n7].node, np[n6].node);
           elt = aTool.AddVolume(np[n1].node, np[n4].node,
                                 np[n3].node, np[n2].node,
                                 np[n5].node, np[n8].node,
@@ -771,7 +690,6 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
     }
   }
   if ( np ) delete [] np;
-  //MESSAGE("End of StdMeshers_Hexa_3D::Compute()");
   return ClearAndReturn( aQuads, true );
 }
 
@@ -781,8 +699,8 @@ bool StdMeshers_Hexa_3D::Compute(SMESH_Mesh & aMesh,
  */
 //=============================================================================
 
-void StdMeshers_Hexa_3D::GetPoint(Pt3 p, int i, int j, int k, int nbx, int nby,
-       int nbz, Point3DStruct * np, const SMESHDS_Mesh * meshDS)
+void StdMeshers_Hexa_3D::GetPoint(Pt3 p, int i, int j, int k, int nbx, int nby, int nbz,
+                                  Point3DStruct * np, const SMESHDS_Mesh * meshDS)
 {
        int ijk = k * nbx * nby + j * nbx + i;
        const SMDS_MeshNode * node = np[ijk].node;
@@ -892,24 +810,27 @@ void StdMeshers_Hexa_3D::GetConv2DCoefs(const faceQuadStruct & quad,
        const TopoDS_Vertex & V2, const TopoDS_Vertex & V3, Conv2DStruct & conv)
 {
 //     MESSAGE("StdMeshers_Hexa_3D::GetConv2DCoefs");
-       const TopoDS_Face & F = TopoDS::Face(aShape);
-       TopoDS_Edge E = quad.edge[0];
-       double f, l;
-       Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
-       TopoDS_Vertex VFirst, VLast;
-       TopExp::Vertices(E, VFirst, VLast);     // corresponds to f and l
-       bool isForward = (((l - f) * (quad.last[0] - quad.first[0])) > 0);
-       TopoDS_Vertex VA, VB;
-       if (isForward)
-       {
-               VA = VFirst;
-               VB = VLast;
-       }
-       else
-       {
-               VA = VLast;
-               VB = VFirst;
-       }
+//     const TopoDS_Face & F = TopoDS::Face(aShape);
+//     TopoDS_Edge E = quad.edge[0];
+//     double f, l;
+//     Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+//     TopoDS_Vertex VFirst, VLast;
+//     TopExp::Vertices(E, VFirst, VLast);     // corresponds to f and l
+//     bool isForward = (((l - f) * (quad.last[0] - quad.first[0])) > 0);
+  TopoDS_Vertex VA, VB;
+//     if (isForward)
+//     {
+//             VA = VFirst;
+//             VB = VLast;
+//     }
+//     else
+//     {
+//             VA = VLast;
+//             VB = VFirst;
+//     }
+  VA = quad.side[0]->FirstVertex();
+  VB = quad.side[0]->LastVertex();
+  
        int a1, b1, c1, a2, b2, c2;
        if (VA.IsSame(V0))
                if (VB.IsSame(V1))
@@ -1000,8 +921,8 @@ void StdMeshers_Hexa_3D::GetConv2DCoefs(const faceQuadStruct & quad,
        conv.b2 = b2;
        conv.c2 = c2;
 
-       int nbdown = quad.nbPts[0];
-       int nbright = quad.nbPts[1];
+       int nbdown = quad.side[0]->NbPoints();
+       int nbright = quad.side[1]->NbPoints();
        conv.ia = int (a1);
        conv.ib = int (b1);
        conv.ic =
@@ -1014,48 +935,40 @@ void StdMeshers_Hexa_3D::GetConv2DCoefs(const faceQuadStruct & quad,
 //     MESSAGE("J " << conv.ja << " " << conv.jb << " " << conv.jc);
 }
 
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-ostream & StdMeshers_Hexa_3D::SaveTo(ostream & save)
-{
-  return save;
-}
-
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-istream & StdMeshers_Hexa_3D::LoadFrom(istream & load)
-{
-  return load;
-}
-
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-ostream & operator <<(ostream & save, StdMeshers_Hexa_3D & hyp)
-{
-  return hyp.SaveTo( save );
-}
-
-//=============================================================================
+//================================================================================
 /*!
- *  
+ * \brief Find a vertex opposite to the given vertex of aQuads[0]
+  * \param aVertex - the vertex
+  * \param aFace - the face aVertex belongs to
+  * \param aQuads - quads
+  * \retval TopoDS_Vertex - found vertex
  */
-//=============================================================================
+//================================================================================
 
-istream & operator >>(istream & load, StdMeshers_Hexa_3D & hyp)
+TopoDS_Vertex StdMeshers_Hexa_3D::OppositeVertex(const TopoDS_Vertex& aVertex,
+                                                 const TopTools_IndexedMapOfShape& aQuads0Vertices,
+                                                 FaceQuadStruct* aQuads[6])
 {
-  return hyp.LoadFrom( load );
+  int i, j;
+  for ( i = 1; i < 6; ++i )
+  {
+    TopoDS_Vertex VV[] = { aQuads[i]->side[0]->FirstVertex(),
+                           aQuads[i]->side[0]->LastVertex() , 
+                           aQuads[i]->side[2]->LastVertex() ,
+                           aQuads[i]->side[2]->FirstVertex() };
+    for ( j = 0; j < 4; ++j )
+      if ( aVertex.IsSame( VV[ j ]))
+        break;
+    if ( j < 4 ) {
+      int jPrev = j ? j - 1 : 3;
+      int jNext = (j + 1) % 4;
+      if ( aQuads0Vertices.Contains( VV[ jPrev ] ))
+        return VV[ jNext ];
+      else
+        return VV[ jPrev ];
+    }
+  }
+  return TopoDS_Vertex();
 }
 
 //modified by NIZNHY-PKV Wed Nov 17 15:34:13 2004 f
@@ -1067,26 +980,35 @@ istream & operator >>(istream & load, StdMeshers_Hexa_3D & hyp)
 //function : ComputePentahedralMesh
 //purpose  : 
 //=======================================================================
-bool ComputePentahedralMesh(SMESH_Mesh & aMesh,        const TopoDS_Shape & aShape)
+
+SMESH_ComputeErrorPtr ComputePentahedralMesh(SMESH_Mesh &         aMesh,
+                                             const TopoDS_Shape & aShape)
 {
   //printf(" ComputePentahedralMesh HERE\n");
   //
   bool bOK;
+  SMESH_ComputeErrorPtr err = SMESH_ComputeError::New();
   //int iErr;
   StdMeshers_Penta_3D anAlgo;
   //
   bOK=anAlgo.Compute(aMesh, aShape);
-  /*
-  iErr=anAlgo.ErrorStatus();
-  
-  if (iErr) {
-    printf("  *** Error# %d\n", iErr);
-  }
-  else {
-    printf("  *** No errors# %d\n", iErr);
+  //
+  err = anAlgo.GetComputeError();
+  //
+  if ( !bOK && anAlgo.ErrorStatus() == 5 )
+  {
+    static StdMeshers_Prism_3D * aPrism3D = 0;
+    if ( !aPrism3D ) {
+      SMESH_Gen* gen = aMesh.GetGen();
+      aPrism3D = new StdMeshers_Prism_3D( gen->GetANewId(), 0, gen );
+    }
+    SMESH_Hypothesis::Hypothesis_Status aStatus;
+    if ( aPrism3D->CheckHypothesis( aMesh, aShape, aStatus ) ) {
+      bOK = aPrism3D->Compute( aMesh, aShape );
+      err = aPrism3D->GetComputeError();
+    }
   }
-  */
-  return bOK;
+  return err;
 }
 
 
index 4fa9311c73472f1dd2294a5d652745fc3e453fc4..09aa813033bcd68b1492a6acb087df477081d882 100644 (file)
@@ -38,6 +38,8 @@
 
 #include "SMESH_MesherHelper.hxx"
 
+class TopTools_IndexedMapOfShape;
+
 typedef struct point3Dstruct
 {
   const SMDS_MeshNode * node;
@@ -76,10 +78,9 @@ public:
                       const TopoDS_Shape& aShape)
     throw (SALOME_Exception);
 
-  ostream & SaveTo(ostream & save);
-  istream & LoadFrom(istream & load);
-  friend ostream & operator << (ostream & save, StdMeshers_Hexa_3D & hyp);
-  friend istream & operator >> (istream & load, StdMeshers_Hexa_3D & hyp);
+  static TopoDS_Vertex OppositeVertex(const TopoDS_Vertex& aVertex,
+                                      const TopTools_IndexedMapOfShape& aQuads0Vertices,
+                                      FaceQuadStruct* aQuads[6]);
 
 protected:
   TopoDS_Edge
index 49ac4365d5089d7ba3a16bbd1b076dd664d9b233..cb4e61fc161b2a9531355add902b62fcc010982a 100644 (file)
 //  $Header$
 
 #include "StdMeshers_MEFISTO_2D.hxx"
+
 #include "SMESH_Gen.hxx"
 #include "SMESH_Mesh.hxx"
 #include "SMESH_subMesh.hxx"
+#include "SMESH_Block.hxx"
+#include "SMESH_MesherHelper.hxx"
+#include "SMESH_Comment.hxx"
 
+#include "StdMeshers_FaceSide.hxx"
 #include "StdMeshers_MaxElementArea.hxx"
 #include "StdMeshers_LengthFromEdges.hxx"
 
 
 #include <TopoDS_Face.hxx>
 #include <TopoDS_Edge.hxx>
-#include <TopoDS_Shape.hxx>
 #include <Geom_Surface.hxx>
-#include <GeomAdaptor_Curve.hxx>
 #include <Geom2d_Curve.hxx>
 #include <gp_Pnt2d.hxx>
 #include <BRep_Tool.hxx>
 #include <BRepTools.hxx>
-#include <BRepTools_WireExplorer.hxx>
-#include <GCPnts_AbscissaPoint.hxx>
-#include <GCPnts_UniformAbscissa.hxx>
-#include <TColStd_ListIteratorOfListOfInteger.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <TopTools_ListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
+
+using namespace std;
 
 //=============================================================================
 /*!
@@ -67,8 +69,8 @@
  */
 //=============================================================================
 
-StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, int studyId,
-                                             SMESH_Gen * gen):SMESH_2D_Algo(hypId, studyId, gen)
+StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, int studyId, SMESH_Gen * gen):
+  SMESH_2D_Algo(hypId, studyId, gen)
 {
   MESSAGE("StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D");
   _name = "MEFISTO_2D";
@@ -101,75 +103,69 @@ StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D()
 //=============================================================================
 
 bool StdMeshers_MEFISTO_2D::CheckHypothesis
-                         (SMESH_Mesh& aMesh,
-                          const TopoDS_Shape& aShape,
+                         (SMESH_Mesh&                          aMesh,
+                          const TopoDS_Shape&                  aShape,
                           SMESH_Hypothesis::Hypothesis_Status& aStatus)
 {
-       //MESSAGE("StdMeshers_MEFISTO_2D::CheckHypothesis");
+  _hypMaxElementArea = NULL;
+  _hypLengthFromEdges = NULL;
 
-       _hypMaxElementArea = NULL;
-       _hypLengthFromEdges = NULL;
+  list <const SMESHDS_Hypothesis * >::const_iterator itl;
+  const SMESHDS_Hypothesis *theHyp;
 
-       list <const SMESHDS_Hypothesis * >::const_iterator itl;
-       const SMESHDS_Hypothesis *theHyp;
+  const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
+  int nbHyp = hyps.size();
+  if (!nbHyp)
+  {
+    aStatus = SMESH_Hypothesis::HYP_MISSING;
+    return false;  // can't work with no hypothesis
+  }
 
-       const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
-       int nbHyp = hyps.size();
-        if (!nbHyp)
-        {
-          aStatus = SMESH_Hypothesis::HYP_MISSING;
-          return false;  // can't work with no hypothesis
-        }
+  itl = hyps.begin();
+  theHyp = (*itl); // use only the first hypothesis
 
-       itl = hyps.begin();
-       theHyp = (*itl); // use only the first hypothesis
-
-       string hypName = theHyp->GetName();
-       //int hypId = theHyp->GetID();
-       //SCRUTE(hypName);
-
-       bool isOk = false;
-
-       if (hypName == "MaxElementArea")
-       {
-               _hypMaxElementArea = static_cast<const StdMeshers_MaxElementArea *>(theHyp);
-               ASSERT(_hypMaxElementArea);
-               _maxElementArea = _hypMaxElementArea->GetMaxArea();
-               _edgeLength = 0;
-               isOk = true;
-                aStatus = SMESH_Hypothesis::HYP_OK;
-       }
-
-       else if (hypName == "LengthFromEdges")
-       {
-               _hypLengthFromEdges = static_cast<const StdMeshers_LengthFromEdges *>(theHyp);
-               ASSERT(_hypLengthFromEdges);
-               _edgeLength = 0;
-               _maxElementArea = 0;
-               isOk = true;
-                aStatus = SMESH_Hypothesis::HYP_OK;
-       }
-        else
-          aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
-
-       if (isOk)
-       {
-               isOk = false;
-               if (_maxElementArea > 0)
-               {
-//                     _edgeLength = 2 * sqrt(_maxElementArea);        // triangles : minorant
-                       _edgeLength = 2 * sqrt(_maxElementArea/sqrt(3.0));
-                       isOk = true;
-               }
-               else
-                       isOk = (_hypLengthFromEdges != NULL);   // **** check mode
-                if (!isOk)
-                  aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER;
-       }
-
-       //SCRUTE(_edgeLength);
-       //SCRUTE(_maxElementArea);
-       return isOk;
+  string hypName = theHyp->GetName();
+
+  bool isOk = false;
+
+  if (hypName == "MaxElementArea")
+  {
+    _hypMaxElementArea = static_cast<const StdMeshers_MaxElementArea *>(theHyp);
+    ASSERT(_hypMaxElementArea);
+    _maxElementArea = _hypMaxElementArea->GetMaxArea();
+    _edgeLength = 0;
+    isOk = true;
+    aStatus = SMESH_Hypothesis::HYP_OK;
+  }
+
+  else if (hypName == "LengthFromEdges")
+  {
+    _hypLengthFromEdges = static_cast<const StdMeshers_LengthFromEdges *>(theHyp);
+    ASSERT(_hypLengthFromEdges);
+    _edgeLength = 0;
+    _maxElementArea = 0;
+    isOk = true;
+    aStatus = SMESH_Hypothesis::HYP_OK;
+  }
+  else
+    aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
+
+  if (isOk)
+  {
+    isOk = false;
+    if (_maxElementArea > 0)
+    {
+      //_edgeLength = 2 * sqrt(_maxElementArea);        // triangles : minorant
+      _edgeLength = sqrt(2. * _maxElementArea/sqrt(3.0));
+      isOk = true;
+    }
+    else
+      isOk = (_hypLengthFromEdges != NULL);     // **** check mode
+    if (!isOk)
+      aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER;
+  }
+
+  return isOk;
 }
 
 //=============================================================================
@@ -182,21 +178,59 @@ bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
 {
   MESSAGE("StdMeshers_MEFISTO_2D::Compute");
 
-  if (_hypLengthFromEdges)
-    _edgeLength = ComputeEdgeElementLength(aMesh, aShape);
-  
-  bool isOk = false;
-  //const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
-  //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
+  TopoDS_Face F = TopoDS::Face(aShape.Oriented(TopAbs_FORWARD));
+
+  // helper builds quadratic mesh if necessary
+  SMESH_MesherHelper helper(aMesh);
+  myTool = &helper;
+  _quadraticMesh = myTool->IsQuadraticSubMesh(aShape);
+  const bool ignoreMediumNodes = _quadraticMesh;
+
+  // get all edges of a face
+  TopoDS_Vertex V1;
+  list< TopoDS_Edge > edges;
+  list< int > nbEdgesInWires;
+  int nbWires = SMESH_Block::GetOrderedEdges (F, V1, edges, nbEdgesInWires);
+
+  if (_hypLengthFromEdges) _edgeLength = 0;
+
+  // split list of all edges into separate wires
+  TWireVector wires ( nbWires );
+  list< int >::iterator nbE = nbEdgesInWires.begin();
+  list< TopoDS_Edge >::iterator from, to;
+  from = to = edges.begin();
+  for ( int iW = 0; iW < nbWires; ++iW )
+  {
+    std::advance( to, *nbE++ );
+    list< TopoDS_Edge > wireEdges( from, to );
+    // assure that there is a node on the first vertex
+    // as StdMeshers_FaceSide::GetUVPtStruct() requires
+    while ( !VertexNode( TopExp::FirstVertex( wireEdges.front(), true),
+                         aMesh.GetMeshDS()))
+    {
+      wireEdges.splice(wireEdges.end(), wireEdges,
+                       wireEdges.begin(), ++wireEdges.begin());
+      if ( from->IsSame( wireEdges.front() ))
+        return error(COMPERR_BAD_INPUT_MESH,"No nodes on vertices");
+    }
+    StdMeshers_FaceSide* wire = new StdMeshers_FaceSide( F, wireEdges, &aMesh,
+                                                         true, ignoreMediumNodes);
+    wires[ iW ] = StdMeshers_FaceSidePtr( wire );
+    if (_hypLengthFromEdges && wire->NbSegments() )
+      _edgeLength += wire->Length() / wire->NbSegments();
+    from = to;
+  }
+  if ( wires[0]->NbSegments() < 3 ) // ex: a circle with 2 segments
+    return error(COMPERR_BAD_INPUT_MESH,
+                 SMESH_Comment("Too few segments")<<wires[0]->NbSegments());
 
-  const TopoDS_Face & FF = TopoDS::Face(aShape);
-  bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
-  TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
+  if (_hypLengthFromEdges && _edgeLength < DBL_MIN )
+    _edgeLength = 100;
 
-  Z nblf;                                              //nombre de lignes fermees (enveloppe en tete)
-  Z *nudslf = NULL;                    //numero du dernier sommet de chaque ligne fermee
-  R2 *uvslf = NULL;
-  Z nbpti = 0;                         //nombre points internes futurs sommets de la triangulation
+  Z nblf;                 //nombre de lignes fermees (enveloppe en tete)
+  Z *nudslf = NULL;       //numero du dernier sommet de chaque ligne fermee
+  R2 *uvslf = NULL;       
+  Z nbpti = 0;            //nombre points internes futurs sommets de la triangulation
   R2 *uvpti = NULL;
   
   Z nbst;
@@ -205,97 +239,57 @@ bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
   Z *nust = NULL;
   Z ierr = 0;
 
-  Z nutysu = 1;                                // 1: il existe un fonction areteideale_()
-  // Z  nutysu=0;              // 0: on utilise aretmx
-  R aretmx = _edgeLength;              // longueur max aretes future triangulation
+  Z nutysu = 1;           // 1: il existe un fonction areteideale_()
+  // Z  nutysu=0;         // 0: on utilise aretmx
+  R aretmx = _edgeLength; // longueur max aretes future triangulation
   
-  nblf = NumberOfWires(F);
+  nblf = nbWires;
   
   nudslf = new Z[1 + nblf];
   nudslf[0] = 0;
   int iw = 1;
   int nbpnt = 0;
 
-  myTool = new SMESH_MesherHelper(aMesh);
-  _quadraticMesh = myTool->IsQuadraticSubMesh(aShape);
-
-  if ( _quadraticMesh && _hypLengthFromEdges )
-    aretmx *= 2.;
-
-  myOuterWire = BRepTools::OuterWire(F);
-  nbpnt += NumberOfPoints(aMesh, myOuterWire);
-  if ( nbpnt < 3 ) { // ex: a circle with 2 segments
-    delete myTool; myTool = 0;
-    return false;
-  }
-  nudslf[iw++] = nbpnt;
-
-  for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) {
-    const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
-    if (!myOuterWire.IsSame(W)) {
-      nbpnt += NumberOfPoints(aMesh, W);
-      nudslf[iw++] = nbpnt;
-    }
+  // count nb of input points
+  for ( int iW = 0; iW < nbWires; ++iW )
+  {
+    nbpnt += wires[iW]->NbPoints() - 1;
+    nudslf[iw++] = nbpnt;
   }
 
-  // avoid passing same uv points for a vertex common to 2 wires
-  TopTools_IndexedDataMapOfShapeListOfShape VWMap;
-  if ( iw - 1 > 1 ) // nbofWires > 1
-    TopExp::MapShapesAndAncestors( F , TopAbs_VERTEX, TopAbs_WIRE, VWMap );
-
   uvslf = new R2[nudslf[nblf]];
-  int m = 0;
 
   double scalex, scaley;
   ComputeScaleOnFace(aMesh, F, scalex, scaley);
 
-  map<int, const SMDS_MeshNode*> mefistoToDS;  // correspondence mefisto index--> points IDNodes
-  if ( !LoadPoints(aMesh, F, myOuterWire, uvslf, m,
-                   mefistoToDS, scalex, scaley, VWMap) ) {
-    delete myTool; myTool = 0;
-    return false;
-  }
+  // correspondence mefisto index --> Nodes
+  vector< const SMDS_MeshNode*> mefistoToDS(nbpnt, (const SMDS_MeshNode*)0);
 
-  for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
+  bool isOk = false;
+
+  // fill input points UV
+  if ( LoadPoints(wires, uvslf, mefistoToDS, scalex, scaley) )
   {
-    const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
-    if (!myOuterWire.IsSame(W))
+    // Compute
+    aptrte(nutysu, aretmx,
+           nblf, nudslf, uvslf, nbpti, uvpti, nbst, uvst, nbt, nust, ierr);
+
+    if (ierr == 0)
     {
-      if (! LoadPoints(aMesh, F, W, uvslf, m,
-                       mefistoToDS, scalex, scaley, VWMap )) {
-        delete myTool; myTool = 0;
-        return false;
-      }
+      MESSAGE("... End Triangulation Generated Triangle Number " << nbt);
+      MESSAGE("                                    Node Number " << nbst);
+      StoreResult(nbst, uvst, nbt, nust, mefistoToDS, scalex, scaley);
+      isOk = true;
+    }
+    else
+    {
+      error(ierr,"Error in Triangulation (aptrte())");
     }
   }
-
-  uvst = NULL;
-  nust = NULL;
-  aptrte(nutysu, aretmx,
-         nblf, nudslf, uvslf, nbpti, uvpti, nbst, uvst, nbt, nust, ierr);
-
-  if (ierr == 0)
-  {
-    MESSAGE("... End Triangulation Generated Triangle Number " << nbt);
-    MESSAGE("                                    Node Number " << nbst);
-    StoreResult(aMesh, nbst, uvst, nbt, nust, F,
-                faceIsForward, mefistoToDS, scalex, scaley);
-    isOk = true;
-  }
-  else
-  {
-    MESSAGE("Error in Triangulation");
-    isOk = false;
-  }
-  if (nudslf != NULL)
-    delete[]nudslf;
-  if (uvslf != NULL)
-    delete[]uvslf;
-  if (uvst != NULL)
-    delete[]uvst;
-  if (nust != NULL)
-    delete[]nust;
-  delete myTool; myTool = 0;
+  if (nudslf != NULL) delete[]nudslf;
+  if (uvslf != NULL)  delete[]uvslf;
+  if (uvst != NULL)   delete[]uvst;
+  if (nust != NULL)   delete[]nust;
 
   return isOk;
 }
@@ -356,25 +350,30 @@ static bool fixOverlappedLinkUV( R2& uv0, const R2& uv1, const R2& uv2 )
 //purpose  : 
 //=======================================================================
 
-static bool fixCommonVertexUV (gp_Pnt2d &           theUV,
+static bool fixCommonVertexUV (R2 &                 theUV,
                                const TopoDS_Vertex& theV,
-                               const TopoDS_Wire&   theW,
-                               const TopoDS_Wire&   theOW,
                                const TopoDS_Face&   theF,
                                const TopTools_IndexedDataMapOfShapeListOfShape & theVWMap,
                                SMESH_Mesh &         theMesh,
-                               bool CreateQuadratic)
+                               const double         theScaleX,
+                               const double         theScaleY,
+                               const bool           theCreateQuadratic)
 {
-  if( theW.IsSame( theOW ) ||
-      !theVWMap.Contains( theV )) return false;
+  if( !theVWMap.Contains( theV )) return false;
 
   // check if there is another wire sharing theV
   const TopTools_ListOfShape& WList = theVWMap.FindFromKey( theV );
   TopTools_ListIteratorOfListOfShape aWIt;
+  TopTools_MapOfShape aWires;
   for ( aWIt.Initialize( WList ); aWIt.More(); aWIt.Next() )
-    if ( !theW.IsSame( aWIt.Value() ))
-      break;
-  if ( !aWIt.More() ) return false;
+    aWires.Add( aWIt.Value() );
+  if ( aWires.Extent() < 2 ) return false;
+
+  TopoDS_Shape anOuterWire = BRepTools::OuterWire(theF);
+  TopoDS_Shape anInnerWire;
+  for ( aWIt.Initialize( WList ); aWIt.More() && anInnerWire.IsNull(); aWIt.Next() )
+    if ( !anOuterWire.IsSame( aWIt.Value() ))
+      anInnerWire = aWIt.Value();
 
   TopTools_ListOfShape EList;
   list< double >       UList;
@@ -382,7 +381,7 @@ static bool fixCommonVertexUV (gp_Pnt2d &           theUV,
   // find edges of theW sharing theV
   // and find 2d normal to them at theV
   gp_Vec2d N(0.,0.);
-  TopoDS_Iterator itE( theW );
+  TopoDS_Iterator itE( anInnerWire );
   for (  ; itE.More(); itE.Next() )
   {
     const TopoDS_Edge& E = TopoDS::Edge( itE.Value() );
@@ -400,7 +399,7 @@ static bool fixCommonVertexUV (gp_Pnt2d &           theUV,
       gp_Vec2d d1;
       gp_Pnt2d p;
       C2d->D1( u, p, d1 );
-      gp_Vec2d n( d1.Y(), -d1.X() );
+      gp_Vec2d n( d1.Y() * theScaleX, -d1.X() * theScaleY);
       if ( E.Orientation() == TopAbs_REVERSED )
         n.Reverse();
       N += n.Normalized();
@@ -410,6 +409,7 @@ static bool fixCommonVertexUV (gp_Pnt2d &           theUV,
   // define step size by which to move theUV
 
   gp_Pnt2d nextUV; // uv of next node on edge, most distant of the four
+  gp_Pnt2d thisUV( theUV.x, theUV.y );
   double maxDist = -DBL_MAX;
   TopTools_ListIteratorOfListOfShape aEIt (EList);
   list< double >::iterator aUIt = UList.begin();
@@ -430,7 +430,7 @@ static bool fixCommonVertexUV (gp_Pnt2d &           theUV,
       while ( nIt->more() ) {
         const SMDS_MeshNode* node = nIt->next();
         // check if node is medium
-        if ( CreateQuadratic && SMESH_MesherHelper::IsMedium( node, SMDSAbs_Edge ))
+        if ( theCreateQuadratic && SMESH_MesherHelper::IsMedium( node, SMDSAbs_Edge ))
           continue;
         const SMDS_EdgePosition* epos =
           static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
@@ -443,29 +443,33 @@ static bool fixCommonVertexUV (gp_Pnt2d &           theUV,
     }
     bool isFirstCommon = ( *aUIt == f );
     gp_Pnt2d uv = C2d->Value( isFirstCommon ? umin : umax );
-    double dist = theUV.SquareDistance( uv );
+    double dist = thisUV.SquareDistance( uv );
     if ( dist > maxDist ) {
       maxDist = dist;
       nextUV  = uv;
     }
   }
   R2 uv0, uv1, uv2;
-  uv0.x = theUV.X();    uv0.y = theUV.Y(); 
+  uv0.x = thisUV.X();   uv0.y = thisUV.Y();
   uv1.x = nextUV.X();   uv1.y = nextUV.Y(); 
-  uv2.x = uv0.x;        uv2.y = uv0.y;
+  uv2.x = thisUV.X();   uv2.y = thisUV.Y();
+
+  uv1.x *= theScaleX;   uv1.y *= theScaleY; 
+
   if ( fixOverlappedLinkUV( uv0, uv1, uv2 ))
   {
-    double step = theUV.Distance( gp_Pnt2d( uv0.x, uv0.y ));
+    double step = thisUV.Distance( gp_Pnt2d( uv0.x, uv0.y ));
 
     // move theUV along the normal by the step
 
     N *= step;
 
-    MESSAGE("--fixCommonVertexUV move(" << theUV.X() << " " << theUV.Y()
+    MESSAGE("--fixCommonVertexUV move(" << theUV.x << " " << theUV.x
             << ") by (" << N.X() << " " << N.Y() << ")" 
             << endl << "--- MAX DIST " << maxDist);
 
-    theUV.SetXY( theUV.XY() + N.XY() );
+    theUV.x += N.X();
+    theUV.y += N.Y();
 
     return true;
   }
@@ -478,111 +482,79 @@ static bool fixCommonVertexUV (gp_Pnt2d &           theUV,
  */
 //=============================================================================
 
-bool StdMeshers_MEFISTO_2D::LoadPoints(SMESH_Mesh &        aMesh,
-                                       const TopoDS_Face & FF,
-                                       const TopoDS_Wire & WW,
-                                       R2 *                uvslf,
-                                       int &               m,
-                                       map<int, const SMDS_MeshNode*>&mefistoToDS,
-                                       double              scalex,
-                                       double              scaley,
-                                       const TopTools_IndexedDataMapOfShapeListOfShape& VWMap)
+bool StdMeshers_MEFISTO_2D::LoadPoints(TWireVector &                 wires,
+                                       R2 *                          uvslf,
+                                       vector<const SMDS_MeshNode*>& mefistoToDS,
+                                       double                        scalex,
+                                       double                        scaley)
 {
-  //  MESSAGE("StdMeshers_MEFISTO_2D::LoadPoints");
+  // to avoid passing same uv points for a vertex common to 2 wires
+  TopoDS_Face F;
+  TopTools_IndexedDataMapOfShapeListOfShape VWMap;
+  if ( wires.size() > 1 )
+  {
+    F = TopoDS::Face( myTool->GetSubShape() );
+    TopExp::MapShapesAndAncestors( F, TopAbs_VERTEX, TopAbs_WIRE, VWMap );
+    int nbVertices = 0;
+    for ( int iW = 0; iW < wires.size(); ++iW )
+      nbVertices += wires[ iW ]->NbEdges();
+    if ( nbVertices == VWMap.Extent() )
+      VWMap.Clear(); // wires have no common vertices
+  }
 
-  TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
+  const bool isXConst = false; // meaningles here
+  const double constValue = 0; // meaningles here
 
+  int m = 0;
   list< int > mOnVertex;
 
-  gp_XY scale( scalex, scaley );
-
-  TopoDS_Wire W = TopoDS::Wire(WW.Oriented(TopAbs_FORWARD));
-  BRepTools_WireExplorer wexp(W, F);
-  for ( wexp.Init(W, F); wexp.More(); wexp.Next() )
+  for ( int iW = 0; iW < wires.size(); ++iW )
   {
-    const TopoDS_Edge & E = wexp.Current();
-    bool isForward = (E.Orientation() == TopAbs_FORWARD);
-
-    // --- IDNodes of first and last Vertex
-
-    TopoDS_Vertex VFirst, VLast, V;
-    TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
-    V = isForward ? VFirst : VLast;
-
-    ASSERT(!V.IsNull());
-    SMDS_NodeIteratorPtr lid= aMesh.GetSubMesh(V)->GetSubMeshDS()->GetNodes();
-    if ( !lid->more() ) {
-      MESSAGE (" NO NODE BUILT ON VERTEX ");
-      return false;
+    const vector<UVPtStruct>& uvPtVec = wires[ iW ]->GetUVPtStruct(isXConst,constValue);
+    if ( uvPtVec.size() != wires[ iW ]->NbPoints() ) {
+      return error(COMPERR_BAD_INPUT_MESH,SMESH_Comment("Unexpected nb of points on wire ")
+                   << iW << uvPtVec.size()<<" != "<<wires[ iW ]->NbPoints());
+    }
+    if ( m + uvPtVec.size()-1 > mefistoToDS.size() ) {
+      MESSAGE("Wrong mefistoToDS.size: "<<mefistoToDS.size()<<" < "<<m + uvPtVec.size()-1);
+      return error(dfltErr(),"Internal error");
     }
-    const SMDS_MeshNode* idFirst = lid->next();
-
-    // --- edge internal IDNodes (relies on good order storage, not checked)
-
-    map<double, const SMDS_MeshNode*> params;
-    const SMDS_MeshNode * node;
 
-    SMDS_NodeIteratorPtr nodeIt= aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
-    while ( nodeIt->more() )
+    vector<UVPtStruct>::const_iterator uvPt = uvPtVec.begin();
+    for ( ++uvPt; uvPt != uvPtVec.end(); ++uvPt )
     {
-      node = nodeIt->next();
-      if ( _quadraticMesh && SMESH_MesherHelper::IsMedium( node, SMDSAbs_Edge ))
-        continue;
-      const SMDS_EdgePosition* epos =
-        static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
-      double param = epos->GetUParameter();
-      if ( !isForward ) param = -param;
-      if ( !params.insert( make_pair( param, node )).second )
-      {
-        MESSAGE( "BAD NODE ON EDGE POSITIONS" );
-        return false;
-      }
+      // bind mefisto ID to node
+      mefistoToDS[m] = uvPt->node;
+      // set UV
+      uvslf[m].x = uvPt->u * scalex;
+      uvslf[m].y = uvPt->v * scaley;
+      if ( uvPt->node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX )
+        mOnVertex.push_back( m );
+      m++;
     }
 
-    // --- load 2D values into MEFISTO structure,
-    //     add IDNodes in mefistoToDS map
-
-    double f, l, uFirst, u;
-    Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
-    uFirst = isForward ? f : l;
-
-    // vertex node
-    gp_Pnt2d p = C2d->Value( uFirst ).XY().Multiplied( scale );
-    if ( fixCommonVertexUV( p, V, W, myOuterWire, F, VWMap, aMesh, _quadraticMesh ))
-      myNodesOnCommonV.push_back( idFirst );
-    mOnVertex.push_back( m );
-    uvslf[m].x = p.X();
-    uvslf[m].y = p.Y();
-    mefistoToDS[m + 1] = idFirst;
-    //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
-    //MESSAGE("__ f "<<uFirst<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
-    m++;
-
-    // internal nodes
-    map<double, const SMDS_MeshNode*>::iterator u_n = params.begin();
-    for ( int i = 0; u_n != params.end(); ++u_n, ++i )
+    int mFirst = mOnVertex.front(), mLast = m - 1;
+    list< int >::iterator mIt = mOnVertex.begin();
+    for ( ; mIt != mOnVertex.end(); ++mIt)
     {
-      u = isForward ? u_n->first : - u_n->first;
-      gp_Pnt2d p = C2d->Value( u ).XY().Multiplied( scale );
-      uvslf[m].x = p.X();
-      uvslf[m].y = p.Y();
-      mefistoToDS[m + 1] = u_n->second;
-      //MESSAGE(" "<<m<<" "<<mefistoToDS[m+1]);
-      //MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
-      m++;
+      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();
+        TopoDS_Vertex V = TopoDS::Vertex( myTool->GetMeshDS()->IndexToShape( vID ));
+        if ( fixCommonVertexUV( uvslf[m], V, F, VWMap, *myTool->GetMesh(),
+                                scalex, scaley, _quadraticMesh )) {
+          myNodesOnCommonV.push_back( mefistoToDS[m] );
+          continue;
+        }
+      }
+      // prevent failure on overlapped adjacent links,
+      // check only links ending in vertex nodes
+      int mB = m - 1, mA = m + 1; // indices Before and After
+      if ( mB < mFirst ) mB = mLast;
+      if ( mA > mLast )  mA = mFirst;
+      fixOverlappedLinkUV (uvslf[ mB ], uvslf[ m ], uvslf[ mA ]);
     }
-  } // for  wexp
-
-  // prevent failure on overlapped adjacent links,
-  // check only links ending in vertex nodes
-  int mFirst = mOnVertex.front(), mLast = m - 1;
-  list< int >::iterator mIt = mOnVertex.begin();
-  for ( ; mIt != mOnVertex.end(); ++mIt ) {
-    int i = *mIt;
-    int iB = i - 1, iA = i + 1; // indices Before and After
-    if ( iB < mFirst ) iB = mLast;
-    if ( iA > mLast )  iA = mFirst;
-    fixOverlappedLinkUV (uvslf[ iB ], uvslf[ i ], uvslf[ iA ]);
   }
 
   return true;
@@ -594,12 +566,12 @@ bool StdMeshers_MEFISTO_2D::LoadPoints(SMESH_Mesh &        aMesh,
  */
 //=============================================================================
 
-void StdMeshers_MEFISTO_2D::ComputeScaleOnFace(SMESH_Mesh & aMesh,
-       const TopoDS_Face & aFace, double &scalex, double &scaley)
+void StdMeshers_MEFISTO_2D::ComputeScaleOnFace(SMESH_Mesh &        aMesh,
+                                               const TopoDS_Face & aFace,
+                                               double &            scalex,
+                                               double &            scaley)
 {
-  //MESSAGE("StdMeshers_MEFISTO_2D::ComputeScaleOnFace");
-  TopoDS_Face F = TopoDS::Face(aFace.Oriented(TopAbs_FORWARD));
-  TopoDS_Wire W = BRepTools::OuterWire(F);
+  TopoDS_Wire W = BRepTools::OuterWire(aFace);
 
   double xmin = 1.e300;         // min & max of face 2D parametric coord.
   double xmax = -1.e300;
@@ -614,7 +586,7 @@ void StdMeshers_MEFISTO_2D::ComputeScaleOnFace(SMESH_Mesh & aMesh,
   {
     const TopoDS_Edge & E = TopoDS::Edge( wexp.Current() );
     double f, l;
-    Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+    Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, aFace, f, l);
     if ( C2d.IsNull() ) continue;
     double du = (l - f) / double (nbp);
     for (int i = 0; i <= nbp; i++)
@@ -641,7 +613,8 @@ void StdMeshers_MEFISTO_2D::ComputeScaleOnFace(SMESH_Mesh & aMesh,
   double xsize = xmax - xmin;
   double ysize = ymax - ymin;
 
-  Handle(Geom_Surface) S = BRep_Tool::Surface(F);       // 3D surface
+  TopLoc_Location L;
+  Handle(Geom_Surface) S = BRep_Tool::Surface(aFace,L);       // 3D surface
 
   double length_x = 0;
   double length_y = 0;
@@ -687,21 +660,21 @@ void StdMeshers_MEFISTO_2D::ComputeScaleOnFace(SMESH_Mesh & aMesh,
  */
 //=============================================================================
 
-void StdMeshers_MEFISTO_2D::StoreResult(SMESH_Mesh & aMesh,
-                                        Z nbst, R2 * uvst, Z nbt, Z * nust,
-                                        const TopoDS_Face & F, bool faceIsForward,
-                                        map<int, const SMDS_MeshNode*>&mefistoToDS,
+void StdMeshers_MEFISTO_2D::StoreResult(Z nbst, R2 * uvst, Z nbt, Z * nust,
+                                        vector< const SMDS_MeshNode*>&mefistoToDS,
                                         double scalex, double scaley)
 {
-  SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
-  int faceID = meshDS->ShapeToIndex( F );
+  SMESHDS_Mesh * meshDS = myTool->GetMeshDS();
+  int faceID = myTool->GetSubShapeID();
 
-  Z n, m;
-  Handle(Geom_Surface) S = BRep_Tool::Surface(F);
+  TopoDS_Face F = TopoDS::Face( myTool->GetSubShape() );
+  Handle(Geom_Surface) S = BRep_Tool::Surface( F );
 
-  for (n = 0; n < nbst; n++)
+  Z n = mefistoToDS.size(); // nb input points
+  mefistoToDS.resize( nbst );
+  for ( ; n < nbst; n++)
   {
-    if (mefistoToDS.find(n + 1) == mefistoToDS.end())
+    if (!mefistoToDS[n])
     {
       double u = uvst[n][0] / scalex;
       double v = uvst[n][1] / scaley;
@@ -711,30 +684,28 @@ void StdMeshers_MEFISTO_2D::StoreResult(SMESH_Mesh & aMesh,
       meshDS->SetNodeOnFace(node, faceID, u, v);
 
       //MESSAGE(P.X()<<" "<<P.Y()<<" "<<P.Z());
-      mefistoToDS[n + 1] = node;
+      mefistoToDS[n] = node;
       //MESSAGE("NEW: "<<n<<" "<<mefistoToDS[n+1]);
     }
   }
 
-  m = 0;
+  m = 0;
 
   // triangle points must be in trigonometric order if face is Forward
   // else they must be put clockwise
 
-  bool triangleIsWellOriented = faceIsForward;
+  bool triangleIsWellOriented = ( F.Orientation() == TopAbs_FORWARD );
 
   for (n = 1; n <= nbt; n++)
   {
-    const SMDS_MeshNode * n1 = mefistoToDS[ nust[m++] ];
-    const SMDS_MeshNode * n2 = mefistoToDS[ nust[m++] ];
-    const SMDS_MeshNode * n3 = mefistoToDS[ nust[m++] ];
+    const SMDS_MeshNode * n1 = mefistoToDS[ nust[m++] - 1 ];
+    const SMDS_MeshNode * n2 = mefistoToDS[ nust[m++] - 1 ];
+    const SMDS_MeshNode * n3 = mefistoToDS[ nust[m++] - 1 ];
 
     SMDS_MeshElement * elt;
     if (triangleIsWellOriented)
-      //elt = meshDS->AddFace(n1, n2, n3);
       elt = myTool->AddFace(n1, n2, n3);
     else
-      //elt = meshDS->AddFace(n1, n3, n2);
       elt = myTool->AddFace(n1, n3, n2);
 
     meshDS->SetMeshElementOnShape(elt, faceID);
@@ -762,82 +733,4 @@ void StdMeshers_MEFISTO_2D::StoreResult(SMESH_Mesh & aMesh,
       }
     }
   }
-
-}
-
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-double StdMeshers_MEFISTO_2D::ComputeEdgeElementLength(SMESH_Mesh & aMesh,
-       const TopoDS_Shape & aShape)
-{
-       //MESSAGE("StdMeshers_MEFISTO_2D::ComputeEdgeElementLength");
-       // **** a mettre dans SMESH_2D_Algo ?
-
-       //const TopoDS_Face & FF = TopoDS::Face(aShape);
-       //bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
-       //TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
-
-       double meanElementLength = 100;
-       double wireLength = 0;
-       int wireElementsNumber = 0;
-               for (TopExp_Explorer expe(aShape, TopAbs_EDGE); expe.More(); expe.Next())
-               {
-                       const TopoDS_Edge & E = TopoDS::Edge(expe.Current());
-                       int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
-                       double length = EdgeLength(E);
-                       wireLength += length;
-                       wireElementsNumber += nb;
-               }
-       if (wireElementsNumber)
-               meanElementLength = wireLength / wireElementsNumber;
-       //SCRUTE(meanElementLength);
-       return meanElementLength;
-}
-
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-ostream & StdMeshers_MEFISTO_2D::SaveTo(ostream & save)
-{
-  return save;
-}
-
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-istream & StdMeshers_MEFISTO_2D::LoadFrom(istream & load)
-{
-  return load;
-}
-
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-ostream & operator <<(ostream & save, StdMeshers_MEFISTO_2D & hyp)
-{
-  return hyp.SaveTo( save );
-}
-
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-istream & operator >>(istream & load, StdMeshers_MEFISTO_2D & hyp)
-{
-  return hyp.LoadFrom( load );
 }
index f9601490fd308cd54f528abc7a512662a054ab92..bc229bd2c61554b012fc8042d4e1aea49a844849 100644 (file)
 #include "SMESH_StdMeshers.hxx"
 
 #include "SMESH_2D_Algo.hxx"
-#include <TopoDS_Wire.hxx>
 
-#include "SMESH_MesherHelper.hxx"
-
-class SMDS_MeshNode;
-class TopTools_IndexedDataMapOfShapeListOfShape;
 class TopoDS_Face;
-class TopoDS_WIre;
 class StdMeshers_MaxElementArea;
 class StdMeshers_LengthFromEdges;
 class SMDS_MeshNode;
+class SMESH_MesherHelper;
+class StdMeshers_FaceSide;
 
+#include <vector>
 #include <list>
-#include <map>
 #include "Rn.h"
 
-class STDMESHERS_EXPORT StdMeshers_MEFISTO_2D:
-  public SMESH_2D_Algo
+class STDMESHERS_EXPORT StdMeshers_MEFISTO_2D: public SMESH_2D_Algo
 {
 public:
   StdMeshers_MEFISTO_2D(int hypId, int studyId, SMESH_Gen* gen);
@@ -63,41 +58,29 @@ public:
   virtual bool Compute(SMESH_Mesh& aMesh,
                       const TopoDS_Shape& aShape);
 
-  double ComputeEdgeElementLength(SMESH_Mesh& aMesh,
-                                 const TopoDS_Shape& aShape);
+  typedef boost::shared_ptr< StdMeshers_FaceSide> StdMeshers_FaceSidePtr;
+  typedef std::vector< StdMeshers_FaceSidePtr > TWireVector;
 
-  bool LoadPoints(SMESH_Mesh& aMesh,
-                 const TopoDS_Face& F, 
-                 const TopoDS_Wire& W,
-                 R2* uvslf, 
-                 int& m,
-                 map<int,const SMDS_MeshNode*>& mefistoToDS,
-                  double scalex, double scaley,
-                  const TopTools_IndexedDataMapOfShapeListOfShape& VWMap);
+  bool LoadPoints(TWireVector &                       wires,
+                 R2*                                 uvslf, 
+                 std::vector< const SMDS_MeshNode*>& mefistoToDS,
+                  double scalex, double               scaley);
 
   void ComputeScaleOnFace(SMESH_Mesh& aMesh,
                          const TopoDS_Face& aFace,
                          double& scalex,
                          double& scaley);
 
-  void StoreResult (SMESH_Mesh& aMesh,
-                   Z nbst, R2* uvst, Z nbt, Z* nust, 
-                   const TopoDS_Face& F, bool faceIsForward,
-                   map<int,const SMDS_MeshNode*>& mefistoToDS,
+  void StoreResult (Z nbst, R2* uvst, Z nbt, Z* nust, 
+                   std::vector< const SMDS_MeshNode*>& mefistoToDS,
                     double scalex, double scaley);
                                          
-  ostream & SaveTo(ostream & save);
-  istream & LoadFrom(istream & load);
-  friend ostream & operator << (ostream & save, StdMeshers_MEFISTO_2D & hyp);
-  friend istream & operator >> (istream & load, StdMeshers_MEFISTO_2D & hyp);
-
 protected:
   double                            _edgeLength;
   double                            _maxElementArea;
   const StdMeshers_MaxElementArea*  _hypMaxElementArea;
   const StdMeshers_LengthFromEdges* _hypLengthFromEdges;
 
-  TopoDS_Wire myOuterWire;
   std::list<const SMDS_MeshNode*> myNodesOnCommonV;
 
   SMESH_MesherHelper* myTool; // toll for working with quadratic elements
index 353afb8712348ab35ea5f3478c432c1f50090666..fd1fe47cf719a5afb75831b7f4862bc0a58c1723 100644 (file)
@@ -38,6 +38,7 @@
 #include "SMESH_MeshEditor.hxx"
 #include "SMESH_subMesh.hxx"
 #include "SMESH_subMeshEventListener.hxx"
+#include "SMESH_Comment.hxx"
 
 #include <BRepTools.hxx>
 #include <BRepTools_WireExplorer.hxx>
@@ -74,7 +75,7 @@ enum { NB_WALL_FACES = 4 };
 //purpose  : 
 //=======================================================================
 StdMeshers_Penta_3D::StdMeshers_Penta_3D()
-: myErrorStatus(1)
+: myErrorStatus(SMESH_ComputeError::New())
 {
   myTol3D=0.1;
   myWallNodesMaps.resize( SMESH_Block::NbFaces() );
@@ -89,8 +90,6 @@ StdMeshers_Penta_3D::StdMeshers_Penta_3D()
 
 StdMeshers_Penta_3D::~StdMeshers_Penta_3D()
 {
-  if ( myTool )
-    delete myTool;
 }
 
 //=======================================================================
@@ -102,51 +101,45 @@ bool StdMeshers_Penta_3D::Compute(SMESH_Mesh& aMesh,
 {
   MESSAGE("StdMeshers_Penta_3D::Compute()");
   //
-  myErrorStatus=0;
-  //
   bool bOK=false;
   //
   myShape=aShape;
   SetMesh(aMesh);
   //
   CheckData();
-  if (myErrorStatus){
+  if (!myErrorStatus->IsOK()) {
     return bOK;
   }
 
-  myTool = new SMESH_MesherHelper(aMesh);
+  SMESH_MesherHelper helper(aMesh);
+  myTool = &helper;
   myCreateQuadratic = myTool->IsQuadraticSubMesh(aShape);
 
   //
   MakeBlock();
-  if (myErrorStatus){
-    delete myTool; myTool = 0;
+  if (!myErrorStatus->IsOK()) {
     return bOK;
   }
   //
   ClearMeshOnFxy1();
-  if (myErrorStatus) {
-    delete myTool; myTool = 0;
+  if (!myErrorStatus->IsOK()) {
     return bOK;
   }
   //
   MakeNodes();
-  if (myErrorStatus){
-    delete myTool; myTool = 0;
+  if (!myErrorStatus->IsOK()) {
     return bOK;
   }
   //
   MakeConnectingMap();
   //
   MakeMeshOnFxy1();
-  if (myErrorStatus) {
-    delete myTool; myTool = 0;
+  if (!myErrorStatus->IsOK()) {
     return bOK;
   }
   //
   MakeVolumeMesh();
   //
-  delete myTool; myTool = 0;
   return !bOK;
 }
 
@@ -156,8 +149,6 @@ bool StdMeshers_Penta_3D::Compute(SMESH_Mesh& aMesh,
 //=======================================================================
 void StdMeshers_Penta_3D::MakeNodes()
 {
-  myErrorStatus=0;
-  //
   const int aNbSIDs=9;
   int i, j, k, ij, iNbN, aNodeID, aSize, iErr;
   double aX, aY, aZ;
@@ -261,7 +252,7 @@ void StdMeshers_Penta_3D::MakeNodes()
       if (iErr) {
         MESSAGE("StdMeshers_Penta_3D::MakeNodes()," <<
                 "SMESHBlock: ComputeParameters operation failed");
-        myErrorStatus=101; // SMESHBlock: ComputeParameters operation failed
+        myErrorStatus=myBlock.GetError();
         return;
       }
       aTNode.SetNormCoord(aCoords);
@@ -287,8 +278,10 @@ void StdMeshers_Penta_3D::MakeNodes()
                            TopoDS::Edge( myBlock.Shape( baseEdgeID[ i ] )),
                            pMesh->GetMeshDS());
     if ( !ok ) {
-      myErrorStatus = i + 1;
-      MESSAGE(" Cant LoadIJNodes() from a wall face " << myErrorStatus );
+      myErrorStatus->myName = COMPERR_BAD_INPUT_MESH;
+      myErrorStatus->myComment = SMESH_Comment() <<
+        "Can't find regular quadrangle mesh on a side face #" <<
+        pMesh->GetMeshDS()->ShapeToIndex( myBlock.Shape( wallFaceID[ i ]));
       return;
     }
   }
@@ -433,7 +426,7 @@ void StdMeshers_Penta_3D::MakeNodes()
       //
       //   suporting shape ID
       ShapeSupportID(bIsUpperLayer, aBNSSID, aSSID);
-      if (myErrorStatus) {
+      if (!myErrorStatus->IsOK()) {
         MESSAGE("StdMeshers_Penta_3D::MakeNodes() ");
        return;
       }
@@ -480,7 +473,7 @@ void StdMeshers_Penta_3D::MakeNodes()
           meshDS->SetNodeOnFace((SMDS_MeshNode*)n, topfaceID, aP.X(), aP.Y());
         }
       }
-      if (myErrorStatus) {
+      if (!myErrorStatus->IsOK()) {
         MESSAGE("StdMeshers_Penta_3D::MakeNodes() ");
        return;
       }
@@ -528,8 +521,6 @@ void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS,
                                           const int           z,
                                          StdMeshers_TNode&   aTN)
 {
-  myErrorStatus=0;
-  //
   double aX, aY, aZ, aD, aTol2, minD;
   gp_Pnt aP1, aP2;
   //
@@ -673,8 +664,6 @@ double StdMeshers_Penta_3D::SetHorizEdgeXYZ(const gp_XYZ&                  aBase
 //=======================================================================
 void StdMeshers_Penta_3D::MakeVolumeMesh()
 {
-  myErrorStatus=0;
-  //
   int i, j, ij, ik, i1, i2, aSSID; 
   //
   SMESH_Mesh*   pMesh = GetMesh();
@@ -727,7 +716,7 @@ void StdMeshers_Penta_3D::MakeVolumeMesh()
         continue;
       aID0 = pNode->GetID();
       aJ[k] = GetIndexOnLayer(aID0);
-      if (myErrorStatus) {
+      if (!myErrorStatus->IsOK()) {
         MESSAGE("StdMeshers_Penta_3D::MakeVolumeMesh");
        return;
       }
@@ -814,8 +803,6 @@ void StdMeshers_Penta_3D::MakeVolumeMesh()
 //=======================================================================
 void StdMeshers_Penta_3D::MakeMeshOnFxy1()
 {
-  myErrorStatus=0;
-  //
   int aID0, aJ, aLevel, ij, aNbNodes, k;
   //
   SMDS_NodeIteratorPtr itn;
@@ -862,14 +849,13 @@ void StdMeshers_Penta_3D::MakeMeshOnFxy1()
     k = aNbNodes-1; // reverse a face
     aItNodes = pE0->nodesIterator();
     while (aItNodes->more()) {
-      //const SMDS_MeshElement* pNode = aItNodes->next();
       const SMDS_MeshNode* pNode =
         static_cast<const SMDS_MeshNode*> (aItNodes->next());
       if(myTool->IsMedium(pNode))
         continue;
       aID0 = pNode->GetID();
       aJ = GetIndexOnLayer(aID0);
-      if (myErrorStatus) {
+      if (!myErrorStatus->IsOK()) {
         MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() ");
        return;
       }
@@ -911,8 +897,6 @@ void StdMeshers_Penta_3D::MakeMeshOnFxy1()
 //=======================================================================
 void StdMeshers_Penta_3D::ClearMeshOnFxy1()
 {
-  myErrorStatus=0;
-  //
   SMESH_subMesh* aSubMesh;
   SMESH_Mesh* pMesh=GetMesh();
   //
@@ -928,14 +912,13 @@ void StdMeshers_Penta_3D::ClearMeshOnFxy1()
 //=======================================================================
 int StdMeshers_Penta_3D::GetIndexOnLayer(const int aID)
 {
-  myErrorStatus=0;
-  //
   int j=-1;
   StdMeshers_IteratorOfDataMapOfIntegerInteger aMapIt;
   //
   aMapIt=myConnectingMap.find(aID);
   if (aMapIt==myConnectingMap.end()) {
-    myErrorStatus=200;
+    myErrorStatus->myName    = 200;
+    myErrorStatus->myComment = "Internal error of StdMeshers_Penta_3D";
     return j;
   }
   j=(*aMapIt).second;
@@ -965,9 +948,6 @@ void StdMeshers_Penta_3D::CreateNode(const bool bIsUpperLayer,
                                     const gp_XYZ& aParams,
                                     StdMeshers_TNode& aTN)
 {
-  myErrorStatus=0;
-  //
-  // int iErr;
   double aX, aY, aZ;
   //
   gp_Pnt aP;
@@ -1025,8 +1005,6 @@ void StdMeshers_Penta_3D::ShapeSupportID(const bool bIsUpperLayer,
                                         const SMESH_Block::TShapeID aBNSSID,
                                         SMESH_Block::TShapeID& aSSID)
 {
-  myErrorStatus=0;
-  //
   switch (aBNSSID) {
     case SMESH_Block::ID_V000:
       aSSID=(bIsUpperLayer) ?  SMESH_Block::ID_V001 : SMESH_Block::ID_E00z;
@@ -1057,7 +1035,8 @@ void StdMeshers_Penta_3D::ShapeSupportID(const bool bIsUpperLayer,
       break;   
     default:
       aSSID=SMESH_Block::ID_NONE;
-      myErrorStatus=10; // Can not find supporting shape ID
+      myErrorStatus->myName=10; // Can not find supporting shape ID
+      myErrorStatus->myComment = "Internal error of StdMeshers_Penta_3D";
       break;
   }
   return;
@@ -1068,8 +1047,6 @@ void StdMeshers_Penta_3D::ShapeSupportID(const bool bIsUpperLayer,
 //=======================================================================
 void StdMeshers_Penta_3D::MakeBlock()
 {
-  myErrorStatus=0;
-  //
   bool bFound;
   int i, j, iNbEV, iNbE, iErr, iCnt, iNbNodes, iNbF;
   //
@@ -1266,7 +1243,8 @@ void StdMeshers_Penta_3D::MakeBlock()
       }
     }
     if (!isOK) {
-      myErrorStatus=5; // more than one face has triangulation
+      myErrorStatus->myName=5; // more than one face has triangulation
+      myErrorStatus->myComment="Incorrect input mesh";
       return;
     }
   }
@@ -1281,7 +1259,9 @@ void StdMeshers_Penta_3D::MakeBlock()
   iNbE = aME.Extent();
   if (iNbE!= NB_WALL_FACES ){
     MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
-    myErrorStatus=7; // too few edges are in base face aFTr 
+    myErrorStatus->myName=7; // too few edges are in base face aFTr
+    myErrorStatus->myComment=SMESH_Comment("Not a quadrilateral face #")
+      <<pMesh->GetMeshDS()->ShapeToIndex( aFTr )<<": "<<iNbE<<" edges" ;
     return;
   }
   const TopoDS_Edge& aE1=TopoDS::Edge(aME(1));
@@ -1296,7 +1276,9 @@ void StdMeshers_Penta_3D::MakeBlock()
   iNbEV=aMEV.Extent();
   if (iNbEV!=3){
     MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
-    myErrorStatus=7; // too few edges meet in base vertex 
+    myErrorStatus->myName=7; // too few edges meet in base vertex 
+    myErrorStatus->myComment=SMESH_Comment("3 edges must share vertex #")
+      <<pMesh->GetMeshDS()->ShapeToIndex( aV000 )<<" but there are "<<iNbEV<<" edges";
     return;
   }
   //
@@ -1321,7 +1303,9 @@ void StdMeshers_Penta_3D::MakeBlock()
   //
   if (!bFound) {
     MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
-    myErrorStatus=8; // can not find reper V001 
+    myErrorStatus->myName=8; // can not find reper V001
+    myErrorStatus->myComment=SMESH_Comment("Can't find opposite vertex for vertex #")
+      <<pMesh->GetMeshDS()->ShapeToIndex( aV000 );
     return;
   }
   //DEB
@@ -1338,7 +1322,8 @@ void StdMeshers_Penta_3D::MakeBlock()
   iNbE=aME.Extent();
   if (iNbE!=1) {
     MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
-    myErrorStatus=9; // number of shells in source shape !=1 
+    myErrorStatus->myName=9; // number of shells in source shape !=1
+    myErrorStatus->myComment=SMESH_Comment("Unexpected nb of shells ")<<iNbE;
     return;
   }
   //
@@ -1348,7 +1333,7 @@ void StdMeshers_Penta_3D::MakeBlock()
   iErr = myBlock.ErrorStatus();
   if (iErr) {
     MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
-    myErrorStatus=100; // SMESHBlock: Load operation failed
+    myErrorStatus=myBlock.GetError(); // SMESHBlock: Load operation failed
     return;
   }
 }
@@ -1358,8 +1343,6 @@ void StdMeshers_Penta_3D::MakeBlock()
 //=======================================================================
 void StdMeshers_Penta_3D::CheckData()
 {
-  myErrorStatus=0;
-  //
   int i, iNb;
   int iNbEx[]={8, 12, 6};
   //
@@ -1371,14 +1354,16 @@ void StdMeshers_Penta_3D::CheckData()
   //
   if (myShape.IsNull()){
     MESSAGE("StdMeshers_Penta_3D::CheckData() ");
-    myErrorStatus=2; // null shape
+    myErrorStatus->myName=2; // null shape
+    myErrorStatus->myComment="Null shape";
     return;
   }
   //
   aST=myShape.ShapeType();
   if (!(aST==TopAbs_SOLID || aST==TopAbs_SHELL)) {
     MESSAGE("StdMeshers_Penta_3D::CheckData() ");
-    myErrorStatus=3; // not compatible type of shape
+    myErrorStatus->myName=3; // not compatible type of shape
+    myErrorStatus->myComment=SMESH_Comment("Wrong shape type (TopAbs_ShapeEnum) ")<<aST;
     return;
   }
   //
@@ -1388,7 +1373,8 @@ void StdMeshers_Penta_3D::CheckData()
     iNb=aM.Extent();
     if (iNb!=iNbEx[i]){
       MESSAGE("StdMeshers_Penta_3D::CheckData() ");
-      myErrorStatus=4; // number of subshape is not compatible
+      myErrorStatus->myName=4; // number of subshape is not compatible
+      myErrorStatus->myComment="Wrong number of subshapes of a block";
       return;
     }
   }
@@ -1557,12 +1543,12 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
   // try to load the rest nodes
 
   // get all faces from theFace
-  map<int,const SMDS_MeshElement*> allFaces, foundFaces;
+  TIDSortedElemSet allFaces, foundFaces;
   SMDS_ElemIteratorPtr eIt = smFace->GetElements();
   while ( eIt->more() ) {
     const SMDS_MeshElement* e = eIt->next();
     if ( e->GetType() == SMDSAbs_Face )
-      allFaces.insert( make_pair(e->GetID(),e) );
+      allFaces.insert( e );
   }
   // Starting from 2 neighbour nodes on theBaseEdge, look for a face
   // the nodes belong to, and between the nodes of the found face,
@@ -1609,7 +1595,7 @@ bool StdMeshers_Penta_3D::LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
             return false;
           }
           par_nVec_2->second[ row ] = node;
-          foundFaces.insert( make_pair(face->GetID(),face) );
+          foundFaces.insert( face );
           n2 = node;
           if ( nbFaceNodes==4 || (myCreateQuadratic && nbFaceNodes==8) ) {
             n1 = par_nVec_1->second[ row ];
@@ -1685,6 +1671,28 @@ int StdMeshers_SMESHBlock::ErrorStatus() const
   return myErrorStatus;
 }
 
+//================================================================================
+/*!
+ * \brief Return problem description
+ */
+//================================================================================
+
+SMESH_ComputeErrorPtr StdMeshers_SMESHBlock::GetError() const
+{
+  SMESH_ComputeErrorPtr err = SMESH_ComputeError::New();
+  string & text = err->myComment;
+  switch ( myErrorStatus ) {
+  case 2:
+  case 3: text = "Internal error of StdMeshers_Penta_3D"; break; 
+  case 4: text = "Can't compute normalized parameters of a point inside a block"; break;
+  case 5: text = "Can't compute coordinates by normalized parameters inside a block"; break;
+  case 6: text = "Can't detect block subshapes. Not a block?"; break;
+  }
+  if (!text.empty())
+    err->myName = myErrorStatus;
+  return err;
+}
+
 //=======================================================================
 //function : Load
 //purpose  : 
@@ -1713,7 +1721,7 @@ void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell,
   myShapeIDMap.Clear();  
   bOk = myTBlock.LoadBlockShapes(myShell, theV000, theV001, myShapeIDMap);
   if (!bOk) {
-    myErrorStatus=2;
+    myErrorStatus=6;
     return;
   }
 }
@@ -1827,7 +1835,7 @@ void StdMeshers_SMESHBlock::ComputeParameters(const double& theU,
     }
   }
   if (!bOk) {
-    myErrorStatus=4; // problems with point computation 
+    myErrorStatus=5; // problems with point computation 
     return;
   }
   aP3D.SetXYZ(aXYZ);
index 18787686c434217f5ed50d29bed1d8aeb382f77f..90eab4c7433ab9ceafdd68f69ef14e32ae3f8111 100644 (file)
@@ -44,7 +44,7 @@
 #include <TColStd_MapOfInteger.hxx>
 
 #include "SMESH_Block.hxx"
-
+#include "SMESH_ComputeError.hxx"
 #include "SMESH_MesherHelper.hxx"
 
 typedef std::map< double, std::vector<const SMDS_MeshNode*> > StdMeshers_IJNodeMap;
@@ -89,6 +89,8 @@ public:
 
   int  ErrorStatus() const;
 
+  SMESH_ComputeErrorPtr GetError() const;
+
 
 protected:
   TopoDS_Shell                       myShell;
@@ -175,6 +177,12 @@ class STDMESHERS_EXPORT StdMeshers_Penta_3D {
     bool Compute(SMESH_Mesh& , const TopoDS_Shape& );
     
     int ErrorStatus() const {
+      if (myErrorStatus->IsOK())
+        return 0;
+      return myErrorStatus->myName;
+    }
+
+    SMESH_ComputeErrorPtr GetComputeError() const {
       return myErrorStatus;
     }
    
@@ -246,7 +254,7 @@ class STDMESHERS_EXPORT StdMeshers_Penta_3D {
     TopoDS_Shape              myShape;
     StdMeshers_SMESHBlock     myBlock;
     void *                    myMesh;
-    int                       myErrorStatus;
+    SMESH_ComputeErrorPtr     myErrorStatus;
     //
     vector <StdMeshers_TNode> myTNodes;
     int                       myISize;
@@ -258,7 +266,7 @@ class STDMESHERS_EXPORT StdMeshers_Penta_3D {
     vector<gp_XYZ>            myShapeXYZ; // point on each sub-shape
 
     bool myCreateQuadratic;
-    SMESH_MesherHelper* myTool; // toll for working with quadratic elements
+    SMESH_MesherHelper* myTool; // tool building quadratic elements
 };
 
 #endif
index db1e082593ba60397c21fbc972b361bcba7f1902..8d87d043fdc1240af6c03ddc410ec71f8bf532a5 100644 (file)
@@ -34,6 +34,7 @@
 #include "SMDS_VolumeTool.hxx"
 #include "SMDS_VolumeOfNodes.hxx"
 #include "SMDS_EdgePosition.hxx"
+#include "SMESH_Comment.hxx"
 
 #include "utilities.h"
 
@@ -55,6 +56,7 @@ using namespace std;
 // }
 
 typedef StdMeshers_ProjectionUtils TAssocTool;
+typedef SMESH_Comment              TCom;
 
 enum { ID_BOT_FACE = SMESH_Block::ID_Fxy0,
        ID_TOP_FACE = SMESH_Block::ID_Fxy1,
@@ -227,15 +229,14 @@ bool StdMeshers_Prism_3D::CheckHypothesis(SMESH_Mesh&                          a
 
 bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theShape)
 {
-  myHelper = new SMESH_MesherHelper( theMesh );
-  // to delete helper at exit from Compute()
-  std::auto_ptr<SMESH_MesherHelper> helperDeleter( myHelper );
+  SMESH_MesherHelper helper( theMesh );
+  myHelper = &helper;
 
   myHelper->IsQuadraticSubMesh( theShape );
 
   // Analyse mesh and geomerty to find block subshapes and submeshes
   if ( !myBlock.Init( myHelper, theShape ))
-    return false;
+    return error( myBlock.GetError());
 
   SMESHDS_Mesh* meshDS = theMesh.GetMeshDS();
 
@@ -282,7 +283,9 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
     myShapeXYZ[ ID_TOP_FACE ] = gpXYZ( column.back() );
     gp_Pnt topCoords = myShapeXYZ[ ID_TOP_FACE ];
     if ( !myBlock.ComputeParameters( topCoords, topParams, ID_TOP_FACE ))
-      RETURN_BAD_RESULT("ComputeParameters() on the top face failed");
+      return error(dfltErr(),TCom("Can't compute normalized parameters ")
+                   << "for node " << column.back()->GetID()
+                   << " on the face #"<< column.back()->GetPosition()->GetShapeId() );
 
     // vertical loop
     TNodeColumn::iterator columnNodes = column.begin();
@@ -308,7 +311,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
       // compute coords for a new node
       gp_XYZ coords;
       if ( !SMESH_Block::ShellPoint( params, myShapeXYZ, coords ))
-        RETURN_BAD_RESULT("SMESH_Block::ShellPoint() failed");
+        return error(dfltErr(),"Can't compute coordinates by normalized parameters");
 
       // create a node
       node = meshDS->AddNode( coords.X(), coords.Y(), coords.Z() );
@@ -320,7 +323,7 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
   // Create volumes
 
   SMESHDS_SubMesh* smDS = myBlock.SubMeshDS( ID_BOT_FACE );
-  if ( !smDS ) RETURN_BAD_RESULT("Null submesh");
+  if ( !smDS ) return error(COMPERR_BAD_INPUT_MESH, "Null submesh");
 
   // loop on bottom mesh faces
   SMDS_ElemIteratorPtr faceIt = smDS->GetElements();
@@ -341,13 +344,13 @@ bool StdMeshers_Prism_3D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& theSh
       if ( n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) {
         bot_column = myBotToColumnMap.find( n );
         if ( bot_column == myBotToColumnMap.end() )
-          RETURN_BAD_RESULT(" node column for a node not found");
+          return error(dfltErr(),TCom("No nodes found above node ") << n->GetID() );
         columns[ i ] = & bot_column->second;
       }
       else {
         columns[ i ] = myBlock.GetNodeColumn( n );
         if ( !columns[ i ] )
-          RETURN_BAD_RESULT(" node column not found for a node " << n->GetID() );
+          return error(dfltErr(),TCom("No side nodes found above node ") << n->GetID() );
       }
     }
     // create prisms
@@ -459,7 +462,7 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top()
   SMESHDS_SubMesh * topSMDS = topSM->GetSubMeshDS();
 
   if ( !botSMDS || botSMDS->NbElements() == 0 )
-    RETURN_BAD_RESULT("Empty horiz submesh");
+    return error(dfltErr(),TCom("No elememts on face #") << botSM->GetId());
 
   bool needProject = false;
   if ( !topSMDS || 
@@ -467,12 +470,15 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top()
        botSMDS->NbNodes()    != topSMDS->NbNodes())
   {
     if ( myBlock.HasNotQuadElemOnTop() )
-      RETURN_BAD_RESULT("Different triangles on 2 sides");
+      return error(dfltErr(),TCom("Mesh on faces #") << botSM->GetId()
+                   <<" and #"<< topSM->GetId() << " seems different" );
     needProject = true;
   }
 
   if ( 0/*needProject && !myProjectTriangles*/ )
-    RETURN_BAD_RESULT("Need to project but not allowed");
+    return error(dfltErr(),TCom("Mesh on faces #") << botSM->GetId()
+                 <<" and #"<< topSM->GetId() << " seems different" );
+  ///RETURN_BAD_RESULT("Need to project but not allowed");
 
   if ( needProject )
   {
@@ -486,14 +492,16 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top()
   if ( !TAssocTool::FindSubShapeAssociation( botFace, myBlock.Mesh(),
                                              topFace, myBlock.Mesh(),
                                              shape2ShapeMap) )
-    RETURN_BAD_RESULT("FindSubShapeAssociation failed");
+    return error(dfltErr(),TCom("Topology of faces #") << botSM->GetId()
+                 <<" and #"<< topSM->GetId() << " seems different" );
 
-  // Find matching nodes of in and out faces
+  // Find matching nodes of top and bottom faces
   TNodeNodeMap n2nMap;
   if ( ! TAssocTool::FindMatchingNodesOnFaces( botFace, myBlock.Mesh(),
                                                topFace, myBlock.Mesh(),
                                                shape2ShapeMap, n2nMap ))
-    RETURN_BAD_RESULT("Different mesh on top and bottom faces");
+    return error(dfltErr(),TCom("Mesh on faces #") << botSM->GetId()
+                 <<" and #"<< topSM->GetId() << " seems different" );
 
   // Fill myBotToColumnMap
 
@@ -508,7 +516,8 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top()
     // compute bottom node params
     TNode bN( botNode );
     if ( !myBlock.ComputeParameters( bN.GetCoords(), bN.ChangeParams(), ID_BOT_FACE ))
-      RETURN_BAD_RESULT("ComputeParameters() on the bottom face failed");
+      return error(dfltErr(),TCom("Can't compute normalized parameters ")
+                   << "for node " << botNode->GetID() << " on the face #"<< botSM->GetId() );
     // create node column
     TNode2ColumnMap::iterator bN_col = 
       myBotToColumnMap.insert( make_pair ( bN, TNodeColumn() )).first;
@@ -555,12 +564,14 @@ bool StdMeshers_Prism_3D::projectBottomToTop()
     // compute bottom node params
     TNode bN( botNode );
     if ( !myBlock.ComputeParameters( bN.GetCoords(), bN.ChangeParams(), ID_BOT_FACE ))
-      RETURN_BAD_RESULT("ComputeParameters() on the bottom face failed");
+      return error(dfltErr(),TCom("Can't compute normalized parameters ")
+                   << "for node " << botNode->GetID() << " on the face #"<< botSM->GetId() );
     // compute top node coords
     gp_XYZ topXYZ; gp_XY topUV;
     if ( !myBlock.FacePoint( ID_TOP_FACE, bN.GetParams(), topXYZ ) ||
          !myBlock.FaceUV   ( ID_TOP_FACE, bN.GetParams(), topUV ))
-      RETURN_BAD_RESULT("SMESH_Block::FacePoint() on the top face failed");
+      return error(dfltErr(),TCom("Can't compute coordinates ")
+                   << "by normalized parameters on the face #"<< topSM->GetId() );
     SMDS_MeshNode * topNode = meshDS->AddNode( topXYZ.X(),topXYZ.Y(),topXYZ.Z() );
     meshDS->SetNodeOnFace( topNode, topFaceID, topUV.X(), topUV.Y() );
     // create node column
@@ -593,13 +604,13 @@ bool StdMeshers_Prism_3D::projectBottomToTop()
       if ( n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) {
         TNode2ColumnMap::iterator bot_column = myBotToColumnMap.find( n );
         if ( bot_column == myBotToColumnMap.end() )
-          RETURN_BAD_RESULT(" node column for a node not found");
+          return error(dfltErr(),TCom("No nodes found above node ") << n->GetID() );
         nodes[ i ] = bot_column->second.back();
       }
       else {
         const TNodeColumn* column = myBlock.GetNodeColumn( n );
         if ( !column )
-          RETURN_BAD_RESULT(" node column not found for a node " << n->GetID() );
+          return error(dfltErr(),TCom("No side nodes found above node ") << n->GetID() );
         nodes[ i ] = column->back();
       }
     }
@@ -700,7 +711,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
   mySide = new TSideFace( sideFaces, params );
 
   myHelper = helper;
-  SMESHDS_Mesh* meshDS = myHelper->GetMesh()->GetMeshDS();
+  SMESHDS_Mesh* meshDS = myHelper->GetMeshDS();
 
   SMESH_Block::init();
   myShapeIDMap.Clear();
@@ -711,6 +722,8 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
     SMESH_Block::ID_Fx1z, SMESH_Block::ID_F0yz
   };
 
+  myError = SMESH_ComputeError::New();
+
   // -------------------------------------------------------------
   // Look for top and bottom faces: not quadrangle ones or meshed
   // with not quadrangle elements
@@ -721,27 +734,31 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
   int nbFaces = 0;
   //
   SMESH_subMesh* mainSubMesh = myHelper->GetMesh()->GetSubMeshContaining( shape3D );
-  if ( !mainSubMesh ) RETURN_BAD_RESULT("Null submesh of shape3D");
-  //
-  const map< int, SMESH_subMesh * >& subSM = mainSubMesh->DependsOn();
-  map< int, SMESH_subMesh * >::const_iterator i_subSM = subSM.begin();
-  for ( ; i_subSM != subSM.end(); ++i_subSM )
+  if ( !mainSubMesh ) return error(COMPERR_BAD_INPUT_MESH,"Null submesh of shape3D");
+
+  // analyse face submeshes
+  SMESH_subMeshIteratorPtr smIt = mainSubMesh->getDependsOnIterator(false,false);
+  while ( smIt->more() )
   {
-    SMESH_subMesh* sm = i_subSM->second;
+    SMESH_subMesh* sm = smIt->next();
     const TopoDS_Shape& face = sm->GetSubShape();
     if ( face.ShapeType() != TopAbs_FACE )
       continue;
     nbFaces++;
 
     // is quadrangle face?
-    if ( TAssocTool::Count( face, TopAbs_EDGE, 0 ) != 4 ||
-         TAssocTool::Count( face, TopAbs_WIRE, 0 ) != 1 )
+    list< TopoDS_Edge > orderedEdges;
+    list< int >         nbEdgesInWires;
+    TopoDS_Vertex       V000;
+    int nbWires = GetOrderedEdges( TopoDS::Face( face ),
+                                   V000, orderedEdges, nbEdgesInWires );
+    if ( nbWires != 1 || nbEdgesInWires.front() != 4 )
       notQuadGeomSubMesh.push_back( sm );
 
-    // count not quadrangle mesh elements
+    // look for not quadrangle mesh elements
     if ( SMESHDS_SubMesh* smDS = sm->GetSubMeshDS() ) {
-      SMDS_ElemIteratorPtr eIt = smDS->GetElements();
       bool hasNotQuad = false;
+      SMDS_ElemIteratorPtr eIt = smDS->GetElements();
       while ( eIt->more() && !hasNotQuad ) {
         const SMDS_MeshElement* elem = eIt->next();
         if ( elem->GetType() == SMDSAbs_Face ) {
@@ -755,7 +772,28 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
         notQuadElemSubMesh.push_back( sm );
     }
     else {
-      RETURN_BAD_RESULT("not meshed face");
+      return error(COMPERR_BAD_INPUT_MESH,TCom("Not meshed face #")<<sm->GetId());
+    }
+    // check if a quadrangle face is meshed with a quadranglar grid
+    if ( notQuadGeomSubMesh.back() != sm &&
+         notQuadElemSubMesh.back() != sm )
+    {
+      // count nb edges on face sides
+      vector< int > nbEdges;
+      nbEdges.reserve( nbEdgesInWires.front() );
+      for ( list< TopoDS_Edge >::iterator edge = orderedEdges.begin();
+            edge != orderedEdges.end(); ++edge )
+      {
+        if ( SMESHDS_SubMesh* smDS = meshDS->MeshElements( *edge ))
+          nbEdges.push_back ( smDS->NbElements() );
+        else
+          nbEdges.push_back ( 0 );
+      }
+      int nbQuads = sm->GetSubMeshDS()->NbElements();
+      if ( nbEdges[0] *  nbEdges[1] != nbQuads ||
+           nbEdges[0] != nbEdges[2] ||
+           nbEdges[1] != nbEdges[3] )
+        notQuadElemSubMesh.push_back( sm );
     }
   }
 
@@ -774,9 +812,13 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
 
   // detect bad cases
   if ( nbNotQuad > 0 && nbNotQuad != 2 )
-    RETURN_BAD_RESULT("Wrong shape geometry");
+    return error(COMPERR_BAD_SHAPE,
+                 TCom("More than 2 not quadrilateral faces")
+                 <<nbNotQuad);
   if ( nbNotQuadMeshed > 2 )
-    RETURN_BAD_RESULT("More then 2 faces meshed with not quadrangle elements");
+    return error(COMPERR_BAD_INPUT_MESH,
+                 TCom("More then 2 faces meshed with not quadrangle elements")
+                 <<nbNotQuadMeshed);
 
   // get found submeshes
   if ( hasNotQuad )
@@ -795,11 +837,11 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
     else
       ok = ( notQuadGeomSubMesh == notQuadElemSubMesh );
     if ( !ok )
-      RETURN_BAD_RESULT("Side face meshed with not quadrangle elements");
+      return error(COMPERR_BAD_INPUT_MESH, "Side face meshed with not quadrangle elements");
   }
 
   myNotQuadOnTop = ( nbNotQuadMeshed > 1 );
-    
   // ----------------------------------------------------------
 
   if ( nbNotQuad == 0 ) // Standard block of 6 quadrangle faces ?
@@ -821,9 +863,17 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
         const TopoDS_Shape & ancestor = ancestIt.Value();
         if ( ancestor.ShapeType() == TopAbs_EDGE && !edgeMap.FindIndex( ancestor ))
         {
-          Vtop = TopExp::LastVertex( TopoDS::Edge( ancestor ));
-          if ( Vbot.IsSame ( Vtop ))
-            Vtop = TopExp::FirstVertex( TopoDS::Edge( ancestor ));
+          TopoDS_Vertex V1, V2;
+          TopExp::Vertices( TopoDS::Edge( ancestor ), V1, V2);
+          if      ( Vbot.IsSame ( V1 )) Vtop = V2;
+          else if ( Vbot.IsSame ( V2 )) Vtop = V1;
+          // check that Vtop belongs to shape3D
+          TopExp_Explorer exp( shape3D, TopAbs_VERTEX );
+          for ( ; exp.More(); exp.Next() )
+            if ( Vtop.IsSame( exp.Current() ))
+              break;
+          if ( !exp.More() )
+            Vtop.Nullify();
         }
       }
     }
@@ -839,7 +889,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
     // Load geometry in SMESH_Block
     if ( !SMESH_Block::FindBlockShapes( shell, Vbot, Vtop, myShapeIDMap )) {
       if ( !hasNotQuad )
-        RETURN_BAD_RESULT("Can not detect top and bottom");
+        return error(COMPERR_BAD_SHAPE, "Can't detect top and bottom of a prism");
     }
     else {
       if ( !botSM ) botSM = Mesh()->GetSubMeshContaining( myShapeIDMap( ID_BOT_FACE ));
@@ -893,7 +943,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
   // Get Wall faces corresponding to the ordered bottom edges
   list< TopoDS_Face > wallFaces;
   if ( !GetWallFaces( Mesh(), shape3D, botSM->GetSubShape(), orderedEdges, wallFaces))
-    RETURN_BAD_RESULT("GetWallFaces() failed");
+    return error(COMPERR_BAD_SHAPE, "Can't find side faces");
 
   // Find columns of wall nodes and calculate edges' lengths
   // --------------------------------------------------------
@@ -911,7 +961,8 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
   {
     TParam2ColumnMap & faceColumns = myParam2ColumnMaps[ iE ];
     if ( !myHelper->LoadNodeColumns( faceColumns, *faceIt, *edgeIt, meshDS ))
-      RETURN_BAD_RESULT("SMESH_MesherHelper::LoadNodeColumns() failed");
+      return error(COMPERR_BAD_INPUT_MESH, TCom("Can't find regular quadrangle mesh ")
+                   << "on a side face #" << MeshDS()->ShapeToIndex( *faceIt ));
 
     SHOWYXZ("\np1 F "<<iE, gpXYZ(faceColumns.begin()->second.front() ));
     SHOWYXZ("p2 F "<<iE, gpXYZ(faceColumns.rbegin()->second.front() ));
@@ -923,7 +974,8 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
     {
       SMESHDS_SubMesh* smDS = meshDS->MeshElements( *edgeIt);
       if ( !smDS )
-        RETURN_BAD_RESULT("Null submesh on a bottom edge");
+        return error(COMPERR_BAD_INPUT_MESH, TCom("Null submesh on the edge #")
+                     << MeshDS()->ShapeToIndex( *edgeIt ));
       // assure length uniqueness
       edgeLength[ iE ] *= smDS->NbNodes() + edgeLength[ iE ] / ( 1000 + iE );
       len2edgeMap[ edgeLength[ iE ]] = iE;
@@ -936,7 +988,8 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
   {
     TParam2ColumnMap & faceColumns = myParam2ColumnMaps[ iE ];
     if ( !myHelper->LoadNodeColumns( faceColumns, *faceIt, *edgeIt, meshDS ))
-      RETURN_BAD_RESULT("SMESH_MesherHelper::LoadNodeColumns() failed");
+      return error(COMPERR_BAD_INPUT_MESH, TCom("Can't find regular quadrangle mesh ")
+                   << "on a side face #" << MeshDS()->ShapeToIndex( *faceIt ));
     // edge columns
     int id = MeshDS()->ShapeToIndex( *edgeIt );
     bool isForward = true; // meaningless for intenal wires
@@ -1599,7 +1652,7 @@ TopoDS_Edge StdMeshers_PrismAsBlock::TSideFace::GetEdge(const int iEdge) const
   }
   default:;
   }
-  if ( !edge.IsNull() || edge.ShapeType() == TopAbs_EDGE )
+  if ( !edge.IsNull() && edge.ShapeType() == TopAbs_EDGE )
     return TopoDS::Edge( edge );
 
   // find edge by 2 vertices
index 82fe08f02a05c5116ce7a1777d2e39707e6c4830..5649199379ba5686ca4cc36116ef4cbe1349031a 100644 (file)
@@ -37,6 +37,7 @@
 #include "SMESHDS_Mesh.hxx"
 #include "SMESH_subMesh.hxx"
 #include "SMESH_MesherHelper.hxx"
+#include "SMESH_Comment.hxx"
 
 #include <vector>
 
@@ -115,6 +116,11 @@ public:
    */
   bool Init(SMESH_MesherHelper* helper, const TopoDS_Shape& shape3D);
 
+  /*!
+   * \brief Return problem description
+   */
+  SMESH_ComputeErrorPtr GetError() const { return myError; }
+
   /*!
    * \brief Return number of nodes on every vertical edge
     * \retval int - number of nodes including end nodes
@@ -343,7 +349,14 @@ private:
   // to find a column for a node by edge SMESHDS Index
   map< int, pair< TParam2ColumnMap*, bool > > myShapeIndex2ColumnMap;
 
-  
+  SMESH_ComputeErrorPtr myError;
+  /*!
+   * \brief store error and comment and then return ( error == COMPERR_OK )
+   */
+  bool error(int error, const SMESH_Comment& comment = "") {
+    myError = SMESH_ComputeError::New(error,comment);
+    return myError->IsOK();
+  }
   //vector< SMESH_subMesh* >           mySubMeshesVec; // submesh by in-block id
 };
 
index 2afedd4ce40c5c50128c4b7b0625739afa22f2f6..c276b3afa70705ebc049ab19c2630874c39b7d21 100644 (file)
@@ -40,6 +40,7 @@
 #include "SMESH_Mesh.hxx"
 #include "SMESH_MeshEditor.hxx"
 #include "SMESH_subMesh.hxx"
+#include "SMESH_subMeshEventListener.hxx"
 #include "SMDS_EdgePosition.hxx"
 
 #include "utilities.h"
@@ -976,12 +977,12 @@ FindMatchingNodesOnFaces( const TopoDS_Face&     face1,
       const SMDS_MeshElement* faceToKeep = 0;
       const SMDS_MeshNode* vNode = is2 ? vNode2 : vNode1;
       const SMDS_MeshNode* eNode = is2 ? eNode2[0] : eNode1[0];
-      std::map<int,const SMDS_MeshElement*> inSet, notInSet;
+      TIDSortedElemSet inSet, notInSet;
 
       const SMDS_MeshElement* f1 =
         SMESH_MeshEditor::FindFaceInSet( vNode, eNode, inSet, notInSet );
       if ( !f1 ) RETURN_BAD_RESULT("The first face on seam not found");
-      SMESH_MeshEditor::Insert( f1, notInSet );
+      notInSet.insert( f1 );
 
       const SMDS_MeshElement* f2 =
         SMESH_MeshEditor::FindFaceInSet( vNode, eNode, inSet, notInSet );
@@ -1128,7 +1129,7 @@ TopoDS_Shape StdMeshers_ProjectionUtils::OuterShape( const TopoDS_Face& face,
 
 //================================================================================
   /*!
-   * \brief Check that submeshis is computed and try to compute it if is not
+   * \brief Check that submesh is computed and try to compute it if is not
     * \param sm - submesh to compute
     * \param iterationNb - int used to stop infinite recursive call
     * \retval bool - true if computed
@@ -1221,21 +1222,87 @@ int StdMeshers_ProjectionUtils::Count(const TopoDS_Shape&    shape,
   }
 }
 
-      // bull shit
-//       Standard_Real f1,l1, f2,l2;
-//       BRep_Tool::Range( edge1, f1,l1 );
-//       BRep_Tool::Range( edge2, f2,l2 );
-//       BRepAdaptor_Curve e1( edge1 ), e2( edge2 );
-//       gp_Pnt pf1, pf2;
-//       gp_Vec dirX1, dirX2; // 1st derivatives
-//       e1.D1( f1, pf1, dirX1 );
-//       e2.D1( f2, pf2, dirX2 );
-//       gp_Pnt pm1 = e1.Value( 0.5 * ( f1 + l1 ));
-//       gp_Pnt pm2 = e2.Value( 0.5 * ( f2 + l2 ));
-//       gp_Vec dirZ1( pf1, pm1 ), dirZ2( pf2, pm2 );
-//       gp_Trsf trsf;
-//       gp_Ax3 fromSys( pf1, dirZ1, dirX1 ), toSys( pf2, dirZ2, dirX2 );
-//       trsf.SetTransformation( fromSys, toSys );
-//       dirX1.Transform( trsf );
-//       bool reverse = ( dirX1 * dirX2 < 0 );
-//       if ( reverse ) edge2.Reverse();
+namespace {
+
+  SMESH_subMeshEventListener* GetSrcSubMeshListener();
+
+  //================================================================================
+  /*!
+   * \brief Listener that resets an event listener on source submesh when 
+   * "ProjectionSource*D" hypothesis is modified
+   */
+  //================================================================================
+
+  struct HypModifWaiter: SMESH_subMeshEventListener
+  {
+    HypModifWaiter():SMESH_subMeshEventListener(0){} // won't be deleted by submesh
+
+    void ProcessEvent(const int event, const int eventType, SMESH_subMesh* subMesh,
+                      EventListenerData*, const SMESH_Hypothesis*)
+    {
+      if ( event     == SMESH_subMesh::MODIF_HYP &&
+           eventType == SMESH_subMesh::ALGO_EVENT)
+      {
+        // delete current source listener
+        subMesh->DeleteEventListener( GetSrcSubMeshListener() );
+        // let algo set a new one
+        SMESH_Gen* gen = subMesh->GetFather()->GetGen();
+        if ( SMESH_Algo* algo = gen->GetAlgo( *subMesh->GetFather(),
+                                              subMesh->GetSubShape() ))
+          algo->SetEventListener( subMesh );
+      }
+    }
+  };
+  //================================================================================
+  /*!
+   * \brief return static HypModifWaiter
+   */
+  //================================================================================
+
+  SMESH_subMeshEventListener* GetHypModifWaiter() {
+    static HypModifWaiter aHypModifWaiter;
+    return &aHypModifWaiter;
+  }
+  //================================================================================
+  /*!
+   * \brief return static listener for source shape submeshes
+   */
+  //================================================================================
+
+  SMESH_subMeshEventListener* GetSrcSubMeshListener() {
+    static SMESH_subMeshEventListener srcListener(0); // won't be deleted by submesh
+    return &srcListener;
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Set event listeners to submesh with projection algo
+ * \param subMesh - submesh with projection algo
+ * \param srcShape - source shape
+ * \param srcMesh - source mesh
+ */
+//================================================================================
+
+void StdMeshers_ProjectionUtils::SetEventListener(SMESH_subMesh* subMesh,
+                                                  TopoDS_Shape   srcShape,
+                                                  SMESH_Mesh*    srcMesh)
+{
+  // Set listener that resets an event listener on source submesh when
+  // "ProjectionSource*D" hypothesis is modified
+  subMesh->SetEventListener( GetHypModifWaiter(),0,subMesh);
+
+  // Set an event listener to submesh of the source shape
+  if ( !srcShape.IsNull() )
+  {
+    if ( !srcMesh )
+      srcMesh = subMesh->GetFather();
+
+    SMESH_subMesh* srcShapeSM = srcMesh->GetSubMesh( srcShape );
+
+    if ( srcShapeSM != subMesh )
+      subMesh->SetEventListener( GetSrcSubMeshListener(),
+                                 SMESH_subMeshEventListenerData::MakeData( subMesh ),
+                                 srcShapeSM );
+  }
+}
index ea7ed73d70cde9b87c7c7f888c7121e0285f1290..53064e7f14028e7f1e6238bc567397e34a2cccaa 100644 (file)
@@ -195,6 +195,16 @@ class STDMESHERS_EXPORT StdMeshers_ProjectionUtils
   static int Count(const TopoDS_Shape&    shape,
                    const TopAbs_ShapeEnum type,
                    const bool             ignoreSame);
+
+  /*!
+   * \brief Set event listeners to submesh with projection algo
+    * \param subMesh - submesh with projection algo
+    * \param srcShape - source shape
+    * \param srcMesh - source mesh
+   */
+  static void SetEventListener(SMESH_subMesh* subMesh,
+                               TopoDS_Shape   srcShape,
+                               SMESH_Mesh*    srcMesh);
 };
 
 #endif
index f487d83925d2e2a668e548eba35647bae3906c2e..1bfdc41c5a3db5df1be7bbeb0f09afcc6b4584c5 100644 (file)
@@ -41,6 +41,7 @@
 #include "SMESH_subMesh.hxx"
 #include "SMESH_subMeshEventListener.hxx"
 #include "SMESH_Gen.hxx"
+#include "SMESH_Comment.hxx"
 
 #include <BRepAdaptor_Curve.hxx>
 #include <BRep_Tool.hxx>
@@ -190,7 +191,7 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap );
   if ( !TAssocTool::FindSubShapeAssociation( tgtEdge, tgtMesh, srcEdge, srcMesh,
                                              shape2ShapeMap) )
-    RETURN_BAD_RESULT("FindSubShapeAssociation failed");
+    return error(dfltErr(),SMESH_Comment("Vertices association failed" ));
 
   // ----------------------------------------------
   // Assure that mesh on a source edge is computed
@@ -201,11 +202,11 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
 
   if ( tgtMesh == srcMesh ) {
     if ( !TAssocTool::MakeComputed( srcSubMesh ))
-      RETURN_BAD_RESULT("Impossible to compute the source mesh");
+      return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
   }
   else {
     if ( !srcSubMesh->IsMeshComputed() )
-      RETURN_BAD_RESULT("Source mesh is not computed");
+      return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
   }
   // -----------------------------------------------
   // Find out nodes distribution on the source edge
@@ -216,7 +217,7 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   
   vector< double > params; // sorted parameters of nodes on the source edge
   if ( !SMESH_Algo::GetNodeParamOnEdge( srcMesh->GetMeshDS(), srcEdge, params ))
-    RETURN_BAD_RESULT("Bad node params on the source edge");
+    return error(COMPERR_BAD_INPUT_MESH,"Bad node parameters on the source edge");
 
   int i, nbNodes = params.size();
 
@@ -248,20 +249,10 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   vector< const SMDS_MeshNode* > nodes ( nbNodes );
 
   // Get the first and last nodes
-  // -----------------------------
-
-  SMESHDS_SubMesh* smV0 = meshDS->MeshElements( tgtV[0] );
-  SMESHDS_SubMesh* smV1 = meshDS->MeshElements( tgtV[1] );
-  if ( !smV0 || !smV1 )
-    RETURN_BAD_RESULT("No submeshes on vertices");
-
-  SMDS_NodeIteratorPtr nItV0 = smV0->GetNodes();
-  SMDS_NodeIteratorPtr nItV1 = smV1->GetNodes();
-  if ( !nItV0->more() || !nItV1->more() )
-    RETURN_BAD_RESULT("No nodes on vertices");
-
-  nodes.front() = nItV0->next();
-  nodes.back()  = nItV1->next();
+  nodes.front() = VertexNode( tgtV[0], meshDS );
+  nodes.back()  = VertexNode( tgtV[1], meshDS );
+  if ( !nodes.front() || !nodes.back() )
+    return error(COMPERR_BAD_INPUT_MESH,"No node on vertex");
 
   // Compute parameters on the target edge and make internal nodes
   // --------------------------------------------------------------
@@ -284,7 +275,7 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
       // from the point at given parameter.
       GCPnts_AbscissaPoint Discret( curveAdaptor, dl * lengths[ i-1 ], tgtParams[ i-1 ] );
       if ( !Discret.IsDone() )
-        RETURN_BAD_RESULT(" GCPnts_AbscissaPoint failed");
+        return error(dfltErr(),"GCPnts_AbscissaPoint failed");
       tgtParams[ i ] = Discret.Parameter();
     }
     // make internal nodes 
@@ -324,7 +315,8 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   }
   // enough nodes to make all edges quadratic?
   if ( quadratic && ( nbNodes < 3 || ( nbNodes % 2 != 1 )))
-    RETURN_BAD_RESULT("Wrong nb nodes to make quadratic mesh");
+    return error(COMPERR_BAD_INPUT_MESH,
+                 SMESH_Comment("Wrong number of nodes to make quadratic mesh: ")<<nbNodes);
 
   // Create edges
   // -------------
@@ -357,19 +349,7 @@ bool StdMeshers_Projection_1D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
 
 void StdMeshers_Projection_1D::SetEventListener(SMESH_subMesh* subMesh)
 {
-  if ( _sourceHypo && ! _sourceHypo->GetSourceEdge().IsNull() )
-  {
-    SMESH_Mesh* srcMesh = _sourceHypo->GetSourceMesh();
-    if ( !srcMesh )
-      srcMesh = subMesh->GetFather();
-
-    SMESH_subMesh* srcEdgeSM =
-      srcMesh->GetSubMesh( _sourceHypo->GetSourceEdge() );
-
-    if ( srcEdgeSM != subMesh )
-      subMesh->SetEventListener( new SMESH_subMeshEventListener(true),
-                                 SMESH_subMeshEventListenerData::MakeData( subMesh ),
-                                 srcEdgeSM );
-  }
+  TAssocTool::SetEventListener( subMesh,
+                                _sourceHypo->GetSourceEdge(),
+                                _sourceHypo->GetSourceMesh() );
 }
-  
index b7b3ff3e61004ecf2fc68d354e14ee3d2cb644c1..4aa83bdd0c30c2482d9e7385284911119602d00b 100644 (file)
@@ -41,6 +41,7 @@
 #include "SMESH_Pattern.hxx"
 #include "SMESH_subMesh.hxx"
 #include "SMESH_subMeshEventListener.hxx"
+#include "SMESH_Comment.hxx"
 #include "SMDS_EdgePosition.hxx"
 
 #include "utilities.h"
@@ -223,10 +224,9 @@ namespace {
         // do not break but iterate over DependsOn()
       }
       default:
-        const map< int, SMESH_subMesh * >& subSM = sm->DependsOn();
-        map< int, SMESH_subMesh * >::const_iterator i_sm = subSM.begin();
-        for ( ; i_sm != subSM.end(); ++i_sm )
-          Clean( i_sm->second );
+        SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(false,false);
+        while ( smIt->more() )
+          Clean( smIt->next() );
       }
     }
   };
@@ -386,7 +386,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   TAssocTool::InitVertexAssociation( _sourceHypo, shape2ShapeMap );
   if ( !TAssocTool::FindSubShapeAssociation( tgtFace, tgtMesh, srcFace, srcMesh,
                                              shape2ShapeMap) )
-    RETURN_BAD_RESULT("FindSubShapeAssociation failed");
+    return error(COMPERR_BAD_SHAPE,"Topology of source and target faces seems different" );
 
   // ----------------------------------------------
   // Assure that mesh on a source Face is computed
@@ -397,11 +397,11 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
 
   if ( tgtMesh == srcMesh ) {
     if ( !TAssocTool::MakeComputed( srcSubMesh ))
-      RETURN_BAD_RESULT("Impossible to compute the source mesh");
+      return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
   }
   else {
     if ( !srcSubMesh->IsMeshComputed() )
-      RETURN_BAD_RESULT("Source mesh is not computed");
+      return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
   }
 
   // --------------------
@@ -412,7 +412,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   SMESH_Pattern mapper;
   mapper.Load( srcMesh, srcFace );
   if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK )
-    RETURN_BAD_RESULT("SMESH_Pattern::Load() failed");
+    return error(COMPERR_BAD_INPUT_MESH,"Can't load mesh pattern from the source face");
 
   // Find the first target vertex corresponding to first vertex of the <mapper>
   // and <theReverse> flag needed to call mapper.Apply()
@@ -463,14 +463,14 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
 
   mapper.Apply( tgtFace, tgtV1, reverse );
   if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK )
-    RETURN_BAD_RESULT("SMESH_Pattern::Apply() failed");
+    return error(dfltErr(),"Can't apply source mesh pattern to the face");
 
   // Create the mesh
 
   const bool toCreatePolygons = false, toCreatePolyedrs = false;
   mapper.MakeMesh( tgtMesh, toCreatePolygons, toCreatePolyedrs );
   if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK )
-    RETURN_BAD_RESULT("SMESH_Pattern::MakeMesh() failed");
+    return error(dfltErr(),"Can't make mesh by source mesh pattern");
 
   // it will remove mesh built by pattern mapper on edges and vertices
   // in failure case
@@ -487,11 +487,10 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
   // Make groups of nodes to merge
 
   // loop on edge and vertex submeshes of a target face
-  const map< int, SMESH_subMesh * >& subSM = tgtSubMesh->DependsOn();
-  map< int, SMESH_subMesh * >::const_iterator i_subSM = subSM.begin();
-  for ( ; i_subSM != subSM.end(); ++i_subSM )
+  SMESH_subMeshIteratorPtr smIt = tgtSubMesh->getDependsOnIterator(false,false);
+  while ( smIt->more() )
   {
-    SMESH_subMesh*     sm = i_subSM->second;
+    SMESH_subMesh*     sm = smIt->next();
     SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
 
     // Sort new and old nodes of a submesh separately
@@ -626,17 +625,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape&
 
 void StdMeshers_Projection_2D::SetEventListener(SMESH_subMesh* subMesh)
 {
-  if ( _sourceHypo && ! _sourceHypo->GetSourceFace().IsNull() )
-  {
-    SMESH_Mesh* srcMesh = _sourceHypo->GetSourceMesh();
-    if ( !srcMesh )
-      srcMesh = subMesh->GetFather();
-
-    SMESH_subMesh* srcFaceSM =
-      srcMesh->GetSubMesh( _sourceHypo->GetSourceFace() );
-
-    subMesh->SetEventListener( new SMESH_subMeshEventListener(true),
-                               SMESH_subMeshEventListenerData::MakeData( subMesh ),
-                               srcFaceSM );
-  }
+  TAssocTool::SetEventListener( subMesh,
+                                _sourceHypo->GetSourceFace(),
+                                _sourceHypo->GetSourceMesh() );
 }
index 241ff7670c79096f8431f5eb7d30106e923cf793..68eda5d6593ea297364697efd0f8b1d9b276a54b 100644 (file)
@@ -42,6 +42,7 @@
 #include "SMESH_subMesh.hxx"
 #include "SMESH_subMeshEventListener.hxx"
 #include "SMESH_MesherHelper.hxx"
+#include "SMESH_Comment.hxx"
 #include "SMDS_VolumeTool.hxx"
 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
 
@@ -204,13 +205,15 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
   for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell )
     srcShell = TopoDS::Shell( exp.Current() );
   if ( nbShell != 1 )
-    RETURN_BAD_RESULT("There must be 1 shell in the source shape");
+    return error(COMPERR_BAD_SHAPE,
+                 SMESH_Comment("Shape must have 1 shell but not") << nbShell);
 
   exp.Init( aShape, TopAbs_SHELL );
   for ( nbShell = 0; exp.More(); exp.Next(), ++nbShell )
     tgtShell = TopoDS::Shell( exp.Current() );
   if ( nbShell != 1 )
-    RETURN_BAD_RESULT("There must be 1 shell in the target shape");
+    return error(COMPERR_BAD_SHAPE,
+                 SMESH_Comment("Shape must have 1 shell but not") << nbShell);
 
   // Assure that mesh on a source shape is computed
 
@@ -219,11 +222,11 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
 
   if ( tgtMesh == srcMesh && !aShape.IsSame( _sourceHypo->GetSource3DShape() )) {
     if ( !TAssocTool::MakeComputed( srcSubMesh ))
-      RETURN_BAD_RESULT("Impossible to compute the source mesh");
+      return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
   }
   else {
     if ( !srcSubMesh->IsMeshComputed() )
-      RETURN_BAD_RESULT("Source mesh is not computed");
+      return error(COMPERR_BAD_INPUT_MESH,"Source mesh not computed");
   }
 
   // Find 2 pairs of corresponding vertices
@@ -242,18 +245,18 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
   {
     if ( !TAssocTool::FindSubShapeAssociation( tgtShell, tgtMesh, srcShell, srcMesh,
                                                shape2ShapeMap) )
-      RETURN_BAD_RESULT("FindSubShapeAssociation() failed");
+      return error(COMPERR_BAD_SHAPE,"Topology of source and target shapes seems different" );
 
     exp.Init( tgtShell, TopAbs_EDGE );
     TopExp::Vertices( TopoDS::Edge( exp.Current() ), tgtV000, tgtV100 );
 
     if ( !shape2ShapeMap.IsBound( tgtV000 ) || !shape2ShapeMap.IsBound( tgtV100 ))
-      RETURN_BAD_RESULT("Shape associating not done");
+      return error(dfltErr(),"Association of subshapes failed" );
     srcV000 = TopoDS::Vertex( shape2ShapeMap( tgtV000 ));
     srcV100 = TopoDS::Vertex( shape2ShapeMap( tgtV100 ));
     if ( !TAssocTool::IsSubShape( srcV000, srcShell ) ||
          !TAssocTool::IsSubShape( srcV100, srcShell ))
-      RETURN_BAD_RESULT("Wrong target vertices");
+      return error(dfltErr(),"Incorrect association of subshapes" );
   }
 
   // Load 2 SMESH_Block's with src and tgt shells
@@ -261,10 +264,10 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
   SMESH_Block srcBlock, tgtBlock;
   TopTools_IndexedMapOfOrientedShape scrShapes, tgtShapes;
   if ( !tgtBlock.LoadBlockShapes( tgtShell, tgtV000, tgtV100, tgtShapes ))
-    RETURN_BAD_RESULT("SMESH_Block::LoadBlockShapes(tgtShell) failed");
+    return error(COMPERR_BAD_SHAPE, "Can't detect block subshapes. Not a block?");
 
   if ( !srcBlock.LoadBlockShapes( srcShell, srcV000, srcV100, scrShapes ))
-    RETURN_BAD_RESULT("SMESH_Block::LoadBlockShapes(srcShell) failed");
+    return error(COMPERR_BAD_SHAPE, "Can't detect block subshapes. Not a block?");
 
   // Find matching nodes of src and tgt shells
 
@@ -293,9 +296,9 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
     TNodeNodeMap faceMatchingNodes;
     if ( ! TAssocTool::FindMatchingNodesOnFaces( srcFace, srcMesh, tgtFace, tgtMesh, 
                                                  shape2ShapeMap, faceMatchingNodes ))
-      RETURN_BAD_RESULT("Different mesh on corresponding src and tgt faces: "
-                        << srcMeshDS->ShapeToIndex( srcFace ) << " and "
-                        << tgtMeshDS->ShapeToIndex( tgtFace ));
+    return error(COMPERR_BAD_INPUT_MESH,SMESH_Comment("Mesh on faces #")
+                 << srcMeshDS->ShapeToIndex( srcFace ) << " and "
+                 << tgtMeshDS->ShapeToIndex( tgtFace ) << " seems different" );
 
     // put found matching nodes of 2 faces to the global map
     src2tgtNodeMap.insert( faceMatchingNodes.begin(), faceMatchingNodes.end() );
@@ -339,11 +342,12 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
         gp_Pnt srcCoord = gpXYZ( srcNode );
         gp_XYZ srcParam;
         if ( !srcBlock.ComputeParameters( srcCoord, srcParam ))
-          RETURN_BAD_RESULT("srcBlock.ComputeParameters() failed");
+          return error(dfltErr(),SMESH_Comment("Can't compute normalized parameters ")
+                       << "for source node " << srcNode->GetID());
         // compute coordinates of target node by srcParam
         gp_XYZ tgtXYZ;
         if ( !tgtBlock.ShellPoint( srcParam, tgtXYZ ))
-          RETURN_BAD_RESULT("tgtBlock.ShellPoint() failed");
+          return error(dfltErr(),"Can't compute coordinates by normalized parameters");
         // add node
         SMDS_MeshNode* newNode = tgtMeshDS->AddNode( tgtXYZ.X(), tgtXYZ.Y(), tgtXYZ.Z() );
         tgtMeshDS->SetNodeInVolume( newNode, helper.GetSubShapeID() );
@@ -356,20 +360,21 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
     // Create a new volume
 
     SMDS_MeshVolume * tgtVol = 0;
+    int id = 0, force3d = false;
     switch ( volType ) {
     case SMDS_VolumeTool::TETRA     :
     case SMDS_VolumeTool::QUAD_TETRA:
       tgtVol = helper.AddVolume( nodes[0],
                                  nodes[1],
                                  nodes[2],
-                                 nodes[3]); break;
+                                 nodes[3], id, force3d); break;
     case SMDS_VolumeTool::PYRAM     :
     case SMDS_VolumeTool::QUAD_PYRAM:
       tgtVol = helper.AddVolume( nodes[0],
                                  nodes[1],
                                  nodes[2],
                                  nodes[3],
-                                 nodes[4]); break;
+                                 nodes[4], id, force3d); break;
     case SMDS_VolumeTool::PENTA     :
     case SMDS_VolumeTool::QUAD_PENTA:
       tgtVol = helper.AddVolume( nodes[0],
@@ -377,7 +382,7 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
                                  nodes[2],
                                  nodes[3],
                                  nodes[4],
-                                 nodes[5]); break;
+                                 nodes[5], id, force3d); break;
     case SMDS_VolumeTool::HEXA      :
     case SMDS_VolumeTool::QUAD_HEXA :
       tgtVol = helper.AddVolume( nodes[0],
@@ -387,16 +392,13 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
                                  nodes[4],
                                  nodes[5],
                                  nodes[6],
-                                 nodes[7]); break;
+                                 nodes[7], id, force3d); break;
     default: // polyhedron
       const SMDS_PolyhedralVolumeOfNodes * poly =
         dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>( srcVol );
       if ( !poly )
         RETURN_BAD_RESULT("Unexpected volume type");
-      vector<int> quantities( poly->NbFaces(), 0 );
-      for ( int i = 0; i < quantities.size(); ++i )
-        quantities[ i ] = poly->NbFaceNodes( i + 1 );
-      tgtVol = tgtMeshDS->AddPolyhedralVolume( nodes, quantities );
+      tgtVol = tgtMeshDS->AddPolyhedralVolume( nodes, poly->GetQuanities() );
     }
     if ( tgtVol ) {
       tgtMeshDS->SetMeshElementOnShape( tgtVol, helper.GetSubShapeID() );
@@ -420,19 +422,8 @@ bool StdMeshers_Projection_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aS
 
 void StdMeshers_Projection_3D::SetEventListener(SMESH_subMesh* subMesh)
 {
-  if ( _sourceHypo && ! _sourceHypo->GetSource3DShape().IsNull() )
-  {
-    SMESH_Mesh* srcMesh = _sourceHypo->GetSourceMesh();
-    if ( !srcMesh )
-      srcMesh = subMesh->GetFather();
-
-    SMESH_subMesh* srcShapeSM =
-      srcMesh->GetSubMesh( _sourceHypo->GetSource3DShape() );
-
-    if ( srcShapeSM != subMesh )
-      subMesh->SetEventListener( new SMESH_subMeshEventListener(true),
-                                 SMESH_subMeshEventListenerData::MakeData( subMesh ),
-                                 srcShapeSM );
-  }
+  TAssocTool::SetEventListener( subMesh,
+                                _sourceHypo->GetSource3DShape(),
+                                _sourceHypo->GetSourceMesh() );
 }
   
index 2591d309d49f73e2a62f2fdf5e6709517a536950..2b701a07ace79d8d21b4caf305e25eed1c610d02 100644 (file)
 
 #include "utilities.h"
 
+#include "SMESH_Mesh.hxx"
+#include "SMESH_subMesh.hxx"
+#include "SMESH_HypoFilter.hxx"
+#include "SMDS_SetIterator.hxx"
+
 using namespace std;
 
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-StdMeshers_Propagation::StdMeshers_Propagation (int hypId, int studyId,
-                                                SMESH_Gen * gen)
-     : SMESH_Hypothesis(hypId, studyId, gen)
-{
-  _name = GetName();
-  _param_algo_dim = -1; // 1D auxiliary
-}
+namespace {
 
-//=============================================================================
-/*!
- *
- */
-//=============================================================================
-StdMeshers_Propagation::~StdMeshers_Propagation()
-{
+  // =======================================================================
+  /*!
+   * \brief Listener managing propagation of 1D hypotheses
+   */
+  // =======================================================================
+
+  class PropagationMgr: public SMESH_subMeshEventListener
+  {
+  public:
+    static PropagationMgr* GetListener();
+    /*!
+     * \brief Set listener on edge submesh
+     */
+    static void Set(SMESH_subMesh * submesh);
+    /*!
+     * \brief Return an edge from which hypotheses are propagated from
+     */
+    static TopoDS_Edge GetSource(SMESH_subMesh * submesh);
+    /*!
+     * \brief Does it's main job
+     */
+    void ProcessEvent(const int          event,
+                      const int          eventType,
+                      SMESH_subMesh*     subMesh,
+                      SMESH_subMeshEventListenerData* data,
+                      const SMESH_Hypothesis*         hyp = 0);
+  private:
+    PropagationMgr();
+  };
 }
 
 //=============================================================================
 /*!
- *
+ * StdMeshers_Propagation Implementation
  */
 //=============================================================================
 
-ostream & StdMeshers_Propagation::SaveTo (ostream & save)
+StdMeshers_Propagation::StdMeshers_Propagation (int hypId, int studyId, SMESH_Gen * gen)
+  : SMESH_Hypothesis(hypId, studyId, gen)
 {
-  return save;
+  _name = GetName();
+  _param_algo_dim = -1; // 1D auxiliary
 }
-
-//=============================================================================
+StdMeshers_Propagation::~StdMeshers_Propagation()                      {}
+string StdMeshers_Propagation::GetName ()                              { return "Propagation"; }
+ostream & StdMeshers_Propagation::SaveTo (ostream & save)              { return save; }
+istream & StdMeshers_Propagation::LoadFrom (istream & load)            { return load; }
+ostream & operator << (ostream & save, StdMeshers_Propagation & hyp)   { return hyp.SaveTo(save); }
+istream & operator >> (istream & load, StdMeshers_Propagation & hyp)   { return hyp.LoadFrom(load); }
+bool StdMeshers_Propagation::SetParametersByMesh(const SMESH_Mesh*,
+                                                 const TopoDS_Shape& ) { return false; }
+void StdMeshers_Propagation::SetPropagationMgr(SMESH_subMesh* subMesh) { PropagationMgr::Set( subMesh ); }
 /*!
- *
+ * \brief Return an edge from which hypotheses are propagated from
  */
-//=============================================================================
-istream & StdMeshers_Propagation::LoadFrom (istream & load)
+TopoDS_Edge StdMeshers_Propagation::GetPropagationSource(SMESH_Mesh& theMesh,
+                                                         const TopoDS_Shape& theEdge)
 {
-  return load;
+  return PropagationMgr::GetSource(theMesh.GetSubMeshContaining( theEdge ));
 }
 
 //=============================================================================
-/*!
- *
- */
 //=============================================================================
-ostream & operator << (ostream & save, StdMeshers_Propagation & hyp)
-{
-  return hyp.SaveTo(save);
-}
-
+// PROPAGATION MANAGEMENT
 //=============================================================================
-/*!
- *
- */
 //=============================================================================
-istream & operator >> (istream & load, StdMeshers_Propagation & hyp)
-{
-  return hyp.LoadFrom(load);
-}
 
-//=============================================================================
-/*!
- *  GetName
- */
-//=============================================================================
-std::string StdMeshers_Propagation::GetName ()
-{
-  return "Propagation";
-}
-//================================================================================
-/*!
- * \brief Initialize my parameter values by the mesh built on the geometry
- * \param theMesh - the built mesh
- * \param theShape - the geometry of interest
- * \retval bool - true if parameter values have been successfully defined
- *
- * Just return false as this hypothesis does not have parameters values
- */
-//================================================================================
+namespace {
 
-bool StdMeshers_Propagation::SetParametersByMesh(const SMESH_Mesh* /*theMesh*/,
-                                                 const TopoDS_Shape& /*theShape*/)
-{
-  return false;
-}
+  enum SubMeshState { WAIT_PROPAG_HYP, // no propagation hyp in chain
+                      HAS_PROPAG_HYP,  // propag hyp on this submesh
+                      IN_CHAIN,        // submesh is in propagation chain
+                      LAST_IN_CHAIN,   // submesh with local 1D hyp breaking a chain
+                      MEANINGLESS_LAST };          // meaningless
+
+  struct PropagationMgrData : public EventListenerData
+  {
+    bool myForward; //!< true if a curve of edge in chain is codirected with one of source edge
+    PropagationMgrData( SubMeshState state ): EventListenerData(true) {
+      myType = state;
+    }
+    SubMeshState State() const {
+      return (SubMeshState) myType;
+    }
+    void SetSource(SMESH_subMesh* sm ) {
+      mySubMeshes.clear(); if ( sm ) mySubMeshes.push_back( sm );
+    }
+    void SetChain(list< SMESH_subMesh* >& chain ) {
+      mySubMeshes.clear(); mySubMeshes.splice( mySubMeshes.end(), chain );
+    }
+    SMESH_subMeshIteratorPtr GetChain() const;
+    SMESH_subMesh* GetSource() const;
+  };
+
+  //=============================================================================
+  /*!
+   * \brief return filter to find Propagation hypothesis
+   */
+  SMESH_HypoFilter & propagHypFilter()
+  {
+    static SMESH_HypoFilter propagHypFilter
+      ( SMESH_HypoFilter::HasName( StdMeshers_Propagation::GetName ()));
+    return propagHypFilter;
+  }
+  //=============================================================================
+  /*!
+   * \brief return static PropagationMgr
+   */
+  PropagationMgr* PropagationMgr::GetListener()
+  {
+    static PropagationMgr theListener;
+    return &theListener;
+  }
+  PropagationMgr* getListener()
+  {
+    return PropagationMgr::GetListener();
+  }
+  //=============================================================================
+  /*!
+   * \brief return PropagationMgrData
+   */
+  PropagationMgrData* getData(SMESH_subMesh* sm)
+  {
+    if ( sm )
+      return static_cast< PropagationMgrData* >( sm->GetEventListenerData( getListener() ));
+    return 0;
+  }
+  //=============================================================================
+  /*!
+   * \brief return PropagationMgrData
+   */
+  PropagationMgrData* getData(SMESH_Mesh& theMesh, const TopoDS_Shape& theEdge)
+  {
+    if ( theEdge.ShapeType() == TopAbs_EDGE )
+      return getData( theMesh.GetSubMeshContaining( theEdge ) );
+    return 0;
+  }
+  //================================================================================
+  /*!
+   * \brief Return an iterator on a chain
+   */
+  SMESH_subMeshIteratorPtr PropagationMgrData::GetChain() const
+  {
+    typedef SMESH_subMesh* TsubMesh;
+    typedef SMDS_SetIterator< TsubMesh, list< TsubMesh >::const_iterator > TIterator;
+    switch ( State() ) {
+    case HAS_PROPAG_HYP:
+      return SMESH_subMeshIteratorPtr
+        ( new TIterator( mySubMeshes.begin(), mySubMeshes.end() ));
+    case IN_CHAIN:
+    case LAST_IN_CHAIN:
+      if ( mySubMeshes.empty() ) break;
+      return getData( mySubMeshes.front() )->GetChain();
+    default:;
+    }
+    return SMESH_subMeshIteratorPtr
+      ( new TIterator( mySubMeshes.end(), mySubMeshes.end() ));
+  }
+  //================================================================================
+  /*!
+   * \brief Return a propagation source submesh
+   */
+  SMESH_subMesh* PropagationMgrData::GetSource() const
+  {
+    if ( myType == IN_CHAIN || myType == LAST_IN_CHAIN )
+      if ( !mySubMeshes.empty() ) 
+        return mySubMeshes.front();
+    return 0;
+  }
+  //=============================================================================
+  /*!
+   * \brief Returns a local 1D hypothesis used for theEdge
+   */
+  const SMESH_Hypothesis* isLocal1DHypothesis (SMESH_Mesh& theMesh,
+                                               const TopoDS_Shape& theEdge)
+  {
+    static SMESH_HypoFilter hypo ( SMESH_HypoFilter::HasDim( 1 ));
+    hypo.AndNot( hypo.IsAlgo() ).AndNot( hypo.IsAssignedTo( theMesh.GetMeshDS()->ShapeToMesh() ));
+
+    return theMesh.GetHypothesis( theEdge, hypo, true );
+  }
+  //================================================================================
+  /*!
+   * \brief Build propagation chain
+    * \param theMainSubMesh - the submesh with Propagation hypothesis
+   */
+  bool buildPropagationChain ( SMESH_subMesh* theMainSubMesh )
+  {
+  //   const TopoDS_Shape& theMainEdge = theMainSubMesh->GetSubShape();
+//     if (theMainEdge.ShapeType() != TopAbs_EDGE) return true;
+
+//     SMESH_Mesh* mesh = theMainSubMesh->GetFather();
+
+//     EventListenerData* chainData = new PropagationMgrData(HAS_PROPAG_HYP);
+//     theMainSubMesh->SetEventListener( getListener(), chainData, theMainSubMesh );
+
+//     // Edges submeshes, on which the 1D hypothesis will be propagated from <theMainEdge>
+//     list<SMESH_subMesh*> & chain = chainData->mySubMeshes;
+
+//     // List of edges, added to chain on the previous cycle pass
+//     TopTools_ListOfShape listPrevEdges;
+//     listPrevEdges.Append(theMainEdge.Oriented( TopAbs_FORWARD ));
+
+//     //   4____3____2____3____4____5
+//     //   |    |    |    |    |    |      Number in the each knot of
+//     //   |    |    |    |    |    |      grid indicates cycle pass,
+//     //   3____2____1____2____3____4      on which corresponding edge
+//     //   |    |    |    |    |    |      (perpendicular to the plane
+//     //   |    |    |    |    |    |      of view) will be found.
+//     //   2____1____0____1____2____3
+//     //   |    |    |    |    |    |
+//     //   |    |    |    |    |    |
+//     //   3____2____1____2____3____4
+
+//     // Collect all edges pass by pass
+//     while (listPrevEdges.Extent() > 0) {
+//       // List of edges, added to chain on this cycle pass
+//       TopTools_ListOfShape listCurEdges;
+
+//       // Find the next portion of edges
+//       TopTools_ListIteratorOfListOfShape itE (listPrevEdges);
+//       for (; itE.More(); itE.Next()) {
+//         TopoDS_Shape anE = itE.Value();
+
+//         // Iterate on faces, having edge <anE>
+//         TopTools_ListIteratorOfListOfShape itA (mesh->GetAncestors(anE));
+//         for (; itA.More(); itA.Next()) {
+//           TopoDS_Shape aW = itA.Value();
+
+//           // There are objects of different type among the ancestors of edge
+//           if (aW.ShapeType() == TopAbs_WIRE) {
+//             TopoDS_Shape anOppE;
+
+//             BRepTools_WireExplorer aWE (TopoDS::Wire(aW));
+//             Standard_Integer nb = 1, found = 0;
+//             TopTools_Array1OfShape anEdges (1,4);
+//             for (; aWE.More(); aWE.Next(), nb++) {
+//               if (nb > 4) {
+//                 found = 0;
+//                 break;
+//               }
+//               anEdges(nb) = aWE.Current();
+//               if (!_mapAncestors.Contains(anEdges(nb))) {
+//                 MESSAGE("WIRE EXPLORER HAVE GIVEN AN INVALID EDGE !!!");
+//                 break;
+//               }
+//               if (anEdges(nb).IsSame(anE)) found = nb;
+//             }
+
+//             if (nb == 5 && found > 0) {
+//               // Quadrangle face found, get an opposite edge
+//               Standard_Integer opp = ( found + 2 ) % 4;
+//               anOppE = anEdges(opp);
+
+//               // add anOppE to aChain if ...
+//               PropagationMgrData* data = getData( *mesh, anOppE );
+//               if ( !data || data->State() == WAIT_PROPAG_HYP ) { // ... anOppE is not in any chain
+//                 if ( !isLocal1DHypothesis( *mesh, anOppE )) { // ... no other 1d hyp on anOppE
+//                   // Add found edge to the chain oriented so that to
+//                   // have it co-directed with a forward MainEdge
+//                     TopAbs_Orientation ori = anE.Orientation();
+//                     if ( anEdges(opp).Orientation() == anEdges(found).Orientation() )
+//                       ori = TopAbs::Reverse( ori );
+//                     anOppE.Orientation( ori );
+//                     aChain.Add(anOppE);
+//                     listCurEdges.Append(anOppE);
+//                   }
+//                   else {
+//                     // Collision!
+//                     MESSAGE("Error: Collision between propagated hypotheses");
+//                     CleanMeshOnPropagationChain(theMainEdge);
+//                     aChain.Clear();
+//                     return ( aMainHyp == isLocal1DHypothesis(aMainEdgeForOppEdge) );
+//                   }
+//                 }
+//               }
+//             } // if (nb == 5 && found > 0)
+//           } // if (aF.ShapeType() == TopAbs_WIRE)
+//         } // for (; itF.More(); itF.Next())
+//       } // for (; itE.More(); itE.Next())
+
+//       listPrevEdges = listCurEdges;
+//     } // while (listPrevEdges.Extent() > 0)
+
+//     CleanMeshOnPropagationChain(theMainEdge);
+    return true;
+  }
+  //================================================================================
+  /*!
+   * \brief Clear propagation chain
+   */
+  //================================================================================
+
+  bool clearPropagationChain( SMESH_subMesh* subMesh )
+  {
+    if ( PropagationMgrData* data = getData( subMesh )) {
+      if ( data->State() == IN_CHAIN )
+        return clearPropagationChain( data->GetSource() );
+      return true;
+    }
+    return false;
+  }  
+
+
+  //================================================================================
+  /*!
+   * \brief Constructor
+   */
+  PropagationMgr::PropagationMgr()
+    : SMESH_subMeshEventListener( false ) // won't be deleted by submesh
+  {}
+  //================================================================================
+  /*!
+   * \brief Set PropagationMgr on a submesh
+   */
+  void PropagationMgr::Set(SMESH_subMesh * submesh)
+  {
+    EventListenerData* data = EventListenerData::MakeData(submesh,WAIT_PROPAG_HYP);
+
+    submesh->SetEventListener( getListener(), data, submesh );
+
+    const SMESH_Hypothesis * propagHyp =
+      submesh->GetFather()->GetHypothesis( submesh->GetSubShape(), propagHypFilter(), true );
+    if ( propagHyp )
+      getListener()->ProcessEvent( SMESH_subMesh::ADD_HYP,
+                                   SMESH_subMesh::ALGO_EVENT,
+                                   submesh,
+                                   data,
+                                   propagHyp);
+  }
+
+  //================================================================================
+  /*!
+   * \brief React on events on 1D submeshes
+   */
+  //================================================================================
+
+  void PropagationMgr::ProcessEvent(const int          event,
+                                    const int          eventType,
+                                    SMESH_subMesh*     subMesh,
+                                    SMESH_subMeshEventListenerData* data,
+                                    const SMESH_Hypothesis*         hyp)
+  {
+    if ( !data )
+      return;
+    if ( !hyp || hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO || hyp->GetDim() != 1 )
+      return;
+    if ( eventType != SMESH_subMesh::ALGO_EVENT )
+      return;
+
+    bool isPropagHyp = ( StdMeshers_Propagation::GetName() != hyp->GetName() );
+
+    switch ( data->myType ) {
+
+    case WAIT_PROPAG_HYP: { // no propagation hyp in chain
+      // --------------------------------------------------------
+      if ( !isPropagHyp )
+        return;
+      if ( !isLocal1DHypothesis( *subMesh->GetFather(), subMesh->GetSubShape()))
+        return;
+      if ( event == SMESH_subMesh::ADD_HYP ||
+           event == SMESH_subMesh::ADD_FATHER_HYP ) // add propagation hyp
+      {
+        // build propagation chain
+        clearPropagationChain( subMesh );
+        buildPropagationChain( subMesh );
+      }
+      return;
+    }
+    case HAS_PROPAG_HYP: {  // propag hyp on this submesh
+      // --------------------------------------------------------
+      switch ( event ) {
+      case SMESH_subMesh::REMOVE_HYP:
+      case SMESH_subMesh::REMOVE_FATHER_HYP: // remove propagation hyp
+        if ( isPropagHyp )
+        {
+          // clear propagation chain
+        }
+        return;
+      case SMESH_subMesh::MODIF_HYP: // hyp modif
+        // clear mesh in a chain
+        return;
+      }
+      return;
+    }
+    case IN_CHAIN: {       // submesh is in propagation chain
+      // --------------------------------------------------------
+      if ( event == SMESH_subMesh::ADD_HYP ) // add local hypothesis
+        if ( isPropagHyp )
+          ; // collision
+        else
+          ; // rebuild propagation chain
+        return;
+    }
+    case LAST_IN_CHAIN: { // submesh with local 1D hyp, breaking a chain
+      // --------------------------------------------------------
+      if ( event == SMESH_subMesh::REMOVE_HYP ) // remove local hyp
+        ; // rebuild propagation chain
+      return;
+    }
+    } // switch by SubMeshState
+  }
+} // namespace
index 3f6fb714a6adb52335322aa1e35f866c97976c86..c0d2f3cdf8a920837b5c3874e2d13ffe3098aee7 100644 (file)
 #include "SMESH_StdMeshers.hxx"
 
 #include "SMESH_Hypothesis.hxx"
+#include "SMESH_subMeshEventListener.hxx"
 #include "Utils_SALOME_Exception.hxx"
 
+#include <TopoDS_Edge.hxx>
+
+
+// =======================================================================
+/*!
+ * \brief Propagation hypothesis
+ */
+// =======================================================================
+
 class STDMESHERS_EXPORT StdMeshers_Propagation:public SMESH_Hypothesis
 {
  public:
@@ -45,6 +55,22 @@ class STDMESHERS_EXPORT StdMeshers_Propagation:public SMESH_Hypothesis
 
   static std::string GetName ();
 
+  /*!
+   * \brief Set EventListener managing propagation of hypotheses
+    * \param subMesh - edge submesh to set event listener on
+   * 
+   * 1D algo is expected to call this method from it's SetEventListener()
+   */
+  static void SetPropagationMgr(SMESH_subMesh* subMesh);
+
+  /*!
+   * \brief Return an edge from which hypotheses are propagated from
+    * \param theMesh - mesh
+    * \param theEdge - edge to which hypotheses are propagated
+    * \retval TopoDS_Edge - source edge, also passing orientation
+   */
+  static TopoDS_Edge GetPropagationSource(SMESH_Mesh& theMesh, const TopoDS_Shape& theEdge);
+
   /*!
    * \brief Initialize my parameter values by the mesh built on the geometry
     * \param theMesh - the built mesh
@@ -55,5 +81,4 @@ class STDMESHERS_EXPORT StdMeshers_Propagation:public SMESH_Hypothesis
    */
   virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape);
 };
-
 #endif
index 15dcdb4359c0806075912ba90b60870e280c324e..0b0d057ed58edecc2ec47bb650894210a645514f 100644 (file)
 //  $Header$
 
 #include "StdMeshers_Quadrangle_2D.hxx"
+
+#include "StdMeshers_FaceSide.hxx"
+
 #include "SMESH_Gen.hxx"
 #include "SMESH_Mesh.hxx"
 #include "SMESH_subMesh.hxx"
+#include "SMESH_MesherHelper.hxx"
+#include "SMESH_Block.hxx"
+#include "SMESH_Comment.hxx"
 
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
 #include "SMDS_EdgePosition.hxx"
 #include "SMDS_FacePosition.hxx"
 
+#include <BRepAdaptor_Curve.hxx>
 #include <BRep_Tool.hxx>
+#include <BRepLProp.hxx>
 #include <BRepTools.hxx>
 #include <BRepTools_WireExplorer.hxx>
-
 #include <Geom_Surface.hxx>
 #include <Geom_Curve.hxx>
 #include <Geom2d_Curve.hxx>
 #include <GeomAdaptor_Curve.hxx>
 #include <GCPnts_UniformAbscissa.hxx>
 #include <TopExp.hxx>
-
 #include <Precision.hxx>
 #include <gp_Pnt2d.hxx>
 #include <TColStd_ListIteratorOfListOfInteger.hxx>
 #include <TColStd_SequenceOfReal.hxx>
 #include <TColgp_SequenceOfXY.hxx>
+#include <NCollection_DefineArray2.hxx>
 
 #include "utilities.h"
 #include "Utils_ExceptHandlers.hxx"
@@ -60,7 +67,6 @@
 #ifndef StdMeshers_Array2OfNode_HeaderFile
 #define StdMeshers_Array2OfNode_HeaderFile
 typedef const SMDS_MeshNode* SMDS_MeshNodePtr;
-#include <NCollection_DefineArray2.hxx>
 DEFINE_BASECOLLECTION (StdMeshers_BaseCollectionNodePtr, SMDS_MeshNodePtr)
 DEFINE_ARRAY2(StdMeshers_Array2OfNode,
               StdMeshers_BaseCollectionNodePtr, SMDS_MeshNodePtr)
@@ -68,6 +74,9 @@ DEFINE_ARRAY2(StdMeshers_Array2OfNode,
 
 using namespace std;
 
+typedef gp_XY gp_UV;
+typedef SMESH_Comment TComm;
+
 //=============================================================================
 /*!
  *  
@@ -93,8 +102,6 @@ StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D (int hypId, int studyId, SMES
 StdMeshers_Quadrangle_2D::~StdMeshers_Quadrangle_2D()
 {
   MESSAGE("StdMeshers_Quadrangle_2D::~StdMeshers_Quadrangle_2D");
-  if ( myTool )
-    delete myTool;
 }
 
 //=============================================================================
@@ -128,52 +135,47 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
                                         const TopoDS_Shape& aShape) throw (SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
-  //MESSAGE("StdMeshers_Quadrangle_2D::Compute");
+
   SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
   aMesh.GetSubMesh(aShape);
 
-  if ( !myTool )
-    myTool = new SMESH_MesherHelper(aMesh);
-  _quadraticMesh = myTool->IsQuadraticSubMesh(aShape);
+  SMESH_MesherHelper helper(aMesh);
+  myTool = &helper;
 
-  //FaceQuadStruct *quad = CheckAnd2Dcompute(aMesh, aShape);
-  FaceQuadStruct* quad = CheckNbEdges(aMesh, aShape);
+  _quadraticMesh = myTool->IsQuadraticSubMesh(aShape);
 
-  if (!quad) {
-    delete myTool; myTool = 0;
+  FaceQuadStruct *quad = CheckNbEdges( aMesh, aShape );
+  std::auto_ptr<FaceQuadStruct> quadDeleter( quad ); // to delete quad at exit from Compute()
+  if (!quad)
     return false;
-  }
 
   if(myQuadranglePreference) {
-    int n1 = quad->nbPts[0];
-    int n2 = quad->nbPts[1];
-    int n3 = quad->nbPts[2];
-    int n4 = quad->nbPts[3];
+    int n1 = quad->side[0]->NbPoints();
+    int n2 = quad->side[1]->NbPoints();
+    int n3 = quad->side[2]->NbPoints();
+    int n4 = quad->side[3]->NbPoints();
     int nfull = n1+n2+n3+n4;
     int ntmp = nfull/2;
     ntmp = ntmp*2;
     if( nfull==ntmp && ( (n1!=n3) || (n2!=n4) ) ) {
       // special path for using only quandrangle faces
       bool ok = ComputeQuadPref(aMesh, aShape, quad);
-      delete myTool; myTool = 0;
       return ok;
     }
   }
 
   // set normalized grid on unit square in parametric domain
-  SetNormalizedGrid(aMesh, aShape, quad);
-  if (!quad) {
-    delete myTool; myTool = 0;
+  
+  if (!SetNormalizedGrid(aMesh, aShape, quad))
     return false;
-  }
 
   // --- compute 3D values on points, store points & quadrangles
 
-  int nbdown  = quad->nbPts[0];
-  int nbup    = quad->nbPts[2];
+  int nbdown  = quad->side[0]->NbPoints();
+  int nbup    = quad->side[2]->NbPoints();
 
-  int nbright = quad->nbPts[1];
-  int nbleft  = quad->nbPts[3];
+  int nbright = quad->side[1]->NbPoints();
+  int nbleft  = quad->side[3]->NbPoints();
 
   int nbhoriz  = Min(nbdown, nbup);
   int nbvertic = Min(nbright, nbleft);
@@ -226,16 +228,15 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
       b = quad->uv_grid[j * nbhoriz + i + 1].node;
       c = quad->uv_grid[(j + 1) * nbhoriz + i + 1].node;
       d = quad->uv_grid[(j + 1) * nbhoriz + i].node;
-      //SMDS_MeshFace * face = meshDS->AddFace(a, b, c, d);
       SMDS_MeshFace* face = myTool->AddFace(a, b, c, d);
       meshDS->SetMeshElementOnShape(face, geomFaceID);
     }
   }
-  
-  UVPtStruct *uv_e0 = quad->uv_edges[0];
-  UVPtStruct *uv_e1 = quad->uv_edges[1];
-  UVPtStruct *uv_e2 = quad->uv_edges[2];
-  UVPtStruct *uv_e3 = quad->uv_edges[3];
+
+  const vector<UVPtStruct>& uv_e0 = quad->side[0]->GetUVPtStruct(true,0 );
+  const vector<UVPtStruct>& uv_e1 = quad->side[1]->GetUVPtStruct(false,1);
+  const vector<UVPtStruct>& uv_e2 = quad->side[2]->GetUVPtStruct(true,1 );
+  const vector<UVPtStruct>& uv_e3 = quad->side[3]->GetUVPtStruct(false,0);
 
   double eps = Precision::Confusion();
 
@@ -549,63 +550,85 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh,
     }
   }
 
-  QuadDelete(quad);
-  delete myTool; myTool = 0;
-
   bool isOk = true;
   return isOk;
 }
 
-
 //=============================================================================
 /*!
  *  
  */
 //=============================================================================
 
-FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMesh,
+FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh &         aMesh,
                                                        const TopoDS_Shape & aShape)
      throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
 
   const TopoDS_Face & F = TopoDS::Face(aShape);
+  const bool ignoreMediumNodes = _quadraticMesh;
 
   // verify 1 wire only, with 4 edges
-
-  if (NumberOfWires(F) != 1) {
-    INFOS("only 1 wire by face (quadrangles)");
+  TopoDS_Vertex V;
+  list< TopoDS_Edge > edges;
+  list< int > nbEdgesInWire;
+  int nbWire = SMESH_Block::GetOrderedEdges (F, V, edges, nbEdgesInWire);
+  if (nbWire != 1) {
+    error(COMPERR_BAD_SHAPE, TComm("Wrong number of wires: ") << nbWire);
     return 0;
   }
-  const TopoDS_Wire& W = BRepTools::OuterWire(F);
-  BRepTools_WireExplorer wexp (W, F);
-
   FaceQuadStruct* quad = new FaceQuadStruct;
-  for (int i = 0; i < 4; i++)
-    quad->uv_edges[i] = 0;
   quad->uv_grid = 0;
-
-  int nbEdges = 0;
-  for (wexp.Init(W, F); wexp.More(); wexp.Next()) {
-    const TopoDS_Edge& E = wexp.Current();
-    int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
-    if (nbEdges < 4) {
-      quad->edge[nbEdges] = E;
-      if(!_quadraticMesh) {
-        quad->nbPts[nbEdges] = nb + 2; // internal points + 2 extrema
+  quad->side.reserve(nbEdgesInWire.front());
+
+  int nbSides = 0;
+  list< TopoDS_Edge >::iterator edgeIt = edges.begin();
+  if ( nbEdgesInWire.front() == 4 ) { // exactly 4 edges
+    for ( ; edgeIt != edges.end(); ++edgeIt, nbSides++ )
+      quad->side.push_back( new StdMeshers_FaceSide(F, *edgeIt, &aMesh,
+                                                    nbSides<TOP_SIDE, ignoreMediumNodes));
+  }
+  else if ( nbEdgesInWire.front() > 4 ) { // more than 4 edges - try to unite some
+    list< TopoDS_Edge > sideEdges;
+    while ( !edges.empty()) {
+      sideEdges.clear();
+      sideEdges.splice( sideEdges.end(), edges, edges.begin()); // edges.front() -> sideEdges.end()
+      bool sameSide = true;
+      while ( !edges.empty() && sameSide ) {
+        GeomAbs_Shape cont = SMESH_Algo::Continuity( sideEdges.back(), edges.front() );
+        sameSide = ( cont >= GeomAbs_G1 );
+        if ( sameSide )
+          sideEdges.splice( sideEdges.end(), edges, edges.begin());
       }
-      else {
-        int tmp = nb/2;
-        quad->nbPts[nbEdges] = tmp + 2; // internal not medium points + 2 extrema
+      if ( nbSides == 0 ) { // go backward from the first edge
+        sameSide = true;
+        while ( !edges.empty() && sameSide ) {
+          GeomAbs_Shape cont = SMESH_Algo::Continuity( sideEdges.front(), edges.back() );
+          sameSide = ( cont >= GeomAbs_G1 );
+          if ( sameSide )
+            sideEdges.splice( sideEdges.begin(), edges, --edges.end());
+        }
       }
+      quad->side.push_back( new StdMeshers_FaceSide(F, sideEdges, &aMesh,
+                                                    nbSides<TOP_SIDE, ignoreMediumNodes));
+      ++nbSides;
     }
-    nbEdges++;
   }
-
-  if (nbEdges != 4) {
-    INFOS("face must have 4 edges /quadrangles");
-    QuadDelete(quad);
-    return 0;
+  if (nbSides != 4) {
+#ifdef _DEBUG_
+    cout << endl << "StdMeshers_Quadrangle_2D. Edge IDs of " << nbSides << " sides:";
+    for ( int i = 0; i < nbSides; ++i ) {
+      cout << " ( ";
+      for ( int e = 0; e < quad->side[i]->NbEdges(); ++e )
+        cout << myTool->GetMeshDS()->ShapeToIndex( quad->side[i]->Edge( e )) << " ";
+      cout << ")";
+    }
+    cout << endl;
+#endif
+    error(COMPERR_BAD_SHAPE, TComm("Face must have 4 side but not ") << nbSides);
+    delete quad;
+    quad = 0;
   }
 
   return quad;
@@ -618,9 +641,9 @@ FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMesh,
 //=============================================================================
 
 FaceQuadStruct *StdMeshers_Quadrangle_2D::CheckAnd2Dcompute
-                           (SMESH_Mesh & aMesh,
+                           (SMESH_Mesh &         aMesh,
                             const TopoDS_Shape & aShape,
-                            const bool CreateQuadratic) throw(SALOME_Exception)
+                            const bool           CreateQuadratic) throw(SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
 
@@ -642,20 +665,23 @@ FaceQuadStruct *StdMeshers_Quadrangle_2D::CheckAnd2Dcompute
  */
 //=============================================================================
 
-void StdMeshers_Quadrangle_2D::QuadDelete (FaceQuadStruct * quad)
+faceQuadStruct::~faceQuadStruct()
 {
-  //MESSAGE("StdMeshers_Quadrangle_2D::QuadDelete");
-  if (quad)
+  for (int i = 0; i < side.size(); i++) {
+    if (side[i])     delete side[i];
+  }
+  if (uv_grid)       delete [] uv_grid;
+}
+
+namespace {
+  inline const vector<UVPtStruct>& GetUVPtStructIn(FaceQuadStruct* quad, int i, int nbSeg)
   {
-    for (int i = 0; i < 4; i++)
-    {
-      if (quad->uv_edges[i])
-        delete [] quad->uv_edges[i];
-      quad->edge[i].Nullify();
-    }
-    if (quad->uv_grid)
-      delete [] quad->uv_grid;
-    delete quad;
+    bool   isXConst   = ( i == BOTTOM_SIDE || i == TOP_SIDE );
+    double constValue = ( i == BOTTOM_SIDE || i == LEFT_SIDE ) ? 0 : 1;
+    return
+      quad->isEdgeOut[i] ?
+      quad->side[i]->SimulateUVPtStruct(nbSeg,isXConst,constValue) :
+      quad->side[i]->GetUVPtStruct(isXConst,constValue);
   }
 }
 
@@ -665,7 +691,7 @@ void StdMeshers_Quadrangle_2D::QuadDelete (FaceQuadStruct * quad)
  */
 //=============================================================================
 
-void StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
+bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
                                                   const TopoDS_Shape& aShape,
                                                   FaceQuadStruct* & quad) throw (SALOME_Exception)
 {
@@ -676,7 +702,7 @@ void StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
   // transport - projection sur le carré unité
 
 //  MESSAGE("StdMeshers_Quadrangle_2D::SetNormalizedGrid");
-  const TopoDS_Face& F = TopoDS::Face(aShape);
+//  const TopoDS_Face& F = TopoDS::Face(aShape);
 
   // 1 --- find orientation of the 4 edges, by test on extrema
 
@@ -692,88 +718,25 @@ void StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
   //             =down
   //
 
-  Handle(Geom2d_Curve) c2d[4];
-  gp_Pnt2d pf[4];
-  gp_Pnt2d pl[4];
-  for (int i = 0; i < 4; i++)
-  {
-    c2d[i] = BRep_Tool::CurveOnSurface(quad->edge[i], F,
-                                       quad->first[i], quad->last[i]);
-    pf[i] = c2d[i]->Value(quad->first[i]);
-    pl[i] = c2d[i]->Value(quad->last[i]);
-    quad->isEdgeForward[i] = false;
-  }
-
-  double l0f1 = pl[0].SquareDistance(pf[1]);
-  double l0l1 = pl[0].SquareDistance(pl[1]);
-  double f0f1 = pf[0].SquareDistance(pf[1]);
-  double f0l1 = pf[0].SquareDistance(pl[1]);
-  if ( Min( l0f1, l0l1 ) < Min ( f0f1, f0l1 ))
-  {
-    quad->isEdgeForward[0] = true;
-  } else {
-    double tmp = quad->first[0];
-    quad->first[0] = quad->last[0];
-    quad->last[0] = tmp;
-    pf[0] = c2d[0]->Value(quad->first[0]);
-    pl[0] = c2d[0]->Value(quad->last[0]);
-  }
-  for (int i = 1; i < 4; i++)
-  {
-    l0l1 = pl[i - 1].SquareDistance(pl[i]);
-    l0f1 = pl[i - 1].SquareDistance(pf[i]);
-    quad->isEdgeForward[i] = ( l0f1 < l0l1 );
-    if (!quad->isEdgeForward[i])
-    {
-      double tmp = quad->first[i];
-      quad->first[i] = quad->last[i];
-      quad->last[i] = tmp;
-      pf[i] = c2d[i]->Value(quad->first[i]);
-      pl[i] = c2d[i]->Value(quad->last[i]);
-    }
-  }
-
-  // 2 --- load 2d edge points (u,v) with orientation and value on unit square
-
-  bool loadOk = true;
-  for (int i = 0; i < 2; i++)
-  {
-    quad->uv_edges[i] = LoadEdgePoints(aMesh, F, quad->edge[i],
-                                       quad->first[i], quad->last[i]);
-    if (!quad->uv_edges[i]) loadOk = false;
-  }
-
-  for (int i = 2; i < 4; i++)
-  {
-    quad->uv_edges[i] = LoadEdgePoints(aMesh, F, quad->edge[i],
-                                       quad->last[i], quad->first[i]);
-    if (!quad->uv_edges[i]) loadOk = false;
-  }
-
-  if (!loadOk)
-  {
-    INFOS("StdMeshers_Quadrangle_2D::SetNormalizedGrid - LoadEdgePoints failed");
-    QuadDelete( quad );
-    quad = 0;
-    return;
-  }
   // 3 --- 2D normalized values on unit square [0..1][0..1]
 
-  int nbhoriz  = Min(quad->nbPts[0], quad->nbPts[2]);
-  int nbvertic = Min(quad->nbPts[1], quad->nbPts[3]);
+  int nbhoriz  = Min(quad->side[0]->NbPoints(), quad->side[2]->NbPoints());
+  int nbvertic = Min(quad->side[1]->NbPoints(), quad->side[3]->NbPoints());
 
-  quad->isEdgeOut[0] = (quad->nbPts[0] > quad->nbPts[2]);
-  quad->isEdgeOut[1] = (quad->nbPts[1] > quad->nbPts[3]);
-  quad->isEdgeOut[2] = (quad->nbPts[2] > quad->nbPts[0]);
-  quad->isEdgeOut[3] = (quad->nbPts[3] > quad->nbPts[1]);
+  quad->isEdgeOut[0] = (quad->side[0]->NbPoints() > quad->side[2]->NbPoints());
+  quad->isEdgeOut[1] = (quad->side[1]->NbPoints() > quad->side[3]->NbPoints());
+  quad->isEdgeOut[2] = (quad->side[2]->NbPoints() > quad->side[0]->NbPoints());
+  quad->isEdgeOut[3] = (quad->side[3]->NbPoints() > quad->side[1]->NbPoints());
 
-  quad->uv_grid = new UVPtStruct[nbvertic * nbhoriz];
+  UVPtStruct *uv_grid = quad->uv_grid = new UVPtStruct[nbvertic * nbhoriz];
 
-  UVPtStruct *uv_grid = quad->uv_grid;
-  UVPtStruct *uv_e0 = quad->uv_edges[0];
-  UVPtStruct *uv_e1 = quad->uv_edges[1];
-  UVPtStruct *uv_e2 = quad->uv_edges[2];
-  UVPtStruct *uv_e3 = quad->uv_edges[3];
+  const vector<UVPtStruct>& uv_e0 = GetUVPtStructIn( quad, 0, nbhoriz - 1 );
+  const vector<UVPtStruct>& uv_e1 = GetUVPtStructIn( quad, 1, nbvertic - 1 );
+  const vector<UVPtStruct>& uv_e2 = GetUVPtStructIn( quad, 2, nbhoriz - 1 );
+  const vector<UVPtStruct>& uv_e3 = GetUVPtStructIn( quad, 3, nbvertic - 1 );
+
+  if ( uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty() )
+    return error(dfltErr(), "Can't find nodes on sides");
 
   // nodes Id on "in" edges
   if (! quad->isEdgeOut[0]) {
@@ -805,21 +768,6 @@ void StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
     }
   }
 
-  // falsificate "out" edges
-  if (quad->isEdgeOut[0]) // down
-    uv_e0 = MakeEdgePoints
-      (aMesh, F, quad->edge[0], quad->first[0], quad->last[0], nbhoriz - 1);
-  else if (quad->isEdgeOut[2]) // up
-    uv_e2 = MakeEdgePoints
-      (aMesh, F, quad->edge[2], quad->last[2], quad->first[2], nbhoriz - 1);
-
-  if (quad->isEdgeOut[1]) // right
-    uv_e1 = MakeEdgePoints
-      (aMesh, F, quad->edge[1], quad->first[1], quad->last[1], nbvertic - 1);
-  else if (quad->isEdgeOut[3]) // left
-    uv_e3 = MakeEdgePoints
-      (aMesh, F, quad->edge[3], quad->last[3], quad->first[3], nbvertic - 1);
-
   // normalized 2d values on grid
   for (int i = 0; i < nbhoriz; i++)
   {
@@ -843,10 +791,10 @@ void StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
   }
 
   // 4 --- projection on 2d domain (u,v)
-  gp_Pnt2d a0 = pf[0];
-  gp_Pnt2d a1 = pf[1];
-  gp_Pnt2d a2 = pf[2];
-  gp_Pnt2d a3 = pf[3];
+  gp_UV a0( uv_e0.front().u, uv_e0.front().v );
+  gp_UV a1( uv_e0.back().u,  uv_e0.back().v );
+  gp_UV a2( uv_e2.back().u,  uv_e2.back().v );
+  gp_UV a3( uv_e2.front().u, uv_e2.front().v );
 
   for (int i = 0; i < nbhoriz; i++)
   {
@@ -855,168 +803,90 @@ void StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh,
       int ij = j * nbhoriz + i;
       double x = uv_grid[ij].x;
       double y = uv_grid[ij].y;
-      double param_0 = uv_e0[0].param + x * (uv_e0[nbhoriz - 1].param - uv_e0[0].param); // sud
-      double param_2 = uv_e2[0].param + x * (uv_e2[nbhoriz - 1].param - uv_e2[0].param); // nord
-      double param_1 = uv_e1[0].param + y * (uv_e1[nbvertic - 1].param - uv_e1[0].param); // est
-      double param_3 = uv_e3[0].param + y * (uv_e3[nbvertic - 1].param - uv_e3[0].param); // ouest
+      double param_0 = uv_e0[0].normParam + x * (uv_e0.back().normParam - uv_e0[0].normParam); // sud
+      double param_2 = uv_e2[0].normParam + x * (uv_e2.back().normParam - uv_e2[0].normParam); // nord
+      double param_1 = uv_e1[0].normParam + y * (uv_e1.back().normParam - uv_e1[0].normParam); // est
+      double param_3 = uv_e3[0].normParam + y * (uv_e3.back().normParam - uv_e3[0].normParam); // ouest
 
       //MESSAGE("params "<<param_0<<" "<<param_1<<" "<<param_2<<" "<<param_3);
-      gp_Pnt2d p0 = c2d[0]->Value(param_0);
-      gp_Pnt2d p1 = c2d[1]->Value(param_1);
-      gp_Pnt2d p2 = c2d[2]->Value(param_2);
-      gp_Pnt2d p3 = c2d[3]->Value(param_3);
+      gp_UV p0 = quad->side[0]->Value2d(param_0).XY();
+      gp_UV p1 = quad->side[1]->Value2d(param_1).XY();
+      gp_UV p2 = quad->side[2]->Value2d(param_2).XY();
+      gp_UV p3 = quad->side[3]->Value2d(param_3).XY();
 
-      double u = (1 - y) * p0.X() + x * p1.X() + y * p2.X() + (1 - x) * p3.X();
-      double v = (1 - y) * p0.Y() + x * p1.Y() + y * p2.Y() + (1 - x) * p3.Y();
+      gp_UV uv = (1 - y) * p0 + x * p1 + y * p2 + (1 - x) * p3;
+      uv -= (1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3;
 
-      u -= (1 - x) * (1 - y) * a0.X() + x * (1 - y) * a1.X() +
-        x * y * a2.X() + (1 - x) * y * a3.X();
-      v -= (1 - x) * (1 - y) * a0.Y() + x * (1 - y) * a1.Y() +
-        x * y * a2.Y() + (1 - x) * y * a3.Y();
-
-      uv_grid[ij].u = u;
-      uv_grid[ij].v = v;
+      uv_grid[ij].u = uv.X();
+      uv_grid[ij].v = uv.Y();
     }
   }
+  return true;
 }
 
-
 //=======================================================================
 //function : ShiftQuad
 //purpose  : auxilary function for ComputeQuadPref
 //=======================================================================
-static void ShiftQuad(FaceQuadStruct* quad, const int num, bool WisF)
+
+static void ShiftQuad(FaceQuadStruct* quad, const int num, bool)
 {
-  if(num>3) return;
-  int i;
-  for(i=1; i<=num; i++) {
-    int nbPts3 = quad->nbPts[0];
-    quad->nbPts[0] = quad->nbPts[1];
-    quad->nbPts[1] = quad->nbPts[2];
-    quad->nbPts[2] = quad->nbPts[3];
-    quad->nbPts[3] = nbPts3;
-    TopoDS_Edge edge3 = quad->edge[0];
-    quad->edge[0] = quad->edge[1];
-    quad->edge[1] = quad->edge[2];
-    quad->edge[2] = quad->edge[3];
-    quad->edge[3] = edge3;
-    double first3 = quad->first[0];
-    quad->first[0] = quad->first[1];
-    quad->first[1] = quad->first[2];
-    quad->first[2] = quad->first[3];
-    quad->first[3] = first3;
-    double last3 = quad->last[0];
-    quad->last[0] = quad->last[1];
-    quad->last[1] = quad->last[2];
-    quad->last[2] = quad->last[3];
-    quad->last[3] = last3;
-    bool isEdgeForward3 = quad->isEdgeForward[0];
-    quad->isEdgeForward[0] = quad->isEdgeForward[1];
-    quad->isEdgeForward[1] = quad->isEdgeForward[2];
-    quad->isEdgeForward[2] = quad->isEdgeForward[3];
-    quad->isEdgeForward[3] = isEdgeForward3;
-    bool isEdgeOut3 = quad->isEdgeOut[0];
-    quad->isEdgeOut[0] = quad->isEdgeOut[1];
-    quad->isEdgeOut[1] = quad->isEdgeOut[2];
-    quad->isEdgeOut[2] = quad->isEdgeOut[3];
-    quad->isEdgeOut[3] = isEdgeOut3;
-    UVPtStruct* uv_edges3 = quad->uv_edges[0];
-    quad->uv_edges[0] = quad->uv_edges[1];
-    quad->uv_edges[1] = quad->uv_edges[2];
-    quad->uv_edges[2] = quad->uv_edges[3];
-    quad->uv_edges[3] = uv_edges3;
-  }
-  if(!WisF) {
-    // replacement left and right edges
-    int nbPts3 = quad->nbPts[1];
-    quad->nbPts[1] = quad->nbPts[3];
-    quad->nbPts[3] = nbPts3;
-    TopoDS_Edge edge3 = quad->edge[1];
-    quad->edge[1] = quad->edge[3];
-    quad->edge[3] = edge3;
-    double first3 = quad->first[1];
-    quad->first[1] = quad->first[3];
-    quad->first[3] = first3;
-    double last3 = quad->last[1];
-    quad->last[1] = quad->last[2];
-    quad->last[3] = last3;
-    bool isEdgeForward3 = quad->isEdgeForward[1];
-    quad->isEdgeForward[1] = quad->isEdgeForward[3];
-    quad->isEdgeForward[3] = isEdgeForward3;
-    bool isEdgeOut3 = quad->isEdgeOut[1];
-    quad->isEdgeOut[1] = quad->isEdgeOut[3];
-    quad->isEdgeOut[3] = isEdgeOut3;
-    UVPtStruct* uv_edges3 = quad->uv_edges[1];
-    quad->uv_edges[1] = quad->uv_edges[3];
-    quad->uv_edges[3] = uv_edges3;
+  StdMeshers_FaceSide* side[4] = { quad->side[0], quad->side[1], quad->side[2], quad->side[3] };
+  for (int i = BOTTOM_SIDE; i < NB_SIDES; ++i ) {
+    int id = ( i + num ) % NB_SIDES;
+    bool wasForward = ( i < TOP_SIDE );
+    bool newForward = ( id < TOP_SIDE );
+    if ( wasForward != newForward )
+      side[ i ]->Reverse();
+    quad->side[ id ] = side[ i ];
   }
 }
 
-
 //=======================================================================
 //function : CalcUV
 //purpose  : auxilary function for ComputeQuadPref
 //=======================================================================
-static gp_XY CalcUV(double x0, double x1, double y0, double y1,
+
+static gp_UV CalcUV(double x0, double x1, double y0, double y1,
                     FaceQuadStruct* quad,
-                    const gp_Pnt2d& a0, const gp_Pnt2d& a1,
-                    const gp_Pnt2d& a2, const gp_Pnt2d& a3,
-                    const Handle(Geom2d_Curve)& c2db,
-                    const Handle(Geom2d_Curve)& c2dr,
-                    const Handle(Geom2d_Curve)& c2dt,
-                    const Handle(Geom2d_Curve)& c2dl)
+                    const gp_UV& a0, const gp_UV& a1,
+                    const gp_UV& a2, const gp_UV& a3)
 {
-  int nb = quad->nbPts[0];
-  int nr = quad->nbPts[1];
-  int nt = quad->nbPts[2];
-  int nl = quad->nbPts[3];
-
-  UVPtStruct* uv_eb = quad->uv_edges[0];
-  UVPtStruct* uv_er = quad->uv_edges[1];
-  UVPtStruct* uv_et = quad->uv_edges[2];
-  UVPtStruct* uv_el = quad->uv_edges[3];
+  const vector<UVPtStruct>& uv_eb = quad->side[0]->GetUVPtStruct(true,0 );
+  const vector<UVPtStruct>& uv_er = quad->side[1]->GetUVPtStruct(false,1);
+  const vector<UVPtStruct>& uv_et = quad->side[2]->GetUVPtStruct(true,1 );
+  const vector<UVPtStruct>& uv_el = quad->side[3]->GetUVPtStruct(false,0);
 
   double x = (x0 + y0 * (x1 - x0)) / (1 - (y1 - y0) * (x1 - x0));
   double y = y0 + x * (y1 - y0);
 
-  double param_b = uv_eb[0].param + x * (uv_eb[nb-1].param - uv_eb[0].param);
-  double param_t = uv_et[0].param + x * (uv_et[nt-1].param - uv_et[0].param);
-  double param_r = uv_er[0].param + y * (uv_er[nr-1].param - uv_er[0].param);
-  double param_l = uv_el[0].param + y * (uv_el[nl-1].param - uv_el[0].param);
-
-  gp_Pnt2d p0 = c2db->Value(param_b);
-  gp_Pnt2d p1 = c2dr->Value(param_r);
-  gp_Pnt2d p2 = c2dt->Value(param_t);
-  gp_Pnt2d p3 = c2dl->Value(param_l);
+  double param_b = uv_eb[0].normParam + x * (uv_eb.back().normParam - uv_eb[0].normParam);
+  double param_t = uv_et[0].normParam + x * (uv_et.back().normParam - uv_et[0].normParam);
+  double param_r = uv_er[0].normParam + y * (uv_er.back().normParam - uv_er[0].normParam);
+  double param_l = uv_el[0].normParam + y * (uv_el.back().normParam - uv_el[0].normParam);
 
-  double u = (1 - y) * p0.X() + x * p1.X() + y * p2.X() + (1 - x) * p3.X();
-  double v = (1 - y) * p0.Y() + x * p1.Y() + y * p2.Y() + (1 - x) * p3.Y();
+  gp_UV p0 = quad->side[BOTTOM_SIDE]->Value2d(param_b).XY();
+  gp_UV p1 = quad->side[RIGHT_SIDE ]->Value2d(param_r).XY();
+  gp_UV p2 = quad->side[TOP_SIDE   ]->Value2d(param_t).XY();
+  gp_UV p3 = quad->side[LEFT_SIDE  ]->Value2d(param_l).XY();
 
-  u -= (1 - x) * (1 - y) * a0.X() + x * (1 - y) * a1.X() +
-    x * y * a2.X() + (1 - x) * y * a3.X();
-  v -= (1 - x) * (1 - y) * a0.Y() + x * (1 - y) * a1.Y() +
-    x * y * a2.Y() + (1 - x) * y * a3.Y();
+  gp_UV uv = p0 * (1 - y) + p1 * x + p2 * y + p3 * (1 - x);
 
-  //cout<<"x0="<<x0<<" x1="<<x1<<" y0="<<y0<<" y1="<<y1<<endl;
-  //cout<<"x="<<x<<" y="<<y<<endl;
-  //cout<<"param_b="<<param_b<<" param_t="<<param_t<<" param_r="<<param_r<<" param_l="<<param_l<<endl;
-  //cout<<"u="<<u<<" v="<<v<<endl;
+  uv -= (1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3;
 
-  return gp_XY(u,v);
+  return uv;
 }
 
-
-//=======================================================================
-//function : ComputeQuadPref
-//purpose  : 
 //=======================================================================
 /*!
- * Special function for creation only quandrangle faces
+ * Create only quandrangle faces
  */
-bool StdMeshers_Quadrangle_2D::ComputeQuadPref
-                          (SMESH_Mesh & aMesh,
-                           const TopoDS_Shape& aShape,
-                           FaceQuadStruct* quad) throw (SALOME_Exception)
+//=======================================================================
+
+bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh &        aMesh,
+                                                const TopoDS_Shape& aShape,
+                                                FaceQuadStruct*     quad)
+  throw (SALOME_Exception)
 {
   Unexpect aCatch(SalomeException);
 
@@ -1033,10 +903,10 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref
   if(!FisF) WisF = !WisF;
   int i,j,geomFaceID = meshDS->ShapeToIndex( F );
 
-  int nb = quad->nbPts[0];
-  int nr = quad->nbPts[1];
-  int nt = quad->nbPts[2];
-  int nl = quad->nbPts[3];
+  int nb = quad->side[0]->NbPoints();
+  int nr = quad->side[1]->NbPoints();
+  int nt = quad->side[2]->NbPoints();
+  int nl = quad->side[3]->NbPoints();
   int dh = abs(nb-nt);
   int dv = abs(nr-nl);
 
@@ -1052,19 +922,19 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref
   }
   else {
     if( nr>nl ) {
-      // we have to shift quad on 3
-      ShiftQuad(quad,3,WisF);
-    }
-    else {
       // we have to shift quad on 1
       ShiftQuad(quad,1,WisF);
     }
+    else {
+      // we have to shift quad on 3
+      ShiftQuad(quad,3,WisF);
+    }
   }
 
-  nb = quad->nbPts[0];
-  nr = quad->nbPts[1];
-  nt = quad->nbPts[2];
-  nl = quad->nbPts[3];
+  nb = quad->side[0]->NbPoints();
+  nr = quad->side[1]->NbPoints();
+  nt = quad->side[2]->NbPoints();
+  nl = quad->side[3]->NbPoints();
   dh = abs(nb-nt);
   dv = abs(nr-nl);
   int nbh  = Max(nb,nt);
@@ -1094,39 +964,17 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref
     nbh = nbh + addh;
   }
 
-  Handle(Geom2d_Curve) c2d[4];
-  for(i=0; i<4; i++) {
-    c2d[i] = BRep_Tool::CurveOnSurface(quad->edge[i], F,
-                                       quad->first[i], quad->last[i]);
-  }
-
-  bool loadOk = true;
-  for(i=0; i<2; i++) {
-    quad->uv_edges[i] = LoadEdgePoints2(aMesh, F, quad->edge[i], false);
-    if(!quad->uv_edges[i]) loadOk = false;
-  }
-  for(i=2; i<4; i++) {
-    quad->uv_edges[i] = LoadEdgePoints2(aMesh, F, quad->edge[i], true);
-    if (!quad->uv_edges[i]) loadOk = false;
-  }
-  if (!loadOk) {
-    INFOS("StdMeshers_Quadrangle_2D::ComputeQuadPref - LoadEdgePoints failed");
-    QuadDelete( quad );
-    quad = 0;
-    return false;
-  }
-
-  UVPtStruct* uv_eb = quad->uv_edges[0];
-  UVPtStruct* uv_er = quad->uv_edges[1];
-  UVPtStruct* uv_et = quad->uv_edges[2];
-  UVPtStruct* uv_el = quad->uv_edges[3];
+  const vector<UVPtStruct>& uv_eb = quad->side[0]->GetUVPtStruct(true,0 );
+  const vector<UVPtStruct>& uv_er = quad->side[1]->GetUVPtStruct(false,1);
+  const vector<UVPtStruct>& uv_et = quad->side[2]->GetUVPtStruct(true,1 );
+  const vector<UVPtStruct>& uv_el = quad->side[3]->GetUVPtStruct(false,0);
 
   // arrays for normalized params
   //cout<<"Dump B:"<<endl;
   TColStd_SequenceOfReal npb, npr, npt, npl;
   for(i=0; i<nb; i++) {
     npb.Append(uv_eb[i].normParam);
-    //cout<<"i="<<i<<" par="<<uv_eb[i].param<<" npar="<<uv_eb[i].normParam;
+    //cout<<"i="<<i<<" par="<<uv_eb[i].normParam<<" npar="<<uv_eb[i].normParam;
     //const SMDS_MeshNode* N = uv_eb[i].node;
     //cout<<" node("<<N->X()<<","<<N->Y()<<","<<N->Z()<<")"<<endl;
   }
@@ -1140,8 +988,7 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref
     npl.Append(uv_el[i].normParam);
   }
 
-  // we have to add few values of params to right and left
-  // insert them after first param
+  // add some params to right and left after the first param
   // insert to right
   int dr = nbv - nr;
   double dpr = (npr.Value(2) - npr.Value(1))/(dr+1);
@@ -1160,13 +1007,12 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref
   //}
   //cout<<endl;
   
-  gp_Pnt2d a[4];
-  c2d[0]->D0(uv_eb[0].param,a[0]);
-  c2d[0]->D0(uv_eb[nb-1].param,a[1]);
-  c2d[2]->D0(uv_et[nt-1].param,a[2]);
-  c2d[2]->D0(uv_et[0].param,a[3]);
-  //cout<<" a[0]("<<a[0].X()<<","<<a[0].Y()<<")"<<" a[1]("<<a[1].X()<<","<<a[1].Y()<<")"
-  //    <<" a[2]("<<a[2].X()<<","<<a[2].Y()<<")"<<" a[3]("<<a[3].X()<<","<<a[3].Y()<<")"<<endl;
+  gp_XY a0( uv_eb.front().u, uv_eb.front().v );
+  gp_XY a1( uv_eb.back().u,  uv_eb.back().v );
+  gp_XY a2( uv_et.back().u,  uv_et.back().v );
+  gp_XY a3( uv_et.front().u, uv_et.front().v );
+  //cout<<" a0("<<a0.X()<<","<<a0.Y()<<")"<<" a1("<<a1.X()<<","<<a1.Y()<<")"
+  //    <<" a2("<<a2.X()<<","<<a2.Y()<<")"<<" a3("<<a3.X()<<","<<a3.Y()<<")"<<endl;
 
   int nnn = Min(nr,nl);
   // auxilary sequence of XY for creation nodes
@@ -1178,7 +1024,7 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref
   // step1: create faces for left domain
   StdMeshers_Array2OfNode NodesL(1,dl+1,1,nl);
   // add left nodes
-  for(j=1; j<=nl; j++) 
+  for(j=1; j<=nl; j++)
     NodesL.SetValue(1,j,uv_el[j-1].node);
   if(dl>0) {
     // add top nodes
@@ -1192,8 +1038,7 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref
       // diagonal node
       double y0 = npl.Value(i+1);
       double y1 = npr.Value(i+1);
-      gp_XY UV = CalcUV(x0, x1, y0, y1, quad, a[0], a[1], a[2], a[3],
-                        c2d[0], c2d[1], c2d[2], c2d[3]);
+      gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
       gp_Pnt P = S->Value(UV.X(),UV.Y());
       SMDS_MeshNode * N = meshDS->AddNode(P.X(), P.Y(), P.Z());
       meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
@@ -1203,8 +1048,7 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref
       for(j=2; j<nl; j++) {
         double y0 = npl.Value(dl+j);
         double y1 = npr.Value(dl+j);
-        gp_XY UV = CalcUV(x0, x1, y0, y1, quad, a[0], a[1], a[2], a[3],
-                          c2d[0], c2d[1], c2d[2], c2d[3]);
+        gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
         gp_Pnt P = S->Value(UV.X(),UV.Y());
         SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
         meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
@@ -1244,9 +1088,7 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref
   else {
     // fill UVL using c2d
     for(i=1; i<npl.Length() && UVL.Length()<nbv-nnn-1; i++) {
-      gp_Pnt2d p2d;
-      c2d[3]->D0(uv_el[i].param,p2d);
-      UVL.Append(p2d.XY());
+      UVL.Append( gp_UV ( uv_el[i].u, uv_el[i].v ));
     }
   }
 
@@ -1267,8 +1109,7 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref
       // diagonal node
       double y0 = npl.Value(i+1);
       double y1 = npr.Value(i+1);
-      gp_XY UV = CalcUV(x0, x1, y0, y1, quad, a[0], a[1], a[2], a[3],
-                        c2d[0], c2d[1], c2d[2], c2d[3]);
+      gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
       gp_Pnt P = S->Value(UV.X(),UV.Y());
       SMDS_MeshNode * N = meshDS->AddNode(P.X(), P.Y(), P.Z());
       meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
@@ -1278,8 +1119,7 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref
       for(j=2; j<nr; j++) {
         double y0 = npl.Value(nbv-j+1);
         double y1 = npr.Value(nbv-j+1);
-        gp_XY UV = CalcUV(x0, x1, y0, y1, quad, a[0], a[1], a[2], a[3],
-                          c2d[0], c2d[1], c2d[2], c2d[3]);
+        gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
         gp_Pnt P = S->Value(UV.X(),UV.Y());
         SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
         meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
@@ -1311,9 +1151,7 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref
   else {
     // fill UVR using c2d
     for(i=1; i<npr.Length() && UVR.Length()<nbv-nnn-1; i++) {
-      gp_Pnt2d p2d;
-      c2d[1]->D0(uv_er[i].param,p2d);
-      UVR.Append(p2d.XY());
+      UVR.Append( gp_UV( uv_er[i].u, uv_er[i].v ));
     }
   }
 
@@ -1333,11 +1171,9 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref
   for(i=dl+2; i<nbh-dr; i++) 
     NodesC.SetValue(i-dl,nbv,uv_et[i-1].node);
   // add bottom nodes (first columns)
-  for(i=2; i<nb; i++) {
+  for(i=2; i<nb; i++)
     NodesC.SetValue(i,1,uv_eb[i-1].node);
-    gp_Pnt2d p2d;
-    c2d[0]->D0(uv_eb[i-1].param,p2d);
-  }
+
   // create and add needed nodes
   // add linear layers
   for(i=2; i<nb; i++) {
@@ -1346,8 +1182,7 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref
     for(j=1; j<nnn; j++) {
       double y0 = npl.Value(nbv-nnn+j);
       double y1 = npr.Value(nbv-nnn+j);
-      gp_XY UV = CalcUV(x0, x1, y0, y1, quad, a[0], a[1], a[2], a[3],
-                        c2d[0], c2d[1], c2d[2], c2d[3]);
+      gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3);
       gp_Pnt P = S->Value(UV.X(),UV.Y());
       SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z());
       meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y());
@@ -1391,470 +1226,7 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref
     }
   }
 
-  QuadDelete(quad);
   bool isOk = true;
   return isOk;
 }
 
-
-//=============================================================================
-/*!
- *  LoadEdgePoints2
- */
-//=============================================================================
-UVPtStruct* StdMeshers_Quadrangle_2D::LoadEdgePoints2 (SMESH_Mesh & aMesh,
-                                                       const TopoDS_Face& F,
-                                                       const TopoDS_Edge& E,
-                                                       bool IsReverse)
-{
-  //MESSAGE("StdMeshers_Quadrangle_2D::LoadEdgePoints");
-  // --- IDNodes of first and last Vertex
-  TopoDS_Vertex VFirst, VLast;
-  TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
-
-  ASSERT(!VFirst.IsNull());
-  SMDS_NodeIteratorPtr lid = aMesh.GetSubMesh(VFirst)->GetSubMeshDS()->GetNodes();
-  if (!lid->more()) {
-    MESSAGE ( "NO NODE BUILT ON VERTEX" );
-    return 0;
-  }
-  const SMDS_MeshNode* idFirst = lid->next();
-
-  ASSERT(!VLast.IsNull());
-  lid = aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes();
-  if (!lid->more()) {
-    MESSAGE ( "NO NODE BUILT ON VERTEX" );
-    return 0;
-  }
-  const SMDS_MeshNode* idLast = lid->next();
-
-  // --- edge internal IDNodes (relies on good order storage, not checked)
-
-  map<double, const SMDS_MeshNode *> params;
-  SMDS_NodeIteratorPtr ite = aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
-  int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
-
-  if(!_quadraticMesh) {
-    while(ite->more()) {
-      const SMDS_MeshNode* node = ite->next();
-      const SMDS_EdgePosition* epos =
-        static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
-      double param = epos->GetUParameter();
-      params[param] = node;
-    }
-  }
-  else {
-    vector<const SMDS_MeshNode*> nodes(nbPoints+2);
-    nodes[0] = idFirst;
-    nodes[nbPoints+1] = idLast;
-    nbPoints = nbPoints/2;
-    int nn = 1;
-    while(ite->more()) {
-      const SMDS_MeshNode* node = ite->next();
-      nodes[nn++] = node;
-      // check if node is medium
-      bool IsMedium = false;
-      SMDS_ElemIteratorPtr itn = node->GetInverseElementIterator();
-      while (itn->more()) {
-        const SMDS_MeshElement* elem = itn->next();
-        if ( elem->GetType() != SMDSAbs_Edge )
-          continue;
-        if(elem->IsMediumNode(node)) {
-          IsMedium = true;
-          break;
-        }
-      }
-      if(IsMedium)
-        continue;
-      const SMDS_EdgePosition* epos =
-        static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
-      double param = epos->GetUParameter();
-      params[param] = node;
-    }
-  }
-
-  if (nbPoints != params.size()) {
-    MESSAGE( "BAD NODE ON EDGE POSITIONS" );
-    return 0;
-  }
-  UVPtStruct* uvslf = new UVPtStruct[nbPoints + 2];
-
-  double f, l;
-  Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
-
-  const TopoDS_Wire& W = BRepTools::OuterWire(F);
-  bool FisF = (F.Orientation()==TopAbs_FORWARD);
-  bool WisF = (W.Orientation()==TopAbs_FORWARD);
-  bool isForward = (E.Orientation()==TopAbs_FORWARD);
-  //if(isForward) cout<<"E is FORWARD"<<endl;
-  //else cout<<"E is REVERSED"<<endl;
-  if(!WisF) isForward = !isForward;
-  if(!FisF) isForward = !isForward;
-  //bool isForward = !(E.Orientation()==TopAbs_FORWARD);
-  if(IsReverse) isForward = !isForward;
-  double paramin = 0;
-  double paramax = 0;
-  if (isForward) {
-    paramin = f;
-    paramax = l;
-    gp_Pnt2d p = C2d->Value(f);        // first point = Vertex Forward
-    uvslf[0].x = p.X();
-    uvslf[0].y = p.Y();
-    uvslf[0].param = f;
-    uvslf[0].node = idFirst;
-    //MESSAGE("__ f "<<f<<" "<<uvslf[0].x <<" "<<uvslf[0].y);
-    map < double, const SMDS_MeshNode* >::iterator itp = params.begin();
-    for (int i = 1; i <= nbPoints; i++)        { // nbPoints internal
-      double param = (*itp).first;
-      gp_Pnt2d p = C2d->Value(param);
-      uvslf[i].x = p.X();
-      uvslf[i].y = p.Y();
-      uvslf[i].param = param;
-      uvslf[i].node = (*itp).second;
-      //MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[i].x <<" "<<uvslf[i].y);
-      itp++;
-    }
-    p = C2d->Value(l);         // last point = Vertex Reversed
-    uvslf[nbPoints + 1].x = p.X();
-    uvslf[nbPoints + 1].y = p.Y();
-    uvslf[nbPoints + 1].param = l;
-    uvslf[nbPoints + 1].node = idLast;
-    //MESSAGE("__ l "<<l<<" "<<uvslf[nbPoints+1].x <<" "<<uvslf[nbPoints+1].y);
-  }
-  else {
-    paramin = l;
-    paramax = f;
-    gp_Pnt2d p = C2d->Value(l);        // first point = Vertex Reversed
-    uvslf[0].x = p.X();
-    uvslf[0].y = p.Y();
-    uvslf[0].param = l;
-    uvslf[0].node = idLast;
-    //MESSAGE("__ l "<<l<<" "<<uvslf[0].x <<" "<<uvslf[0].y);
-    map < double, const SMDS_MeshNode* >::reverse_iterator itp = params.rbegin();
-    for (int j = nbPoints; j >= 1; j--)        { // nbPoints internal
-      double param = (*itp).first;
-      int i = nbPoints + 1 - j;
-      gp_Pnt2d p = C2d->Value(param);
-      uvslf[i].x = p.X();
-      uvslf[i].y = p.Y();
-      uvslf[i].param = param;
-      uvslf[i].node = (*itp).second;
-      //MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[i].x <<" "<<uvslf[i].y);
-      itp++;
-    }
-    p = C2d->Value(f);         // last point = Vertex Forward
-    uvslf[nbPoints + 1].x = p.X();
-    uvslf[nbPoints + 1].y = p.Y();
-    uvslf[nbPoints + 1].param = f;
-    uvslf[nbPoints + 1].node = idFirst;
-    //MESSAGE("__ f "<<f<<" "<<uvslf[nbPoints+1].x <<" "<<uvslf[nbPoints+1].y);
-  }
-
-  ASSERT(paramin != paramax);
-  for (int i = 0; i < nbPoints + 2; i++) {
-    uvslf[i].normParam = (uvslf[i].param - paramin) / (paramax - paramin);
-  }
-
-  return uvslf;
-}
-
-
-//=============================================================================
-/*!
- *  LoadEdgePoints
- */
-//=============================================================================
-UVPtStruct* StdMeshers_Quadrangle_2D::LoadEdgePoints (SMESH_Mesh & aMesh,
-                                                      const TopoDS_Face& F,
-                                                      const TopoDS_Edge& E,
-                                                      double first, double last)
-//                        bool isForward)
-{
-  //MESSAGE("StdMeshers_Quadrangle_2D::LoadEdgePoints");
-
-  // --- IDNodes of first and last Vertex
-
-  TopoDS_Vertex VFirst, VLast;
-  TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
-
-  ASSERT(!VFirst.IsNull());
-  SMDS_NodeIteratorPtr lid = aMesh.GetSubMesh(VFirst)->GetSubMeshDS()->GetNodes();
-  if (!lid->more())
-  {
-    MESSAGE ( "NO NODE BUILT ON VERTEX" );
-    return 0;
-  }
-  const SMDS_MeshNode* idFirst = lid->next();
-
-  ASSERT(!VLast.IsNull());
-  lid = aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes();
-  if (!lid->more())
-  {
-    MESSAGE ( "NO NODE BUILT ON VERTEX" );
-    return 0;
-  }
-  const SMDS_MeshNode* idLast = lid->next();
-
-  // --- edge internal IDNodes (relies on good order storage, not checked)
-
-//  if(_quadraticMesh) {
-    // fill myNLinkNodeMap
-//    SMDS_ElemIteratorPtr iter = aMesh.GetSubMesh(E)->GetSubMeshDS()->GetElements();
-//    while(iter->more()) {
-//      const SMDS_MeshElement* elem = iter->next();
-//      SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
-//      const SMDS_MeshNode* n1 = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-//      const SMDS_MeshNode* n2 = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-//      const SMDS_MeshNode* n3 = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-//      NLink link(( n1 < n2 ? n1 : n2 ), ( n1 < n2 ? n2 : n1 ));
-//      myNLinkNodeMap.insert(NLinkNodeMap::value_type(link,n3));
-//      myNLinkNodeMap[link] = n3;
-//    }
-//  }
-
-  map<double, const SMDS_MeshNode *> params;
-  SMDS_NodeIteratorPtr ite = aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
-  int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
-
-  if(!_quadraticMesh) {
-    while(ite->more()) {
-      const SMDS_MeshNode* node = ite->next();
-      const SMDS_EdgePosition* epos =
-        static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
-      double param = epos->GetUParameter();
-      params[param] = node;
-    }
-  }
-  else {
-    nbPoints = nbPoints/2;
-    while(ite->more()) {
-      const SMDS_MeshNode* node = ite->next();
-      // check if node is medium
-      bool IsMedium = false;
-      SMDS_ElemIteratorPtr itn = node->GetInverseElementIterator();
-      while (itn->more()) {
-        const SMDS_MeshElement* elem = itn->next();
-        if ( elem->GetType() != SMDSAbs_Edge )
-          continue;
-        if(elem->IsMediumNode(node)) {
-          IsMedium = true;
-          break;
-        }
-      }
-      if(IsMedium)
-        continue;
-      const SMDS_EdgePosition* epos =
-        static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
-      double param = epos->GetUParameter();
-      params[param] = node;
-    }
-  }
-
-  if (nbPoints != params.size()) {
-    MESSAGE( "BAD NODE ON EDGE POSITIONS" );
-    return 0;
-  }
-  UVPtStruct* uvslf = new UVPtStruct[nbPoints + 2];
-
-  double f, l;
-  Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
-
-  bool isForward = (((l - f) * (last - first)) > 0);
-  double paramin = 0;
-  double paramax = 0;
-  if (isForward)
-  {
-    paramin = f;
-    paramax = l;
-    gp_Pnt2d p = C2d->Value(f);        // first point = Vertex Forward
-    uvslf[0].x = p.X();
-    uvslf[0].y = p.Y();
-    uvslf[0].param = f;
-    uvslf[0].node = idFirst;
-    //MESSAGE("__ f "<<f<<" "<<uvslf[0].x <<" "<<uvslf[0].y);
-    map < double, const SMDS_MeshNode* >::iterator itp = params.begin();
-    for (int i = 1; i <= nbPoints; i++)        // nbPoints internal
-    {
-      double param = (*itp).first;
-      gp_Pnt2d p = C2d->Value(param);
-      uvslf[i].x = p.X();
-      uvslf[i].y = p.Y();
-      uvslf[i].param = param;
-      uvslf[i].node = (*itp).second;
-      //MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[i].x <<" "<<uvslf[i].y);
-      itp++;
-    }
-    p = C2d->Value(l);         // last point = Vertex Reversed
-    uvslf[nbPoints + 1].x = p.X();
-    uvslf[nbPoints + 1].y = p.Y();
-    uvslf[nbPoints + 1].param = l;
-    uvslf[nbPoints + 1].node = idLast;
-    //MESSAGE("__ l "<<l<<" "<<uvslf[nbPoints+1].x <<" "<<uvslf[nbPoints+1].y);
-  } else
-  {
-    paramin = l;
-    paramax = f;
-    gp_Pnt2d p = C2d->Value(l);        // first point = Vertex Reversed
-    uvslf[0].x = p.X();
-    uvslf[0].y = p.Y();
-    uvslf[0].param = l;
-    uvslf[0].node = idLast;
-    //MESSAGE("__ l "<<l<<" "<<uvslf[0].x <<" "<<uvslf[0].y);
-    map < double, const SMDS_MeshNode* >::reverse_iterator itp = params.rbegin();
-
-    for (int j = nbPoints; j >= 1; j--)        // nbPoints internal
-    {
-      double param = (*itp).first;
-      int i = nbPoints + 1 - j;
-      gp_Pnt2d p = C2d->Value(param);
-      uvslf[i].x = p.X();
-      uvslf[i].y = p.Y();
-      uvslf[i].param = param;
-      uvslf[i].node = (*itp).second;
-      //MESSAGE("__ "<<i<<" "<<param<<" "<<uvslf[i].x <<" "<<uvslf[i].y);
-      itp++;
-    }
-    p = C2d->Value(f);         // last point = Vertex Forward
-    uvslf[nbPoints + 1].x = p.X();
-    uvslf[nbPoints + 1].y = p.Y();
-    uvslf[nbPoints + 1].param = f;
-    uvslf[nbPoints + 1].node = idFirst;
-    //MESSAGE("__ f "<<f<<" "<<uvslf[nbPoints+1].x <<" "<<uvslf[nbPoints+1].y);
-  }
-
-  ASSERT(paramin != paramax);
-  for (int i = 0; i < nbPoints + 2; i++)
-  {
-    uvslf[i].normParam = (uvslf[i].param - paramin) / (paramax - paramin);
-  }
-
-  return uvslf;
-}
-
-//=============================================================================
-/*!
- *  MakeEdgePoints
- */
-//=============================================================================
-UVPtStruct* StdMeshers_Quadrangle_2D::MakeEdgePoints (SMESH_Mesh & aMesh,
-                                                      const TopoDS_Face& F,
-                                                      const TopoDS_Edge& E,
-                                                      double first, double last,
-                                                      int nb_segm)
-{
-//  MESSAGE("StdMeshers_Quadrangle_2D::MakeEdgePoints");
-
-  UVPtStruct* uvslf = new UVPtStruct[nb_segm + 1];
-  list<double> params;
-
-  // --- edge internal points
-  double fi, li;
-  Handle(Geom_Curve) Curve = BRep_Tool::Curve(E, fi, li);
-  if (!Curve.IsNull()) {
-    try {
-      GeomAdaptor_Curve C3d (Curve);
-      double length = EdgeLength(E);
-      double eltSize = length / nb_segm;
-      GCPnts_UniformAbscissa Discret (C3d, eltSize, fi, li);
-      if (!Discret.IsDone()) return false;
-      int NbPoints = Discret.NbPoints();
-      for (int i = 1; i <= NbPoints; i++) {
-        double param = Discret.Parameter(i);
-        params.push_back(param);
-      }
-    }
-    catch (Standard_Failure) {
-      return 0;
-    }
-  }
-  else
-  {
-    // Edge is a degenerated Edge
-    BRep_Tool::Range(E, fi, li);
-    double du = (li - fi) / nb_segm;
-    for (int i = 1; i <= nb_segm + 1; i++)
-    {
-      double param = fi + (i - 1) * du;
-      params.push_back(param);
-    }
-  }
-
-  double f, l;
-  Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
-  ASSERT(f != l);
-
-  bool isForward = (((l - f) * (last - first)) > 0);
-  if (isForward) {
-    list<double>::iterator itU = params.begin();
-    for (int i = 0; i <= nb_segm; i++) // nbPoints internal
-    {
-      double param = *itU;
-      gp_Pnt2d p = C2d->Value(param);
-      uvslf[i].x = p.X();
-      uvslf[i].y = p.Y();
-      uvslf[i].param = param;
-      uvslf[i].normParam = (param - f) / (l - f);
-      itU++;
-    }
-  } else {
-    list<double>::reverse_iterator itU = params.rbegin();
-    for (int j = nb_segm; j >= 0; j--) // nbPoints internal
-    {
-      double param = *itU;
-      int i = nb_segm - j;
-      gp_Pnt2d p = C2d->Value(param);
-      uvslf[i].x = p.X();
-      uvslf[i].y = p.Y();
-      uvslf[i].param = param;
-      uvslf[i].normParam = (param - l) / (f - l);
-      itU++;
-    }
-  }
-
-  return uvslf;
-}
-
-
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-ostream & StdMeshers_Quadrangle_2D::SaveTo(ostream & save)
-{
-  return save;
-}
-
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-istream & StdMeshers_Quadrangle_2D::LoadFrom(istream & load)
-{
-  return load;
-}
-
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-ostream & operator <<(ostream & save, StdMeshers_Quadrangle_2D & hyp)
-{
-  return hyp.SaveTo( save );
-}
-
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-istream & operator >>(istream & load, StdMeshers_Quadrangle_2D & hyp)
-{
-  return hyp.LoadFrom( load );
-}
index 9b1b0b6f32da7c5aacf033043161124d29ad6f1e..90db88e55f9048b743f5b4622159fed33544be4c 100644 (file)
 #include "SMESH_StdMeshers.hxx"
 
 #include "SMESH_2D_Algo.hxx"
-#include "SMESH_Mesh.hxx"
 #include "Utils_SALOME_Exception.hxx"
 
-#include "gp_XY.hxx"
-
-#include "SMESH_MesherHelper.hxx"
+class SMESH_Mesh;
+class SMESH_MesherHelper;
+class StdMeshers_FaceSide;
+struct uvPtStruct;
 
 //class SMDS_MeshNode;
 
-typedef struct uvPtStruct
-{
-  double param;
-  double normParam;
-  double u; // original 2d parameter
-  double v;
-  double x; // 2d parameter, normalized [0,1]
-  double y; 
-  const SMDS_MeshNode * node;
-} UVPtStruct;
+enum TSideID { BOTTOM_SIDE=0, RIGHT_SIDE, TOP_SIDE, LEFT_SIDE, NB_SIDES };
 
+typedef uvPtStruct UVPtStruct;
 typedef struct faceQuadStruct
 {
-  int nbPts[4];
-  TopoDS_Edge edge[4];
-  double first[4];
-  double last[4];
-  bool isEdgeForward[4];
+  //int nbPts[4];
+  //TopoDS_Edge edge[4];
+  vector< StdMeshers_FaceSide*> side;
+  //double first[4];
+  //double last[4];
+  //bool isEdgeForward[4];
   bool isEdgeOut[4]; // true, if an edge has more nodes, than the opposite
-  UVPtStruct* uv_edges[4];
+  //UVPtStruct* uv_edges[4];
   UVPtStruct* uv_grid;
+  ~faceQuadStruct();
 } FaceQuadStruct;
 
-class STDMESHERS_EXPORT StdMeshers_Quadrangle_2D:
-  public SMESH_2D_Algo
+class STDMESHERS_EXPORT StdMeshers_Quadrangle_2D: public SMESH_2D_Algo
 {
 public:
   StdMeshers_Quadrangle_2D(int hypId, int studyId, SMESH_Gen* gen);
@@ -85,25 +78,13 @@ public:
                                     const bool CreateQuadratic)
     throw (SALOME_Exception);
 
-  static void QuadDelete(FaceQuadStruct* quad);
-
-  /**
-   * Returns NLinkNodeMap from myTool
-   */
-  const NLinkNodeMap& GetNLinkNodeMap() { return myTool->GetNLinkNodeMap(); }
-
-  ostream & SaveTo(ostream & save);
-  istream & LoadFrom(istream & load);
-  friend ostream & operator << (ostream & save, StdMeshers_Quadrangle_2D & hyp);
-  friend istream & operator >> (istream & load, StdMeshers_Quadrangle_2D & hyp);
-
 protected:
 
   FaceQuadStruct* CheckNbEdges(SMESH_Mesh& aMesh,
                                const TopoDS_Shape& aShape)
     throw (SALOME_Exception);
 
-  void SetNormalizedGrid(SMESH_Mesh& aMesh,
+  bool SetNormalizedGrid(SMESH_Mesh& aMesh,
                         const TopoDS_Shape& aShape,
                         FaceQuadStruct*& quad)
     throw (SALOME_Exception);
@@ -133,7 +114,7 @@ protected:
   // is not the same in the case where the global number of nodes on edges is even
   bool myQuadranglePreference;
 
-  SMESH_MesherHelper* myTool; // toll for working with quadratic elements
+  SMESH_MesherHelper* myTool; // tool for working with quadratic elements
 };
 
 #endif
index 4564000325e6691c2f26480c41ea41f2cf06171f..c83bff5250a62d5bf73eee982f1b4d511d9f5b41 100644 (file)
@@ -48,6 +48,7 @@
 #include <TopoDS_Solid.hxx>
 #include <TopoDS_Shell.hxx>
 #include <BRepTools.hxx>
+#include <BRepAdaptor_Curve.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <BRepBuilderAPI_MakeEdge.hxx>
 #include <gp.hxx>
@@ -166,7 +167,7 @@ bool StdMeshers_RadialPrism_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& a
     if ( !outerShell.IsSame( It.Value() ))
       innerShell = It.Value();
   if ( nbShells != 2 )
-    RETURN_BAD_RESULT("Must be 2 shells");
+    return error(COMPERR_BAD_SHAPE, SMESH_Comment("Must be 2 shells but not")<<nbShells);
 
   // ----------------------------------
   // Associate subshapes of the shells
@@ -176,7 +177,7 @@ bool StdMeshers_RadialPrism_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& a
   if ( !TAssocTool::FindSubShapeAssociation( outerShell, &aMesh,
                                              innerShell, &aMesh,
                                              shape2ShapeMap) )
-    RETURN_BAD_RESULT("FindSubShapeAssociation failed");
+    return error(COMPERR_BAD_SHAPE,"Topology of inner and outer shells seems different" );
 
   // ------------------
   // Make mesh
@@ -191,7 +192,8 @@ bool StdMeshers_RadialPrism_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& a
     TopoDS_Face outFace = TopoDS::Face( exp.Current() );
     TopoDS_Face inFace;
     if ( !shape2ShapeMap.IsBound( outFace )) {
-      RETURN_BAD_RESULT("Association not found for face " << meshDS->ShapeToIndex( outFace ));
+      return error(dfltErr(),SMESH_Comment("Corresponding inner face not found for face #" )
+                   << meshDS->ShapeToIndex( outFace ));
     } else {
       inFace = TopoDS::Face( shape2ShapeMap( outFace ));
     }
@@ -200,9 +202,10 @@ bool StdMeshers_RadialPrism_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& a
     TNodeNodeMap nodeIn2OutMap;
     if ( ! TAssocTool::FindMatchingNodesOnFaces( inFace, &aMesh, outFace, &aMesh,
                                                  shape2ShapeMap, nodeIn2OutMap ))
-      RETURN_BAD_RESULT("Different mesh on corresponding out and in faces: "
-                        << meshDS->ShapeToIndex( outFace ) << " and "
-                        << meshDS->ShapeToIndex( inFace ));
+      return error(COMPERR_BAD_INPUT_MESH,SMESH_Comment("Mesh on faces #")
+                   << meshDS->ShapeToIndex( outFace ) << " and "
+                   << meshDS->ShapeToIndex( inFace ) << " seems different" );
+
     // Create volumes
 
     SMDS_ElemIteratorPtr faceIt = meshDS->MeshElements( inFace )->GetElements();
@@ -251,9 +254,10 @@ TNodeColumn* StdMeshers_RadialPrism_3D::makeNodeColumn( TNode2ColumnMap&     n2C
   SMESHDS_Mesh * meshDS = myHelper->GetMeshDS();
   int shapeID = myHelper->GetSubShapeID();
 
-  if ( myLayerPositions.empty() )
-    computeLayerPositions( gpXYZ( inNode ), gpXYZ( outNode ));
-
+  if ( myLayerPositions.empty() ) {
+    gp_Pnt pIn = gpXYZ( inNode ), pOut = gpXYZ( outNode );
+    computeLayerPositions( pIn, pOut );
+  }
   int nbSegments = myLayerPositions.size() + 1;
 
   TNode2ColumnMap::iterator n_col =
@@ -286,7 +290,7 @@ TNodeColumn* StdMeshers_RadialPrism_3D::makeNodeColumn( TNode2ColumnMap&     n2C
 //================================================================================
 //================================================================================
 
-class TNodeDistributor: private StdMeshers_Regular_1D
+class TNodeDistributor: public StdMeshers_Regular_1D
 {
   list <const SMESHDS_Hypothesis *> myUsedHyps;
 public:
@@ -308,22 +312,24 @@ public:
                 const StdMeshers_LayerDistribution* hyp)
   {
     double len = pIn.Distance( pOut );
-    if ( len <= DBL_MIN ) RETURN_BAD_RESULT("Bad points");
+    if ( len <= DBL_MIN ) return error(dfltErr(),"Too close points of inner and outer shells");
 
     if ( !hyp || !hyp->GetLayerDistribution() )
-      RETURN_BAD_RESULT("Bad StdMeshers_LayerDistribution hypothesis");
+      return error(dfltErr(), "Invalid LayerDistribution hypothesis");
     myUsedHyps.clear();
     myUsedHyps.push_back( hyp->GetLayerDistribution() );
 
     TopoDS_Edge edge = BRepBuilderAPI_MakeEdge( pIn, pOut );
-
     SMESH_Hypothesis::Hypothesis_Status aStatus;
     if ( !StdMeshers_Regular_1D::CheckHypothesis( aMesh, edge, aStatus ))
-      RETURN_BAD_RESULT("StdMeshers_Regular_1D::CheckHypothesis() failed with status "<<aStatus);
+      return error(dfltErr(), "StdMeshers_Regular_1D::CheckHypothesis() failed"
+                   "with LayerDistribution hypothesis");
 
+    BRepAdaptor_Curve C3D(edge);
+    double f = C3D.FirstParameter(), l = C3D.LastParameter();
     list< double > params;
-    if ( !StdMeshers_Regular_1D::computeInternalParameters( edge, params, false ))
-      RETURN_BAD_RESULT("StdMeshers_Regular_1D::computeInternalParameters() failed");
+    if ( !StdMeshers_Regular_1D::computeInternalParameters( C3D, len, f, l, params, false ))
+      return error(dfltErr(),"StdMeshers_Regular_1D failed to compute layers distribution");
 
     positions.clear();
     positions.reserve( params.size() );
@@ -353,7 +359,8 @@ protected:
  */
 //================================================================================
 
-bool StdMeshers_RadialPrism_3D::computeLayerPositions(gp_Pnt pIn, gp_Pnt pOut)
+bool StdMeshers_RadialPrism_3D::computeLayerPositions(const gp_Pnt& pIn,
+                                                      const gp_Pnt& pOut)
 {
   if ( myNbLayerHypo )
   {
@@ -365,8 +372,12 @@ bool StdMeshers_RadialPrism_3D::computeLayerPositions(gp_Pnt pIn, gp_Pnt pOut)
   }
   if ( myDistributionHypo ) {
     SMESH_Mesh * mesh = myHelper->GetMesh();
-    return TNodeDistributor::GetDistributor(*mesh)->Compute( myLayerPositions, pIn, pOut,
-                                                             *mesh, myDistributionHypo );
+    if ( !TNodeDistributor::GetDistributor(*mesh)->Compute( myLayerPositions, pIn, pOut,
+                                                            *mesh, myDistributionHypo ))
+    {
+      error( TNodeDistributor::GetDistributor(*mesh)->GetComputeError() );
+      return false;
+    }
   }
-  RETURN_BAD_RESULT("Bad hypothesis");  
+  RETURN_BAD_RESULT("Bad hypothesis");
 }
index 1fb6e8fdf047b5d09bd3130cf945ebfdce232fd7..b7d7968021c9192ec5c7c45902a7a199ffe14f28 100644 (file)
@@ -38,6 +38,7 @@
 class StdMeshers_NumberOfLayers;
 class StdMeshers_LayerDistribution;
 class SMESH_MesherHelper;
+class gp_Pnt;
 
 class STDMESHERS_EXPORT StdMeshers_RadialPrism_3D: public SMESH_3D_Algo
 {
@@ -60,7 +61,8 @@ protected:
                                const SMDS_MeshNode* outNode,
                                const SMDS_MeshNode* inNode);
 
-  bool computeLayerPositions(gp_Pnt pIn, gp_Pnt pOut);
+  bool computeLayerPositions(const gp_Pnt& pIn,
+                             const gp_Pnt& pOut);
 
 
   const StdMeshers_NumberOfLayers*    myNbLayerHypo;
index e7f45cd66da0320742cbcc35e7ccf273d7d32eda..9e59aa0c6b4a28c654a274a61fd9dee4265ad322 100644 (file)
 #include "StdMeshers_StartEndLength.hxx"
 #include "StdMeshers_Deflection1D.hxx"
 #include "StdMeshers_AutomaticLength.hxx"
+#include "StdMeshers_SegmentLengthAroundVertex.hxx"
 
 #include "SMESH_Gen.hxx"
 #include "SMESH_Mesh.hxx"
 #include "SMESH_HypoFilter.hxx"
 #include "SMESH_subMesh.hxx"
+#include "SMESH_subMeshEventListener.hxx"
+#include "SMESH_Comment.hxx"
 
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
-#include "SMDS_EdgePosition.hxx"
 
 #include "Utils_SALOME_Exception.hxx"
 #include "utilities.h"
 
+#include <BRepAdaptor_Curve.hxx>
 #include <BRep_Tool.hxx>
 #include <TopoDS_Edge.hxx>
-#include <TopoDS_Shape.hxx>
-#include <TopTools_ListIteratorOfListOfShape.hxx>
-#include <GeomAdaptor_Curve.hxx>
+#include <TopExp_Explorer.hxx>
 #include <GCPnts_AbscissaPoint.hxx>
 #include <GCPnts_UniformAbscissa.hxx>
 #include <GCPnts_UniformDeflection.hxx>
 #include <Precision.hxx>
-#include <Expr_GeneralExpression.hxx>
-#include <Expr_NamedUnknown.hxx>
-#include <Expr_Array1OfNamedUnknown.hxx>
-#include <ExprIntrp_GenExp.hxx>
-#include <TColStd_Array1OfReal.hxx>
-#include <OSD.hxx>
-
-#include <Standard_ErrorHandler.hxx>
-#include <Standard_Failure.hxx>
 
 #include <string>
-#include <math.h>
 
 using namespace std;
 
@@ -240,49 +231,6 @@ bool StdMeshers_Regular_1D::CheckHypothesis
   return ( _hypType != NONE );
 }
 
-//=======================================================================
-//function : compensateError
-//purpose  : adjust theParams so that the last segment length == an
-//=======================================================================
-
-static void compensateError(double a1, double an,
-                            double U1, double Un,
-                            double             length,
-                            GeomAdaptor_Curve& C3d,
-                            list<double> &     theParams)
-{
-  int i, nPar = theParams.size();
-  if ( a1 + an < length && nPar > 1 )
-  {
-    list<double>::reverse_iterator itU = theParams.rbegin();
-    double Ul = *itU++;
-    // dist from the last point to the edge end <Un>, it should be equal <an>
-    double Ln = GCPnts_AbscissaPoint::Length( C3d, Ul, Un );
-    double dLn = an - Ln; // error of <an>
-    if ( Abs( dLn ) <= Precision::Confusion() )
-      return;
-    double dU = Abs( Ul - *itU ); // parametric length of the last but one segment
-    double dUn = dLn * Abs( Un - U1 ) / length; // parametric error of <an>
-    if ( dUn < 0.5 * dU ) { // last segment is a bit shorter than it should
-      dUn = -dUn; // move the last parameter to the edge beginning
-    }
-    else {  // last segment is much shorter than it should -> remove the last param and
-      theParams.pop_back(); nPar--; // move the rest points toward the edge end
-      Ln = GCPnts_AbscissaPoint::Length( C3d, theParams.back(), Un );
-      dUn = ( an - Ln ) * Abs( Un - U1 ) / length;
-      if ( dUn < 0.5 * dU )
-        dUn = -dUn;
-    }
-    if ( U1 > Un )
-      dUn = -dUn;
-    double q  = dUn / ( nPar - 1 );
-    for ( itU = theParams.rbegin(), i = 1; i < nPar; itU++, i++ ) {
-      (*itU) += dUn;
-      dUn -= q;
-    }
-  }
-}
-
 static bool computeParamByFunc(Adaptor3d_Curve& C3d, double first, double last,
                                double length, bool theReverse, 
                                int nbSeg, Function& func,
@@ -336,22 +284,274 @@ static bool computeParamByFunc(Adaptor3d_Curve& C3d, double first, double last,
   return true;
 }
 
+
+//================================================================================
+/*!
+ * \brief adjust internal node parameters so that the last segment length == an
+  * \param a1 - the first segment length
+  * \param an - the last segment length
+  * \param U1 - the first edge parameter
+  * \param Un - the last edge parameter
+  * \param length - the edge length
+  * \param C3d - the edge curve
+  * \param theParams - internal node parameters to adjust
+  * \param adjustNeighbors2an - to adjust length of segments next to the last one
+  *  and not to remove parameters
+ */
+//================================================================================
+
+static void compensateError(double a1, double an,
+                            double U1, double Un,
+                            double            length,
+                            Adaptor3d_Curve&  C3d,
+                            list<double> &    theParams,
+                            bool              adjustNeighbors2an = false)
+{
+  int i, nPar = theParams.size();
+  if ( a1 + an < length && nPar > 1 )
+  {
+    bool reverse = ( U1 > Un );
+    GCPnts_AbscissaPoint Discret(C3d, reverse ? an : -an, Un);
+    if ( !Discret.IsDone() )
+      return;
+    double Utgt = Discret.Parameter(); // target value of the last parameter
+    list<double>::reverse_iterator itU = theParams.rbegin();
+    double Ul = *itU++; // real value of the last parameter
+    double dUn = Utgt - Ul; // parametric error of <an>
+    if ( Abs(dUn) <= Precision::Confusion() )
+      return;
+    double dU = Abs( Ul - *itU ); // parametric length of the last but one segment
+    if ( adjustNeighbors2an || Abs(dUn) < 0.5 * dU ) { // last segment is a bit shorter than it should
+      // move the last parameter to the edge beginning
+    }
+    else {  // last segment is much shorter than it should -> remove the last param and
+      theParams.pop_back(); nPar--; // move the rest points toward the edge end
+      dUn = Utgt - theParams.back();
+    }
+
+    double q  = dUn / ( nPar - 1 );
+    if ( !adjustNeighbors2an ) {
+      for ( itU = theParams.rbegin(), i = 1; i < nPar; itU++, i++ ) {
+        (*itU) += dUn;
+        dUn -= q;
+      }
+    }
+    else {
+      theParams.back() += dUn;
+      double sign = reverse ? -1 : 1;
+      double prevU = theParams.back();
+      itU = theParams.rbegin();
+      for ( ++itU, i = 2; i < nPar; ++itU, i++ ) {
+        double newU = *itU + dUn;
+        if ( newU*sign < prevU*sign ) {
+          prevU = *itU = newU;
+          dUn -= q;
+        }
+        else { // set U between prevU and next valid param
+          list<double>::reverse_iterator itU2 = itU;
+          ++itU2;
+          int nb = 2;
+          while ( (*itU2)*sign > prevU*sign ) {
+            ++itU2; ++nb;
+          }
+          dU = ( *itU2 - prevU ) / nb;
+          while ( itU != itU2 ) {
+            *itU += dU; ++itU;
+          }
+          break;
+        }
+      }
+    }
+  }
+}
+
+//================================================================================
+/*!
+ * \brief Class used to clean mesh on edges when 0D hyp modified.
+ * Common approach doesn't work when 0D algo is missing because the 0D hyp is
+ * considered as not participating in computation whereas it is used by 1D algo.
+ */
+//================================================================================
+
+// struct VertexEventListener : public SMESH_subMeshEventListener
+// {
+//   VertexEventListener():SMESH_subMeshEventListener(0) // won't be deleted by submesh
+//   {}
+//   /*!
+//    * \brief Clean mesh on edges
+//    * \param event - algo_event or compute_event itself (of SMESH_subMesh)
+//    * \param eventType - ALGO_EVENT or COMPUTE_EVENT (of SMESH_subMesh)
+//    * \param subMesh - the submesh where the event occures
+//    */
+//   void ProcessEvent(const int event, const int eventType, SMESH_subMesh* subMesh,
+//                     EventListenerData*, const SMESH_Hypothesis*)
+//   {
+//     if ( eventType == SMESH_subMesh::ALGO_EVENT) // all algo events
+//     {
+//       subMesh->ComputeStateEngine( SMESH_subMesh::MODIF_ALGO_STATE );
+//     }
+//   }
+// }; // struct VertexEventListener
+
+//=============================================================================
+/*!
+ * \brief Sets event listener to vertex submeshes
+ * \param subMesh - submesh where algo is set
+ *
+ * This method is called when a submesh gets HYP_OK algo_state.
+ * After being set, event listener is notified on each event of a submesh.
+ */
+//=============================================================================
+
+void StdMeshers_Regular_1D::SetEventListener(SMESH_subMesh* subMesh)
+{
+//   static VertexEventListener listener;
+//   SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
+//   while (smIt->more()) {
+//     subMesh->SetEventListener( &listener, 0, smIt->next() );
+//   }
+}
+
+//=============================================================================
+/*!
+ * \brief Do nothing
+ * \param subMesh - restored submesh
+ *
+ * This method is called only if a submesh has HYP_OK algo_state.
+ */
+//=============================================================================
+
+void StdMeshers_Regular_1D::SubmeshRestored(SMESH_subMesh* subMesh)
+{
+}
+
+//=============================================================================
+/*!
+ * \brief Return StdMeshers_SegmentLengthAroundVertex assigned to vertex
+ */
+//=============================================================================
+
+const StdMeshers_SegmentLengthAroundVertex*
+StdMeshers_Regular_1D::getVertexHyp(SMESH_Mesh &          theMesh,
+                                    const TopoDS_Vertex & theV)
+{
+  static SMESH_HypoFilter filter( SMESH_HypoFilter::HasName("SegmentAroundVertex_0D"));
+  if ( const SMESH_Hypothesis * h = theMesh.GetHypothesis( theV, filter, true ))
+  {
+    SMESH_Algo* algo = const_cast< SMESH_Algo* >( static_cast< const SMESH_Algo* > ( h ));
+    const list <const SMESHDS_Hypothesis *> & hypList = algo->GetUsedHypothesis( theMesh, theV, 0 );
+    if ( !hypList.empty() && string("SegmentLengthAroundVertex") == hypList.front()->GetName() )
+      return static_cast<const StdMeshers_SegmentLengthAroundVertex*>( hypList.front() );
+  }
+  return 0;
+}
+
+//================================================================================
+/*!
+ * \brief Tune parameters to fit "SegmentLengthAroundVertex" hypothesis
+  * \param theC3d - wire curve
+  * \param theLength - curve length
+  * \param theParameters - internal nodes parameters to modify
+  * \param theVf - 1st vertex
+  * \param theVl - 2nd vertex
+ */
+//================================================================================
+
+void StdMeshers_Regular_1D::redistributeNearVertices (SMESH_Mesh &          theMesh,
+                                                      Adaptor3d_Curve &     theC3d,
+                                                      double                theLength,
+                                                      std::list< double > & theParameters,
+                                                      const TopoDS_Vertex & theVf,
+                                                      const TopoDS_Vertex & theVl)
+{
+  double f = theC3d.FirstParameter(), l = theC3d.LastParameter();
+  int nPar = theParameters.size();
+  for ( int isEnd1 = 0; isEnd1 < 2; ++isEnd1 )
+  {
+    const TopoDS_Vertex & V = isEnd1 ? theVf : theVl;
+    const StdMeshers_SegmentLengthAroundVertex* hyp = getVertexHyp (theMesh, V );
+    if ( hyp ) {
+      double vertexLength = hyp->GetLength();
+      if ( vertexLength > theLength / 2.0 )
+        continue;
+      if ( isEnd1 ) { // to have a segment of interest at end of theParameters
+        theParameters.reverse();
+        std::swap( f, l );
+      }
+      if ( _hypType == NB_SEGMENTS )
+      {
+        compensateError(0, vertexLength, f, l, theLength, theC3d, theParameters, true );
+      }
+      else if ( nPar <= 3 )
+      {
+        if ( !isEnd1 )
+          vertexLength = -vertexLength;
+        GCPnts_AbscissaPoint Discret(theC3d, vertexLength, l);
+        if ( Discret.IsDone() ) {
+          if ( nPar == 0 )
+            theParameters.push_back( Discret.Parameter());
+          else {
+            double L = GCPnts_AbscissaPoint::Length( theC3d, theParameters.back(), l);
+            if ( vertexLength < L / 2.0 )
+              theParameters.push_back( Discret.Parameter());
+            else
+              compensateError(0, vertexLength, f, l, theLength, theC3d, theParameters, true );
+          }
+        }
+      }
+      else
+      {
+        // recompute params between the last segment and a middle one.
+        // find size of a middle segment
+        int nHalf = ( nPar-1 ) / 2;
+        list< double >::reverse_iterator itU = theParameters.rbegin();
+        std::advance( itU, nHalf );
+        double Um = *itU++;
+        double Lm = GCPnts_AbscissaPoint::Length( theC3d, Um, *itU);
+        double L = GCPnts_AbscissaPoint::Length( theC3d, *itU, l);
+        StdMeshers_Regular_1D algo( *this );
+        algo._hypType = BEG_END_LENGTH;
+        algo._value[ BEG_LENGTH_IND ] = Lm;
+        algo._value[ END_LENGTH_IND ] = vertexLength;
+        double from = *itU, to = l;
+        if ( isEnd1 ) {
+          std::swap( from, to );
+          std::swap( algo._value[ BEG_LENGTH_IND ], algo._value[ END_LENGTH_IND ]);
+        }
+        list<double> params;
+        if ( algo.computeInternalParameters( theC3d, L, from, to, params, false ))
+        {
+          if ( isEnd1 ) params.reverse();
+          while ( 1 + nHalf-- )
+            theParameters.pop_back();
+          theParameters.splice( theParameters.end(), params );
+        }
+        else
+        {
+          compensateError(0, vertexLength, f, l, theLength, theC3d, theParameters, true );
+        }
+      }
+      if ( isEnd1 )
+        theParameters.reverse();
+    }
+  }
+}
+
 //=============================================================================
 /*!
  *  
  */
 //=============================================================================
-bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge,
-                                                      list<double> &     theParams,
-                                                      const bool         theReverse) const
+bool StdMeshers_Regular_1D::computeInternalParameters(Adaptor3d_Curve& theC3d,
+                                                      double           theLength,
+                                                      double           theFirstU,
+                                                      double           theLastU,
+                                                      list<double> &   theParams,
+                                                      const bool       theReverse)
 {
   theParams.clear();
 
-  double f, l;
-  Handle(Geom_Curve) Curve = BRep_Tool::Curve(theEdge, f, l);
-  GeomAdaptor_Curve C3d (Curve, f, l);
-
-  double length = EdgeLength(theEdge);
+  double f = theFirstU, l = theLastU;
 
   switch( _hypType )
   {
@@ -362,10 +562,10 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge
     if ( _hypType == LOCAL_LENGTH )
     {
       // Local Length hypothesis
-      double nbseg = ceil(length / _value[ BEG_LENGTH_IND ]); // integer sup
+      double nbseg = ceil(theLength / _value[ BEG_LENGTH_IND ]); // integer sup
       if (nbseg <= 0)
         nbseg = 1;                        // degenerated edge
-      eltSize = length / nbseg;
+      eltSize = theLength / nbseg;
     }
     else
     {
@@ -405,7 +605,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge
       case StdMeshers_NumberOfSegments::DT_TabFunc:
         {
           FunctionTable func(_vvalue[ TAB_FUNC_IND ], _ivalue[ CONV_MODE_IND ]);
-          return computeParamByFunc(C3d, f, l, length, theReverse,
+          return computeParamByFunc(theC3d, f, l, theLength, theReverse,
                                     _ivalue[ NB_SEGMENTS_IND ], func,
                                     theParams);
         }
@@ -413,21 +613,21 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge
       case StdMeshers_NumberOfSegments::DT_ExprFunc:
         {
           FunctionExpr func(_svalue[ EXPR_FUNC_IND ].c_str(), _ivalue[ CONV_MODE_IND ]);
-          return computeParamByFunc(C3d, f, l, length, theReverse,
+          return computeParamByFunc(theC3d, f, l, theLength, theReverse,
                                     _ivalue[ NB_SEGMENTS_IND ], func,
                                     theParams);
         }
         break;
       case StdMeshers_NumberOfSegments::DT_Regular:
-        eltSize = length / _ivalue[ NB_SEGMENTS_IND ];
+        eltSize = theLength / _ivalue[ NB_SEGMENTS_IND ];
         break;
       default:
         return false;
       }
     }
-    GCPnts_UniformAbscissa Discret(C3d, eltSize, f, l);
+    GCPnts_UniformAbscissa Discret(theC3d, eltSize, f, l);
     if ( !Discret.IsDone() )
-      return false;
+      return error( dfltErr(), "GCPnts_UniformAbscissa failed");
 
     int NbPoints = Discret.NbPoints();
     for ( int i = 2; i < NbPoints; i++ )
@@ -435,26 +635,26 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge
       double param = Discret.Parameter(i);
       theParams.push_back( param );
     }
-    compensateError( eltSize, eltSize, f, l, length, C3d, theParams ); // for PAL9899
+    compensateError( eltSize, eltSize, f, l, theLength, theC3d, theParams ); // for PAL9899
     return true;
   }
 
   case BEG_END_LENGTH: {
 
-    // geometric progression: SUM(n) = ( a1 - an * q ) / ( 1 - q ) = length
+    // geometric progression: SUM(n) = ( a1 - an * q ) / ( 1 - q ) = theLength
 
     double a1 = _value[ BEG_LENGTH_IND ];
     double an = _value[ END_LENGTH_IND ];
-    double q  = ( length - a1 ) / ( length - an );
+    double q  = ( theLength - a1 ) / ( theLength - an );
 
     double U1 = theReverse ? l : f;
     double Un = theReverse ? f : l;
     double param = U1;
     double eltSize = theReverse ? -a1 : a1;
     while ( 1 ) {
-      // computes a point on a curve <C3d> at the distance <eltSize>
+      // computes a point on a curve <theC3d> at the distance <eltSize>
       // from the point of parameter <param>.
-      GCPnts_AbscissaPoint Discret( C3d, eltSize, param );
+      GCPnts_AbscissaPoint Discret( theC3d, eltSize, param );
       if ( !Discret.IsDone() ) break;
       param = Discret.Parameter();
       if ( param > f && param < l )
@@ -463,18 +663,18 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge
         break;
       eltSize *= q;
     }
-    compensateError( a1, an, U1, Un, length, C3d, theParams );
+    compensateError( a1, an, U1, Un, theLength, theC3d, theParams );
     return true;
   }
 
   case ARITHMETIC_1D: {
 
-    // arithmetic progression: SUM(n) = ( an - a1 + q ) * ( a1 + an ) / ( 2 * q ) = length
+    // arithmetic progression: SUM(n) = ( an - a1 + q ) * ( a1 + an ) / ( 2 * q ) = theLength
 
     double a1 = _value[ BEG_LENGTH_IND ];
     double an = _value[ END_LENGTH_IND ];
 
-    double  q = ( an - a1 ) / ( 2 *length/( a1 + an ) - 1 );
+    double  q = ( an - a1 ) / ( 2 *theLength/( a1 + an ) - 1 );
     int     n = int( 1 + ( an - a1 ) / q );
 
     double U1 = theReverse ? l : f;
@@ -486,9 +686,9 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge
       q = -q;
     }
     while ( n-- > 0 && eltSize * ( Un - U1 ) > 0 ) {
-      // computes a point on a curve <C3d> at the distance <eltSize>
+      // computes a point on a curve <theC3d> at the distance <eltSize>
       // from the point of parameter <param>.
-      GCPnts_AbscissaPoint Discret( C3d, eltSize, param );
+      GCPnts_AbscissaPoint Discret( theC3d, eltSize, param );
       if ( !Discret.IsDone() ) break;
       param = Discret.Parameter();
       if ( param > f && param < l )
@@ -497,14 +697,14 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge
         break;
       eltSize += q;
     }
-    compensateError( a1, an, U1, Un, length, C3d, theParams );
+    compensateError( a1, an, U1, Un, theLength, theC3d, theParams );
 
     return true;
   }
 
   case DEFLECTION: {
 
-    GCPnts_UniformDeflection Discret(C3d, _value[ DEFLECTION_IND ], f, l, true);
+    GCPnts_UniformDeflection Discret(theC3d, _value[ DEFLECTION_IND ], f, l, true);
     if ( !Discret.IsDone() )
       return false;
 
@@ -532,13 +732,10 @@ bool StdMeshers_Regular_1D::computeInternalParameters(const TopoDS_Edge& theEdge
 
 bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
 {
-  MESSAGE("StdMeshers_Regular_1D::Compute");
-
   if ( _hypType == NONE )
     return false;
 
   SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
-  aMesh.GetSubMesh(aShape);
 
   const TopoDS_Edge & EE = TopoDS::Edge(aShape);
   TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD));
@@ -551,40 +748,25 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
   TopExp::Vertices(E, VFirst, VLast);   // Vfirst corresponds to f and Vlast to l
 
   ASSERT(!VFirst.IsNull());
-  SMDS_NodeIteratorPtr lid= aMesh.GetSubMesh(VFirst)->GetSubMeshDS()->GetNodes();
-  if (!lid->more())
-  {
-    MESSAGE (" NO NODE BUILT ON VERTEX ");
-    return false;
-  }
-  const SMDS_MeshNode * idFirst = lid->next();
-
   ASSERT(!VLast.IsNull());
-  lid=aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes();
-  if (!lid->more()) {
-    MESSAGE (" NO NODE BUILT ON VERTEX ");
-    return false;
-  }
-  const SMDS_MeshNode * idLast = lid->next();
+  const SMDS_MeshNode * idFirst = SMESH_Algo::VertexNode( VFirst, meshDS );
+  const SMDS_MeshNode * idLast = SMESH_Algo::VertexNode( VLast, meshDS );
+  if (!idFirst || !idLast)
+    return error( COMPERR_BAD_INPUT_MESH, "No node on vertex");
 
-  if (!Curve.IsNull()) {
+  if (!Curve.IsNull())
+  {
     list< double > params;
     bool reversed = false;
     if ( !_mainEdge.IsNull() )
       reversed = aMesh.IsReversedInChain( EE, _mainEdge );
-    try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
-      OCC_CATCH_SIGNALS;
-#endif
-      if ( ! computeInternalParameters( E, params, reversed )) {
-        //cout << "computeInternalParameters() failed" <<endl;
-        return false;
-      }
-    }
-    catch ( Standard_Failure ) {
-      //cout << "computeInternalParameters() failed, Standard_Failure" <<endl;
+
+    BRepAdaptor_Curve C3d( E );
+    double length = EdgeLength( E );
+    if ( ! computeInternalParameters( C3d, length, f, l, params, reversed )) {
       return false;
     }
+    redistributeNearVertices( aMesh, C3d, length, params, VFirst, VLast );
 
     // edge extrema (indexes : 1 & NbPoints) already in SMDS (TopoDS_Vertex)
     // only internal nodes receive an edge position with param on curve
@@ -592,10 +774,6 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
     const SMDS_MeshNode * idPrev = idFirst;
     double parPrev = f;
     double parLast = l;
-//     if(reversed) {
-//       parPrev = l;
-//       parLast = f;
-//     }
     
     for (list<double>::iterator itU = params.begin(); itU != params.end(); itU++) {
       double param = *itU;
@@ -638,13 +816,11 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
   else {
     // Edge is a degenerated Edge : We put n = 5 points on the edge.
     const int NbPoints = 5;
-    BRep_Tool::Range(E, f, l);
+    BRep_Tool::Range( E, f, l ); // PAL15185
     double du = (l - f) / (NbPoints - 1);
     //MESSAGE("************* Degenerated edge! *****************");
 
-    TopoDS_Vertex V1, V2;
-    TopExp::Vertices(E, V1, V2);
-    gp_Pnt P = BRep_Tool::Pnt(V1);
+    gp_Pnt P = BRep_Tool::Pnt(VFirst);
 
     const SMDS_MeshNode * idPrev = idFirst;
     for (int i = 2; i < NbPoints; i++) {
@@ -730,47 +906,3 @@ StdMeshers_Regular_1D::GetUsedHypothesis(SMESH_Mesh &         aMesh,
 
   return _usedHypList;
 }
-
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-ostream & StdMeshers_Regular_1D::SaveTo(ostream & save)
-{
-  return save;
-}
-
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-istream & StdMeshers_Regular_1D::LoadFrom(istream & load)
-{
-  return load;
-}
-
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-ostream & operator <<(ostream & save, StdMeshers_Regular_1D & hyp)
-{
-  return hyp.SaveTo( save );
-}
-
-//=============================================================================
-/*!
- *  
- */
-//=============================================================================
-
-istream & operator >>(istream & load, StdMeshers_Regular_1D & hyp)
-{
-  return hyp.LoadFrom( load );
-}
index c8a856d0b2b287550f33c885579de43514af0030..269a034bc0039699e1417581e5ebb5edf242e395 100644 (file)
 
 #include "SMESH_1D_Algo.hxx"
 
-class TopoDS_Edge;
+class Adaptor3d_Curve;
+class TopoDS_Vertex;
+class StdMeshers_SegmentLengthAroundVertex;
 
-class STDMESHERS_EXPORT StdMeshers_Regular_1D:
-  public SMESH_1D_Algo
+class STDMESHERS_EXPORT StdMeshers_Regular_1D: public SMESH_1D_Algo
 {
 public:
   StdMeshers_Regular_1D(int hypId, int studyId, SMESH_Gen* gen);
@@ -53,16 +54,45 @@ public:
   virtual const std::list <const SMESHDS_Hypothesis *> &
     GetUsedHypothesis(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, const bool=true);
 
-  ostream & SaveTo(ostream & save);
-  istream & LoadFrom(istream & load);
-  friend ostream & operator << (ostream & save, StdMeshers_Regular_1D & hyp);
-  friend istream & operator >> (istream & load, StdMeshers_Regular_1D & hyp);
+  /*!
+   * \brief Sets event listener to submeshes if necessary
+    * \param subMesh - submesh where algo is set
+   *
+   * This method is called when a submesh gets HYP_OK algo_state.
+   * After being set, event listener is notified on each event of a submesh.
+   */
+  virtual void SetEventListener(SMESH_subMesh* subMesh);
+
+  /*!
+   * \brief Allow algo to do something after persistent restoration
+   * \param subMesh - restored submesh
+   *
+   * This method is called only if a submesh has HYP_OK algo_state.
+   */
+  void SubmeshRestored(SMESH_subMesh* subMesh);
 
 protected:
 
-  virtual bool computeInternalParameters (const TopoDS_Edge&    theEdge,
+  virtual bool computeInternalParameters (Adaptor3d_Curve &     theC3d,
+                                          double                theLength,
+                                          double                theFirstU,
+                                          double                theLastU,
                                           std::list< double > & theParameters,
-                                          const bool            theReverse) const;
+                                          const bool            theReverse);
+
+  virtual void redistributeNearVertices (SMESH_Mesh &          theMesh,
+                                         Adaptor3d_Curve &     theC3d,
+                                         double                theLength,
+                                         std::list< double > & theParameters,
+                                         const TopoDS_Vertex & theVf,
+                                         const TopoDS_Vertex & theVl);
+
+  /*!
+   * \brief Return StdMeshers_SegmentLengthAroundVertex assigned to vertex
+   */
+  static const
+  StdMeshers_SegmentLengthAroundVertex* getVertexHyp(SMESH_Mesh &          theMesh,
+                                                     const TopoDS_Vertex & theV);
 
   enum HypothesisType { LOCAL_LENGTH, NB_SEGMENTS, BEG_END_LENGTH, DEFLECTION, ARITHMETIC_1D, NONE };
 
diff --git a/src/StdMeshers/StdMeshers_SegmentAroundVertex_0D.cxx b/src/StdMeshers/StdMeshers_SegmentAroundVertex_0D.cxx
new file mode 100644 (file)
index 0000000..c4e809d
--- /dev/null
@@ -0,0 +1,96 @@
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+// File      : StdMeshers_SegmentAroundVertex_0D.cxx
+// Module    : SMESH
+// Created   : Fri Oct 20 11:37:07 2006
+// Author    : Edward AGAPOV (eap)
+
+
+#include "StdMeshers_SegmentAroundVertex_0D.hxx"
+
+//=======================================================================
+//function : StdMeshers_SegmentAroundVertex_0D
+//purpose  : 
+//=======================================================================
+
+StdMeshers_SegmentAroundVertex_0D::StdMeshers_SegmentAroundVertex_0D
+                                   (int hypId, int studyId, SMESH_Gen* gen)
+  :SMESH_0D_Algo(hypId, studyId, gen)
+{
+  _name = "SegmentAroundVertex_0D";
+  // it is assigned to vertices but influence a state of EDGE submeshes 
+  _shapeType = (1 << TopAbs_VERTEX);   // 1 bit per shape type
+
+  _compatibleHypothesis.push_back("SegmentLengthAroundVertex");
+}
+
+//================================================================================
+/*!
+ * \brief Destructor
+ */
+//================================================================================
+
+StdMeshers_SegmentAroundVertex_0D::~StdMeshers_SegmentAroundVertex_0D()
+{}
+
+//=======================================================================
+//function : CheckHypothesis
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_SegmentAroundVertex_0D::CheckHypothesis(SMESH_Mesh&                          aMesh,
+                                                        const TopoDS_Shape&                  aShape,
+                                                        SMESH_Hypothesis::Hypothesis_Status& aStatus)
+{
+  list <const SMESHDS_Hypothesis * >::const_iterator itl;
+
+  const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
+  if ( hyps.size() == 0 )
+  {
+    aStatus = SMESH_Hypothesis::HYP_MISSING;
+    return false;  // can't work with no hypothesis
+  }
+
+  if ( hyps.size() > 1 )
+  {
+    aStatus = SMESH_Hypothesis::HYP_ALREADY_EXIST;
+  }
+  else
+  {
+    aStatus = SMESH_Hypothesis::HYP_OK;
+  }
+  return ( aStatus == HYP_OK );
+}
+
+//=======================================================================
+//function : Compute
+//purpose  : 
+//=======================================================================
+
+bool StdMeshers_SegmentAroundVertex_0D::Compute(SMESH_Mesh&, const TopoDS_Shape&)
+{
+  // This algorithm exists in order just to enable assignation of
+  // StdMeshers_SegmentLengthAroundVertex hypothesis
+  return true;
+}
diff --git a/src/StdMeshers/StdMeshers_SegmentAroundVertex_0D.hxx b/src/StdMeshers/StdMeshers_SegmentAroundVertex_0D.hxx
new file mode 100644 (file)
index 0000000..01bf758
--- /dev/null
@@ -0,0 +1,50 @@
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : StdMeshers_SegmentAroundVertex_0D.hxx
+//  Module : SMESH
+
+#ifndef _SMESH_SegmentAroundVertex_0D_HXX_
+#define _SMESH_SegmentAroundVertex_0D_HXX_
+
+#include "SMESH_0D_Algo.hxx"
+
+/*!
+ * \brief Algorithm existing in order just to enable assignation of
+ * StdMeshers_SegmentLengthAroundVertex hypothesis
+ */
+class StdMeshers_SegmentAroundVertex_0D: public SMESH_0D_Algo
+{
+public:
+  StdMeshers_SegmentAroundVertex_0D(int hypId, int studyId, SMESH_Gen* gen);
+  virtual ~StdMeshers_SegmentAroundVertex_0D();
+
+  virtual bool CheckHypothesis(SMESH_Mesh&                          aMesh,
+                               const TopoDS_Shape&                  aShape,
+                               SMESH_Hypothesis::Hypothesis_Status& aStatus);
+
+  virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape);
+  
+};
+
+#endif
diff --git a/src/StdMeshers/StdMeshers_SegmentLengthAroundVertex.cxx b/src/StdMeshers/StdMeshers_SegmentLengthAroundVertex.cxx
new file mode 100644 (file)
index 0000000..f44b755
--- /dev/null
@@ -0,0 +1,204 @@
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : StdMeshers_SegmentLengthAroundVertex.cxx
+//  Module : SMESH
+//  $Header$
+
+#include "StdMeshers_SegmentLengthAroundVertex.hxx"
+
+#include "SMESH_Mesh.hxx"
+#include "SMESH_Algo.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMESHDS_Mesh.hxx"
+#include "SMESHDS_SubMesh.hxx"
+#include "SMESH_MeshEditor.hxx"
+#include "SMESH_MesherHelper.hxx"
+
+#include "utilities.h"
+
+#include <BRepAdaptor_Curve.hxx>
+#include <GCPnts_AbscissaPoint.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+
+using namespace std;
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+StdMeshers_SegmentLengthAroundVertex::StdMeshers_SegmentLengthAroundVertex
+                                       (int hypId, int studyId, SMESH_Gen * gen)
+  :SMESH_Hypothesis(hypId, studyId, gen)
+{
+  _length = 1.;
+  _name = "SegmentLengthAroundVertex";
+  _param_algo_dim = 0; // is used by StdMeshers_SegmentAroundVertex_0D
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+StdMeshers_SegmentLengthAroundVertex::~StdMeshers_SegmentLengthAroundVertex()
+{
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+void StdMeshers_SegmentLengthAroundVertex::SetLength(double length) throw(SALOME_Exception)
+{
+  if (length <= 0)
+    throw SALOME_Exception(LOCALIZED("length must be positive"));
+  if (_length != length) {
+    _length = length;
+    NotifySubMeshesHypothesisModification();
+  }
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+double StdMeshers_SegmentLengthAroundVertex::GetLength() const
+{
+  return _length;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+ostream & StdMeshers_SegmentLengthAroundVertex::SaveTo(ostream & save)
+{
+  save << this->_length;
+  return save;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+istream & StdMeshers_SegmentLengthAroundVertex::LoadFrom(istream & load)
+{
+  bool isOK = true;
+  double a;
+  isOK = (load >> a);
+  if (isOK)
+    this->_length = a;
+  else
+    load.clear(ios::badbit | load.rdstate());
+  return load;
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+ostream & operator <<(ostream & save, StdMeshers_SegmentLengthAroundVertex & hyp)
+{
+  return hyp.SaveTo( save );
+}
+
+//=============================================================================
+/*!
+ *  
+ */
+//=============================================================================
+
+istream & operator >>(istream & load, StdMeshers_SegmentLengthAroundVertex & hyp)
+{
+  return hyp.LoadFrom( load );
+}
+
+//================================================================================
+/*!
+ * \brief Initialize segment length by the mesh built on the geometry
+ * \param theMesh - the built mesh
+ * \param theShape - the geometry of interest
+ * \retval bool - true if parameter values have been successfully defined
+ */
+//================================================================================
+
+bool StdMeshers_SegmentLengthAroundVertex::SetParametersByMesh(const SMESH_Mesh*   theMesh,
+                                                               const TopoDS_Shape& theShape)
+{
+  if ( !theMesh || theShape.IsNull() || theShape.ShapeType() != TopAbs_VERTEX )
+    return false;
+
+  SMESH_MeshEditor editor( const_cast<SMESH_Mesh*>( theMesh ) );
+  SMESH_MesherHelper helper( *editor.GetMesh() );
+
+  // get node built on theShape vertex
+  SMESHDS_Mesh* meshDS = editor.GetMeshDS();
+  SMESHDS_SubMesh* smV = meshDS->MeshElements( theShape );
+  if ( !smV || smV->NbNodes() == 0 )
+    return false;
+  const SMDS_MeshNode* vNode = smV->GetNodes()->next();
+
+  // calculate average length of segments sharing vNode
+
+  _length = 0.;
+  int nbSegs = 0;
+
+  SMDS_ElemIteratorPtr segIt = vNode->GetInverseElementIterator(SMDSAbs_Edge);
+  while ( segIt->more() ) {
+    const SMDS_MeshElement* seg = segIt->next();
+    // get geom edge
+    int shapeID = editor.FindShape( seg );
+    if (!shapeID) continue;
+    const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
+    if ( s.IsNull() || s.ShapeType() != TopAbs_EDGE ) continue;
+    const TopoDS_Edge& edge = TopoDS::Edge( s );
+    // params of edge ends
+    double u0 = helper.GetNodeU( edge, seg->GetNode(0) );
+    double u1 = helper.GetNodeU( edge, seg->GetNode(1) );
+    // length
+    BRepAdaptor_Curve AdaptCurve( edge );
+    _length += GCPnts_AbscissaPoint::Length( AdaptCurve, u0, u1);
+    nbSegs++;
+  }
+  
+  if ( nbSegs > 1 )
+    _length /= nbSegs;
+
+  return nbSegs;
+}
diff --git a/src/StdMeshers/StdMeshers_SegmentLengthAroundVertex.hxx b/src/StdMeshers/StdMeshers_SegmentLengthAroundVertex.hxx
new file mode 100644 (file)
index 0000000..a1297c8
--- /dev/null
@@ -0,0 +1,66 @@
+//  SMESH SMESH : implementaion of SMESH idl descriptions
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : StdMeshers_SegmentLengthAroundVertex.hxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+#ifndef _SMESH_SegmentLengthAroundVertex_HXX_
+#define _SMESH_SegmentLengthAroundVertex_HXX_
+
+#include "SMESH_Hypothesis.hxx"
+#include "Utils_SALOME_Exception.hxx"
+
+/*!
+ * \brief This hypothesis specifies length of segments adjacent to the vertex the
+ * hypothesis is assigned to
+ */
+class StdMeshers_SegmentLengthAroundVertex:public SMESH_Hypothesis
+{
+ public:
+  StdMeshers_SegmentLengthAroundVertex(int hypId, int studyId, SMESH_Gen * gen);
+  virtual ~ StdMeshers_SegmentLengthAroundVertex();
+
+  void SetLength(double length) throw(SALOME_Exception);
+
+  double GetLength() const;
+
+  virtual std::ostream & SaveTo(std::ostream & save);
+  virtual std::istream & LoadFrom(std::istream & load);
+  friend std::ostream & operator <<(std::ostream & save, StdMeshers_SegmentLengthAroundVertex & hyp);
+  friend std::istream & operator >>(std::istream & load, StdMeshers_SegmentLengthAroundVertex & hyp);
+
+  /*!
+   * \brief Initialize segment length by the mesh built on the geometry
+   * \param theMesh - the built mesh
+   * \param theShape - the geometry of interest
+   * \retval bool - true if parameter values have been successfully defined
+   */
+  virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape);
+
+ protected:
+  double _length;
+};
+
+#endif
index 76a946c659e4cfa8422d44fadbbb5692c058ff9d..1be50e5d19a41676b2a34cd10245a54e5c407f80 100644 (file)
@@ -172,36 +172,36 @@ void StdMeshersGUI_StdHypothesisCreator::retrieveParams() const
   }
 }
 
-//================================================================================
-/*!
- * \brief Widget: slider with left and right labels
- */
-//================================================================================
+namespace {
 
-class TDoubleSliderWith2Lables: public QHBox
-{
-public:
-  TDoubleSliderWith2Lables( const QString& leftLabel, const QString& rightLabel,
-                            const double   initValue, const double   bottom,
-                            const double   top      , const double   precision,
-                            QWidget *      parent=0 , const char *   name=0 )
-    :QHBox(parent,name), _bottom(bottom), _precision(precision)
-  {
-    if ( !leftLabel.isEmpty() ) (new QLabel( this ))->setText( leftLabel );
-    _slider = new QSlider( Horizontal, this );
-    _slider->setRange( 0, toInt( top ));
-    _slider->setValue( toInt( initValue ));
-    if ( !rightLabel.isEmpty() ) (new QLabel( this ))->setText( rightLabel );
-  }
-  double value() const { return _bottom + _slider->value() * _precision; }
-  QSlider * getSlider() const { return _slider; }
-  int toInt( double val ) const { return (int) ceil(( val - _bottom ) / _precision ); }
-private:
-  double _bottom, _precision;
-  QSlider * _slider;
-};
+  //================================================================================
+  /*!
+   * \brief Widget: slider with left and right labels
+   */
+  //================================================================================
 
-namespace {
+  class TDoubleSliderWith2Lables: public QHBox
+  {
+  public:
+    TDoubleSliderWith2Lables( const QString& leftLabel, const QString& rightLabel,
+                              const double   initValue, const double   bottom,
+                              const double   top      , const double   precision,
+                              QWidget *      parent=0 , const char *   name=0 )
+      :QHBox(parent,name), _bottom(bottom), _precision(precision)
+    {
+      if ( !leftLabel.isEmpty() ) (new QLabel( this ))->setText( leftLabel );
+      _slider = new QSlider( Horizontal, this );
+      _slider->setRange( 0, toInt( top ));
+      _slider->setValue( toInt( initValue ));
+      if ( !rightLabel.isEmpty() ) (new QLabel( this ))->setText( rightLabel );
+    }
+    double value() const { return _bottom + _slider->value() * _precision; }
+    QSlider * getSlider() const { return _slider; }
+    int toInt( double val ) const { return (int) ceil(( val - _bottom ) / _precision ); }
+  private:
+    double _bottom, _precision;
+    QSlider * _slider;
+  };
 
   //================================================================================
   /*!
@@ -381,6 +381,13 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const
 
       h->SetLength( params[0].myValue.toDouble() );
     }
+    else if( hypType()=="SegmentLengthAroundVertex" )
+    {
+      StdMeshers::StdMeshers_SegmentLengthAroundVertex_var h =
+       StdMeshers::StdMeshers_SegmentLengthAroundVertex::_narrow( hypothesis() );
+
+      h->SetLength( params[0].myValue.toDouble() );
+    }
     else if( hypType()=="Arithmetic1D" )
     {
       StdMeshers::StdMeshers_Arithmetic1D_var h =
@@ -521,6 +528,15 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const
     item.myValue = h->GetLength();
     p.append( item );
   }
+  else if( hypType()=="SegmentLengthAroundVertex" )
+  {
+    StdMeshers::StdMeshers_SegmentLengthAroundVertex_var h =
+      StdMeshers::StdMeshers_SegmentLengthAroundVertex::_narrow( hyp );
+
+    item.myName = tr("SMESH_LOCAL_LENGTH_PARAM");
+    item.myValue = h->GetLength();
+    p.append( item );
+  }
   else if( hypType()=="Arithmetic1D" )
   {
     StdMeshers::StdMeshers_Arithmetic1D_var h =
@@ -777,6 +793,7 @@ QString StdMeshersGUI_StdHypothesisCreator::hypTypeName( const QString& t ) cons
     types.insert( "ProjectionSource3D", "PROJECTION_SOURCE_3D" );
     types.insert( "NumberOfLayers", "NUMBER_OF_LAYERS" );
     types.insert( "LayerDistribution", "LAYER_DISTRIBUTION" );
+    types.insert( "SegmentLengthAroundVertex", "SEGMENT_LENGTH_AROUND_VERTEX" );
   }
 
   QString res;
index 5fd2cf40c51736c2e9333ac72a2a84533612ca0c..e087d1d1ee50e406506bf32f7e8e87b3a56c5e24 100644 (file)
@@ -41,6 +41,9 @@ msgstr "select1.png"
 msgid "ICON_DLG_LOCAL_LENGTH"
 msgstr "mesh_hypo_length.png"
 
+msgid "ICON_DLG_SEGMENT_LENGTH_AROUND_VERTEX"
+msgstr "mesh_hypo_length.png"
+
 msgid "ICON_DLG_NB_SEGMENTS"
 msgstr "mesh_hypo_segment.png"
 
@@ -88,6 +91,9 @@ msgstr "mesh_hypo_source_3d.png"
 msgid "ICON_SMESH_TREE_ALGO_Regular_1D"
 msgstr "mesh_tree_algo_regular.png"
 
+msgid "ICON_SMESH_TREE_ALGO_CompositeSegment_1D"
+msgstr "mesh_tree_algo_regular.png"
+
 msgid "ICON_SMESH_TREE_ALGO_Hexa_3D"
 msgstr "mesh_tree_algo_hexa.png"
 
@@ -169,3 +175,9 @@ msgstr "mesh_tree_hypo_source_face.png"
 
 msgid "ICON_SMESH_TREE_HYPO_ProjectionSource3D"
 msgstr "mesh_tree_hypo_source_3d_shape.png"
+
+msgid "ICON_SMESH_TREE_ALGO_SegmentAroundVertex_0D"
+msgstr "mesh_tree_algo_regular.png"
+
+msgid "ICON_SMESH_TREE_HYPO_SegmentLengthAroundVertex"
+msgstr "mesh_tree_hypo_length.png"
index b1842159e5f463f88dc903c0d59282139a382e63..922119e1491cc7ca1366b8b40fc117e8e73275da 100644 (file)
@@ -256,3 +256,15 @@ msgstr "Create"
 msgid "StdMeshersGUI_LayerDistributionParamWdg::EDIT"
 msgstr "Edit"
 
+
+# -------------- Segment Length Around Vertex --------------
+
+msgid "SMESH_SEGMENT_LENGTH_AROUND_VERTEX_HYPOTHESIS"
+msgstr "Segment Length Around Vertex"
+
+msgid "SMESH_SEGMENT_LENGTH_AROUND_VERTEX_PARAM"
+msgstr "Length"
+
+msgid "SMESH_SEGMENT_LENGTH_AROUND_VERTEX_TITLE"
+msgstr "Hypothesis Construction"
+
index 5939cb4da45ba2f5456ec243e709659cb9495eeb..93099b12b8b45cd5ee7987d77e44be288cd505d5 100644 (file)
@@ -55,6 +55,9 @@ salomeinclude_HEADERS = \
        StdMeshers_Projection_1D_2D_3D_i.hxx \
        StdMeshers_ObjRefUlils.hxx \
        StdMeshers_LayerDistribution_i.hxx \
+       StdMeshers_CompositeSegment_1D_i.hxx \
+       StdMeshers_SegmentAroundVertex_0D_i.hxx \
+       StdMeshers_SegmentLengthAroundVertex_i.hxx \
        SMESH_StdMeshers_I.hxx
 
 # Libraries targets
@@ -86,7 +89,10 @@ dist_libStdMeshersEngine_la_SOURCES = \
        StdMeshers_ProjectionSource3D_i.cxx \
        StdMeshers_Projection_1D_2D_3D_i.cxx \
        StdMeshers_ObjRefUlils.cxx \
-       StdMeshers_LayerDistribution_i.cxx
+       StdMeshers_LayerDistribution_i.cxx \
+       StdMeshers_CompositeSegment_1D_i.hxx \
+       StdMeshers_SegmentAroundVertex_0D_i.hxx \
+       StdMeshers_SegmentLengthAroundVertex_i.hxx
 
 # additionnal information to compil and link file
 libStdMeshersEngine_la_CPPFLAGS = \
diff --git a/src/StdMeshers_I/StdMeshers_CompositeSegment_1D_i.cxx b/src/StdMeshers_I/StdMeshers_CompositeSegment_1D_i.cxx
new file mode 100644 (file)
index 0000000..b8b0126
--- /dev/null
@@ -0,0 +1,85 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : StdMeshers_CompositeSegment_1D_i.cxx
+//  Module : SMESH
+//  $Header$
+
+#include "StdMeshers_CompositeSegment_1D_i.hxx"
+#include "SMESH_Gen.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+using namespace std;
+
+//=============================================================================
+/*!
+ *  StdMeshers_CompositeSegment_1D_i::StdMeshers_CompositeSegment_1D_i
+ *
+ *  Constructor
+ */
+//=============================================================================
+
+StdMeshers_CompositeSegment_1D_i::StdMeshers_CompositeSegment_1D_i
+                                                ( PortableServer::POA_ptr thePOA,
+                                                  int                     theStudyId,
+                                                  ::SMESH_Gen*            theGenImpl )
+     : SALOME::GenericObj_i( thePOA ), 
+       SMESH_Hypothesis_i( thePOA ), 
+       SMESH_Algo_i( thePOA ),
+       SMESH_1D_Algo_i( thePOA )
+{
+  MESSAGE( "StdMeshers_CompositeSegment_1D_i::StdMeshers_CompositeSegment_1D_i" );
+  myBaseImpl = new ::StdMeshers_CompositeSegment_1D( theGenImpl->GetANewId(),
+                                                     theStudyId,
+                                                     theGenImpl );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_CompositeSegment_1D_i::~StdMeshers_CompositeSegment_1D_i
+ *
+ *  Destructor
+ */
+//=============================================================================
+
+StdMeshers_CompositeSegment_1D_i::~StdMeshers_CompositeSegment_1D_i()
+{
+  MESSAGE( "StdMeshers_CompositeSegment_1D_i::~StdMeshers_CompositeSegment_1D_i" );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_CompositeSegment_1D_i::GetImpl
+ *
+ *  Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_CompositeSegment_1D* StdMeshers_CompositeSegment_1D_i::GetImpl()
+{
+  MESSAGE( "StdMeshers_CompositeSegment_1D_i::GetImpl" );
+  return ( ::StdMeshers_CompositeSegment_1D* )myBaseImpl;
+}
+
diff --git a/src/StdMeshers_I/StdMeshers_CompositeSegment_1D_i.hxx b/src/StdMeshers_I/StdMeshers_CompositeSegment_1D_i.hxx
new file mode 100644 (file)
index 0000000..d2d3ddc
--- /dev/null
@@ -0,0 +1,56 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : StdMeshers_CompositeSegment_1D_i.hxx
+//  Module : SMESH
+//  $Header$
+
+#ifndef _SMESH_CompositeSegment_1D_I_HXX_
+#define _SMESH_CompositeSegment_1D_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_1D_Algo_i.hxx"
+#include "StdMeshers_CompositeSegment_1D.hxx"
+
+// ======================================================
+// Wire Discretization 1d algorithm
+// ======================================================
+class StdMeshers_CompositeSegment_1D_i:
+  public virtual POA_StdMeshers::StdMeshers_CompositeSegment_1D,
+  public virtual SMESH_1D_Algo_i
+{
+public:
+  // Constructor
+  StdMeshers_CompositeSegment_1D_i( PortableServer::POA_ptr thePOA,
+                                    int                     theStudyId,
+                                    ::SMESH_Gen*            theGenImpl );
+  // Destructor
+  virtual ~StdMeshers_CompositeSegment_1D_i();
+  // Get implementation
+  ::StdMeshers_CompositeSegment_1D* GetImpl();
+};
+
+#endif
index 5ecf5c443e58fb73e5960c73eebfbe9299539adf..5cfbe8b146307db080e3a16495a4cd76d4a7089a 100644 (file)
@@ -44,8 +44,8 @@ using namespace std;
 //=============================================================================
 
 StdMeshers_Regular_1D_i::StdMeshers_Regular_1D_i( PortableServer::POA_ptr thePOA,
-                                       int                     theStudyId,
-                                       ::SMESH_Gen*            theGenImpl )
+                                                  int                     theStudyId,
+                                                  ::SMESH_Gen*            theGenImpl )
      : SALOME::GenericObj_i( thePOA ), 
        SMESH_Hypothesis_i( thePOA ), 
        SMESH_Algo_i( thePOA ),
@@ -53,8 +53,8 @@ StdMeshers_Regular_1D_i::StdMeshers_Regular_1D_i( PortableServer::POA_ptr thePOA
 {
   MESSAGE( "StdMeshers_Regular_1D_i::StdMeshers_Regular_1D_i" );
   myBaseImpl = new ::StdMeshers_Regular_1D( theGenImpl->GetANewId(),
-                                      theStudyId,
-                                      theGenImpl );
+                                            theStudyId,
+                                            theGenImpl );
 }
 
 //=============================================================================
diff --git a/src/StdMeshers_I/StdMeshers_SegmentAroundVertex_0D_i.cxx b/src/StdMeshers_I/StdMeshers_SegmentAroundVertex_0D_i.cxx
new file mode 100644 (file)
index 0000000..8e4ff30
--- /dev/null
@@ -0,0 +1,71 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : StdMeshers_Projection_3D_i.cxx
+//           Moved here from SMESH_Projection_3D_i.cxx
+//  Author : Paul RASCLE, EDF
+//  Module : SMESH
+//  $Header$
+
+#include "StdMeshers_SegmentAroundVertex_0D_i.hxx"
+
+#include "SMESH_Gen.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+using namespace std;
+
+//=============================================================================
+/*!
+ *  StdMeshers_SegmentAroundVertex_0D_i::StdMeshers_SegmentAroundVertex_0D_i
+ */
+//=============================================================================
+
+StdMeshers_SegmentAroundVertex_0D_i::StdMeshers_SegmentAroundVertex_0D_i
+                                               ( PortableServer::POA_ptr thePOA,
+                                                 int                     theStudyId,
+                                                 ::SMESH_Gen*            theGenImpl )
+     : SALOME::GenericObj_i( thePOA ), 
+       SMESH_Hypothesis_i( thePOA ), 
+       SMESH_Algo_i( thePOA ),
+       SMESH_0D_Algo_i( thePOA )
+{
+  MESSAGE( "StdMeshers_SegmentAroundVertex_0D_i::StdMeshers_SegmentAroundVertex_0D_i" );
+  myBaseImpl = new ::StdMeshers_SegmentAroundVertex_0D( theGenImpl->GetANewId(),
+                                                        theStudyId,
+                                                        theGenImpl );
+}
+//-----------------------------------------------------------------------------
+
+StdMeshers_SegmentAroundVertex_0D_i::~StdMeshers_SegmentAroundVertex_0D_i()
+{
+  MESSAGE( "StdMeshers_SegmentAroundVertex_0D_i::~StdMeshers_SegmentAroundVertex_0D_i" );
+}
+//-----------------------------------------------------------------------------
+
+::StdMeshers_SegmentAroundVertex_0D* StdMeshers_SegmentAroundVertex_0D_i::GetImpl()
+{
+  MESSAGE( "StdMeshers_SegmentAroundVertex_0D_i::GetImpl" );
+  return ( ::StdMeshers_SegmentAroundVertex_0D* )myBaseImpl;
+}
diff --git a/src/StdMeshers_I/StdMeshers_SegmentAroundVertex_0D_i.hxx b/src/StdMeshers_I/StdMeshers_SegmentAroundVertex_0D_i.hxx
new file mode 100644 (file)
index 0000000..5f42d62
--- /dev/null
@@ -0,0 +1,57 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : StdMeshers_SegmentAroundVertex_0D.hxx
+//  Module : SMESH
+//  $Header$
+
+#ifndef _SMESH_SegmentAroundVertex_0D_I_HXX_
+#define _SMESH_SegmentAroundVertex_0D_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_0D_Algo_i.hxx"
+#include "StdMeshers_SegmentAroundVertex_0D.hxx"
+
+class SMESH_Gen;
+
+class StdMeshers_SegmentAroundVertex_0D_i:
+  public virtual POA_StdMeshers::StdMeshers_SegmentAroundVertex_0D,
+  public virtual SMESH_0D_Algo_i
+{
+public:
+  // Constructor
+  StdMeshers_SegmentAroundVertex_0D_i( PortableServer::POA_ptr thePOA,
+                              int                     theStudyId,
+                              ::SMESH_Gen*            theGenImpl );
+
+  // Destructor
+  virtual ~StdMeshers_SegmentAroundVertex_0D_i();
+
+  // Get implementation
+  ::StdMeshers_SegmentAroundVertex_0D* GetImpl();
+};
+
+
+#endif
diff --git a/src/StdMeshers_I/StdMeshers_SegmentLengthAroundVertex_i.cxx b/src/StdMeshers_I/StdMeshers_SegmentLengthAroundVertex_i.cxx
new file mode 100644 (file)
index 0000000..42a5c41
--- /dev/null
@@ -0,0 +1,140 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : StdMeshers_SegmentLengthAroundVertex_i.cxx
+//  Module : SMESH
+//  $Header$
+
+#include "StdMeshers_SegmentLengthAroundVertex_i.hxx"
+#include "SMESH_Gen.hxx"
+#include "SMESH_PythonDump.hxx"
+
+#include "Utils_CorbaException.hxx"
+#include "utilities.h"
+
+#include <TCollection_AsciiString.hxx>
+
+using namespace std;
+
+//=============================================================================
+/*!
+ *  StdMeshers_SegmentLengthAroundVertex_i::StdMeshers_SegmentLengthAroundVertex_i
+ *
+ *  Constructor
+ */
+//=============================================================================
+
+StdMeshers_SegmentLengthAroundVertex_i::StdMeshers_SegmentLengthAroundVertex_i
+                                                    ( PortableServer::POA_ptr thePOA,
+                                                      int                     theStudyId,
+                                                      ::SMESH_Gen*            theGenImpl )
+  : SALOME::GenericObj_i( thePOA ), 
+    SMESH_Hypothesis_i( thePOA )
+{
+  MESSAGE( "StdMeshers_SegmentLengthAroundVertex_i::StdMeshers_SegmentLengthAroundVertex_i" );
+  myBaseImpl = new ::StdMeshers_SegmentLengthAroundVertex( theGenImpl->GetANewId(),
+                                                           theStudyId,
+                                                           theGenImpl );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_SegmentLengthAroundVertex_i::~StdMeshers_SegmentLengthAroundVertex_i
+ *
+ *  Destructor
+ */
+//=============================================================================
+
+StdMeshers_SegmentLengthAroundVertex_i::~StdMeshers_SegmentLengthAroundVertex_i()
+{
+  MESSAGE( "StdMeshers_SegmentLengthAroundVertex_i::~StdMeshers_SegmentLengthAroundVertex_i" );
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_SegmentLengthAroundVertex_i::SetLength
+ *
+ *  Set length
+ */
+//=============================================================================
+
+void StdMeshers_SegmentLengthAroundVertex_i::SetLength( CORBA::Double theLength )
+     throw ( SALOME::SALOME_Exception )
+{
+  MESSAGE( "StdMeshers_SegmentLengthAroundVertex_i::SetLength" );
+  ASSERT( myBaseImpl );
+  try {
+    this->GetImpl()->SetLength( theLength );
+  }
+  catch ( SALOME_Exception& S_ex ) {
+    THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),SALOME::BAD_PARAM );
+  }
+
+  // Update Python script
+  SMESH::TPythonDump() << _this() << ".SetLength( " << theLength << " )";
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_SegmentLengthAroundVertex_i::GetLength
+ *
+ *  Get length
+ */
+//=============================================================================
+
+CORBA::Double StdMeshers_SegmentLengthAroundVertex_i::GetLength()
+{
+  MESSAGE( "StdMeshers_SegmentLengthAroundVertex_i::GetLength" );
+  ASSERT( myBaseImpl );
+  return this->GetImpl()->GetLength();
+}
+
+//=============================================================================
+/*!
+ *  StdMeshers_SegmentLengthAroundVertex_i::GetImpl
+ *
+ *  Get implementation
+ */
+//=============================================================================
+
+::StdMeshers_SegmentLengthAroundVertex* StdMeshers_SegmentLengthAroundVertex_i::GetImpl()
+{
+  MESSAGE( "StdMeshers_SegmentLengthAroundVertex_i::GetImpl" );
+  return ( ::StdMeshers_SegmentLengthAroundVertex* )myBaseImpl;
+}
+
+//================================================================================
+/*!
+ * \brief Verify whether hypothesis supports given entity type 
+  * \param type - dimension (see SMESH::Dimension enumeration)
+  * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise
+ * 
+ * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration)
+ */
+//================================================================================  
+
+CORBA::Boolean StdMeshers_SegmentLengthAroundVertex_i::IsDimSupported( SMESH::Dimension type )
+{
+  return type == SMESH::DIM_1D;
+}
+
diff --git a/src/StdMeshers_I/StdMeshers_SegmentLengthAroundVertex_i.hxx b/src/StdMeshers_I/StdMeshers_SegmentLengthAroundVertex_i.hxx
new file mode 100644 (file)
index 0000000..f7be903
--- /dev/null
@@ -0,0 +1,70 @@
+//  SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
+//
+//  Copyright (C) 2003  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
+//
+//
+//
+//  File   : StdMeshers_SegmentLengthAroundVertex_i.hxx
+//  Module : SMESH
+//  $Header$
+
+#ifndef _SMESH_SegmentLengthAroundVertex_I_HXX_
+#define _SMESH_SegmentLengthAroundVertex_I_HXX_
+
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis)
+
+#include "SMESH_Hypothesis_i.hxx"
+#include "StdMeshers_SegmentLengthAroundVertex.hxx"
+
+class SMESH_Gen;
+
+/*!
+ * \brief This hypothesis specifies length of segments adjacent to the vertex the
+ * hypothesis is assigned to
+ */
+class StdMeshers_SegmentLengthAroundVertex_i:
+  public virtual POA_StdMeshers::StdMeshers_SegmentLengthAroundVertex,
+  public virtual SMESH_Hypothesis_i
+{
+public:
+  // Constructor
+  StdMeshers_SegmentLengthAroundVertex_i( PortableServer::POA_ptr thePOA,
+                                          int                     theStudyId,
+                                          ::SMESH_Gen*            theGenImpl );
+  // Destructor
+  virtual ~StdMeshers_SegmentLengthAroundVertex_i();
+
+  // Set length
+  void SetLength( CORBA::Double theLength )
+    throw ( SALOME::SALOME_Exception );
+
+  // Get length
+  CORBA::Double GetLength();
+
+  // Get implementation
+  ::StdMeshers_SegmentLengthAroundVertex* GetImpl();
+  
+  // Verify whether hypothesis supports given entity type 
+  CORBA::Boolean IsDimSupported( SMESH::Dimension type );
+};
+
+#endif
+
index 20e120ea54098b96294e43647c2876235a469684..d5aa8f6fc77b8361a6a6c7c3b3fcb41751eccfe6 100644 (file)
 #include "StdMeshers_MaxElementArea_i.hxx"
 #include "StdMeshers_MaxElementVolume_i.hxx"
 #include "StdMeshers_NotConformAllowed_i.hxx"
-
 #include "StdMeshers_ProjectionSource3D_i.hxx"
 #include "StdMeshers_ProjectionSource2D_i.hxx"
 #include "StdMeshers_ProjectionSource1D_i.hxx"
 #include "StdMeshers_NumberOfLayers_i.hxx"
 #include "StdMeshers_LayerDistribution_i.hxx"
+#include "StdMeshers_SegmentLengthAroundVertex_i.hxx"
 
 #include "StdMeshers_Regular_1D_i.hxx"
 #include "StdMeshers_MEFISTO_2D_i.hxx"
 #include "StdMeshers_Quadrangle_2D_i.hxx"
 #include "StdMeshers_Hexa_3D_i.hxx"
-
 #include "StdMeshers_Projection_1D_2D_3D_i.hxx"
 #include "StdMeshers_Prism_3D_i.hxx"
+#include "StdMeshers_SegmentAroundVertex_0D_i.hxx"
+#include "StdMeshers_CompositeSegment_1D_i.hxx"
 
 
 template <class T> class StdHypothesisCreator_i:public HypothesisCreator_i<T>
@@ -118,6 +119,8 @@ STDMESHERS_I_EXPORT
       aCreator = new StdHypothesisCreator_i<StdMeshers_NumberOfLayers_i>;
     else if (strcmp(aHypName, "LayerDistribution") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_LayerDistribution_i>;
+    else if (strcmp(aHypName, "SegmentLengthAroundVertex") == 0)
+      aCreator = new StdHypothesisCreator_i<StdMeshers_SegmentLengthAroundVertex_i>;
 
     // Algorithms
     else if (strcmp(aHypName, "Regular_1D") == 0)
@@ -138,6 +141,10 @@ STDMESHERS_I_EXPORT
       aCreator = new StdHypothesisCreator_i<StdMeshers_Prism_3D_i>;
     else if (strcmp(aHypName, "RadialPrism_3D") == 0)
       aCreator = new StdHypothesisCreator_i<StdMeshers_RadialPrism_3D_i>;
+    else if (strcmp(aHypName, "SegmentAroundVertex_0D") == 0)
+      aCreator = new StdHypothesisCreator_i<StdMeshers_SegmentAroundVertex_0D_i>;
+    else if (strcmp(aHypName, "CompositeSegment_1D") == 0)
+      aCreator = new StdHypothesisCreator_i<StdMeshers_CompositeSegment_1D_i>;
     else ;
 
     return aCreator;