Salome HOME
Merge from V6_2_BR 23/12/2010
authorinv <inv@opencascade.com>
Fri, 24 Dec 2010 08:18:34 +0000 (08:18 +0000)
committerinv <inv@opencascade.com>
Fri, 24 Dec 2010 08:18:34 +0000 (08:18 +0000)
84 files changed:
Makefile.am
configure.ac
doc/docutils/Makefile.am
doc/docutils/conf.py [deleted file]
doc/docutils/conf.py.in [new file with mode: 0644]
doc/salome/gui/SMESH/images/bare_border_faces_smpl.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/bare_border_volumes_smpl.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/controls_popup.png [new file with mode: 0755]
doc/salome/gui/SMESH/images/copy_mesh_dlg.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/copy_mesh_icon.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/over_constrained_faces.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/over_constrained_volumes.png [new file with mode: 0644]
doc/salome/gui/SMESH/images/scalar_bar_dlg.png [new file with mode: 0755]
doc/salome/gui/SMESH/input/about_meshes.doc
doc/salome/gui/SMESH/input/about_quality_controls.doc
doc/salome/gui/SMESH/input/bare_border_face.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/bare_border_volumes.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/copy_mesh.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/over_constrained_faces.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/over_constrained_volumes.doc [new file with mode: 0644]
doc/salome/gui/SMESH/input/projection_algos.doc
doc/salome/gui/SMESH/input/scalar_bar.doc [new file with mode: 0755]
doc/salome/gui/SMESH/input/selection_filter_library.doc
doc/salome/gui/SMESH/input/tui_creating_meshes.doc
doc/salome/gui/SMESH/input/tui_filters.doc
doc/salome/gui/SMESH/input/tui_quality_controls.doc
idl/SMESH_Filter.idl
idl/SMESH_Gen.idl
resources/Makefile.am
resources/bare_border_face.png [new file with mode: 0644]
resources/bare_border_volume.png [new file with mode: 0644]
resources/copy_mesh.png [new file with mode: 0644]
resources/over_constrained_face.png [new file with mode: 0644]
resources/over_constrained_volume.png [new file with mode: 0644]
src/Controls/SMESH_Controls.cxx
src/Controls/SMESH_ControlsDef.hxx
src/OBJECT/SMESH_Actor.cxx
src/OBJECT/SMESH_Actor.h
src/OBJECT/SMESH_ActorDef.h
src/OBJECT/SMESH_DeviceActor.cxx
src/OBJECT/SMESH_PreviewActorsCollection.cxx
src/SMDS/SMDS_MeshElement.cxx
src/SMDS/SMDS_MeshElement.hxx
src/SMDS/SMDS_MeshNode.cxx
src/SMDS/SMDS_MeshNode.hxx
src/SMDS/SMDS_VtkEdge.cxx
src/SMDS/SMDS_VtkFace.cxx
src/SMDS/SMDS_VtkFace.hxx
src/SMDS/SMDS_VtkVolume.cxx
src/SMESH/Makefile.am
src/SMESH/SMESH_Mesh.cxx
src/SMESH/SMESH_Mesh.hxx
src/SMESH/SMESH_MeshEditor.cxx
src/SMESH/SMESH_subMesh.cxx
src/SMESH/SMESH_subMesh.hxx
src/SMESHFiltersSelection/SMESH_Type.h
src/SMESHFiltersSelection/SMESH_TypeFilter.cxx
src/SMESHGUI/Makefile.am
src/SMESHGUI/SMESHGUI.cxx
src/SMESHGUI/SMESHGUI_ClippingDlg.cxx
src/SMESHGUI/SMESHGUI_CopyMeshDlg.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_CopyMeshDlg.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_FilterDlg.cxx
src/SMESHGUI/SMESHGUI_Hypotheses.cxx
src/SMESHGUI/SMESHGUI_MeshInfo.cxx
src/SMESHGUI/SMESHGUI_MeshInfo.h
src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx
src/SMESHGUI/SMESHGUI_Utils.cxx
src/SMESHGUI/SMESH_images.ts
src/SMESHGUI/SMESH_msg_en.ts
src/SMESHGUI/SMESH_msg_fr.ts
src/SMESH_I/SMESH_2smeshpy.cxx
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_SWIG/ex19_sphereINcube.py
src/SMESH_SWIG/smeshDC.py
src/StdMeshers/StdMeshers_Import_1D.cxx
src/StdMeshers/StdMeshers_Import_1D2D.cxx
src/StdMeshers/StdMeshers_ProjectionUtils.cxx
src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx

index 8b479765a247e9e650f4dc20ff8de1bf946fdd69..b37435467094c97c3d4584c2bebcd8b3bc42f1e2 100644 (file)
@@ -41,7 +41,7 @@ SUBDIRS = idl adm_local resources src doc bin
 
 DIST_SUBDIRS = idl adm_local resources src doc bin 
 
-DISTCLEANFILES = a.out aclocal.m4 configure local-install.sh
+DISTCLEANFILES = a.out aclocal.m4 configure local-install.sh hack_libtool
 
 salomeinclude_DATA = SMESH_version.h
 
index bd170516077ac3deb0f2c6ca85abf07e1cdba60c..9fd33f5ca515820a08faaa9c6b8e16b18d28776d 100644 (file)
@@ -444,6 +444,9 @@ sed -i "s%^CC=\"\(.*\)\"%hack_libtool (){ \n\
   $(pwd)/hack_libtool \1 \"\$[@]\" \n\
 }\n\
 CC=\"hack_libtool\"%g" libtool
+sed -i "s%\(\s*\)for searchdir in \$newlib_search_path \$lib_search_path \$sys_lib_search_path \$shlib_search_path; do%\1searchdirs=\"\$newlib_search_path \$lib_search_path \$sys_lib_search_path \$shlib_search_path\"\n\1for searchdir in \$searchdirs; do%g" libtool
+sed -i "s%\(\s*\)searchdirs=\"\$newlib_search_path \$lib_search_path \(.*\)\"%\1searchdirs=\"\$newlib_search_path \$lib_search_path\"\n\1sss_beg=\"\"\n\1sss_end=\"\2\"%g" libtool
+sed -i "s%\(\s*\)\(for searchdir in \$searchdirs; do\)%\1for sss in \$searchdirs; do\n\1  if ! test -d \$sss; then continue; fi\n\1  ssss=\$(cd \$sss; pwd)\n\1  if test \"\$ssss\" != \"\" \&\& test -d \$ssss; then\n\1    case \$ssss in\n\1      /usr/lib | /usr/lib64 ) ;;\n\1      * ) sss_beg=\"\$sss_beg \$ssss\" ;;\n\1    esac\n\1  fi\n\1done\n\1searchdirs=\"\$sss_beg \$sss_end\"\n\1\2%g" libtool
 ],[])
 
 # This list is initiated using autoscan and must be updated manually
@@ -460,6 +463,7 @@ AC_OUTPUT([ \
   SMESH_version.h \
   doc/Makefile \
   doc/docutils/Makefile \
+  doc/docutils/conf.py \
   doc/salome/Makefile \
   doc/salome/gui/Makefile \
   doc/salome/gui/SMESH/Makefile \
index 867fd0a30bbbd3ced5cc19c9a8b72010299f3a32..573f4a4f0b57801ca3329374080ea956d06046b2 100644 (file)
@@ -47,7 +47,7 @@ htm:
        mkdir -p html doctrees
        PYTHONPATH=$(SPHINX_PYTHONPATH):${PYTHONPATH} \
        LD_LIBRARY_PATH=$(SPHINX_LD_LIBRARY_PATH):${LD_LIBRARY_PATH} \
-       $(SPHINXBUILD) -W -b html $(ALLSPHINXOPTS) html
+       $(SPHINXBUILD) -c $(top_builddir)/doc/docutils -W -b html $(ALLSPHINXOPTS) html
        @echo
        @echo "Build finished. The HTML pages are in html."
 
@@ -55,7 +55,7 @@ latex:
        mkdir -p latex doctrees
        PYTHONPATH=$(SPHINX_PYTHONPATH):${PYTHONPATH} \
        LD_LIBRARY_PATH=$(SPHINX_LD_LIBRARY_PATH):${LD_LIBRARY_PATH} \
-       $(SPHINXBUILD) -W -b latex $(ALLSPHINXOPTS) latex
+       $(SPHINXBUILD) -c $(top_builddir)/doc/docutils -W -b latex $(ALLSPHINXOPTS) latex
        @echo
        @echo "Build finished; the LaTeX files are in latex."
        @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
@@ -71,9 +71,6 @@ RSTFILES= \
 
 EXTRA_DIST+= $(RSTFILES)
 
-EXTRA_DIST+= \
-       conf.py 
-
 install-data-local: html/index.html
        test -z $(pydocdir) || mkdir -p $(DESTDIR)$(pydocdir)
        if test -d "html"; then b=; else b="$(srcdir)/"; fi; \
diff --git a/doc/docutils/conf.py b/doc/docutils/conf.py
deleted file mode 100644 (file)
index aebd4b1..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-# -*- coding: iso-8859-1 -*-
-#
-# yacs documentation build configuration file, created by
-# sphinx-quickstart on Fri Aug 29 09:57:25 2008.
-#
-# This file is execfile()d with the current directory set to its containing dir.
-#
-# The contents of this file are pickled, so don't put values in the namespace
-# that aren't pickleable (module imports are okay, they're removed automatically).
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-import sys, os
-
-# If your extensions are in another directory, add it here. If the directory
-# is relative to the documentation root, use os.path.abspath to make it
-# absolute, like shown here.
-#sys.path.append(os.path.abspath('.'))
-
-# General configuration
-# ---------------------
-
-# Add any Sphinx extension module names here, as strings. They can be extensions
-# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.autodoc']
-
-# Uncomment the following line to build the links with Python documentation
-# (you might need to set http_proxy environment variable for this to work)
-#extensions += ['sphinx.ext.intersphinx']
-
-# Intersphinx mapping to add links to modules and objects in the Python
-# standard library documentation
-intersphinx_mapping = {'http://docs.python.org': None}
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
-
-# The suffix of source filenames.
-source_suffix = '.rst'
-
-# The encoding of source files.
-source_encoding = 'utf-8'
-
-# The master toctree document.
-master_doc = 'index'
-
-# General information about the project.
-project = 'SMESH python packages'
-copyright = '2010 EDF R&D'
-
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-version = '6.2.0'
-# The full version, including alpha/beta/rc tags.
-release = '6.2.0'
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-language = 'en'
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-#today = ''
-# Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
-
-# List of documents that shouldn't be included in the build.
-#unused_docs = []
-
-# List of directories, relative to source directory, that shouldn't be searched
-# for source files.
-exclude_trees = ['.build','ref','images','CVS','.svn']
-
-# The reST default role (used for this markup: `text`) to use for all documents.
-#default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-#add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-#show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-
-# Options for HTML output
-# -----------------------
-
-# The theme to use for HTML and HTML Help pages.  Major themes that come with
-# Sphinx are currently 'default' and 'sphinxdoc'.
-html_theme = 'default'
-#html_theme = 'nature'
-#html_theme = 'agogo'
-#html_theme = 'sphinxdoc'
-#html_theme = 'omadoc'
-
-# Add any paths that contain custom themes here, relative to this directory.
-#html_theme_path = ['themes']
-
-# The name for this set of Sphinx documents.  If None, it defaults to
-# "<project> v<release> documentation".
-#html_title = None
-
-# A shorter title for the navigation bar.  Default is the same as html_title.
-#html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-#html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-#html_favicon = None
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-#html_static_path = ['_static']
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-#html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#html_additional_pages = {}
-
-# If false, no module index is generated.
-html_use_modindex = False
-
-# If false, no index is generated.
-#html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-#html_split_index = False
-
-# If true, the reST sources are included in the HTML build as _sources/<name>.
-html_copy_source = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it.  The value of this option must be the
-# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
-
-# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = ''
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'smeshpydoc'
-
-
-# Options for LaTeX output
-# ------------------------
-
-# The paper size ('letter' or 'a4').
-latex_paper_size = 'a4'
-
-# The font size ('10pt', '11pt' or '12pt').
-latex_font_size = '10pt'
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, document class [howto/manual]).
-latex_documents = [
-  ('index', 'smeshpy.tex', 'Documentation of the SMESH python packages', 'EDF R\&D', 'manual')
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-latex_logo = '../salome/tui/images/head.png'
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#latex_use_parts = True
-
-# Additional stuff for the LaTeX preamble.
-#latex_preamble = ''
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-latex_use_modindex = False
diff --git a/doc/docutils/conf.py.in b/doc/docutils/conf.py.in
new file mode 100644 (file)
index 0000000..b2bb21f
--- /dev/null
@@ -0,0 +1,200 @@
+# -*- coding: iso-8859-1 -*-
+#
+# yacs documentation build configuration file, created by
+# sphinx-quickstart on Fri Aug 29 09:57:25 2008.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# The contents of this file are pickled, so don't put values in the namespace
+# that aren't pickleable (module imports are okay, they're removed automatically).
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If your extensions are in another directory, add it here. If the directory
+# is relative to the documentation root, use os.path.abspath to make it
+# absolute, like shown here.
+#sys.path.append(os.path.abspath('.'))
+
+# General configuration
+# ---------------------
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc']
+
+# Uncomment the following line to build the links with Python documentation
+# (you might need to set http_proxy environment variable for this to work)
+#extensions += ['sphinx.ext.intersphinx']
+
+# Intersphinx mapping to add links to modules and objects in the Python
+# standard library documentation
+intersphinx_mapping = {'http://docs.python.org': None}
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+source_encoding = 'utf-8'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = 'SMESH python packages'
+copyright = '2010 EDF R&D'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '@VERSION@'
+# The full version, including alpha/beta/rc tags.
+release = '@VERSION@'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+language = 'en'
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of documents that shouldn't be included in the build.
+#unused_docs = []
+
+# List of directories, relative to source directory, that shouldn't be searched
+# for source files.
+exclude_trees = ['.build','ref','images','CVS','.svn']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+
+# Options for HTML output
+# -----------------------
+
+# The theme to use for HTML and HTML Help pages.  Major themes that come with
+# Sphinx are currently 'default' and 'sphinxdoc'.
+html_theme = 'default'
+#html_theme = 'nature'
+#html_theme = 'agogo'
+#html_theme = 'sphinxdoc'
+#html_theme = 'omadoc'
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = ['themes']
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+#html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+html_use_modindex = False
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, the reST sources are included in the HTML build as _sources/<name>.
+html_copy_source = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = ''
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'smeshpydoc'
+
+
+# Options for LaTeX output
+# ------------------------
+
+# The paper size ('letter' or 'a4').
+latex_paper_size = 'a4'
+
+# The font size ('10pt', '11pt' or '12pt').
+latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, document class [howto/manual]).
+latex_documents = [
+  ('index', 'smeshpy.tex', 'Documentation of the SMESH python packages', 'EDF R\&D', 'manual')
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+latex_logo = '../salome/tui/images/head.png'
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = True
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+latex_use_modindex = False
diff --git a/doc/salome/gui/SMESH/images/bare_border_faces_smpl.png b/doc/salome/gui/SMESH/images/bare_border_faces_smpl.png
new file mode 100644 (file)
index 0000000..6b7ead8
Binary files /dev/null and b/doc/salome/gui/SMESH/images/bare_border_faces_smpl.png differ
diff --git a/doc/salome/gui/SMESH/images/bare_border_volumes_smpl.png b/doc/salome/gui/SMESH/images/bare_border_volumes_smpl.png
new file mode 100644 (file)
index 0000000..a1e799a
Binary files /dev/null and b/doc/salome/gui/SMESH/images/bare_border_volumes_smpl.png differ
diff --git a/doc/salome/gui/SMESH/images/controls_popup.png b/doc/salome/gui/SMESH/images/controls_popup.png
new file mode 100755 (executable)
index 0000000..b0bd01f
Binary files /dev/null and b/doc/salome/gui/SMESH/images/controls_popup.png differ
diff --git a/doc/salome/gui/SMESH/images/copy_mesh_dlg.png b/doc/salome/gui/SMESH/images/copy_mesh_dlg.png
new file mode 100644 (file)
index 0000000..db9c929
Binary files /dev/null and b/doc/salome/gui/SMESH/images/copy_mesh_dlg.png differ
diff --git a/doc/salome/gui/SMESH/images/copy_mesh_icon.png b/doc/salome/gui/SMESH/images/copy_mesh_icon.png
new file mode 100644 (file)
index 0000000..263479f
Binary files /dev/null and b/doc/salome/gui/SMESH/images/copy_mesh_icon.png differ
diff --git a/doc/salome/gui/SMESH/images/over_constrained_faces.png b/doc/salome/gui/SMESH/images/over_constrained_faces.png
new file mode 100644 (file)
index 0000000..9d584e8
Binary files /dev/null and b/doc/salome/gui/SMESH/images/over_constrained_faces.png differ
diff --git a/doc/salome/gui/SMESH/images/over_constrained_volumes.png b/doc/salome/gui/SMESH/images/over_constrained_volumes.png
new file mode 100644 (file)
index 0000000..7611443
Binary files /dev/null and b/doc/salome/gui/SMESH/images/over_constrained_volumes.png differ
diff --git a/doc/salome/gui/SMESH/images/scalar_bar_dlg.png b/doc/salome/gui/SMESH/images/scalar_bar_dlg.png
new file mode 100755 (executable)
index 0000000..59ca530
Binary files /dev/null and b/doc/salome/gui/SMESH/images/scalar_bar_dlg.png differ
index 8a81c7ea0c26383801607913983f7a225a0c7440..c79f26644446b7e287180b6cfc1fe284debfa005 100644 (file)
@@ -16,6 +16,9 @@ for example, a face.
 
 Several created meshes can be \subpage building_compounds_page "combined into mesh compounds".
 
+The whole mesh or it's part can be \subpage copy_mesh_page "copied"
+into another mesh.
+
 All created meshes and submeshes can be \subpage editing_meshes_page "edited".
 
 Meshes can be also edited using the MESH functions destined for 
index 8f78c38c5340d8ff4b4ed58fe057ca9bf3c8753a..ee57c8c815b01523d07956b01af44ce04383e322 100644 (file)
@@ -32,6 +32,8 @@ Edge quality controls:
 Face quality controls:
 <ul>
 <li>\subpage free_faces_page "Free faces"</li>
+<li>\subpage bare_border_faces_page "Bare border faces"</li>
+<li>\subpage over_constrained_faces_page "Over-constrained faces"</li>
 <li>\subpage length_2d_page "Length 2D"</li>
 <li>\subpage borders_at_multi_connection_2d_page "Borders at multi-connection 2D"</li>
 <li>\subpage area_page "Area"</li>
@@ -40,14 +42,31 @@ Face quality controls:
 <li>\subpage minimum_angle_page "Minimum angle"</li>
 <li>\subpage warping_page "Warping"</li>
 <li>\subpage skew_page "Skew"</li>
-<li>\subpage max_element_length_2d_page "Max element length 2D"</li>
+<li>\subpage max_element_length_2d_page "Element Diameter 2D"</li>
 </ul>
 
 Volume quality controls:
 <ul>
 <li>\subpage aspect_ratio_3d_page "Aspect ratio 3D"</li>
 <li>\subpage volume_page "Volume"</li>
-<li>\subpage max_element_length_3d_page "Max element length 3D"</li>
+<li>\subpage max_element_length_3d_page "Element Diameter 3D"</li>
+<li>\subpage bare_border_volumes_page "Bare border volumes"</li>
+<li>\subpage over_constrained_volumes_page "Over-constrained volumes"</li>
 </ul>
 
+To manage the quality controls call pop-up in the VTK viewer and select "Controls" sub-menu
+\image html controls_popup.png
+
+<ul>
+<li> <b>Reset</b> switches off quality controls;</li>
+<li> <b>Node Controls</b> provides access to the node quality controls;</li>
+<li> <b>Edge Controls</b> provides access to the edge quality controls;</li>
+<li> <b>Face Controls</b> provides access to the face quality controls;</li>
+<li> <b>Volume Controls</b> provides access to the volume quality controls;</li>
+<li> <b>Scalar Bar Properties</b> allows setting \subpage scalar_bar_dlg;</li>
+<li> <b>Export Distribution...</b> allows saving the distribution of quality control values in the text file;</li>
+<li> <b>Show Distribution</b> Shows/Hides the distribution histogram of the quality control values in the VTK Viewer.</li>
+</ul>
+
+
 */
diff --git a/doc/salome/gui/SMESH/input/bare_border_face.doc b/doc/salome/gui/SMESH/input/bare_border_face.doc
new file mode 100644 (file)
index 0000000..2115d32
--- /dev/null
@@ -0,0 +1,15 @@
+/*!
+
+\page bare_border_faces_page Bare border faces
+
+This mesh quality control highlights the faces having the border not
+shared with other faces (free border) and missing an edge based on
+nodes of the free border. The faces with bare border are shown with a
+color different from the color of shared faces.
+
+\image html bare_border_faces_smpl.png
+
+\sa A sample TUI Script making a group of faces highlighted in the
+picture is \ref tui_bare_border_faces "Bare border faces Control".
+
+*/
diff --git a/doc/salome/gui/SMESH/input/bare_border_volumes.doc b/doc/salome/gui/SMESH/input/bare_border_volumes.doc
new file mode 100644 (file)
index 0000000..d0dd894
--- /dev/null
@@ -0,0 +1,15 @@
+/*!
+
+\page bare_border_volumes_page Bare border volumes
+
+This mesh quality control highlights the volumes having the border not
+shared with other volumes (free border) and missing a face based on
+nodes of the free border. The volumes with bare border are shown with a
+color different from the color of shared volumes.
+
+\image html bare_border_volumes_smpl.png
+
+\sa A sample TUI Script making a group of volumes highlighted in the
+picture is \ref tui_bare_border_volumes "Bare border volumes Control".
+
+*/
diff --git a/doc/salome/gui/SMESH/input/copy_mesh.doc b/doc/salome/gui/SMESH/input/copy_mesh.doc
new file mode 100644 (file)
index 0000000..2c65ab8
--- /dev/null
@@ -0,0 +1,56 @@
+/*!
+
+\page copy_mesh_page Copy Mesh
+
+\n A mesh can be created by copying a part of or the whole other mesh.
+
+<em>To make a copy of a mesh:</em>
+
+\par
+From the \b Mesh menu select <b>Copy Mesh</b> or click <em>"Copy Mesh"</em>
+button in the toolbar.
+
+\image html copy_mesh_icon.png
+<center><em>"Copy Mesh" button</em></center>
+
+\par
+The following dialog box will appear:
+
+\image html copy_mesh_dlg.png
+
+\par
+In the dialog:
+<ul>
+<li>specify the part of mesh to copy:
+
+<ul>
+<li><b>Select the whole mesh, submesh or group</b> by mouse activating
+this checkbox; or</li>
+<li>choose mesh elements with the mouse in the 3D Viewer. It is
+possible to select a whole area with a mouse frame; or</li> 
+<li>input the <b>Source Element IDs</b> directly in this field. The
+selected elements will be highlighted in the viewer; or</li>
+<li>apply Filters. <b>Set filter</b> button allows to apply a filter
+to the selection of elements. See more about filters in the \ref
+selection_filter_library_page "Selection filter library" page.</li>
+</ul>
+</li>
+
+<li>specify the <b>New Mesh Name</b>;</li>
+
+<li>specify the conditions of copying:
+<ul>
+<li>activate <b>Generate groups</b> checkbox to copy the groups of
+elements of the source mesh to the newly created mesh.</li>
+<li>activate <b>Preserve IDs of elements</b> checkbox to keep
+the IDs of new nodes and elements the same as the IDs of source nodes
+and elements.</li>
+</ul>
+</li>
+
+<li>Click \b Apply or <b>Apply and Close</b> button to confirm the operation.</li>
+</ul>
+
+<b>See Also</b> a sample 
+\ref tui_copy_mesh "TUI Example of mesh copying."
+*/
diff --git a/doc/salome/gui/SMESH/input/over_constrained_faces.doc b/doc/salome/gui/SMESH/input/over_constrained_faces.doc
new file mode 100644 (file)
index 0000000..26ad944
--- /dev/null
@@ -0,0 +1,14 @@
+/*!
+
+\page over_constrained_faces_page Over-constrained faces
+
+\n This mesh quality control highlights faces sharing only one of its borders with other faces.
+
+\image html over_constrained_faces.png
+
+In this picture the over-constrained face is displayed in red.
+
+<br><b>See Also</b> a sample TUI Script of a 
+\ref tui_over_constrained_faces "Over-constrained faces" filter.  
+
+*/
diff --git a/doc/salome/gui/SMESH/input/over_constrained_volumes.doc b/doc/salome/gui/SMESH/input/over_constrained_volumes.doc
new file mode 100644 (file)
index 0000000..1519e0a
--- /dev/null
@@ -0,0 +1,14 @@
+/*!
+
+\page over_constrained_volumes_page Over-constrained volumes
+
+\n This mesh quality control highlights volumes sharing only one of its borders with other volumes.
+
+\image html over_constrained_volumes.png
+
+In this picture the over-constrained volume is displayed in red.
+
+<br><b>See Also</b> a sample TUI Script of a 
+\ref tui_over_constrained_volumes "Over-constrained volumes" filter.  
+
+*/
\ No newline at end of file
index ddd3bf708e01919a80db9ff64b53baf80199cd58..07e7c343e25c4428d0ef91f466c84c7ccf8c6d0b 100644 (file)
@@ -17,12 +17,13 @@ The following dialog box will appear:
 \image html projection_1d.png
 
 In this menu you can define the \b Name of the algorithm, the already
-meshed source \b Edge and the \b Mesh (optional, use it if there are several
-different meshes on the same edge). It could also be necessary to
-define the orientation of edges, which is done by indicating the
-<b>Source Vertex</b> being the first point of the Source Edge and the 
-<b>Target Vertex</b> being the first point of the created \b Edge. For
-a group of edges, <b>Source</b> and <b>Target</b> vertices should be
+meshed source \b Edge and the \b Mesh  (It can be omitted only when 
+projecting a submesh on another one from the same global Mesh). 
+It could also be necessary to define the orientation of edges, 
+which is done by indicating the <b>Source Vertex</b> being the first point 
+of the Source Edge and the <b>Target Vertex</b> being the first point of 
+the created \b Edge. 
+For a group of edges, <b>Source</b> and <b>Target</b> vertices should be
 shared by only one edge of the group. If <b>Source</b> and
 <b>Target</b> vertices are specified, the elements of the group must be ajacent.
 
@@ -42,17 +43,17 @@ following dialog box will appear:
 \image html projection_2d.png
 
 In this menu you can define the \b Name of the algorithm, the already
-meshed source \b Face and the \b Mesh (optional, use it if there are several
-different meshes on the same face). It could also be necessary to
-define the orientation of mesh on the face, which is done by
-indicating two <b>Source Vertices</b>, which belong to the same edge of the
-source face, and two <b>Target Vertices</b>, which belong to the same edge of
-the created \b Face.
+meshed source \b Face and the \b Mesh (It can be omitted only when 
+projecting a submesh on another one from the same global Mesh). 
+It could also be necessary to define the orientation of mesh on the face
+, which is done by indicating two <b>Source Vertices</b>, which belong 
+to the same edge of the source face, and two <b>Target Vertices</b>, which 
+belong to the same edge of the created \b Face.
 
 \n <b>Projection 3D</b> algorithm allows to define the mesh of a shape by
 the projection of another already meshed shape.  This algorithm works
-only if all faces and edges of the target face have been meshed as 1D
-Projections of the faces and edges of the source face. Another
+only if all faces and edges of the target shape have been meshed as 1D-2D
+Projections of the faces and edges of the source shape. Another
 limitation is that this algorithm currently works only on boxes.
 
 To apply this algorithm select the solid to be meshed (indicated in
@@ -63,9 +64,9 @@ following dialog box will appear:
 \image html projection_3d.png
 
 In this menu you can define the \b Name of the algorithm, the already
-meshed source <b>3D shape</b> and the \b Mesh (optional, use it if there are
-several different meshes on the same shape). It could also be
-necessary to define the orientation of mesh on the shape, which is
+meshed source <b>3D shape</b> and the \b Mesh (It can be omitted only when 
+projecting a submesh on another one from the same global Mesh). 
+It could also be necessary to define the orientation of mesh on the shape, which is
 done by indicating two <b>Source Vertices</b>, which belong to the same edge
 of the source <b>3D Shape</b>, and two <b>Target Vertices</b>, which belong to the
 same edge of the source <b>3D Shape</b>.
diff --git a/doc/salome/gui/SMESH/input/scalar_bar.doc b/doc/salome/gui/SMESH/input/scalar_bar.doc
new file mode 100755 (executable)
index 0000000..146a7fa
--- /dev/null
@@ -0,0 +1,40 @@
+/*!
+
+\page scalar_bar_dlg Scalar Bar properties
+
+In this dialog you can specify the properties of the scalar bar
+
+\image html scalar_bar_dlg.png
+
+<ul>
+<li><b>Scalar Range</b> in this menu you can specify 
+<b>Min value</b> and <b>Max value</b> of the <b>Scalar Bar</b> </li>
+
+<li><b>Font</b> - in this menu you can set type, face and color for
+the font of <b>Title</b> and <b>Labels</b> of the <b>Scalar
+Bar</b></li>
+
+<li><b>Colors & Labels</b> - in this menu you can set the <b>number of
+colors</b> and the <b>number of labels</b> of the <b>Scalar
+Bar</b></li>
+
+<li><b>Orientation</b> - allows choosing between vertical and
+horizontal orientation of the <b>Scalar Bar</b></li>.
+
+<li><b>Origin & Size Vertical & Horizontal</b> - allows defining the
+location (<b>X</b> and <b>Y</b>) and size (<b>Width</b> and
+<b>Height</b>) of <b>Scalar Bar</b></li>
+<ul>
+<li><b>X</b>: abscissa of the origin (from the left
+side)</li>
+<li><b>Y</b>: ordinate of the origin (from the bottom)</li>
+</ul>
+<li><b>Distribution</b> in this menu you can Show/Hide distribution histogram of the values of the <b>Scalar Bar</b> and specify histogram properties</li>
+<ul>
+<li><b>Multicolor</b> the histogram is colored as <b>Scalar Bar</b></li>
+<li><b>Monocolor</b> the histogram is colored as selected with <b>Distribution color</b> selector</li>
+</ul>
+</ul>
+
+
+*/
index 1f612994f18438ce6a05af2a9a0e21b50083a7e5..9657f4c0df3266604ef54216055b7c2ebede66a6 100644 (file)
@@ -144,7 +144,14 @@ Additional criteria to select mesh <b>Faces</b> are the following:
 one element of mesh only. See also a
 \ref free_edges_page "Free Edges quality control".
 </li><li>
-<b>Free faces</b> selects 3D mesh elements wich belong to less than two volumes.
+<b>Free faces</b> selects 2D mesh elements wich belong to less than two volumes.
+</li><li>
+<b>Faces with bare border</b> selects 2D mesh elements having a free border without an edge on it.
+See also \ref bare_border_faces_page "Bare border faces quality control".
+</li><li>
+<b>Over-constrained faces</b> selects 2D mesh elements having only one border shared 
+with other 2D elements.
+See also \ref over_constrained_faces_page "Over-constrained faces quality control".
 </li><li>
 <b>Borders at Multi-Connections 2D</b> selects cells consisting of edges belonging to
 several elements of mesh. The number of mesh elements should be more, less or equal
@@ -187,6 +194,13 @@ diagonals with a value of length, which is more, less or equal
 </li><li>
 <b>Bad oriented volume</b> selects mesh volumes, which are incorrectly oriented from
 the point of view of MED convention.
+</li><li>
+<b>Over-constrained volumes</b> selects mesh volumes having only one border shared 
+with other volumes.
+See also \ref over_constrained_volumes_page "Over-constrained volumes quality control".
+</li><li>
+<b>Volumes with bare border</b> selects 3D mesh elements having a free border without a face on it.
+See also \ref bare_border_volumes_page "Bare border volumes quality control".
 </li>
 </ul>
 
index 359ffd7d5cde75615d5bc737e3bfc7d513e0410b..bad32ebf42a901e87ec65b679b87057aee53ecd3 100644 (file)
@@ -249,4 +249,48 @@ demonstrating the resulting mesh.
 \skipline import geompy
 \until #end
 
+<br>
+\anchor tui_copy_mesh
+<h2>Mesh Copying</h2>
+\code
+from smesh import *
+SetCurrentStudy(salome.myStudy)
+
+# make geometry of a box
+box = geompy.MakeBoxDXDYDZ(100,100,100)
+face = geompy.SubShapeAllSorted(box, geompy.ShapeType["FACE"])[0]
+
+# generate 3D mesh
+mesh = Mesh(box)
+localAlgo = mesh.Triangle(face)
+mesh.AutomaticHexahedralization()
+
+# objects to copy
+fGroup = mesh.GroupOnGeom( face, "2D on face")
+nGroup = mesh.GroupOnGeom( face, "nodes on face", NODE)
+subMesh = localAlgo.GetSubMesh()
+
+# make a new mesh by copying different part of the mesh
+
+# 1. copy the whole mesh
+newMesh = CopyMesh( mesh, "whole mesh copy")
+
+# 2. copy a group of 2D elements along with groups
+newMesh = CopyMesh( fGroup,  "face group copy with groups",toCopyGroups=True)
+
+# 3. copy a group of nodes with preseving their ids
+newMesh = CopyMesh( nGroup, "node group copy", toKeepIDs=True)
+
+# 4. copy some faces
+faceIds = fGroup.GetIDs()[-10:]
+newMesh = CopyMesh( mesh.GetIDSource( faceIds, FACE ), "some faces copy")
+
+# 5. copy some nodes
+nodeIds = nGroup.GetIDs()[-10:]
+newMesh = CopyMesh( mesh.GetIDSource( nodeIds, NODE), "some nodes copy")
+
+# 6. copy a sub-mesh
+newMesh = CopyMesh( subMesh, "submesh copy" )
+\endcode
+
 */
index 6677b2ab592bb5281c1e18b6fcd7237f4a9977aa..aa3e1eb1cc9cf199186d0e09ec41f6894cc924ef 100755 (executable)
@@ -90,7 +90,7 @@ Filter 2D mesh elements (faces) according to the minimum angle value:
 # create mesh
 from SMESH_mechanic import *
 # get faces with minimum angle > 75
-filter = smesh.GetFilter(smesh.FACE, smesh.FT_MinimumAngle, smesh.FT_MoreThan, 75)
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_MinimumAngle,">", 75)
 ids = mesh.GetIdsFromFilter(filter)
 print "Number of faces with minimum angle > 75:", len(ids)
 \endcode
@@ -237,7 +237,7 @@ from SMESH_mechanic import *
 # add node
 mesh.AddNode(0,0,0)
 # get all free nodes
-filter = smesh.GetFilter(smesh.EDGE, smesh.FT_FreeNodes)
+filter = smesh.GetFilter(smesh.NODE, smesh.FT_FreeNodes)
 ids = mesh.GetIdsFromFilter(filter)
 print "Number of free nodes:", len(ids)
 \endcode
@@ -255,13 +255,69 @@ Filter free faces:
 # create mesh
 from SMESH_mechanic import *
 # get all free faces
-filter = smesh.GetFilter(smesh.EDGE, smesh.FT_FreeFaces)
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_FreeFaces)
 ids = mesh.GetIdsFromFilter(filter)
 print "Number of free faces:", len(ids)
 \endcode
 
 \sa \ref tui_free_faces
 
+\section filter_bare_border_faces Bare border faces
+
+Filter faces with bare borders:
+- element type is \a smesh.FACE
+- functor type is \a smesh.FT_BareBorderFace
+- threshold value is not required
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# remove some faces to have faces with bare borders
+mesh.RemoveElements( mesh.GetElementsByType(FACE)[0:5] )
+# get all faces bare borders
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_BareBorderFace)
+ids = mesh.GetIdsFromFilter(filter)
+print "Faces with bare borders:", ids
+\endcode
+
+\sa \ref tui_bare_border_faces
+
+\section filter_coplanar_faces Coplanar faces
+
+Filter faces with bare borders:
+- element type is \a smesh.FACE
+- functor type is \a smesh.FT_CoplanarFaces
+- threshold value is the face ID
+- tolerance is in degrees
+
+\code
+# create mesh
+from SMESH_mechanic import *
+faceID = mesh.GetElementsByType(FACE)[0]
+# get all faces co-planar to the first face with tolerance 5 degrees
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_CoplanarFaces,faceID,Tolerance=5.0)
+ids = mesh.GetIdsFromFilter(filter)
+print "Number of faces coplanar with the first one:", len(ids)
+\endcode
+
+\section filter_over_constrained_faces Over-constrained faces
+
+Filter over-constrained faces:
+- element type is \a smesh.FACE
+- functor type is \a smesh.FT_OverConstrainedFace
+- threshold value is not required
+
+\code
+# create mesh
+from SMESH_mechanic import *
+# get all over-constrained faces
+filter = smesh.GetFilter(smesh.FACE, smesh.FT_OverConstrainedFace)
+ids = mesh.GetIdsFromFilter(filter)
+print "Over-constrained faces:", ids
+\endcode
+
+\sa \ref tui_over_constrained_faces
+
 \section filter_borders_multiconnection Borders at multi-connection
 
 Filter border 1D mesh elements (edges) according to the specified number of
@@ -377,6 +433,48 @@ print "Number of volumes with maximum element length > 10:", len(ids)
 
 \sa \ref tui_max_element_length_3d
 
+\section filter_bare_border_volumes Bare border volumes
+
+Filter 3D mesh elements with bare borders:
+- element type is \a smesh.VOLUME
+- functor type is \a smesh.FT_BareBorderVolume
+- threshold value is not required
+
+\code
+# create mesh
+from SMESH_mechanic import *
+mesh.Tetrahedron()
+mesh.Compute()
+# remove some volumes to have volumes with bare borders
+mesh.RemoveElements( mesh.GetElementsByType(VOLUME)[0:5] )
+# get all volumes with bare borders
+filter = smesh.GetFilter(smesh.VOLUME, smesh.FT_BareBorderVolume)
+ids = mesh.GetIdsFromFilter(filter)
+print "Volumes with bare borders:", ids
+\endcode
+
+\sa \ref tui_bare_border_volumes
+
+\section filter_over_constrained_volumes Over-constrained volumes
+
+Filter over-constrained volumes:
+- element type is \a smesh.VOLUME
+- functor type is \a smesh.FT_OverConstrainedVolume
+- threshold value is not required
+
+\code
+# create mesh
+from SMESH_mechanic import *
+mesh.Tetrahedron()
+mesh.Compute()
+# get all over-constrained volumes
+filter = smesh.GetFilter(smesh.VOLUME, smesh.FT_OverConstrainedVolume)
+ids = mesh.GetIdsFromFilter(filter)
+print "Over-constrained volumes:", ids
+\endcode
+
+\sa \ref tui_over_constrained_faces
+
 \section filter_belong_to_geom Belong to Geom
 
 Filter mesh entities (nodes or elements) which all nodes lie on the
index fc496dcde0f507966b4509ccefe66dd655d9e00d..420e507e19881a56f4ce625c79012fdd011af241 100644 (file)
@@ -309,6 +309,90 @@ aGroup.Add(aFaceIds)
 salome.sg.updateObjBrowser(1)
 \endcode
 
+\section tui_bare_border_faces Bare border faces
+
+\code
+from smesh import *
+SetCurrentStudy(salome.myStudy)
+
+box = geompy.MakeBoxDXDYDZ(100, 100, 100)
+geompy.addToStudy( box, "box" )
+
+mesh = smesh.Mesh(box)
+mesh.Segment().NumberOfSegments(3)
+mesh.Quadrangle()
+mesh.Compute()
+
+# remove 2 faces
+allFaces = mesh.GetElementsByType(FACE)
+mesh.RemoveElements( allFaces[0:2])
+
+bareGroup = mesh.MakeGroup("bare faces", FACE, FT_BareBorderFace)
+assert(bareGroup.Size() == 3)
+\endcode
+
+\section tui_bare_border_volumes Bare border volumes
+
+\code
+from smesh import *
+SetCurrentStudy(salome.myStudy)
+
+box = geompy.MakeBoxDXDYDZ(100, 30, 10)
+# the smallest face of the box
+face = geompy.SubShapeAllSorted( box, geompy.ShapeType["FACE"])[0]
+
+geompy.addToStudy( box, "box" )
+geompy.addToStudyInFather( box, face, "face" )
+
+mesh = Mesh(box)
+mesh.AutomaticHexahedralization();
+
+# remove half of mesh faces from the smallest face
+faceFaces = mesh.GetSubMeshElementsId(face)
+faceToRemove = faceFaces[: len(faceFaces)/2]
+mesh.RemoveElements( faceToRemove )
+
+# make a group of volumes missing the removed faces
+bareGroup = mesh.MakeGroup("bare volumes", VOLUME, FT_BareBorderVolume)
+assert(bareGroup.Size() == len( faceToRemove))
+\endcode
+
+\section tui_over_constrained_faces Over-constrained faces
+\code
+from smesh import *
+SetCurrentStudy(salome.myStudy)
+
+mesh = Mesh()
+faceFilter = GetFilter(FACE,FT_OverConstrainedFace)
+
+#make an edge
+n1 = mesh.AddNode(0,0,0)
+n2 = mesh.AddNode(10,0,0)
+edge = mesh.AddEdge([n1,n2])
+assert( not mesh.GetIdsFromFilter( faceFilter ))
+
+# make faces 
+mesh.ExtrusionSweep([edge], MakeDirStruct(0,7,0), 5)
+assert( 2 == len( mesh.GetIdsFromFilter( faceFilter )))
+\endcode
+
+\section tui_over_constrained_volumes Over-constrained volumes
+\code
+from smesh import *
+SetCurrentStudy(salome.myStudy)
+
+mesh = Mesh()
+volumeFilter = GetFilter(VOLUME,FT_OverConstrainedVolume)
+
+# make volumes by extrusion of one face
+n1 = mesh.AddNode(0,0,0)
+n2 = mesh.AddNode(10,0,0)
+edge = mesh.AddEdge([n1,n2])
+mesh.ExtrusionSweep([edge], MakeDirStruct(0,7,0), 1)
+mesh.ExtrusionSweep( mesh.GetElementsByType(FACE), MakeDirStruct(0,0,5), 7)
+assert( 2 == len( mesh.GetIdsFromFilter( volumeFilter )))
+\endcode
+
 \section tui_length_2d Length 2D
 
 \code
index e12607bcda9252aa7d35ca337d9c961ee18c30fd..087a0b48bab9a7a5aa6c25bec63c4a1919083178 100644 (file)
@@ -64,6 +64,10 @@ module SMESH
     FT_LyingOnGeom,
     FT_RangeOfIds,
     FT_BadOrientedVolume,
+    FT_BareBorderVolume,
+    FT_BareBorderFace,
+    FT_OverConstrainedVolume,
+    FT_OverConstrainedFace,
     FT_LinearOrQuadratic,
     FT_GroupColor,
     FT_ElemGeomType,
@@ -88,6 +92,7 @@ module SMESH
   };
   typedef sequence<HistogramRectangle> Histogram;
 
+
   /*!
   * Base interface for all functors ( i.e. numerical functors and predicates )
   */
@@ -98,8 +103,6 @@ module SMESH
     ElementType     GetElementType();
   };
 
-
-
   /*!
   * Numerical functors are intended for calculating value by Id of mesh entity
   */
@@ -150,6 +153,7 @@ module SMESH
     Values GetValues();
   };
   
+
   /*!
   * Predicates are intended for verification of criteria,
   *            must return bool value by mesh id
@@ -166,6 +170,29 @@ module SMESH
    */
   interface BadOrientedVolume: Predicate {};
 
+  /*!
+   * Logical functor (predicate) "Volumes with bare border".
+   * Verify whether a mesh volume has a free facet without a mesh face on it
+   */
+  interface BareBorderVolume: Predicate {};
+  /*!
+   * Logical functor (predicate) "Faces with bare border".
+   * Verify whether a mesh face has a side not shared with another face
+   * and without a mesh edge on it
+   */
+  interface BareBorderFace: Predicate {};
+
+  /*!
+   * Logical functor (predicate) "Over-constrained Volume"
+   * Verify whether a mesh volume has only one facet shared with other volumes
+   */
+  interface OverConstrainedVolume: Predicate {};
+  /*!
+   * Logical functor (predicate) "Over-constrained Face".
+   * Verify whether a mesh face has only one border shared with other faces
+   */
+  interface OverConstrainedFace: Predicate {};
+
   /*!
    * Logical functor (predicate) "Belong To Geometry".
    * Verify whether mesh element or node belong to pointed Geom Object
@@ -503,6 +530,10 @@ module SMESH
     RangeOfIds        CreateRangeOfIds();
 
     BadOrientedVolume CreateBadOrientedVolume();
+    BareBorderVolume  CreateBareBorderVolume();
+    BareBorderFace    CreateBareBorderFace();
+    OverConstrainedVolume CreateOverConstrainedVolume();
+    OverConstrainedFace   CreateOverConstrainedFace();
     LinearOrQuadratic CreateLinearOrQuadratic();
 
     GroupColor        CreateGroupColor();
index 3c375e625747bd9d665c0abe2bf7efa621776939..d958719e325730a28db98ed60212a8680841de7b 100644 (file)
@@ -221,10 +221,45 @@ module SMESH
       raises ( SALOME::SALOME_Exception );
 
     /*!
-     * Create a Mesh object, without a geometry shape reference
+     * Create a mesh by copying a part of another mesh
+     *  \param meshPart - a part of mesh to copy
+     *  \param meshName - a name of the new mesh
+     *  \param toCopyGroups - to create in the new mesh groups
+     *                        the copied elements belongs to
+     *  \param toKeepIDs - to preserve IDs of the copied elements or not
      */
-//      SMESH_Mesh NewEmpty()
-//        raises ( SALOME::SALOME_Exception );
+    SMESH_Mesh CopyMesh(in SMESH_IDSource meshPart,
+                        in string         meshName,
+                        in boolean        toCopyGroups,
+                        in boolean        toKeepIDs)
+      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 );
+
+    /*!
+     * 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.
+     * Create the groups of all elements from initial meshes.
+     */
+    SMESH_Mesh ConcatenateWithGroups(in mesh_array theMeshesArray, 
+                                    in boolean    theUniteIdenticalGroups, 
+                                     in boolean    theMergeNodesAndElements, 
+                                     in double     theMergeTolerance)
+      raises ( SALOME::SALOME_Exception );
 
     /*!
      * Mesh a subShape. 
@@ -309,33 +344,6 @@ 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 );
-
-    /*!
-     * 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.
-     * Create the groups of all elements from initial meshes.
-     */
-    SMESH_Mesh ConcatenateWithGroups(in mesh_array theMeshesArray, 
-                                    in boolean    theUniteIdenticalGroups, 
-                                     in boolean    theMergeNodesAndElements, 
-                                     in double     theMergeTolerance)
-      raises ( SALOME::SALOME_Exception );
-
     /*!
      * \brief Return id of object, registered in current study context
      *
index cc7d5a885fc87001d1c98d041ff6923219fa7d12..623d04ff1e795f31624852172f06143260e9a94b 100644 (file)
@@ -107,6 +107,10 @@ dist_salomeres_DATA = \
        mesh_vertex_n.png \
        mesh_vertex.png \
        mesh_volume_3d.png \
+       bare_border_volume.png \
+       bare_border_face.png \
+       over_constrained_volume.png \
+       over_constrained_face.png \
        mesh_wireframe.png \
        mesh_points.png \
        mesh_wrap.png \
@@ -173,6 +177,7 @@ dist_salomeres_DATA = \
        mesh_tree_hypo_projection_3d.png \
        mesh_tree_hypo_projection_2d.png \
        mesh_build_compound.png \
+       copy_mesh.png \
        mesh_node_to_point.png \
        mesh_tree_mesh_partial.png \
        mesh_extractGroup.png \
diff --git a/resources/bare_border_face.png b/resources/bare_border_face.png
new file mode 100644 (file)
index 0000000..1993f20
Binary files /dev/null and b/resources/bare_border_face.png differ
diff --git a/resources/bare_border_volume.png b/resources/bare_border_volume.png
new file mode 100644 (file)
index 0000000..3ef6e6a
Binary files /dev/null and b/resources/bare_border_volume.png differ
diff --git a/resources/copy_mesh.png b/resources/copy_mesh.png
new file mode 100644 (file)
index 0000000..263479f
Binary files /dev/null and b/resources/copy_mesh.png differ
diff --git a/resources/over_constrained_face.png b/resources/over_constrained_face.png
new file mode 100644 (file)
index 0000000..22b61bb
Binary files /dev/null and b/resources/over_constrained_face.png differ
diff --git a/resources/over_constrained_volume.png b/resources/over_constrained_volume.png
new file mode 100644 (file)
index 0000000..0e2da26
Binary files /dev/null and b/resources/over_constrained_volume.png differ
index 677f467de9fa18915f173c5dd0f974e8b438cf52..42b5b6a1a366b3fea541a7ad325aa64194d89e5a 100644 (file)
@@ -310,12 +310,16 @@ double NumericalFunctor::GetValue( long theId )
  *  \param nbIntervals - number of intervals
  *  \param nbEvents - number of mesh elements having values within i-th interval
  *  \param funValues - boundaries of intervals
+ *  \param elements - elements to check vulue of; empty list means "of all"
+ *  \param minmax - boundaries of diapason of values to divide into intervals
  */
 //================================================================================
 
 void NumericalFunctor::GetHistogram(int                  nbIntervals,
                                     std::vector<int>&    nbEvents,
-                                    std::vector<double>& funValues)
+                                    std::vector<double>& funValues,
+                                    const vector<int>&   elements,
+                                    const double*        minmax)
 {
   if ( nbIntervals < 1 ||
        !myMesh ||
@@ -326,13 +330,30 @@ void NumericalFunctor::GetHistogram(int                  nbIntervals,
 
   // get all values sorted
   std::multiset< double > values;
-  SMDS_ElemIteratorPtr elemIt = myMesh->elementsIterator(GetType());
-  while ( elemIt->more() )
-    values.insert( GetValue( elemIt->next()->GetID() ));
+  if ( elements.empty() )
+  {
+    SMDS_ElemIteratorPtr elemIt = myMesh->elementsIterator(GetType());
+    while ( elemIt->more() )
+      values.insert( GetValue( elemIt->next()->GetID() ));
+  }
+  else
+  {
+    vector<int>::const_iterator id = elements.begin();
+    for ( ; id != elements.end(); ++id )
+      values.insert( GetValue( *id ));
+  }
 
+  if ( minmax )
+  {
+    funValues[0] = minmax[0];
+    funValues[nbIntervals] = minmax[1];
+  }
+  else
+  {
+    funValues[0] = *values.begin();
+    funValues[nbIntervals] = *values.rbegin();
+  }
   // case nbIntervals == 1
-  funValues[0] = *values.begin();
-  funValues[nbIntervals] = *values.rbegin();
   if ( nbIntervals == 1 )
   {
     nbEvents[0] = values.size();
@@ -350,15 +371,21 @@ void NumericalFunctor::GetHistogram(int                  nbIntervals,
   std::multiset< double >::iterator min = values.begin(), max;
   for ( int i = 0; i < nbIntervals; ++i )
   {
+    // find end value of i-th interval
     double r = (i+1) / double( nbIntervals );
     funValues[i+1] = funValues.front() * (1-r) + funValues.back() * r;
+
+    // count values in the i-th interval if there are any
     if ( min != values.end() && *min <= funValues[i+1] )
     {
-      max = values.upper_bound( funValues[i+1] ); // greater than funValues[i+1], or end()
+      // find the first value out of the interval
+      max = values.upper_bound( funValues[i+1] ); // max is greater than funValues[i+1], or end()
       nbEvents[i] = std::distance( min, max );
       min = max;
     }
   }
+  // add values larger than minmax[1]
+  nbEvents.back() += std::distance( min, values.end() );
 }
 
 //=======================================================================
@@ -1902,7 +1929,115 @@ SMDSAbs_ElementType BadOrientedVolume::GetType() const
   return SMDSAbs_Volume;
 }
 
+/*
+  Class       : BareBorderVolume
+*/
+
+bool BareBorderVolume::IsSatisfy(long theElementId )
+{
+  SMDS_VolumeTool  myTool;
+  if ( myTool.Set( myMesh->FindElement(theElementId)))
+  {
+    for ( int iF = 0; iF < myTool.NbFaces(); ++iF )
+      if ( myTool.IsFreeFace( iF ))
+      {
+        const SMDS_MeshNode** n = myTool.GetFaceNodes(iF);
+        vector< const SMDS_MeshNode*> nodes( n, n+myTool.NbFaceNodes(iF));
+        if ( !myMesh->FindElement( nodes, SMDSAbs_Face, /*Nomedium=*/false))
+          return true;
+      }
+  }
+  return false;
+}
+
+/*
+  Class       : BareBorderFace
+*/
+
+bool BareBorderFace::IsSatisfy(long theElementId )
+{
+  if ( const SMDS_MeshElement* face = myMesh->FindElement(theElementId))
+    if ( face->GetType() == SMDSAbs_Face )
+    {
+      int nbN = face->NbCornerNodes();
+      for ( int i = 0; i < nbN; ++i )
+      {
+        // check if a link is shared by another face
+        const SMDS_MeshNode* n1 = face->GetNode( i );
+        const SMDS_MeshNode* n2 = face->GetNode( (i+1)%nbN );
+        SMDS_ElemIteratorPtr fIt = n1->GetInverseElementIterator( SMDSAbs_Face );
+        bool isShared = false;
+        while ( !isShared && fIt->more() )
+        {
+          const SMDS_MeshElement* f = fIt->next();
+          isShared = ( f != face && f->GetNodeIndex(n2) != -1 );
+        }
+        if ( !isShared )
+        {
+          myLinkNodes.resize( 2 + face->IsQuadratic());
+          myLinkNodes[0] = n1;
+          myLinkNodes[1] = n2;
+          if ( face->IsQuadratic() )
+            myLinkNodes[2] = face->GetNode( i+nbN );
+          return !myMesh->FindElement( myLinkNodes, SMDSAbs_Edge, /*noMedium=*/false);
+        }
+      }
+    }
+  return false;
+}
+
+/*
+  Class       : OverConstrainedVolume
+*/
 
+bool OverConstrainedVolume::IsSatisfy(long theElementId )
+{
+  // An element is over-constrained if it has N-1 free borders where
+  // N is the number of edges/faces for a 2D/3D element.
+  SMDS_VolumeTool  myTool;
+  if ( myTool.Set( myMesh->FindElement(theElementId)))
+  {
+    int nbSharedFaces = 0;
+    for ( int iF = 0; iF < myTool.NbFaces(); ++iF )
+      if ( !myTool.IsFreeFace( iF ) && ++nbSharedFaces > 1 )
+        break;
+    return ( nbSharedFaces == 1 );
+  }
+  return false;
+}
+
+/*
+  Class       : OverConstrainedFace
+*/
+
+bool OverConstrainedFace::IsSatisfy(long theElementId )
+{
+  // An element is over-constrained if it has N-1 free borders where
+  // N is the number of edges/faces for a 2D/3D element.
+  if ( const SMDS_MeshElement* face = myMesh->FindElement(theElementId))
+    if ( face->GetType() == SMDSAbs_Face )
+    {
+      int nbSharedBorders = 0;
+      int nbN = face->NbCornerNodes();
+      for ( int i = 0; i < nbN; ++i )
+      {
+        // check if a link is shared by another face
+        const SMDS_MeshNode* n1 = face->GetNode( i );
+        const SMDS_MeshNode* n2 = face->GetNode( (i+1)%nbN );
+        SMDS_ElemIteratorPtr fIt = n1->GetInverseElementIterator( SMDSAbs_Face );
+        bool isShared = false;
+        while ( !isShared && fIt->more() )
+        {
+          const SMDS_MeshElement* f = fIt->next();
+          isShared = ( f != face && f->GetNodeIndex(n2) != -1 );
+        }
+        if ( isShared && ++nbSharedBorders > 1 )
+          break;
+      }
+      return ( nbSharedBorders == 1 );
+    }
+  return false;
+}
 
 /*
   Class       : FreeBorders
index 915bd9f4bf1126485f452b2c1d839fec2453fe9e..0a71438d7806c43053938606b0acfa9d0dc4cc1f 100644 (file)
@@ -127,9 +127,11 @@ namespace SMESH{
       virtual void SetMesh( const SMDS_Mesh* theMesh );
       virtual double GetValue( long theElementId );
       virtual double GetValue(const TSequenceOfXYZ& thePoints) { return -1.0;};
-      void GetHistogram(int                  nbIntervals,
-                        std::vector<int>&    nbEvents,
-                        std::vector<double>& funValues);
+      void GetHistogram(int                     nbIntervals,
+                        std::vector<int>&       nbEvents,
+                        std::vector<double>&    funValues,
+                        const std::vector<int>& elements,
+                        const double*           minmax=0);
       virtual SMDSAbs_ElementType GetType() const = 0;
       virtual double GetBadRate( double Value, int nbNodes ) const = 0;
       long  GetPrecision() const;
@@ -373,11 +375,72 @@ namespace SMESH{
       virtual void SetMesh( const SMDS_Mesh* theMesh );
       virtual bool IsSatisfy( long theElementId );
       virtual SMDSAbs_ElementType GetType() const;
-            
+
     protected:
       const SMDS_Mesh* myMesh;
     };
-   
+
+    /*
+      BareBorderVolume
+    */
+    class SMESHCONTROLS_EXPORT BareBorderVolume: public Predicate
+    {
+    public:
+      BareBorderVolume():myMesh(0) {}
+      virtual void SetMesh( const SMDS_Mesh* theMesh ) { myMesh = theMesh; }
+      virtual SMDSAbs_ElementType GetType() const      { return SMDSAbs_Volume; }
+      virtual bool IsSatisfy( long theElementId );
+    protected:
+      const SMDS_Mesh* myMesh;
+    };
+    typedef boost::shared_ptr<BareBorderVolume> BareBorderVolumePtr;
+
+    /*
+      BareBorderFace
+    */
+    class SMESHCONTROLS_EXPORT BareBorderFace: public Predicate
+    {
+    public:
+      BareBorderFace():myMesh(0) {}
+      virtual void SetMesh( const SMDS_Mesh* theMesh ) { myMesh = theMesh; }
+      virtual SMDSAbs_ElementType GetType() const      { return SMDSAbs_Face; }
+      virtual bool IsSatisfy( long theElementId );
+    protected:
+      const SMDS_Mesh* myMesh;
+      std::vector< const SMDS_MeshNode* > myLinkNodes;
+    };
+    typedef boost::shared_ptr<BareBorderFace> BareBorderFacePtr;
+
+    /*
+      OverConstrainedVolume
+    */
+    class SMESHCONTROLS_EXPORT OverConstrainedVolume: public Predicate
+    {
+    public:
+      OverConstrainedVolume():myMesh(0) {}
+      virtual void SetMesh( const SMDS_Mesh* theMesh ) { myMesh = theMesh; }
+      virtual SMDSAbs_ElementType GetType() const      { return SMDSAbs_Volume; }
+      virtual bool IsSatisfy( long theElementId );
+    protected:
+      const SMDS_Mesh* myMesh;
+    };
+    typedef boost::shared_ptr<OverConstrainedVolume> OverConstrainedVolumePtr;
+
+    /*
+      OverConstrainedFace
+    */
+    class SMESHCONTROLS_EXPORT OverConstrainedFace: public Predicate
+    {
+    public:
+      OverConstrainedFace():myMesh(0) {}
+      virtual void SetMesh( const SMDS_Mesh* theMesh ) { myMesh = theMesh; }
+      virtual SMDSAbs_ElementType GetType() const      { return SMDSAbs_Face; }
+      virtual bool IsSatisfy( long theElementId );
+    protected:
+      const SMDS_Mesh* myMesh;
+      std::vector< const SMDS_MeshNode* > myLinkNodes;
+    };
+    typedef boost::shared_ptr<OverConstrainedFace> OverConstrainedFacePtr;
 
     /*
       Class       : FreeEdges
@@ -399,7 +462,7 @@ namespace SMESH{
       };
       typedef std::set<Border> TBorders;
       void GetBoreders(TBorders& theBorders);
-      
+
     protected:
       const SMDS_Mesh* myMesh;
     };
index 4b4f432ffb958531bc5751f5683eb0e8491acc75..cafd4b00045fe5cd1a883905e8a4c51a10b5f4b9 100644 (file)
@@ -204,6 +204,25 @@ SMESH_ActorDef::SMESH_ActorDef()
   aFilter->RegisterCellsWithType(VTK_POLYHEDRON);
 //#endif
 
+  my3DExtActor = SMESH_DeviceActor::New();
+  my3DExtActor->SetUserMatrix(aMatrix);
+  my3DExtActor->PickableOff();
+  my3DExtActor->SetProperty(my2DExtProp);
+  my3DExtActor->SetBackfaceProperty(my2DExtProp);
+  my3DExtActor->SetRepresentation(SMESH_DeviceActor::eSurface);
+  aFilter = my3DExtActor->GetExtractUnstructuredGrid();
+  aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
+  aFilter->RegisterCellsWithType(VTK_TETRA);
+  aFilter->RegisterCellsWithType(VTK_VOXEL);
+  aFilter->RegisterCellsWithType(VTK_HEXAHEDRON);
+  aFilter->RegisterCellsWithType(VTK_WEDGE);
+  aFilter->RegisterCellsWithType(VTK_PYRAMID);
+  aFilter->RegisterCellsWithType(VTK_QUADRATIC_TETRA);
+  aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON);
+  aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE);
+  aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID);
+  aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
+
   //Definition 1D device of the actor
   //---------------------------------
   myEdgeProp = vtkProperty::New();
@@ -537,6 +556,7 @@ SMESH_ActorDef::~SMESH_ActorDef()
   my2DExtProp->Delete();
   my2DExtActor->Delete();
   my3DActor->Delete();
+  my3DExtActor->Delete();
 
   myNodeActor->Delete();
   myBaseActor->Delete();
@@ -728,8 +748,8 @@ SetControlMode(eControl theMode,
 
   bool anIsScalarVisible = theMode > eNone;
 
-  if(anIsScalarVisible){
-    switch(theMode){
+  if(anIsScalarVisible) {
+    switch(theMode) {
     case eLength:
     {
       SMESH::Controls::Length* aControl = new SMESH::Controls::Length();
@@ -760,6 +780,14 @@ SetControlMode(eControl theMode,
       myFunctor.reset(new SMESH::Controls::FreeFaces());
       myControlActor = my2DActor;
       break;
+    case eBareBorderFace:
+      myFunctor.reset(new SMESH::Controls::BareBorderFace());
+      myControlActor = my2DActor;
+      break;
+    case eOverConstrainedFace:
+      myFunctor.reset(new SMESH::Controls::OverConstrainedFace());
+      myControlActor = my2DActor;
+      break;
     case eMultiConnection:
       myFunctor.reset(new SMESH::Controls::MultiConnection());
       myControlActor = my1DActor;
@@ -824,6 +852,18 @@ SetControlMode(eControl theMode,
       myControlActor = my3DActor;
       break;
     }
+    case eBareBorderVolume:
+    {
+      myFunctor.reset(new SMESH::Controls::BareBorderVolume());
+      myControlActor = my3DActor;
+      break;
+    }
+    case eOverConstrainedVolume:
+    {
+      myFunctor.reset(new SMESH::Controls::OverConstrainedVolume());
+      myControlActor = my3DActor;
+      break;
+    }
     case eMinimumAngle:
     {
       SMESH::Controls::MinimumAngle* aControl = new SMESH::Controls::MinimumAngle();
@@ -865,14 +905,22 @@ SetControlMode(eControl theMode,
         my1DExtActor->SetExtControlMode(myFunctor);
         break;
       case eFreeFaces:
+      case eBareBorderFace:
+      case eOverConstrainedFace:
         my2DExtActor->SetExtControlMode(myFunctor);
         break;
+      case eBareBorderVolume:
+      case eOverConstrainedVolume:
+        my3DExtActor->SetExtControlMode(myFunctor);
+        break;
       case eLength2D:
       case eMultiConnection2D:
         my1DExtActor->SetExtControlMode(myFunctor,myScalarBarActor,myLookupTable);
+        UpdateDistribution();
         break;
       default:
         myControlActor->SetControlMode(myFunctor,myScalarBarActor,myLookupTable);
+        UpdateDistribution();
       }
     }
 
@@ -916,6 +964,7 @@ void SMESH_ActorDef::AddToRender(vtkRenderer* theRenderer){
   theRenderer->AddActor(myNodeExtActor);
 
   my3DActor->AddToRender(theRenderer);
+  my3DExtActor->AddToRender(theRenderer);
   my2DActor->AddToRender(theRenderer);
   my2DExtActor->AddToRender(theRenderer);
 
@@ -959,6 +1008,7 @@ void SMESH_ActorDef::RemoveFromRender(vtkRenderer* theRenderer){
   my2DActor->RemoveFromRender(theRenderer);
   my2DExtActor->RemoveFromRender(theRenderer);
   my3DActor->RemoveFromRender(theRenderer);
+  my3DExtActor->RemoveFromRender(theRenderer);
 
   theRenderer->RemoveActor(myScalarBarActor);
   theRenderer->RemoveActor(myPointLabels);
@@ -994,6 +1044,7 @@ bool SMESH_ActorDef::Init(TVisualObjPtr theVisualObj,
   my2DActor->Init(myVisualObj,myImplicitBoolean);
   my2DExtActor->Init(myVisualObj,myImplicitBoolean);
   my3DActor->Init(myVisualObj,myImplicitBoolean);
+  my3DExtActor->Init(myVisualObj,myImplicitBoolean);
   
   my0DActor->GetMapper()->SetLookupTable(myLookupTable);
   //my0DExtActor->GetMapper()->SetLookupTable(myLookupTable);
@@ -1004,6 +1055,7 @@ bool SMESH_ActorDef::Init(TVisualObjPtr theVisualObj,
   my2DActor->GetMapper()->SetLookupTable(myLookupTable);
   my2DExtActor->GetMapper()->SetLookupTable(myLookupTable);
   my3DActor->GetMapper()->SetLookupTable(myLookupTable);
+  my3DExtActor->GetMapper()->SetLookupTable(myLookupTable);
     
   vtkFloatingPointType aFactor, aUnits;
   my2DActor->GetPolygonOffsetParameters(aFactor,aUnits);
@@ -1076,6 +1128,7 @@ void SMESH_ActorDef::SetTransform(VTKViewer_Transform* theTransform){
   my2DActor->SetTransform(theTransform);
   my2DExtActor->SetTransform(theTransform);
   my3DActor->SetTransform(theTransform);
+  my3DExtActor->SetTransform(theTransform);
 
   Modified();
 }
@@ -1131,6 +1184,7 @@ void SMESH_ActorDef::SetShrinkFactor(vtkFloatingPointType theValue){
   my2DActor->SetShrinkFactor(theValue);
   my2DExtActor->SetShrinkFactor(theValue);
   my3DActor->SetShrinkFactor(theValue);
+  my3DExtActor->SetShrinkFactor(theValue);
 
   Modified();
 }
@@ -1146,6 +1200,7 @@ void SMESH_ActorDef::SetShrink(){
   my2DActor->SetShrink();
   my2DExtActor->SetShrink();
   my3DActor->SetShrink();
+  my3DExtActor->SetShrink();
 
   myIsShrunk = true;
   Modified();
@@ -1162,6 +1217,7 @@ void SMESH_ActorDef::UnShrink(){
   my2DActor->UnShrink();
   my2DExtActor->UnShrink();
   my3DActor->UnShrink();
+  my3DExtActor->UnShrink();
 
   myIsShrunk = false;
   Modified();
@@ -1208,6 +1264,7 @@ void SMESH_ActorDef::SetVisibility(int theMode, bool theIsUpdateRepersentation){
   my2DActor->VisibilityOff();
   my2DExtActor->VisibilityOff();
   my3DActor->VisibilityOff();
+  my3DExtActor->VisibilityOff();
   
   myScalarBarActor->VisibilityOff();
   myPointLabels->VisibilityOff();
@@ -1227,8 +1284,14 @@ void SMESH_ActorDef::SetVisibility(int theMode, bool theIsUpdateRepersentation){
         my1DExtActor->VisibilityOn();
         break;
       case eFreeFaces:
+      case eBareBorderFace:
+      case eOverConstrainedFace:
         my2DExtActor->VisibilityOn();
         break;
+      case eBareBorderVolume:
+      case eOverConstrainedVolume:
+        my3DExtActor->VisibilityOn();
+        break;
       case eLength2D:
       case eMultiConnection2D:
         my1DExtActor->VisibilityOn();
@@ -1467,6 +1530,7 @@ void SMESH_ActorDef::SetRepresentation (int theMode)
   //my0DExtActor->SetVisibility(false);
   my1DExtActor->SetVisibility(false);
   my2DExtActor->SetVisibility(false);
+  my3DExtActor->SetVisibility(false);
 
   // ???
   //my0DActor->SetProperty(aProp);
@@ -1797,6 +1861,7 @@ SMESH_ActorDef::SetImplicitFunctionUsed(bool theIsImplicitFunctionUsed)
   my2DActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
   my2DExtActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
   my3DActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
+  my3DExtActor->SetImplicitFunctionUsed(theIsImplicitFunctionUsed);
 }
 
 vtkIdType 
@@ -1958,7 +2023,7 @@ void SMESH_ActorDef::UpdateScalarBar()
   myScalarBarActor->SetDistributionColoringType(coloringType);
   
   QColor distributionColor = mgr->colorValue("SMESH", "distribution_color",
-                                            QColor(255, 255, 255));
+                                             QColor(255, 255, 255));
   double rgb[3];
   rgb[0]= distributionColor.red()/255.;
   rgb[1]= distributionColor.green()/255.;
@@ -1968,6 +2033,27 @@ void SMESH_ActorDef::UpdateScalarBar()
   
 }
 
+void SMESH_ActorDef::UpdateDistribution()
+{
+  if(SMESH::Controls::NumericalFunctor* fun =
+     dynamic_cast<SMESH::Controls::NumericalFunctor*>(myFunctor.get()))
+  {
+    int nbIntervals = myScalarBarActor->GetMaximumNumberOfColors();
+    std::vector<int> nbEvents;
+    std::vector<double> funValues;
+    SMESH_VisualObjDef::TEntityList elems;
+    if ( ! dynamic_cast<SMESH_MeshObj*>(myVisualObj.get()))
+      dynamic_cast<SMESH_VisualObjDef*>(myVisualObj.get())->GetEntities( fun->GetType(), elems );
+    std::vector<int> elemIds;
+    for ( SMESH_VisualObjDef::TEntityList::iterator e = elems.begin(); e != elems.end(); ++e)
+      elemIds.push_back( (*e)->GetID());
+    vtkLookupTable* lookupTable = static_cast<vtkLookupTable*>(myScalarBarActor->GetLookupTable());
+    double * range = lookupTable->GetRange();
+    fun->GetHistogram(nbIntervals, nbEvents, funValues, elemIds, range);
+    myScalarBarActor->SetDistribution(nbEvents);
+  }
+}
+
 void SMESH_ActorDef::SetQuadratic2DRepresentation(EQuadratic2DRepresentation theMode)
 {
   switch(theMode) {
index 24a57a00ab582cd6b502dea7184ea1351151c5b6..744571e41360280a92dbb6cfd3a50821ad74b496 100644 (file)
@@ -123,7 +123,8 @@ class SMESHOBJECT_EXPORT SMESH_Actor: public SALOME_Actor
   enum eControl{eNone, eLength, eLength2D, eFreeBorders, eFreeEdges, eFreeNodes,
                 eFreeFaces, eMultiConnection, eArea, eTaper, eAspectRatio,
                 eMinimumAngle, eWarping, eSkew, eAspectRatio3D, eMultiConnection2D, eVolume3D,
-                eMaxElementLength2D, eMaxElementLength3D};
+                eMaxElementLength2D, eMaxElementLength3D, eBareBorderFace, eBareBorderVolume,
+                eOverConstrainedFace, eOverConstrainedVolume};
   virtual void SetControlMode(eControl theMode) = 0;
   virtual eControl GetControlMode() = 0;
   virtual SMESH::Controls::FunctorPtr GetFunctor() = 0;
@@ -141,6 +142,7 @@ class SMESHOBJECT_EXPORT SMESH_Actor: public SALOME_Actor
   virtual long GetControlsPrecision() const = 0;
 
   virtual void UpdateScalarBar() = 0;
+  virtual void UpdateDistribution() = 0;
 };
 
 
index 09b2232f0bd660194c09227b804e8c0ab9b58371..53001f4efbf9f7c62519b1036095426900b62c45 100644 (file)
@@ -196,6 +196,7 @@ class SMESH_ActorDef : public SMESH_Actor
   virtual long GetControlsPrecision() const { return myControlsPrecision; }
 
   virtual void UpdateScalarBar();
+  virtual void UpdateDistribution();
 
 
   virtual void SetQuadratic2DRepresentation(EQuadratic2DRepresentation);
@@ -234,6 +235,7 @@ class SMESH_ActorDef : public SMESH_Actor
   SMESH_DeviceActor* my2DActor;
   SMESH_DeviceActor* my2DExtActor;
   SMESH_DeviceActor* my3DActor;
+  SMESH_DeviceActor* my3DExtActor;
   SMESH_DeviceActor* myControlActor;
 
   vtkProperty* myNodeExtProp;
index 600a4987cfb05e19059e9309cc6d9443c45c7dca..d4a04203bb16663384de8af2e094fe943cd4a272 100644 (file)
@@ -310,12 +310,6 @@ SMESH_DeviceActor
         double aValue = aNumericalFunctor->GetValue(anObjId);
         aScalars->SetValue(i,aValue);
       }
-      int nbIntervals = theScalarBarActor->GetMaximumNumberOfColors();
-      std::vector<int> nbEvents;
-      std::vector<double> funValues;
-      aNumericalFunctor->GetHistogram(nbIntervals, nbEvents, funValues);
-      theScalarBarActor->SetDistribution(nbEvents);
-
     }else if(Predicate* aPredicate = dynamic_cast<Predicate*>(theFunctor.get())){
       for(vtkIdType i = 0; i < aNbCells; i++){
         vtkIdType anId = myExtractUnstructuredGrid->GetInputId(i);
@@ -475,16 +469,6 @@ SMESH_DeviceActor
       myMergeFilter->SetScalars(aDataSet);
       aDataSet->Delete();
     }
-    
-    //Set Distribution 
-    if(NumericalFunctor* aNumericalFunctor = dynamic_cast<NumericalFunctor*>(theFunctor.get())){
-      int nbIntervals = theScalarBarActor->GetMaximumNumberOfColors();
-      std::vector<int> nbEvents;
-      std::vector<double> funValues;
-      aNumericalFunctor->GetHistogram(nbIntervals, nbEvents, funValues);
-      theScalarBarActor->SetDistribution(nbEvents);
-    }
-    
   }
   GetMapper()->SetScalarVisibility(anIsInitialized);
   theScalarBarActor->SetVisibility(anIsInitialized);
@@ -500,8 +484,13 @@ SMESH_DeviceActor
   myVisualObj->UpdateFunctor(theFunctor);
 
   using namespace SMESH::Controls;
-  if ( dynamic_cast<FreeBorders*>(theFunctor.get()) ||
-       dynamic_cast<FreeFaces*>(theFunctor.get()) ) {
+  if ( dynamic_cast<FreeBorders          *>(theFunctor.get()) ||
+       dynamic_cast<FreeFaces            *>(theFunctor.get()) ||
+       dynamic_cast<BareBorderVolume     *>(theFunctor.get()) ||
+       dynamic_cast<BareBorderFace       *>(theFunctor.get()) ||
+       dynamic_cast<OverConstrainedVolume*>(theFunctor.get()) ||
+       dynamic_cast<OverConstrainedFace  *>(theFunctor.get()))
+  {
     Predicate* aFreePredicate = dynamic_cast<Predicate*>(theFunctor.get());
     myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
     vtkUnstructuredGrid* aGrid = myVisualObj->GetUnstructuredGrid();
@@ -514,7 +503,9 @@ SMESH_DeviceActor
     if(!myExtractUnstructuredGrid->IsCellsRegistered())
       myExtractUnstructuredGrid->RegisterCell(-1);
     SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid());
-  }else if(FreeEdges* aFreeEdges = dynamic_cast<FreeEdges*>(theFunctor.get())){
+  }
+  else if(FreeEdges* aFreeEdges = dynamic_cast<FreeEdges*>(theFunctor.get()))
+  {
     SMESH::Controls::FreeEdges::TBorders aBorders;
     aFreeEdges->GetBoreders(aBorders);
     vtkUnstructuredGrid* aDataSet = vtkUnstructuredGrid::New();
@@ -561,7 +552,9 @@ SMESH_DeviceActor
 
     SetUnstructuredGrid(aDataSet);
     aDataSet->Delete();
-  }else if(FreeNodes* aFreeNodes = dynamic_cast<FreeNodes*>(theFunctor.get())){
+  }
+  else if(FreeNodes* aFreeNodes = dynamic_cast<FreeNodes*>(theFunctor.get()))
+  {
     myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
     vtkIdType aNbNodes = myVisualObj->GetNbEntities(SMDSAbs_Node);
     for( vtkIdType i = 0; i < aNbNodes; i++ ){
index 059edd9270b3aa35a096a6ce30388fe5f6e96ea5..91e38e35418a441c2582cdb2dcce3ffce8a425f7 100644 (file)
@@ -101,7 +101,7 @@ bool SMESH_PreviewActorsCollection::Init( const TopoDS_Shape& theShape, TopAbs_S
     int index = myMapOfShapes.FindIndex( exp.Current() );
     if ( index && !myMapOfActors.contains( index ) ) { 
       // create actor if the index is present
-      if ( GEOM_Actor* anActor = createActor( exp.Current() )) {
+      if ( GEOM_Actor* anActor = createActor( exp.Current().Oriented(TopAbs_FORWARD))) {
         // Create new entry for actor
         QString aString = theEntry;
         aString += QString("_%1").arg( index ); // add index to actor entry
index 3b4cd2520115c4f741c4ab737b7f8911a76e9700..17a1935aedfc0adb60a2f632f4fc9d33935bfe09 100644 (file)
 
 using namespace std;
 
-SMDS_MeshElement::SMDS_MeshElement(int ID):myID(ID), myMeshId(-1), myShapeId(0), myIdInShape(-1)
+SMDS_MeshElement::SMDS_MeshElement(int ID)
 {
+  init(ID);
 }
 
-SMDS_MeshElement::SMDS_MeshElement(int id, ShortType meshId, ShortType shapeId):
-  myID(id), myMeshId(meshId), myShapeId(shapeId), myIdInShape(-1)
+SMDS_MeshElement::SMDS_MeshElement(int id, ShortType meshId, ShortType shapeId)
 {
+  init(id, meshId, shapeId);
+}
+
+void SMDS_MeshElement::init(int id, ShortType meshId, ShortType shapeId )
+{
+  myID = id;
+  myMeshId = meshId;
+  myShapeId = shapeId;
+  myIdInShape = -1;
 }
 
 void SMDS_MeshElement::Print(ostream & OS) const
index d4f32a51b40e68426a55d5fc545abed0a570f51a..374d67379aafbd865f53a253aa1725352a07e524 100644 (file)
@@ -151,6 +151,7 @@ protected:
   inline void setVtkId(int vtkId) { myVtkID = vtkId; };
   SMDS_MeshElement(int ID=-1);
   SMDS_MeshElement(int id, ShortType meshId, ShortType shapeId = 0);
+  virtual void init(int id = -1, ShortType meshId = -1, ShortType shapeId = 0);
   virtual void Print(std::ostream & OS) const;
 
   //! Element index in vector SMDS_Mesh::myNodes or SMDS_Mesh::myCells
index de0f10e3e42c7e173ede193e5ecb0f4f2f31ea3b..fd6116368b61892a03e9040fd90dd6a505c419ff 100644 (file)
@@ -61,12 +61,9 @@ SMDS_MeshNode::SMDS_MeshNode(int id, int meshId, int shapeId, double x, double y
 
 void SMDS_MeshNode::init(int id, int meshId, int shapeId, double x, double y, double z)
 {
+  SMDS_MeshElement::init(id, meshId, shapeId);
   myVtkID = id -1;
   assert(myVtkID >= 0);
-  myID = id;
-  myMeshId = meshId;
-  myShapeId = shapeId;
-  myIdInShape = -1;
   //MESSAGE("Node " << myID << " " << myVtkID << " (" << x << ", " << y << ", " << z << ")");
   SMDS_Mesh* mesh = SMDS_Mesh::_meshList[myMeshId];
   SMDS_UnstructuredGrid * grid = mesh->getGrid();
@@ -312,9 +309,12 @@ vtkIdType SMDS_MeshNode::GetVtkType() const
 //=======================================================================
 void SMDS_MeshNode::AddInverseElement(const SMDS_MeshElement* ME)
 {
-    const SMDS_MeshCell *cell = dynamic_cast<const SMDS_MeshCell*>(ME);
-    assert(cell);
-    SMDS_Mesh::_meshList[myMeshId]->getGrid()->AddReferenceToCell(myVtkID, cell->getVtkId());
+  const SMDS_MeshCell *cell = dynamic_cast<const SMDS_MeshCell*> (ME);
+  assert(cell);
+  SMDS_UnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
+  vtkCellLinks *Links = grid->GetCellLinks();
+  Links->ResizeCellList(myVtkID, 1);
+  Links->AddCellReference(cell->getVtkId(), myVtkID);
 }
 
 //=======================================================================
index 02fc1ef61bb0bdbe21bc94e429ffbd329196bd77..773f39fcf97ecfb186a46f6ff906e9adc6396138 100644 (file)
@@ -40,6 +40,7 @@ public:
   friend class SMESHDS_Mesh;
   friend class SMDS_Mesh;
   friend class ObjectPool<SMDS_MeshNode>;
+  friend class SMDS_VtkFace;
 
   void Print(std::ostream & OS) const;
   double X() const;
index 6cd006d51752510429018d70e5bd89c45acad1ba..a314565c7b670742ae4f8b3276491ca30628e068 100644 (file)
@@ -25,8 +25,8 @@ SMDS_VtkEdge::~SMDS_VtkEdge()
 
 void SMDS_VtkEdge::init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
 {
+  SMDS_MeshEdge::init();
   vtkUnstructuredGrid* grid = mesh->getGrid();
-  myIdInShape = -1;
   myMeshId = mesh->getMeshId();
   vtkIdType aType = VTK_LINE;
   if (nodeIds.size() == 3)
index 79a087709d43857ffb2a97618b225385f24eb62d..0a7d5163f65512f2789df8634128c74c3d076417 100644 (file)
@@ -24,8 +24,8 @@ SMDS_VtkFace::~SMDS_VtkFace()
 
 void SMDS_VtkFace::init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
 {
+  SMDS_MeshFace::init();
   vtkUnstructuredGrid* grid = mesh->getGrid();
-  myIdInShape = -1;
   myMeshId = mesh->getMeshId();
   vtkIdType aType = VTK_TRIANGLE;
   switch (nodeIds.size())
@@ -53,8 +53,8 @@ void SMDS_VtkFace::init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
 
 void SMDS_VtkFace::initPoly(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
 {
+  SMDS_MeshFace::init();
   vtkUnstructuredGrid* grid = mesh->getGrid();
-  myIdInShape = -1;
   myMeshId = mesh->getMeshId();
   myVtkID = grid->InsertNextLinkedCell(VTK_POLYGON, nodeIds.size(), &nodeIds[0]);
   mesh->setMyModified();
@@ -249,7 +249,7 @@ SMDS_ElemIteratorPtr SMDS_VtkFace::interlacedNodesElemIterator() const
 }
 
 //! change only the first node, used for temporary triangles in quadrangle to triangle adaptor
-void SMDS_VtkFace::ChangeApex(const SMDS_MeshNode* node)
+void SMDS_VtkFace::ChangeApex(SMDS_MeshNode* node)
 {
   vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid();
   vtkIdType npts = 0;
@@ -257,6 +257,6 @@ void SMDS_VtkFace::ChangeApex(const SMDS_MeshNode* node)
   grid->GetCellPoints(myVtkID, npts, pts);
   grid->RemoveReferenceToCell(pts[0], myVtkID);
   pts[0] = node->getVtkId();
-  grid->AddReferenceToCell(pts[0], myVtkID);
+  node->AddInverseElement(this),
   SMDS_Mesh::_meshList[myMeshId]->setMyModified();
 }
index 7a346fd55b21bb258c4d82218d4d25404370dc15..ea1bf0ba8d4627ec2c86cb58c8ae91efee974dfd 100644 (file)
@@ -16,7 +16,7 @@ public:
   void init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh);
   void initPoly(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh);
   bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes);
-  void ChangeApex(const SMDS_MeshNode* node); // to use only for tmp triangles
+  void ChangeApex(SMDS_MeshNode* node); // to use only for tmp triangles
   void Print(std::ostream & OS) const;
   int NbEdges() const;
   int NbFaces() const;
index 3f5026f371b15f792872354221655b3140e570d0..15664b6107a1f1b7899a97c7528c0ecf5a961f80 100644 (file)
@@ -21,8 +21,8 @@ SMDS_VtkVolume::SMDS_VtkVolume(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
  */
 void SMDS_VtkVolume::init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
 {
+  SMDS_MeshVolume::init();
   vtkUnstructuredGrid* grid = mesh->getGrid();
-  myIdInShape = -1;
   myMeshId = mesh->getMeshId();
   vtkIdType aType = VTK_TETRA;
   switch (nodeIds.size())
@@ -63,6 +63,7 @@ void SMDS_VtkVolume::init(std::vector<vtkIdType> nodeIds, SMDS_Mesh* mesh)
 //#ifdef VTK_HAVE_POLYHEDRON
 void SMDS_VtkVolume::initPoly(std::vector<vtkIdType> nodeIds, std::vector<int> nbNodesPerFace, SMDS_Mesh* mesh)
 {
+  SMDS_MeshVolume::init();
   //MESSAGE("SMDS_VtkVolume::initPoly");
   SMDS_UnstructuredGrid* grid = mesh->getGrid();
   double center[3];
index 9db3b14506b0ddd0594da91f39364a1183ee26dc..47543642883ce6afd8481d75c44aa445beda1390 100644 (file)
@@ -60,6 +60,7 @@ salomeinclude_HEADERS = \
 lib_LTLIBRARIES = libSMESHimpl.la
 
 dist_libSMESHimpl_la_SOURCES = \
+       memoire.h \
        SMESH_Gen.cxx \
        SMESH_Mesh.cxx \
        SMESH_subMesh.cxx \
index 39c2ca9762d8e6ce72a8ce054edef8dc5d140cfa..7a0b5130eecfb485775dca7d1deb7ef06d2671c4 100644 (file)
@@ -105,6 +105,23 @@ SMESH_Mesh::SMESH_Mesh(int               theLocalId,
   _myMeshDS->ShapeToMesh( PseudoShape() );
 }
 
+//================================================================================
+/*!
+ * \brief Constructor of SMESH_Mesh being a base of some descendant class
+ */
+//================================================================================
+
+SMESH_Mesh::SMESH_Mesh():
+  _groupId( 0 ), _nbSubShapes( 0 )
+{
+  _myMeshDS      = 0;
+  _isShapeToMesh = false;
+  _isAutoColor   = false;
+  _isModified    = false;
+  _shapeDiagonal = 0.0;
+  _rmGroupCallUp = 0;
+}
+
 //=============================================================================
 /*!
  * 
@@ -265,14 +282,12 @@ void SMESH_Mesh::Clear()
   _myMeshDS->ClearMesh();
 
   // update compute state of submeshes
-  if ( SMESH_subMesh *sm = GetSubMeshContaining( GetShapeToMesh() ) ) {
-    SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true,
-                                                             /*complexShapeFirst=*/false);
-    while ( smIt->more() ) {
-      sm = smIt->next();
-      sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
-      sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); // for event listeners (issue 0020918)
-    }
+  if ( SMESH_subMesh *sm = GetSubMeshContaining( GetShapeToMesh() ) )
+  {
+    sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+    sm->ComputeSubMeshStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
+    sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); // for event listeners (issue 0020918)
+    sm->ComputeSubMeshStateEngine( SMESH_subMesh::CLEAN );
   }
   _isModified = false;
 }
index c88bbd02dee23a2066f6df93a5f3c08c8417a493..df5b281fb344e49c5f490a205c57661893784dbd 100644 (file)
@@ -332,7 +332,7 @@ protected:
   TRmGroupCallUp*            _rmGroupCallUp;
 
 protected:
-  SMESH_Mesh() {};
+  SMESH_Mesh();
   SMESH_Mesh(const SMESH_Mesh&) {};
 };
 
index 4a970ffa2718255aa0bc23ae24a8558b4f8b111a..198cf0f2da50310c81b584dadef6b9cf30c9d36e 100644 (file)
@@ -132,114 +132,125 @@ SMESH_MeshEditor::AddElement(const vector<const SMDS_MeshNode*> & node,
   int nbnode = node.size();
   SMESHDS_Mesh* mesh = GetMeshDS();
   switch ( type ) {
-  case SMDSAbs_0DElement:
-    if ( nbnode == 1 ) {
-      if ( ID >= 0 ) e = mesh->Add0DElementWithID(node[0], ID);
-      else      e = mesh->Add0DElement      (node[0] );
-    }
-    break;
-  case SMDSAbs_Edge:
-    if ( nbnode == 2 ) {
-      if ( ID >= 0 ) e = mesh->AddEdgeWithID(node[0], node[1], ID);
-      else      e = mesh->AddEdge      (node[0], node[1] );
-    }
-    else if ( nbnode == 3 ) {
-      if ( ID >= 0 ) e = mesh->AddEdgeWithID(node[0], node[1], node[2], ID);
-      else      e = mesh->AddEdge      (node[0], node[1], node[2] );
-    }
-    break;
   case SMDSAbs_Face:
     if ( !isPoly ) {
       if      (nbnode == 3) {
         if ( ID >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], ID);
-        else      e = mesh->AddFace      (node[0], node[1], node[2] );
+        else           e = mesh->AddFace      (node[0], node[1], node[2] );
       }
       else if (nbnode == 4) {
         if ( ID >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3], ID);
-        else      e = mesh->AddFace      (node[0], node[1], node[2], node[3] );
+        else           e = mesh->AddFace      (node[0], node[1], node[2], node[3] );
       }
       else if (nbnode == 6) {
         if ( ID >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3],
-                                          node[4], node[5], ID);
-        else      e = mesh->AddFace      (node[0], node[1], node[2], node[3],
-                                          node[4], node[5] );
+                                              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 >= 0 ) e = mesh->AddFaceWithID(node[0], node[1], node[2], node[3],
-                                          node[4], node[5], node[6], node[7], ID);
-        else      e = mesh->AddFace      (node[0], node[1], node[2], node[3],
-                                          node[4], node[5], node[6], node[7] );
+                                              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 >= 0 ) e = mesh->AddPolygonalFaceWithID(node, ID);
-      else      e = mesh->AddPolygonalFace      (node    );
+      else           e = mesh->AddPolygonalFace      (node    );
     }
     break;
+
   case SMDSAbs_Volume:
     if ( !isPoly ) {
       if      (nbnode == 4) {
         if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3], ID);
-        else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3] );
+        else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3] );
       }
       else if (nbnode == 5) {
         if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                            node[4], ID);
-        else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                            node[4] );
+                                                node[4], ID);
+        else           e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
+                                                node[4] );
       }
       else if (nbnode == 6) {
         if ( ID >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                            node[4], node[5], ID);
-        else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                            node[4], node[5] );
+                                                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 >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7], ID);
-        else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7] );
+                                                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 >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7],
-                                            node[8], node[9], ID);
-        else      e = mesh->AddVolume      (node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7],
-                                            node[8], node[9] );
+                                                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 >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7],
-                                            node[8], node[9], node[10],node[11],
-                                            node[12],ID);
-        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[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 >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7],
-                                            node[8], node[9], node[10],node[11],
-                                            node[12],node[13],node[14],ID);
-        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[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 >= 0 ) e = mesh->AddVolumeWithID(node[0], node[1], node[2], node[3],
-                                            node[4], node[5], node[6], node[7],
-                                            node[8], node[9], node[10],node[11],
-                                            node[12],node[13],node[14],node[15],
-                                            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] );
+                                                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] );
       }
     }
+    break;
+
+  case SMDSAbs_Edge:
+    if ( nbnode == 2 ) {
+      if ( ID >= 0 ) e = mesh->AddEdgeWithID(node[0], node[1], ID);
+      else           e = mesh->AddEdge      (node[0], node[1] );
+    }
+    else if ( nbnode == 3 ) {
+      if ( ID >= 0 ) e = mesh->AddEdgeWithID(node[0], node[1], node[2], ID);
+      else           e = mesh->AddEdge      (node[0], node[1], node[2] );
+    }
+    break;
+
+  case SMDSAbs_0DElement:
+    if ( nbnode == 1 ) {
+      if ( ID >= 0 ) e = mesh->Add0DElementWithID(node[0], ID);
+      else           e = mesh->Add0DElement      (node[0] );
+    }
+    break;
+
+  case SMDSAbs_Node:
+    if ( ID >= 0 ) e = mesh->AddNodeWithID(node[0]->X(), node[0]->Y(), node[0]->Z(), ID);
+    else           e = mesh->AddNode      (node[0]->X(), node[0]->Y(), node[0]->Z());
+    break;
+
+  default:;
   }
   if ( e ) myLastCreatedElems.Append( e );
   return e;
@@ -3874,6 +3885,8 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
     const SMDS_MeshElement* elem = itElem->first;
     vector<TNodeOfNodeListMapItr>& vecNewNodes = itElemNodes->second;
 
+    if(itElem->second.size()==0) continue;
+
     if ( elem->GetType() == SMDSAbs_Edge ) {
       // create a ceiling edge
       if (!elem->IsQuadratic()) {
@@ -3898,8 +3911,6 @@ void SMESH_MeshEditor::makeWalls (TNodeOfNodeListMap &     mapNewNodes,
     if ( elem->GetType() != SMDSAbs_Face )
       continue;
 
-    if(itElem->second.size()==0) continue;
-
     bool hasFreeLinks = false;
 
     TIDSortedElemSet avoidSet;
index a02800b056c0f7d6ab7afafb4ab0073badbf2044..f90f792da4374bd169af4f2d9bd06402ded22acb 100644 (file)
@@ -1700,7 +1700,7 @@ bool SMESH_subMesh::CheckComputeError(SMESH_Algo* theAlgo, const TopoDS_Shape& t
     // Check my state
     if ( !_computeError || _computeError->IsOK() )
     {
-      _computeState = COMPUTE_OK;
+      _computeState = IsMeshComputed() ? COMPUTE_OK : FAILED_TO_COMPUTE;
     }
     else
     {
index 58318b1e1b167a92e50ed25c16a47c4d88942a48..54ffcdac0450ce48ebe90dce6ab27b06d47a4c50 100644 (file)
@@ -193,6 +193,7 @@ public:
   void DumpAlgoState(bool isMain);
 
   bool ComputeStateEngine(int event);
+  void ComputeSubMeshStateEngine(int event);
 
   bool Evaluate(MapShapeNbElems& aResMap);
 
@@ -250,7 +251,6 @@ protected:
   void RemoveSubMeshElementsAndNodes();
   void UpdateDependantsState(const compute_event theEvent);
   void UpdateSubMeshState(const compute_state theState);
-  void ComputeSubMeshStateEngine(int event);
   void CleanDependants();
   void CleanDependsOn();
   void SetAlgoState(int state);
index 89857d89ccfb420af18d062df2e51fb2d4e7176a..ee962f22e65fda32791d632dec87e182f9f54b49 100644 (file)
@@ -25,7 +25,6 @@
 //  Author    : Nicolas REJNERI
 //  Project   : SALOME
 //  Module    : SMESH
-//  $Header$
 //
 #ifndef SMESH_TYPE_HEADER
 #define SMESH_TYPE_HEADER
@@ -57,7 +56,8 @@ enum MeshObjectType {
   GROUP_FACE,
   GROUP_VOLUME,
   GROUP_0D,
-  COMPONENT
+  COMPONENT,
+  IDSOURCE
 };
 
 #endif
index 1fbb375169074e23f1f0af2cab8bc7898fc396ea..a684d70234619c31a3f5403181c9db0edf7d145a 100644 (file)
@@ -203,6 +203,12 @@ bool SMESH_TypeFilter::isOk (const SUIT_DataOwner* theDataOwner) const
             Ok = true;
           break;
         }
+      case IDSOURCE:
+        {
+          Ok = ( SMESH_TypeFilter(MESHorSUBMESH).isOk( theDataOwner ) ||
+                 SMESH_TypeFilter(GROUP)        .isOk( theDataOwner ));
+          break;
+        }
     }
   }
   return Ok;
index 7e7448f59556982a622799adcf6fcd36c6458315..6da5d4076cf01594987c4cd99be7576a2cad4112 100644 (file)
@@ -94,6 +94,7 @@ salomeinclude_HEADERS = \
        SMESHGUI_MeshOrderDlg.h \
        SMESHGUI_MeshOrderOp.h \
        SMESHGUI_FileValidator.h \
+       SMESHGUI_CopyMeshDlg.h \
        SMESH_SMESHGUI.hxx
 
 # Libraries targets
@@ -167,6 +168,7 @@ dist_libSMESH_la_SOURCES = \
        SMESHGUI_FindElemByPointDlg.cxx \
        SMESHGUI_MeshOrderDlg.cxx \
        SMESHGUI_MeshOrderOp.cxx \
+       SMESHGUI_CopyMeshDlg.cxx \
        SMESHGUI_FileValidator.cxx
 
 MOC_FILES = \
@@ -224,6 +226,7 @@ MOC_FILES = \
        SMESHGUI_Make2DFrom3DOp_moc.cxx \
        SMESHGUI_FindElemByPointDlg_moc.cxx \
        SMESHGUI_MeshOrderDlg_moc.cxx \
+       SMESHGUI_CopyMeshDlg_moc.cxx \
        SMESHGUI_MeshOrderOp_moc.cxx
 
 nodist_libSMESH_la_SOURCES= \
index efc9c9ea1424c235a665ab1d85176464048c59ab..c78fd71d155839f51a1477276c1d20c09d8a9c4f 100644 (file)
@@ -76,6 +76,7 @@
 #include "SMESHGUI_TransparencyDlg.h"
 //#include "SMESHGUI_WhatIsDlg.h"
 #include "SMESHGUI_DuplicateNodesDlg.h"
+#include "SMESHGUI_CopyMeshDlg.h"
 
 #include "SMESHGUI_Utils.h"
 #include "SMESHGUI_MeshUtils.h"
 #include <vtkRenderer.h>
 #include <vtkPlane.h>
 #include <vtkCallbackCommand.h>
+#include <vtkLookupTable.h>
 
 // SALOME KERNEL includes
 #include <SALOMEDS_Study.hxx>
       type = QObject::tr( "FREE_BORDERS" );
     else if ( dynamic_cast< SMESH::Controls::FreeFaces* >( f.get() ) )
       type = QObject::tr( "FREE_FACES" );
+    else if ( dynamic_cast< SMESH::Controls::BareBorderVolume* >( f.get() ) )
+      type = QObject::tr( "BARE_BORDER_VOLUME" );
+    else if ( dynamic_cast< SMESH::Controls::BareBorderFace* >( f.get() ) )
+      type = QObject::tr( "BARE_BORDER_FACE" );
+    else if ( dynamic_cast< SMESH::Controls::OverConstrainedVolume* >( f.get() ) )
+      type = QObject::tr( "OVER_CONSTRAINED_VOLUME" );
+    else if ( dynamic_cast< SMESH::Controls::OverConstrainedFace* >( f.get() ) )
+      type = QObject::tr( "OVER_CONSTRAINED_FACE" );
     return type;
   }
 
           if ( aScalarBarActor && aFunctor ) {
             SMESH::Controls::NumericalFunctor* aNumFun = dynamic_cast<SMESH::Controls::NumericalFunctor*>( aFunctor.get() );
             if ( aNumFun ) {
-              int nbRanges = aScalarBarActor->GetMaximumNumberOfColors();
+              std::vector<int> elements;
+              SMESH::SMESH_Mesh_var mesh = SMESH::IObjectToInterface<SMESH::SMESH_Mesh>(anIO);
+              if ( mesh->_is_nil() ) {
+                SMESH::SMESH_IDSource_var idSource =
+                  SMESH::IObjectToInterface<SMESH::SMESH_IDSource>(anIO);
+                if ( !idSource->_is_nil() )
+                {
+                  SMESH::long_array_var ids = idSource->GetIDs();
+                  elements.resize( ids->length() );
+                  for ( unsigned i = 0; i < elements.size(); ++i )
+                    elements[i] = ids[i];
+                }
+              }
+              int nbIntervals = aScalarBarActor->GetMaximumNumberOfColors();
+              vtkLookupTable* lookupTable =
+                static_cast<vtkLookupTable*>(aScalarBarActor->GetLookupTable());
+              double * minmax = lookupTable->GetRange();
               std::vector<int>    nbEvents;
               std::vector<double> funValues;
-              aNumFun->GetHistogram( nbRanges, nbEvents, funValues );
+              aNumFun->GetHistogram( nbIntervals, nbEvents, funValues, elements, minmax );
               QString anInitialPath = "";
               if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() )
                 anInitialPath = QDir::currentPath();
     if ( selected.Extent() == 1 ) {
       Handle(SALOME_InteractiveObject) anIO = selected.First();
       if ( anIO->hasEntry() ) {
-       SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() );
-       if ( anActor && anActor->GetScalarBarActor() && anActor->GetControlMode() != SMESH_Actor::eNone ) {
-         SMESH_ScalarBarActor *aScalarBarActor = anActor->GetScalarBarActor();
-         aScalarBarActor->SetDistributionVisibility(!aScalarBarActor->GetDistributionVisibility());
-       }
+        SMESH_Actor* anActor = SMESH::FindActorByEntry( anIO->getEntry() );
+        if ( anActor && anActor->GetScalarBarActor() && anActor->GetControlMode() != SMESH_Actor::eNone ) {
+          SMESH_ScalarBarActor *aScalarBarActor = anActor->GetScalarBarActor();
+          aScalarBarActor->SetDistributionVisibility(!aScalarBarActor->GetDistributionVisibility());
+        }
       }
     }
   }
           case 6023:
             aControl = SMESH_Actor::eMaxElementLength3D;
             break;
+          case 6024:
+            aControl = SMESH_Actor::eBareBorderVolume;
+            break;
+          case 6025:
+            aControl = SMESH_Actor::eBareBorderFace;
+            break;
+          case 6026:
+            aControl = SMESH_Actor::eOverConstrainedVolume;
+            break;
+          case 6027:
+            aControl = SMESH_Actor::eOverConstrainedFace;
+            break;
           }
           anActor->SetControlMode(aControl);
           anActor->GetScalarBarActor()->SetTitle( functorToString( anActor->GetFunctor() ).toLatin1().constData() );
@@ -2024,6 +2062,13 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case 704: // Edit mesh/sub-mesh
     startOperation( theCommandID );
     break;
+  case 705: // copy mesh
+    {
+      if (checkLock(aStudy)) break;
+      EmitSignalDeactivateDialog();
+      ( new SMESHGUI_CopyMeshDlg( this ) )->show();
+    }
+    break;
   case 710: // Build compound mesh
     {
       if (checkLock(aStudy)) break;
@@ -2973,6 +3018,10 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
   case 6021:
   case 6022:
   case 6023:
+  case 6024:
+  case 6025:
+  case 6026:
+  case 6027:
     if ( vtkwnd ) {
 
       LightApp_SelectionMgr* mgr = selectionMgr();
@@ -3189,6 +3238,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   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(  705, "COPY_MESH",       "ICON_COPY_MESH" );
   createSMESHAction(  710, "BUILD_COMPOUND",  "ICON_BUILD_COMPOUND" );
   createSMESHAction(  711, "PRECOMPUTE",      "ICON_PRECOMPUTE" );
   createSMESHAction(  712, "EVALUATE",        "ICON_COMPUTE" );
@@ -3214,6 +3264,10 @@ void SMESHGUI::initialize( CAM_Application* app )
   createSMESHAction( 6021, "FREE_FACES",      "ICON_FREE_FACES",    0, true );
   createSMESHAction( 6022, "MAX_ELEMENT_LENGTH_2D", "ICON_MAX_ELEMENT_LENGTH_2D", 0, true );
   createSMESHAction( 6023, "MAX_ELEMENT_LENGTH_3D", "ICON_MAX_ELEMENT_LENGTH_3D", 0, true );
+  createSMESHAction( 6024, "BARE_BORDER_VOLUME","ICON_BARE_BORDER_VOLUME", 0, true );
+  createSMESHAction( 6025, "BARE_BORDER_FACE","ICON_BARE_BORDER_FACE", 0, true );
+  createSMESHAction( 6026, "OVER_CONSTRAINED_VOLUME","ICON_OVER_CONSTRAINED_VOLUME", 0, true );
+  createSMESHAction( 6027, "OVER_CONSTRAINED_FACE","ICON_OVER_CONSTRAINED_FACE", 0, true );
   createSMESHAction( 6003, "FREE_BORDER",     "ICON_FREE_EDGE_2D",  0, true );
   createSMESHAction( 6004, "CONNECTION",      "ICON_CONNECTION",    0, true );
   createSMESHAction( 6005, "FREE_NODE",       "ICON_FREE_NODE",     0, true );
@@ -3353,6 +3407,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( 703, meshId, -1 );
   createMenu( 704, meshId, -1 );
   createMenu( 710, meshId, -1 );
+  createMenu( 705, meshId, -1 );
   createMenu( separator(), meshId, -1 );
   createMenu( 701, meshId, -1 );
   createMenu( 711, meshId, -1 );
@@ -3371,8 +3426,6 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( separator(), meshId, -1 );
   createMenu( 814, meshId, -1 );
   createMenu( separator(), meshId, -1 );
-  createMenu( 813, meshId, -1 );
-  createMenu( separator(), meshId, -1 );
   createMenu( 900, meshId, -1 );
   //createMenu( 902, meshId, -1 );
   createMenu( 903, meshId, -1 );
@@ -3385,6 +3438,8 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( 6001, edgeId, -1 );
   createMenu( 6004, edgeId, -1 );
   createMenu( 6021, faceId, -1 );
+  createMenu( 6025, faceId, -1 );
+  createMenu( 6027, faceId, -1 );
   createMenu( 6018, faceId, -1 );
   createMenu( 6019, faceId, -1 );
   createMenu( 6011, faceId, -1 );
@@ -3397,6 +3452,8 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( 6017, volumeId, -1 );
   createMenu( 6009, volumeId, -1 );
   createMenu( 6023, volumeId, -1 );
+  createMenu( 6024, volumeId, -1 );
+  createMenu( 6026, volumeId, -1 );
 
   createMenu( 4000, addId, -1 );
   createMenu( 4009, addId, -1 );
@@ -3420,6 +3477,8 @@ void SMESHGUI::initialize( CAM_Application* app )
   createMenu( 4042, removeId, -1 );
   createMenu( 4044, removeId, -1 );
   createMenu( separator(), removeId, -1 );
+  createMenu( 813, removeId, -1 );
+  createMenu( separator(), removeId, -1 );
   createMenu( 4043, removeId, -1 );
 
   createMenu( 4051, renumId, -1 );
@@ -3464,6 +3523,7 @@ void SMESHGUI::initialize( CAM_Application* app )
   createTool( 703, meshTb );
   createTool( 704, meshTb );
   createTool( 710, meshTb );
+  createTool( 705, meshTb );
   createTool( separator(), meshTb );
   createTool( 701, meshTb );
   createTool( 711, meshTb );
@@ -3490,6 +3550,8 @@ void SMESHGUI::initialize( CAM_Application* app )
   createTool( 6004, ctrlTb );
   createTool( separator(), ctrlTb );
   createTool( 6021, ctrlTb );
+  createTool( 6025, ctrlTb );
+  createTool( 6027, ctrlTb );
   createTool( 6018, ctrlTb );
   createTool( 6019, ctrlTb );
   createTool( 6011, ctrlTb );
@@ -3503,6 +3565,8 @@ void SMESHGUI::initialize( CAM_Application* app )
   createTool( 6017, ctrlTb );
   createTool( 6009, ctrlTb );
   createTool( 6023, ctrlTb );
+  createTool( 6024, ctrlTb );
+  createTool( 6026, ctrlTb );
   createTool( separator(), ctrlTb );
 
   createTool( 4000, addRemTb );
@@ -3805,50 +3869,58 @@ void SMESHGUI::initialize( CAM_Application* app )
 
   aSubId = popupMgr()->insert( tr( "MEN_FACE_CTRL" ), anId, -1 ); // FACE CONTROLS
 
-  popupMgr()->insert( action( 6021 ), aSubId, -1 ); // FREE_FACE
+  popupMgr()->insert ( action( 6021 ), aSubId, -1 ); // FREE_FACE
   popupMgr()->setRule( action( 6021 ), aMeshInVtkHasFaces /*aMeshInVtkHasVolumes*/,
                                        QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6021 ), "controlMode = 'eFreeFaces'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6018 ), aSubId, -1 ); // LENGTH_2D
+  popupMgr()->insert ( action( 6018 ), aSubId, -1 ); // LENGTH_2D
   popupMgr()->setRule( action( 6018 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6018 ), "controlMode = 'eLength2D'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6019 ), aSubId, -1 ); // CONNECTION_2D
+  popupMgr()->insert ( action( 6019 ), aSubId, -1 ); // CONNECTION_2D
   popupMgr()->setRule( action( 6019 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6019 ), "controlMode = 'eMultiConnection2D'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6011 ), aSubId, -1 ); // AREA
+  popupMgr()->insert ( action( 6011 ), aSubId, -1 ); // AREA
   popupMgr()->setRule( action( 6011 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6011 ), "controlMode = 'eArea'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6012 ), aSubId, -1 ); // TAPER
+  popupMgr()->insert ( action( 6012 ), aSubId, -1 ); // TAPER
   popupMgr()->setRule( action( 6012 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6012 ), "controlMode = 'eTaper'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6013 ), aSubId, -1 ); // ASPECT
+  popupMgr()->insert ( action( 6013 ), aSubId, -1 ); // ASPECT
   popupMgr()->setRule( action( 6013 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6013 ), "controlMode = 'eAspectRatio'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6014 ), aSubId, -1 ); // MIN_ANG
+  popupMgr()->insert ( action( 6014 ), aSubId, -1 ); // MIN_ANG
   popupMgr()->setRule( action( 6014 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6014 ), "controlMode = 'eMinimumAngle'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6015 ), aSubId, -1 ); // WARP
+  popupMgr()->insert ( action( 6015 ), aSubId, -1 ); // WARP
   popupMgr()->setRule( action( 6015 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6015 ), "controlMode = 'eWarping'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6016 ), aSubId, -1 ); // SKEW
+  popupMgr()->insert ( action( 6016 ), aSubId, -1 ); // SKEW
   popupMgr()->setRule( action( 6016 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6016 ), "controlMode = 'eSkew'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6022 ), aSubId, -1 ); // MAX_ELEMENT_LENGTH_2D
+  popupMgr()->insert ( action( 6022 ), aSubId, -1 ); // MAX_ELEMENT_LENGTH_2D
   popupMgr()->setRule( action( 6022 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6022 ), "controlMode = 'eMaxElementLength2D'", QtxPopupMgr::ToggleRule );
 
+  popupMgr()->insert ( action( 6025 ), aSubId, -1 ); // BARE_BORDER_FACE
+  popupMgr()->setRule( action( 6025 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 6025 ), "controlMode = 'eBareBorderFace'", QtxPopupMgr::ToggleRule );
+
+  popupMgr()->insert ( action( 6027 ), aSubId, -1 ); // OVER_CONSTRAINED_FACE
+  popupMgr()->setRule( action( 6027 ), aMeshInVtkHasFaces, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 6027 ), "controlMode = 'eOverConstrainedFace'", QtxPopupMgr::ToggleRule );
+
   aSubId = popupMgr()->insert( tr( "MEN_VOLUME_CTRL" ), anId, -1 ); // VOLUME CONTROLS
 
-  popupMgr()->insert( action( 6017 ), aSubId, -1 ); // ASPECT_3D
+  popupMgr()->insert ( action( 6017 ), aSubId, -1 ); // ASPECT_3D
   popupMgr()->setRule( action( 6017 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6017 ), "controlMode = 'eAspectRatio3D'", QtxPopupMgr::ToggleRule );
 
@@ -3856,10 +3928,18 @@ void SMESHGUI::initialize( CAM_Application* app )
   popupMgr()->setRule( action( 6009 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6009 ), "controlMode = 'eVolume3D'", QtxPopupMgr::ToggleRule );
 
-  popupMgr()->insert( action( 6023 ), aSubId, -1 ); // MAX_ELEMENT_LENGTH_3D
+  popupMgr()->insert ( action( 6023 ), aSubId, -1 ); // MAX_ELEMENT_LENGTH_3D
   popupMgr()->setRule( action( 6023 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
   popupMgr()->setRule( action( 6023 ), "controlMode = 'eMaxElementLength3D'", QtxPopupMgr::ToggleRule );
 
+  popupMgr()->insert ( action( 6024 ), aSubId, -1 ); // BARE_BORDER_VOLUME
+  popupMgr()->setRule( action( 6024 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 6024 ), "controlMode = 'eBareBorderVolume'", QtxPopupMgr::ToggleRule );
+
+  popupMgr()->insert ( action( 6026 ), aSubId, -1 ); // OVER_CONSTRAINED_VOLUME
+  popupMgr()->setRule( action( 6026 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule );
+  popupMgr()->setRule( action( 6026 ), "controlMode = 'eOverConstrainedVolume'", QtxPopupMgr::ToggleRule );
+
   popupMgr()->insert( separator(), anId, -1 );
 
   popupMgr()->insert( action( 201 ), anId, -1 ); // SCALAR_BAR_PROP
@@ -5359,7 +5439,15 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
                     aPlaneInfo.PlaneId = aPlaneId;
                     aPlaneInfo.ActorList.push_back( aSmeshActor );
                     aPlaneInfo.ViewManager = vman;
-                    aPlaneInfoList.push_back( aPlaneInfo );
+
+                    // to make the list sorted by plane id
+                    anIter = aPlaneInfoList.begin();
+                    for( ; anIter != aPlaneInfoList.end(); anIter++ ) {
+                      const TPlaneInfo& aPlaneInfoRef = *anIter;
+                      if( aPlaneInfoRef.PlaneId > aPlaneId )
+                        break;
+                    }
+                    aPlaneInfoList.insert( anIter, aPlaneInfo );
                   }
                 }
               }
@@ -5370,6 +5458,52 @@ void SMESHGUI::restoreVisualParameters (int savePoint)
     } // for names/parameters iterator
   } // for entries iterator
 
+  // take into account planes with empty list of actors referred to them
+  QList<SUIT_ViewManager*> aVMList;
+  getApp()->viewManagers(SVTK_Viewer::Type(), aVMList);
+
+  TPlaneDataMap::const_iterator aPlaneDataIter = aPlaneDataMap.begin();
+  for( ; aPlaneDataIter != aPlaneDataMap.end(); aPlaneDataIter++ ) {
+    int aViewId = aPlaneDataIter->first;
+    if( aViewId >= 0 && aViewId < aVMList.count() ) {
+      SUIT_ViewManager* aViewManager = aVMList.at( aViewId );
+
+      const TPlaneDataList& aPlaneDataList = aPlaneDataIter->second;
+
+      TPlaneInfoList& aPlaneInfoList = aPlaneInfoMap[ aViewId ];
+      TPlaneDataList::const_iterator anIter2 = aPlaneDataList.begin();
+      for( ; anIter2 != aPlaneDataList.end(); anIter2++ ) {
+        const TPlaneData& aPlaneData = *anIter2;
+        int aPlaneId = aPlaneData.Id;
+
+        bool anIsFound = false;
+        TPlaneInfoList::const_iterator anIter3 = aPlaneInfoList.begin();
+        for( ; anIter3 != aPlaneInfoList.end(); anIter3++ ) {
+          const TPlaneInfo& aPlaneInfo = *anIter3;
+          if( aPlaneInfo.PlaneId == aPlaneId ) {
+            anIsFound = true;
+            break;
+          }
+        }
+
+        if( !anIsFound ) {
+          TPlaneInfo aPlaneInfo; // ActorList field is empty
+          aPlaneInfo.PlaneId = aPlaneId;
+          aPlaneInfo.ViewManager = aViewManager;
+
+          // to make the list sorted by plane id
+          TPlaneInfoList::iterator anIter4 = aPlaneInfoList.begin();
+          for( ; anIter4 != aPlaneInfoList.end(); anIter4++ ) {
+            const TPlaneInfo& aPlaneInfoRef = *anIter4;
+            if( aPlaneInfoRef.PlaneId > aPlaneId )
+              break;
+          }
+          aPlaneInfoList.insert( anIter4, aPlaneInfo );
+        }
+      }
+    }
+  }
+
   // add clipping planes to actors according to the restored parameters
   // and update the clipping plane map
   TPlaneInfoMap::const_iterator anIter1 = aPlaneInfoMap.begin();
index ac190be77b4c17d6a890f56631cf20e4e67b2fd2..486a859ac52559c0bd19c903fe3d9967cdcf5cc7 100644 (file)
@@ -194,7 +194,8 @@ private:
 struct TSetVisibility {
   TSetVisibility(int theIsVisible): myIsVisible(theIsVisible){}
   void operator()(SMESH::TPlaneData& thePlaneData){
-    thePlaneData.Plane.GetPointer()->myActor->SetVisibility(myIsVisible);
+    bool anIsEmpty = thePlaneData.ActorList.empty();
+    thePlaneData.Plane.GetPointer()->myActor->SetVisibility(myIsVisible && !anIsEmpty);
   }
   int myIsVisible;
 };
@@ -261,11 +262,22 @@ SMESH::OrientedPlane* SMESHGUI_ClippingDlg::AddPlane (SMESH::TActorList
 
   vtkFloatingPointType aBounds[6];
   vtkFloatingPointType anOrigin[3];
-  bool anIsOk = SMESH::ComputeClippingPlaneParameters( theActorList,
-                                                       aNormal,
-                                                       theDistance,
-                                                       aBounds,
-                                                       anOrigin );
+
+  bool anIsOk = false;
+  if( theActorList.empty() ) {
+    // to support planes with empty actor list we should create
+    // a nullified plane that will be initialized later 
+    anOrigin[0] = anOrigin[1] = anOrigin[2] = 0;
+    aBounds[0] = aBounds[2] = aBounds[4] = 0;
+    aBounds[1] = aBounds[3] = aBounds[5] = 0;
+    anIsOk = true;
+  }
+  else
+    anIsOk = SMESH::ComputeClippingPlaneParameters( theActorList,
+                                                    aNormal,
+                                                    theDistance,
+                                                    aBounds,
+                                                    anOrigin );
   if( !anIsOk )
     return NULL;
 
@@ -545,8 +557,10 @@ void SMESHGUI_ClippingDlg::ClickOnApply()
       SMESH::TPlaneData aPlaneData = *anIter2;
       SMESH::TPlane aPlane = aPlaneData.Plane;
       SMESH::TActorList anActorList = aPlaneData.ActorList;
-      if( anActorList.empty() )
-        continue;
+
+      // the check is disabled to support planes with empty actor list
+      //if( anActorList.empty() )
+      //  continue;
 
       SMESH::OrientedPlane* anOrientedPlane = SMESH::OrientedPlane::New(myViewWindow);
       anOrientedPlane->ShallowCopy(aPlane.GetPointer());
diff --git a/src/SMESHGUI/SMESHGUI_CopyMeshDlg.cxx b/src/SMESHGUI/SMESHGUI_CopyMeshDlg.cxx
new file mode 100644 (file)
index 0000000..f4b6950
--- /dev/null
@@ -0,0 +1,667 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//  SMESH SMESHGUI : GUI for SMESH component
+//  File   : SMESHGUI_CopyMeshDlg.cxx
+
+#include "SMESHGUI_CopyMeshDlg.h"
+
+#include "SMESHGUI.h"
+#include "SMESHGUI_SpinBox.h"
+#include "SMESHGUI_Utils.h"
+#include "SMESHGUI_VTKUtils.h"
+#include "SMESHGUI_MeshUtils.h"
+#include "SMESHGUI_IdValidator.h"
+#include "SMESHGUI_FilterDlg.h"
+
+#include <SMESH_Actor.h>
+#include <SMESH_TypeFilter.hxx>
+#include <SMDS_Mesh.hxx>
+
+// SALOME GUI includes
+#include <SUIT_Desktop.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_Session.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_OverrideCursor.h>
+
+#include <LightApp_Application.h>
+#include <LightApp_SelectionMgr.h>
+
+#include <SVTK_ViewModel.h>
+#include <SVTK_ViewWindow.h>
+#include <SALOME_ListIO.hxx>
+
+// SALOME KERNEL includes
+#include <SALOMEDSClient_SObject.hxx>
+
+// OCCT includes
+#include <TColStd_MapOfInteger.hxx>
+
+// Qt includes
+#include <QApplication>
+#include <QButtonGroup>
+#include <QGroupBox>
+#include <QLabel>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QRadioButton>
+#include <QCheckBox>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QGridLayout>
+#include <QSpinBox>
+#include <QKeyEvent>
+
+// IDL includes
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Group)
+#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
+
+/*!
+  \class BusyLocker
+  \brief Simple 'busy state' flag locker.
+  \internal
+*/
+
+namespace
+{
+  class BusyLocker
+  {
+  public:
+    //! Constructor. Sets passed boolean flag to \c true.
+    BusyLocker( bool& busy ) : myBusy( busy ) { myBusy = true; }
+    //! Destructor. Clear external boolean flag passed as parameter to the constructor to \c false.
+    ~BusyLocker() { myBusy = false; }
+  private:
+    bool& myBusy; //! External 'busy state' boolean flag
+  };
+}
+
+#define SPACING 6
+#define MARGIN  11
+
+//To disable automatic genericobj management, the following line should be commented.
+//Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
+#define WITHGENERICOBJ
+
+
+//================================================================================
+/*!
+ * \brief Constructor
+ */
+//================================================================================
+
+SMESHGUI_CopyMeshDlg::SMESHGUI_CopyMeshDlg( SMESHGUI* theModule )
+  : QDialog( SMESH::GetDesktop( theModule ) ),
+    mySMESHGUI( theModule ),
+    mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ),
+    myFilterDlg(0),
+    mySelectedObject(SMESH::SMESH_IDSource::_nil())
+{
+  QPixmap image (SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap("SMESH", tr("ICON_COPY_MESH")));
+
+  setModal(false);
+  setAttribute(Qt::WA_DeleteOnClose, true);
+  setWindowTitle(tr("SMESH_COPY_MESH_TITLE"));
+  setSizeGripEnabled(true);
+
+  QVBoxLayout* SMESHGUI_CopyMeshDlgLayout = new QVBoxLayout(this);
+  SMESHGUI_CopyMeshDlgLayout->setSpacing(SPACING);
+  SMESHGUI_CopyMeshDlgLayout->setMargin(MARGIN);
+
+  /***************************************************************/
+  ConstructorsBox = new QGroupBox(tr("SMESH_COPY_MESH_TITLE"), this);
+  QButtonGroup* GroupConstructors = new QButtonGroup(this);
+  QHBoxLayout* ConstructorsBoxLayout = new QHBoxLayout(ConstructorsBox);
+  ConstructorsBoxLayout->setSpacing(SPACING);
+  ConstructorsBoxLayout->setMargin(MARGIN);
+
+  QRadioButton* RadioButton1= new QRadioButton(ConstructorsBox);
+  RadioButton1->setIcon(image);
+  GroupConstructors->addButton(RadioButton1, 0);
+
+  ConstructorsBoxLayout->addWidget(RadioButton1);
+  RadioButton1->setChecked(true);
+  GroupConstructors->addButton(RadioButton1, 0);
+
+  /***************************************************************/
+  GroupArguments = new QGroupBox(tr("SMESH_ARGUMENTS"), this);
+  QGridLayout* GroupArgumentsLayout = new QGridLayout(GroupArguments);
+  GroupArgumentsLayout->setSpacing(SPACING);
+  GroupArgumentsLayout->setMargin(MARGIN);
+
+  myIdValidator = new SMESHGUI_IdValidator(this);
+
+  // Controls for idSource/elements selection
+  myTextLabelElements = new QLabel(tr("OBJECT_NAME"), GroupArguments);
+  myLineEditElements = new QLineEdit(GroupArguments);
+  myLineEditElements->setValidator(myIdValidator);
+  myLineEditElements->setMaxLength(-1);
+  myFilterBtn = new QPushButton( tr( "SMESH_BUT_FILTER" ), GroupArguments );
+  connect(myFilterBtn,   SIGNAL(clicked()), this, SLOT(setFilters()));
+
+  // Control for the mesh objects selection
+  myIdSourceCheck = new QCheckBox(tr("SMESH_SELECT_WHOLE_MESH"), GroupArguments);
+
+  // Name of a mesh to create
+  QLabel* meshNameLabel = new QLabel(tr("NEW_NAME"), GroupArguments);
+  myMeshNameEdit = new QLineEdit(GroupArguments);
+
+  // CheckBox for copying groups
+  myCopyGroupsCheck = new QCheckBox(tr("SMESH_MAKE_GROUPS"), GroupArguments);
+  myCopyGroupsCheck->setChecked(false);
+
+  // CheckBox for keeping ids
+  myKeepIdsCheck = new QCheckBox(tr("SMESH_KEEP_IDS"), GroupArguments);
+  myKeepIdsCheck->setChecked(true);
+
+  // layout
+  GroupArgumentsLayout->addWidget(myTextLabelElements,  0, 0);
+  GroupArgumentsLayout->addWidget(myLineEditElements,   0, 1, 1, 5);
+  GroupArgumentsLayout->addWidget(myFilterBtn,          0, 6);
+  GroupArgumentsLayout->addWidget(myIdSourceCheck,      1, 0, 1, 6);
+  GroupArgumentsLayout->addWidget(meshNameLabel,        2, 0);
+  GroupArgumentsLayout->addWidget(myMeshNameEdit,       2, 1, 1, 5);
+  GroupArgumentsLayout->addWidget(myCopyGroupsCheck,    3, 0, 1, 6);
+  GroupArgumentsLayout->addWidget(myKeepIdsCheck,       4, 0, 1, 6);
+
+  /***************************************************************/
+  GroupButtons = new QGroupBox(this);
+  QHBoxLayout* GroupButtonsLayout = new QHBoxLayout(GroupButtons);
+  GroupButtonsLayout->setSpacing(SPACING);
+  GroupButtonsLayout->setMargin(MARGIN);
+
+  buttonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), GroupButtons);
+  buttonOk->setAutoDefault(true);
+  buttonOk->setDefault(true);
+  buttonApply = new QPushButton(tr("SMESH_BUT_APPLY"), GroupButtons);
+  buttonApply->setAutoDefault(true);
+  buttonCancel = new QPushButton(tr("SMESH_BUT_CLOSE"), GroupButtons);
+  buttonCancel->setAutoDefault(true);
+  buttonHelp = new QPushButton(tr("SMESH_BUT_HELP"), GroupButtons);
+  buttonHelp->setAutoDefault(true);
+
+  GroupButtonsLayout->addWidget(buttonOk);
+  GroupButtonsLayout->addSpacing(10);
+  GroupButtonsLayout->addWidget(buttonApply);
+  GroupButtonsLayout->addSpacing(10);
+  GroupButtonsLayout->addStretch();
+  GroupButtonsLayout->addWidget(buttonCancel);
+  GroupButtonsLayout->addWidget(buttonHelp);
+
+  /***************************************************************/
+  SMESHGUI_CopyMeshDlgLayout->addWidget(ConstructorsBox);
+  SMESHGUI_CopyMeshDlgLayout->addWidget(GroupArguments);
+  SMESHGUI_CopyMeshDlgLayout->addWidget(GroupButtons);
+
+  /* Initialisations */
+  mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector();
+
+  mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+
+  // Selection filter
+  myIdSourceFilter = new SMESH_TypeFilter( IDSOURCE );
+
+  myHelpFileName = "copy_mesh_page.html";
+
+  Init();
+
+  /* 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(mySMESHGUI,     SIGNAL (SignalDeactivateActiveDialog()),
+          this,           SLOT   (DeactivateActiveDialog()));
+  connect(mySelectionMgr, SIGNAL (currentSelectionChanged()),
+          this,           SLOT   (SelectionIntoArgument()));
+  connect(mySMESHGUI,     SIGNAL (SignalCloseAllDialogs()),/* to close dialog if study change */
+          this,           SLOT   (ClickOnCancel()));
+
+  connect(myLineEditElements, SIGNAL(textChanged(const QString&)),
+          this,               SLOT  (onTextChange(const QString&)));
+  connect(myIdSourceCheck,    SIGNAL(toggled(bool)),
+          this,               SLOT  (onSelectIdSource(bool)));
+
+  SelectionIntoArgument();
+}
+
+//=================================================================================
+// function : ~SMESHGUI_CopyMeshDlg()
+// purpose  : Destroys the object and frees any allocated resources
+//=================================================================================
+
+SMESHGUI_CopyMeshDlg::~SMESHGUI_CopyMeshDlg()
+{
+  if ( myFilterDlg )
+  {
+    myFilterDlg->setParent( 0 );
+    delete myFilterDlg; myFilterDlg = 0;
+  }
+  if ( myIdSourceFilter )
+  {
+    if ( mySelectionMgr )
+      mySelectionMgr->removeFilter( myIdSourceFilter );
+    delete myIdSourceFilter; myIdSourceFilter=0;
+  }
+}
+
+//=================================================================================
+// function : Init()
+// purpose  :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::Init (bool ResetControls)
+{
+  myBusy = false;
+
+  myMeshNameEdit->setText( SMESH::UniqueMeshName("Mesh"));
+  if ( ResetControls )
+  {
+    myLineEditElements->clear();
+    //myElementsId = "";
+    myNbOkElements = 0;
+
+    buttonOk->setEnabled(false);
+    buttonApply->setEnabled(false);
+
+    myActor = 0;
+    myMesh = SMESH::SMESH_Mesh::_nil();
+
+    myIdSourceCheck->setChecked(true);
+    myCopyGroupsCheck->setChecked(false);
+    myKeepIdsCheck->setChecked(false);
+
+    onSelectIdSource( myIdSourceCheck->isChecked() );
+  }
+}
+
+//=================================================================================
+// function : ClickOnApply()
+// purpose  :
+//=================================================================================
+
+bool SMESHGUI_CopyMeshDlg::ClickOnApply()
+{
+  if (mySMESHGUI->isActiveStudyLocked())
+    return false;
+
+  if( !isValid() )
+    return false;
+
+  try
+  {
+    SUIT_OverrideCursor aWaitCursor;
+    SMESH::SMESH_IDSource_var aPartToCopy;
+    if ( myIdSourceCheck->isChecked())
+    {
+      aPartToCopy = mySelectedObject;
+    }
+    else
+    {
+      QStringList aListElementsId = myLineEditElements->text().split(" ", QString::SkipEmptyParts);
+      SMESH::long_array_var anElementsId = new SMESH::long_array;
+      anElementsId->length(aListElementsId.count());
+      for (int i = 0; i < aListElementsId.count(); i++)
+        anElementsId[i] = aListElementsId[i].toInt();
+
+      SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
+      aPartToCopy = aMeshEditor->MakeIDSource( anElementsId, SMESH::ALL );
+    }
+    QByteArray meshName = myMeshNameEdit->text().toLatin1();
+    bool toCopyGroups = ( myCopyGroupsCheck->isChecked() );
+    bool toKeepIDs    = ( myKeepIdsCheck->isChecked() );
+
+    SMESH::SMESH_Gen_var gen = SMESHGUI::GetSMESHGen();
+    SMESH::SMESH_Mesh_var newMesh =
+      gen->CopyMesh(aPartToCopy, meshName.constData(), toCopyGroups, toKeepIDs);
+#ifdef WITHGENERICOBJ
+    // obj has been published in study. Its refcount has been incremented.
+    // It is safe to decrement its refcount
+    // so that it will be destroyed when the entry in study will be removed
+    newMesh->Destroy();
+#endif
+  } catch (...) {
+  }
+
+  mySMESHGUI->updateObjBrowser(true);
+  SMESHGUI::Modified();
+
+  Init(false);
+  mySelectedObject = SMESH::SMESH_IDSource::_nil();
+  SelectionIntoArgument();
+
+  return true;
+}
+
+//=================================================================================
+// function : ClickOnOk()
+// purpose  :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::ClickOnOk()
+{
+  if( ClickOnApply() )
+    ClickOnCancel();
+}
+
+//=================================================================================
+// function : ClickOnCancel()
+// purpose  :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::ClickOnCancel()
+{
+  disconnect(mySelectionMgr, 0, this, 0);
+  if ( mySelectionMgr )
+    mySelectionMgr->removeFilter( myIdSourceFilter );
+  if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+    aViewWindow->SetSelectionMode( ActorSelection );
+  mySMESHGUI->ResetState();
+  reject();
+}
+
+//=================================================================================
+// function : ClickOnHelp()
+// purpose  :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::ClickOnHelp()
+{
+  LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
+  if (app)
+    app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName);
+  else {
+    QString platform;
+#ifdef WIN32
+    platform = "winapplication";
+#else
+    platform = "application";
+#endif
+    SUIT_MessageBox::warning(this, tr("WRN_WARNING"),
+                             tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE").
+                             arg(app->resourceMgr()->stringValue("ExternalBrowser",
+                                                                 platform)).
+                             arg(myHelpFileName));
+  }
+}
+
+//=======================================================================
+// function : onTextChange()
+// purpose  :
+//=======================================================================
+
+void SMESHGUI_CopyMeshDlg::onTextChange (const QString& theNewText)
+{
+  QLineEdit* send = (QLineEdit*)sender();
+
+  if (myBusy) return;
+  BusyLocker lock( myBusy );
+
+  //if (send == myLineEditElements)
+  myNbOkElements = 0;
+
+  buttonOk->setEnabled(false);
+  buttonApply->setEnabled(false);
+
+  // hilight entered elements
+  SMDS_Mesh* aMesh = 0;
+  if (myActor)
+    aMesh = myActor->GetObject()->GetMesh();
+
+  QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts);
+  if (myActor && aMesh)
+  {
+    TColStd_MapOfInteger newIndices;
+    if (send == myLineEditElements) {
+      for (int i = 0; i < aListId.count(); i++)
+        if ( const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt()))
+        {
+          newIndices.Add(e->GetID());
+        }
+    }
+    myNbOkElements = newIndices.Extent();
+
+    Handle(SALOME_InteractiveObject) anIO = myActor->getIO();
+    mySelector->AddOrRemoveIndex( anIO, newIndices, false );
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->highlight( anIO, true, true );
+  }
+  else
+  {
+    myNbOkElements = aListId.count();
+  }
+
+  if (myNbOkElements) {
+    buttonOk->setEnabled(true);
+    buttonApply->setEnabled(true);
+  }
+}
+
+//=================================================================================
+// function : SelectionIntoArgument()
+// purpose  : Called when selection as changed or other case
+//=================================================================================
+
+void SMESHGUI_CopyMeshDlg::SelectionIntoArgument()
+{
+  if (myBusy) return;
+  BusyLocker lock( myBusy );
+
+  // clear
+  myActor = 0;
+  QString aString = "";
+
+  myLineEditElements->setText(aString);
+  myNbOkElements = 0;
+  buttonOk->setEnabled(false);
+  buttonApply->setEnabled(false);
+  myFilterBtn->setEnabled(false);
+
+  // get selected mesh
+  SALOME_ListIO aList;
+  mySelectionMgr->selectedObjects(aList,SVTK_Viewer::Type());
+  int nbSel = aList.Extent();
+  if (nbSel != 1)
+    return;
+
+  Handle(SALOME_InteractiveObject) IO = aList.First();
+  mySelectedObject = SMESH::IObjectToInterface<SMESH::SMESH_IDSource>( IO );
+  if ( mySelectedObject->_is_nil() )
+    return;
+
+  myMesh = SMESH::GetMeshByIO(IO);
+  if (myMesh->_is_nil())
+    return;
+
+  myActor = SMESH::FindActorByEntry(IO->getEntry());
+  if (!myActor)
+    myActor = SMESH::FindActorByObject(myMesh);
+
+  if (myIdSourceCheck->isChecked())
+  {
+    SMESH::GetNameOfSelectedIObjects( mySelectionMgr, aString );
+    if ( aString.isEmpty() ) aString = " ";
+  }
+  else
+  {
+    SMESH::GetNameOfSelectedElements( mySelector, IO, aString );
+    myNbOkElements = aString.size();
+    myFilterBtn->setEnabled(true);
+  }
+  myLineEditElements->setText( aString );
+  bool ok = !aString.isEmpty();
+
+  buttonOk->setEnabled(ok);
+  buttonApply->setEnabled(ok);
+}
+
+//=======================================================================
+//function : onSelectIdSource
+//purpose  :
+//=======================================================================
+void SMESHGUI_CopyMeshDlg::onSelectIdSource (bool toSelectMesh)
+{
+  if (toSelectMesh)
+    myTextLabelElements->setText(tr("OBJECT_NAME"));
+  else
+    myTextLabelElements->setText(tr("ELEM_IDS"));
+
+  if (toSelectMesh) {
+    myLineEditElements->clear();
+  }
+
+  mySelectionMgr->clearFilters();
+  mySelectionMgr->installFilter(myIdSourceFilter);
+  SMESH::SetPointRepresentation(false);
+
+  if (toSelectMesh) {
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->SetSelectionMode( ActorSelection );
+    myLineEditElements->setReadOnly(true);
+    myLineEditElements->setValidator(0);
+  }
+  else
+  {
+    if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ))
+      aViewWindow->SetSelectionMode( CellSelection );
+    myLineEditElements->setReadOnly(false);
+    myLineEditElements->setValidator(myIdValidator);
+    onTextChange(myLineEditElements->text());
+  }
+
+  SelectionIntoArgument();
+}
+
+//=================================================================================
+// function : isValid
+// purpose  :
+//=================================================================================
+
+bool SMESHGUI_CopyMeshDlg::isValid()
+{
+  if ( myIdSourceCheck->isChecked() )
+    return !mySelectedObject->_is_nil();
+
+  return myNbOkElements > 0;
+}
+
+//=================================================================================
+// function : DeactivateActiveDialog()
+// purpose  :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::DeactivateActiveDialog()
+{
+  if (ConstructorsBox->isEnabled()) {
+    ConstructorsBox->setEnabled(false);
+    GroupArguments->setEnabled(false);
+    GroupButtons->setEnabled(false);
+    mySMESHGUI->ResetState();
+    mySMESHGUI->SetActiveDialogBox(0);
+    if ( mySelectionMgr )
+      mySelectionMgr->removeFilter( myIdSourceFilter );
+  }
+}
+
+//=================================================================================
+// function : ActivateThisDialog()
+// purpose  :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::ActivateThisDialog()
+{
+  /* Emit a signal to deactivate the active dialog */
+  mySMESHGUI->EmitSignalDeactivateDialog();
+  ConstructorsBox->setEnabled(true);
+  GroupArguments->setEnabled(true);
+  GroupButtons->setEnabled(true);
+
+  mySMESHGUI->SetActiveDialogBox((QDialog*)this);
+
+  onSelectIdSource( myIdSourceCheck->isChecked() );
+
+  SelectionIntoArgument();
+}
+
+//=================================================================================
+// function : enterEvent()
+// purpose  :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::enterEvent (QEvent*)
+{
+  if (!ConstructorsBox->isEnabled())
+    ActivateThisDialog();
+}
+
+//=================================================================================
+// function : closeEvent()
+// purpose  :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::closeEvent (QCloseEvent*)
+{
+  /* same than click on cancel button */
+  ClickOnCancel();
+}
+
+//=======================================================================
+//function : hideEvent
+//purpose  : caused by ESC key
+//=======================================================================
+void SMESHGUI_CopyMeshDlg::hideEvent (QHideEvent*)
+{
+  if (!isMinimized())
+    ClickOnCancel();
+}
+
+//=================================================================================
+// function : keyPressEvent()
+// purpose  :
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::keyPressEvent( QKeyEvent* e )
+{
+  QDialog::keyPressEvent( e );
+  if ( e->isAccepted() )
+    return;
+
+  if ( e->key() == Qt::Key_F1 ) {
+    e->accept();
+    ClickOnHelp();
+  }
+}
+
+//=================================================================================
+// function : setFilters()
+// purpose  : SLOT. Called when "Filter" button pressed.
+//=================================================================================
+void SMESHGUI_CopyMeshDlg::setFilters()
+{
+  if(myMesh->_is_nil()) {
+    SUIT_MessageBox::critical(this,
+                              tr("SMESH_ERROR"),
+                              tr("NO_MESH_SELECTED"));
+   return;
+  }
+  if ( !myFilterDlg )
+    myFilterDlg = new SMESHGUI_FilterDlg( mySMESHGUI, SMESH::ALL );
+
+  myFilterDlg->SetSelection();
+  myFilterDlg->SetMesh( myMesh );
+  myFilterDlg->SetSourceWg( myLineEditElements );
+
+  myFilterDlg->show();
+}
diff --git a/src/SMESHGUI/SMESHGUI_CopyMeshDlg.h b/src/SMESHGUI/SMESHGUI_CopyMeshDlg.h
new file mode 100644 (file)
index 0000000..83fcd09
--- /dev/null
@@ -0,0 +1,125 @@
+//  Copyright (C) 2007-2010  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+//  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// SMESH SMESHGUI : GUI for SMESH component
+// File   : SMESHGUI_CopyMeshDlg.h
+//
+#ifndef SMESHGUI_CopyMeshDLG_H
+#define SMESHGUI_CopyMeshDLG_H
+
+// SMESH includes
+#include "SMESH_SMESHGUI.hxx"
+
+// Qt includes
+#include <QDialog>
+
+// IDL includes
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+
+class QCheckBox;
+class QGroupBox;
+class QLabel;
+class QLineEdit;
+class QPushButton;
+
+class SMESHGUI;
+class SMESHGUI_IdValidator;
+class SMESHGUI_FilterDlg;
+class SMESH_Actor;
+class SVTK_Selector;
+class LightApp_SelectionMgr;
+class SUIT_SelectionFilter;
+
+//=================================================================================
+// class    : SMESHGUI_CopyMeshDlg
+// purpose  : copy some elements or a mesh object into a new mesh
+//=================================================================================
+
+class SMESHGUI_EXPORT SMESHGUI_CopyMeshDlg : public QDialog
+{ 
+  Q_OBJECT
+
+public:
+  SMESHGUI_CopyMeshDlg( SMESHGUI* );
+  ~SMESHGUI_CopyMeshDlg();
+
+private:
+  void                   Init( bool = true );
+  void                   closeEvent( QCloseEvent* );
+  void                   enterEvent( QEvent* );           /* mouse enter the QWidget */
+  void                   hideEvent( QHideEvent* );        /* ESC key */
+  void                   keyPressEvent( QKeyEvent* );
+  int                    GetConstructorId();
+  void                   setNewMeshName();
+
+  bool                   isValid();
+
+  SMESHGUI*              mySMESHGUI;              /* Current SMESHGUI object */
+  SMESHGUI_IdValidator*  myIdValidator;
+  LightApp_SelectionMgr* mySelectionMgr;          /* User shape selection */
+  int                    myNbOkElements;          /* to check when elements are defined */
+
+  SVTK_Selector*         mySelector;
+
+  bool                   myBusy;
+  SMESH::SMESH_Mesh_var  myMesh;
+  SMESH_Actor*           myActor;
+  SUIT_SelectionFilter*  myIdSourceFilter;
+
+  SMESH::SMESH_IDSource_var mySelectedObject;
+
+  QGroupBox*             ConstructorsBox;
+  QGroupBox*             GroupArguments;
+  QGroupBox*             GroupButtons;
+  
+  QPushButton*           buttonOk;
+  QPushButton*           buttonCancel;
+  QPushButton*           buttonApply;
+  QPushButton*           buttonHelp;
+
+  QLabel*                myTextLabelElements;
+  QLineEdit*             myLineEditElements;
+  QLineEdit*             myMeshNameEdit;
+  QCheckBox*             myIdSourceCheck;
+  QCheckBox*             myCopyGroupsCheck;
+  QCheckBox*             myKeepIdsCheck;
+
+  QPushButton*           myFilterBtn;
+  SMESHGUI_FilterDlg*    myFilterDlg;
+   
+  QString                myHelpFileName;
+
+private slots:
+  void                   ClickOnOk();
+  void                   ClickOnCancel();
+  bool                   ClickOnApply();
+  void                   ClickOnHelp();
+  void                   SelectionIntoArgument();
+  void                   DeactivateActiveDialog();
+  void                   ActivateThisDialog();
+  void                   onTextChange( const QString& );
+  void                   onSelectIdSource( bool );
+  void                   setFilters();
+};
+
+#endif // SMESHGUI_CopyMeshDLG_H
index ee88f766262184a064d2372f1dba5adeaad7b08c..de2d8e05d526caf2d710def9599316b34d143e4b 100755 (executable)
@@ -1169,18 +1169,22 @@ void SMESHGUI_FilterTable::SetCriterion (const int                       theRow,
     aTable->item( theRow, 2 )->setText( QString( theCriterion.ThresholdID ) );
   }
   else if (theCriterion.Type != SMESH::FT_RangeOfIds &&
-           theCriterion.Type != SMESH::FT_BelongToGeom &&
-           theCriterion.Type != SMESH::FT_BelongToPlane &&
-           theCriterion.Type != SMESH::FT_BelongToCylinder &&
-           theCriterion.Type != SMESH::FT_BelongToGenSurface &&
-           theCriterion.Type != SMESH::FT_LyingOnGeom &&
-           theCriterion.Type != SMESH::FT_CoplanarFaces &&
-           theCriterion.Type != SMESH::FT_FreeBorders &&
-           theCriterion.Type != SMESH::FT_FreeEdges &&
-           theCriterion.Type != SMESH::FT_FreeNodes &&
-           theCriterion.Type != SMESH::FT_FreeFaces &&
-           theCriterion.Type != SMESH::FT_BadOrientedVolume &&
-           theCriterion.Type != SMESH::FT_LinearOrQuadratic)
+          theCriterion.Type != SMESH::FT_BelongToGeom &&
+          theCriterion.Type != SMESH::FT_BelongToPlane &&
+          theCriterion.Type != SMESH::FT_BelongToCylinder &&
+          theCriterion.Type != SMESH::FT_BelongToGenSurface &&
+          theCriterion.Type != SMESH::FT_LyingOnGeom &&
+          theCriterion.Type != SMESH::FT_CoplanarFaces &&
+          theCriterion.Type != SMESH::FT_FreeBorders &&
+          theCriterion.Type != SMESH::FT_FreeEdges &&
+          theCriterion.Type != SMESH::FT_FreeNodes &&
+          theCriterion.Type != SMESH::FT_FreeFaces &&
+          theCriterion.Type != SMESH::FT_BadOrientedVolume &&
+          theCriterion.Type != SMESH::FT_BareBorderFace &&
+          theCriterion.Type != SMESH::FT_BareBorderVolume &&
+          theCriterion.Type != SMESH::FT_OverConstrainedFace &&
+          theCriterion.Type != SMESH::FT_OverConstrainedVolume &&
+          theCriterion.Type != SMESH::FT_LinearOrQuadratic)
   {
     aTable->item( theRow, 2 )->setText(QString("%1").arg(theCriterion.Threshold, 0, 'g', 15));
   }
@@ -1341,10 +1345,14 @@ void SMESHGUI_FilterTable::updateAdditionalWidget()
                    aCriterion != SMESH::FT_RangeOfIds &&
                    aCriterion != SMESH::FT_FreeEdges &&
                    aCriterion != SMESH::FT_FreeFaces &&
-                   aCriterion != SMESH::FT_BadOrientedVolume)
+                   aCriterion != SMESH::FT_BadOrientedVolume &&
+                   aCriterion != SMESH::FT_BareBorderFace &&
+                   aCriterion != SMESH::FT_BareBorderVolume &&
+                   aCriterion != SMESH::FT_OverConstrainedFace &&
+                   aCriterion != SMESH::FT_OverConstrainedVolume)
                    ||
                    aCriterion == SMESH::FT_CoplanarFaces);
-
+  
   if (!myAddWidgets.contains(anItem))
   {
     myAddWidgets[ anItem ] = new AdditionalWidget(myWgStack);
@@ -1520,9 +1528,13 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con
 
   if ((aType == SMESH::NODE && aCriterionType == SMESH::FT_FreeNodes ) ||
       (aType == SMESH::EDGE && aCriterionType == SMESH::FT_FreeBorders ) ||
-      (aType == SMESH::FACE && (aCriterionType == SMESH::FT_FreeEdges ||
+      (aType == SMESH::FACE && (aCriterionType == SMESH::FT_BareBorderFace ||
+                               aCriterionType == SMESH::FT_OverConstrainedFace ||
+                               aCriterionType == SMESH::FT_FreeEdges ||
                                 aCriterionType == SMESH::FT_FreeFaces)) ||
-      (aType == SMESH::VOLUME && aCriterionType == SMESH::FT_BadOrientedVolume) ||
+      (aType == SMESH::VOLUME && (aCriterionType == SMESH::FT_BadOrientedVolume ||
+                                 aCriterionType == SMESH::FT_OverConstrainedVolume ||
+                                 aCriterionType == SMESH::FT_BareBorderVolume)) ||
       aCriterionType == SMESH::FT_LinearOrQuadratic ||
       aCriterionType == SMESH::FT_GroupColor ||
       aCriterionType == SMESH::FT_ElemGeomType ||
@@ -1808,6 +1820,8 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
       aCriteria[ SMESH::FT_Length2D           ] = tr("LENGTH2D");
       aCriteria[ SMESH::FT_MultiConnection2D  ] = tr("MULTI2D_BORDERS");
       aCriteria[ SMESH::FT_FreeFaces          ] = tr("FREE_FACES");
+      aCriteria[ SMESH::FT_BareBorderFace     ] = tr("BARE_BORDER_FACE");
+      aCriteria[ SMESH::FT_OverConstrainedFace] = tr("OVER_CONSTRAINED_FACE");
       aCriteria[ SMESH::FT_LinearOrQuadratic  ] = tr("LINEAR");
       aCriteria[ SMESH::FT_GroupColor         ] = tr("GROUP_COLOR");
       aCriteria[ SMESH::FT_ElemGeomType       ] = tr("GEOM_TYPE");
@@ -1820,16 +1834,18 @@ const QMap<int, QString>& SMESHGUI_FilterTable::getCriteria (const int theType)
     static QMap<int, QString> aCriteria;
     if (aCriteria.isEmpty())
     {
-      aCriteria[ SMESH::FT_AspectRatio3D      ] = tr("ASPECT_RATIO_3D");
-      aCriteria[ SMESH::FT_RangeOfIds         ] = tr("RANGE_OF_IDS");
-      aCriteria[ SMESH::FT_BelongToGeom       ] = tr("BELONG_TO_GEOM");
-      aCriteria[ SMESH::FT_LyingOnGeom        ] = tr("LYING_ON_GEOM");
-      aCriteria[ SMESH::FT_BadOrientedVolume  ] = tr("BAD_ORIENTED_VOLUME");
-      aCriteria[ SMESH::FT_Volume3D           ] = tr("VOLUME_3D");
-      aCriteria[ SMESH::FT_MaxElementLength3D ] = tr("MAX_ELEMENT_LENGTH_3D");
-      aCriteria[ SMESH::FT_LinearOrQuadratic  ] = tr("LINEAR");
-      aCriteria[ SMESH::FT_GroupColor         ] = tr("GROUP_COLOR");
-      aCriteria[ SMESH::FT_ElemGeomType       ] = tr("GEOM_TYPE");
+      aCriteria[ SMESH::FT_AspectRatio3D        ] = tr("ASPECT_RATIO_3D");
+      aCriteria[ SMESH::FT_RangeOfIds           ] = tr("RANGE_OF_IDS");
+      aCriteria[ SMESH::FT_BelongToGeom         ] = tr("BELONG_TO_GEOM");
+      aCriteria[ SMESH::FT_LyingOnGeom          ] = tr("LYING_ON_GEOM");
+      aCriteria[ SMESH::FT_BadOrientedVolume    ] = tr("BAD_ORIENTED_VOLUME");
+      aCriteria[ SMESH::FT_BareBorderVolume     ] = tr("BARE_BORDER_VOLUME");
+      aCriteria[ SMESH::FT_OverConstrainedVolume] = tr("OVER_CONSTRAINED_VOLUME");
+      aCriteria[ SMESH::FT_Volume3D             ] = tr("VOLUME_3D");
+      aCriteria[ SMESH::FT_MaxElementLength3D   ] = tr("MAX_ELEMENT_LENGTH_3D");
+      aCriteria[ SMESH::FT_LinearOrQuadratic    ] = tr("LINEAR");
+      aCriteria[ SMESH::FT_GroupColor           ] = tr("GROUP_COLOR");
+      aCriteria[ SMESH::FT_ElemGeomType         ] = tr("GEOM_TYPE");
     }
     return aCriteria;
   }
index a964d8cfc8865f9313ed560aac86199f353a00e6..30aeaa3c850fb04428379d077bc0430939c7b0dc 100644 (file)
@@ -309,7 +309,7 @@ void SMESHGUI_GenericHypothesisCreator::onDialogFinished( int result )
 
   disconnect( myDlg, SIGNAL( finished( int ) ), this, SLOT( onDialogFinished( int ) ) );
   myDlg->close();
-  //delete myDlg;
+  //delete myDlg; since WA_DeleteOnClose==true
   myDlg = 0;
   emit finished( result );
 }
@@ -557,6 +557,8 @@ QString SMESHGUI_GenericHypothesisCreator::helpPage() const
     aHelpFileName = "segments_around_vertex_algo_page.html";
   else if ( aHypType == "QuadrangleParams")
     aHelpFileName = "a2d_meshing_hypo_page.html#hypo_quad_params_anchor";
+  else if ( aHypType == "ImportSource1D" || aHypType == "ImportSource2D")
+    aHelpFileName = "import_algos_page.html";
   return aHelpFileName;
 }
 
index 255951008d61b34e164fef509623fdf3f1ce6537..15ab587262aeb966dfde22b62ca83d860f53a65b 100644 (file)
@@ -60,8 +60,9 @@
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Group)
 
-const int SPACING = 6;
-const int MARGIN  = 9;
+const int SPACING  = 6;
+const int MARGIN   = 9;
+const int MAXITEMS = 10;
 
 /*!
   \class SMESHGUI_MeshInfo
@@ -465,8 +466,29 @@ void SMESHGUI_MeshInfo::setFieldsVisible( int start, int end, bool on )
   \param parent parent widget
 */
 SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent )
-: QWidget( parent ), myActor( 0 ), myID( 0 ), myIsElement( -1 )
+: QWidget( parent ), myActor( 0 ), myIsElement( -1 )
 {
+  myFrame = new QWidget( this );
+  myExtra = new QWidget( this );
+  myCurrent = new QLabel( "10/43 items shown", myExtra );
+  myCurrent->setAlignment( Qt::AlignRight | Qt::AlignVCenter );
+  myPrev = new QPushButton( tr( "<<" ), myExtra );
+  myNext = new QPushButton( tr( ">>" ), myExtra );
+  QHBoxLayout* hbl = new QHBoxLayout( myExtra );
+  hbl->setContentsMargins( 0, SPACING, 0, 0 );
+  hbl->setSpacing( SPACING );
+  hbl->addStretch();
+  hbl->addWidget( myCurrent );
+  hbl->addWidget( myPrev );
+  hbl->addWidget( myNext );
+  QVBoxLayout* vbl = new QVBoxLayout( this );
+  vbl->setMargin( 0 );
+  vbl->setSpacing( 0 );
+  vbl->addWidget( myFrame );
+  vbl->addWidget( myExtra );
+  connect( myPrev, SIGNAL( clicked() ), this, SLOT( showPrevious() ) );
+  connect( myNext, SIGNAL( clicked() ), this, SLOT( showNext() ) );
+  clear();
 }
 
 /*!
@@ -484,7 +506,6 @@ void SMESHGUI_ElemInfo::setSource( SMESH_Actor* actor )
 {
   if ( myActor != actor ) {
     myActor = actor;
-    myID = 0;
     myIsElement = -1;
     clear();
   }
@@ -492,19 +513,87 @@ void SMESHGUI_ElemInfo::setSource( SMESH_Actor* actor )
 
 /*!
   \brief Show mesh element information
-  \param long id mesh node / element ID
+  \param id mesh node / element ID
   \param isElem show mesh element information if \c true or mesh node information if \c false
 */
 void SMESHGUI_ElemInfo::showInfo( long id, bool isElem )
 {
-  myID = id;
+  QSet<long> ids;
+  ids << id;
+  showInfo( ids, isElem );
+}
+
+/*!
+  \brief Show mesh element information
+  \param ids mesh nodes / elements identifiers
+  \param isElem show mesh element information if \c true or mesh node information if \c false
+*/
+void SMESHGUI_ElemInfo::showInfo( QSet<long> ids, bool isElem )
+{
+  QList<long> newIds = ids.toList();
+  qSort( newIds );
+  if ( myIDs == newIds && myIsElement == isElem ) return;
+
+  myIDs = newIds;
   myIsElement = isElem;
+  myIndex = 0;
+  updateControls();
+  information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
 }
 
 /*!
-  \fn void SMESHGUI_ElemInfo::clear()
   \brief Clear mesh element information widget
 */
+void SMESHGUI_ElemInfo::clear()
+{
+  myIDs.clear();
+  myIndex = 0;
+  clearInternal();
+  updateControls();
+}
+
+/*!
+  \brief Get central area widget
+  \return central widget
+*/
+QWidget* SMESHGUI_ElemInfo::frame() const
+{
+  return myFrame;
+}
+
+/*!
+  \brief Get actor
+  \return actor being used
+*/
+SMESH_Actor* SMESHGUI_ElemInfo::actor() const
+{
+  return myActor;
+}
+
+/*!
+  \brief Get current info mode.
+  \return \c true if mesh element information is shown or \c false if node information is shown
+*/
+bool SMESHGUI_ElemInfo::isElements() const
+{
+  return myIsElement;
+}
+
+/*!
+  \fn void SMESHGUI_ElemInfo::information( const QList<long>& ids )
+  \brief Show information on the specified nodes / elements
+
+  This function is to be redefined in sub-classes.
+
+  \param ids nodes / elements identifiers information is to be shown on
+*/
+
+/*!
+  \brief Internal clean-up (reset widget)
+*/
+void SMESHGUI_ElemInfo::clearInternal()
+{
+}
 
 /*!
   \brief Get node connectivity
@@ -560,6 +649,39 @@ SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement*
   return xyz;
 }
 
+/*!
+  \brief This slot is called from "Show Previous" button click.
+  Shows information on the previous group of the items.
+*/
+void SMESHGUI_ElemInfo::showPrevious()
+{
+  myIndex = qMax( 0, myIndex-1 );
+  updateControls();
+  information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
+}
+
+/*!
+  \brief This slot is called from "Show Next" button click.
+  Shows information on the next group of the items.
+*/
+void SMESHGUI_ElemInfo::showNext()
+{
+  myIndex = qMin( myIndex+1, myIDs.count() / MAXITEMS );
+  updateControls();
+  information( myIDs.mid( myIndex*MAXITEMS, MAXITEMS ) );
+}
+
+/*!
+  \brief Update widgets state
+*/
+void SMESHGUI_ElemInfo::updateControls()
+{
+  myExtra->setVisible( myIDs.count() > MAXITEMS );
+  myCurrent->setText( tr( "X_FROM_Y_ITEMS_SHOWN" ).arg( myIndex*MAXITEMS+1 ).arg(qMin(myIndex*MAXITEMS+MAXITEMS, myIDs.count())).arg( myIDs.count() ) );
+  myPrev->setEnabled( myIndex > 0 );
+  myNext->setEnabled( (myIndex+1)*MAXITEMS < myIDs.count() );
+}
+
 /*!
   \class SMESHGUI_SimpleElemInfo
   \brief Represents mesh element information in the simple text area.
@@ -572,148 +694,43 @@ SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement*
 SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent )
 : SMESHGUI_ElemInfo( parent )
 {
-  myInfo = new QTextBrowser( this );
-  QVBoxLayout* l = new QVBoxLayout( this );
+  myInfo = new QTextBrowser( frame() );
+  QVBoxLayout* l = new QVBoxLayout( frame() );
   l->setMargin( 0 );
   l->addWidget( myInfo );
 }
 
 /*!
   \brief Show mesh element information
-  \param long id mesh node / element ID
-  \param isElem show mesh element information if \c true or mesh node information if \c false
+  \param ids mesh nodes / elements identifiers
 */
-void SMESHGUI_SimpleElemInfo::showInfo( long id, bool isElem )
+void SMESHGUI_SimpleElemInfo::information( const QList<long>& ids )
 {
-  if ( myID == id && myIsElement == isElem ) return;
-
-  SMESHGUI_ElemInfo::showInfo( id, isElem );
-
-  clear();
+  clearInternal();
   
-  if ( myActor ) {
+  if ( actor() ) {
     int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
-    if ( !isElem ) {
-      //
-      // show node info
-      //
-      const SMDS_MeshElement* e = myActor->GetObject()->GetMesh()->FindNode( id );
-      if ( !e ) return;
-      const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( e );
-      
-      // node ID
-      myInfo->append( QString( "<b>%1 #%2</b>" ).arg( tr( "NODE" ) ).arg( id ) );
-      // separator
-      myInfo->append( "" );
-      // coordinates
-      myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( tr( "COORDINATES" ) ).
-                     arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
-                     arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
-                     arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
-      // separator
-      myInfo->append( "" );
-      // connectivity
-      Connectivity connectivity = nodeConnectivity( node );
-      if ( !connectivity.isEmpty() ) {
-       myInfo->append( QString( "<b>%1:</b>" ).arg( tr( "CONNECTIVITY" ) ) );
-       QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
-       if ( !con.isEmpty() )
-         myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "0D_ELEMENTS" ) ).arg( con ) );
-       con = formatConnectivity( connectivity, SMDSAbs_Edge );
-       if ( !con.isEmpty() )
-         myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "EDGES" ) ).arg( con ) );
-       con = formatConnectivity( connectivity, SMDSAbs_Face );
-       if ( !con.isEmpty() )
-         myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "FACES" ) ).arg( con ) );
-       con = formatConnectivity( connectivity, SMDSAbs_Volume );
-       if ( !con.isEmpty() )
-         myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "VOLUMES" ) ).arg( con ) );
-      }
-      else {
-       myInfo->append( QString( "<b>%1</b>" ).arg( tr( "FREE_NODE" ) ).arg( id ) );
-      }
-    }
-    else {
-      //
-      // show element info
-      // 
-      const SMDS_MeshElement* e = myActor->GetObject()->GetMesh()->FindElement( id );
-      if ( !e ) return;
-
-      // element ID && type
-      QString stype;
-      switch( e->GetType() ) {
-      case SMDSAbs_0DElement:
-       stype = tr( "0D ELEMENT" ); break;
-      case SMDSAbs_Edge:
-       stype = tr( "EDGE" ); break;
-      case SMDSAbs_Face:
-       stype = tr( "FACE" ); break;
-      case SMDSAbs_Volume:
-       stype = tr( "VOLUME" ); break;
-      default: 
-       break;
-      }
-      if ( stype.isEmpty() ) return;
-      myInfo->append( QString( "<b>%1 #%2</b>" ).arg( stype ).arg( id ) );
-      // separator
-      myInfo->append( "" );
-      // geometry type
-      QString gtype;
-      switch( e->GetEntityType() ) {
-      case SMDSEntity_Triangle:
-      case SMDSEntity_Quad_Triangle:
-       gtype = tr( "TRIANGLE" ); break;
-      case SMDSEntity_Quadrangle:
-      case SMDSEntity_Quad_Quadrangle:
-       gtype = tr( "QUADRANGLE" ); break;
-      case SMDSEntity_Polygon:
-      case SMDSEntity_Quad_Polygon:
-       gtype = tr( "POLYGON" ); break;
-      case SMDSEntity_Tetra:
-      case SMDSEntity_Quad_Tetra:
-       gtype = tr( "TETRAHEDRON" ); break;
-      case SMDSEntity_Pyramid:
-      case SMDSEntity_Quad_Pyramid:
-       gtype = tr( "PYRAMID" ); break;
-      case SMDSEntity_Hexa:
-      case SMDSEntity_Quad_Hexa:
-       gtype = tr( "HEXAHEDRON" ); break;
-      case SMDSEntity_Penta:
-      case SMDSEntity_Quad_Penta:
-       gtype = tr( "PRISM" ); break;
-      case SMDSEntity_Polyhedra:
-      case SMDSEntity_Quad_Polyhedra:
-       gtype = tr( "POLYHEDRON" ); break;
-      default: 
-       break;
-      }
-      if ( !gtype.isEmpty() )
-       myInfo->append( QString( "<b>%1:</b> %2" ).arg( tr( "TYPE" ) ).arg( gtype ) );
-      // quadratic flag and gravity center (any element except 0D)
-      if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Last ) {
-       // quadratic flag
-       myInfo->append( QString( "<b>%1?</b> %2" ).arg( tr( "QUADRATIC" ) ).arg( e->IsQuadratic() ? tr( "YES" ) : tr( "NO" ) ) );
+    foreach ( long id, ids ) {
+      if ( !isElements() ) {
+       //
+       // show node info
+       //
+       const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindNode( id );
+       if ( !e ) return;
+       const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( e );
+       
+       // node ID
+       myInfo->append( QString( "<b>%1 #%2</b>" ).arg( tr( "NODE" ) ).arg( id ) );
        // separator
        myInfo->append( "" );
-       // gravity center
-       XYZ gc = gravityCenter( e );
-       myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( tr( "GRAVITY_CENTER" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) );
-      }
-      // separator
-      myInfo->append( "" );
-      // connectivity
-      SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
-      for ( int idx = 1; nodeIt->more(); idx++ ) {
-       const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-       // node number and ID
-       myInfo->append( QString( "<b>%1 %2/%3</b> - #%4" ).arg( tr( "NODE" ) ).arg( idx ).arg( e->NbNodes() ).arg( node->GetID() ) );
-       // node coordinates
+       // coordinates
        myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( tr( "COORDINATES" ) ).
                        arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
                        arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
                        arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
-       // node connectivity
+       // separator
+       myInfo->append( "" );
+       // connectivity
        Connectivity connectivity = nodeConnectivity( node );
        if ( !connectivity.isEmpty() ) {
          myInfo->append( QString( "<b>%1:</b>" ).arg( tr( "CONNECTIVITY" ) ) );
@@ -733,17 +750,123 @@ void SMESHGUI_SimpleElemInfo::showInfo( long id, bool isElem )
        else {
          myInfo->append( QString( "<b>%1</b>" ).arg( tr( "FREE_NODE" ) ).arg( id ) );
        }
+      }
+      else {
+       //
+       // show element info
+       // 
+       const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
+       if ( !e ) return;
+       
+       // element ID && type
+       QString stype;
+       switch( e->GetType() ) {
+       case SMDSAbs_0DElement:
+         stype = tr( "0D ELEMENT" ); break;
+       case SMDSAbs_Edge:
+         stype = tr( "EDGE" ); break;
+       case SMDSAbs_Face:
+         stype = tr( "FACE" ); break;
+       case SMDSAbs_Volume:
+         stype = tr( "VOLUME" ); break;
+       default: 
+         break;
+       }
+       if ( stype.isEmpty() ) return;
+       myInfo->append( QString( "<b>%1 #%2</b>" ).arg( stype ).arg( id ) );
        // separator
        myInfo->append( "" );
+       // geometry type
+       QString gtype;
+       switch( e->GetEntityType() ) {
+       case SMDSEntity_Triangle:
+       case SMDSEntity_Quad_Triangle:
+         gtype = tr( "TRIANGLE" ); break;
+       case SMDSEntity_Quadrangle:
+       case SMDSEntity_Quad_Quadrangle:
+         gtype = tr( "QUADRANGLE" ); break;
+       case SMDSEntity_Polygon:
+       case SMDSEntity_Quad_Polygon:
+         gtype = tr( "POLYGON" ); break;
+       case SMDSEntity_Tetra:
+       case SMDSEntity_Quad_Tetra:
+         gtype = tr( "TETRAHEDRON" ); break;
+       case SMDSEntity_Pyramid:
+       case SMDSEntity_Quad_Pyramid:
+         gtype = tr( "PYRAMID" ); break;
+       case SMDSEntity_Hexa:
+       case SMDSEntity_Quad_Hexa:
+         gtype = tr( "HEXAHEDRON" ); break;
+       case SMDSEntity_Penta:
+       case SMDSEntity_Quad_Penta:
+         gtype = tr( "PRISM" ); break;
+       case SMDSEntity_Polyhedra:
+       case SMDSEntity_Quad_Polyhedra:
+         gtype = tr( "POLYHEDRON" ); break;
+       default: 
+         break;
+       }
+       if ( !gtype.isEmpty() )
+         myInfo->append( QString( "<b>%1:</b> %2" ).arg( tr( "TYPE" ) ).arg( gtype ) );
+       // quadratic flag and gravity center (any element except 0D)
+       if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Last ) {
+         // quadratic flag
+         myInfo->append( QString( "<b>%1?</b> %2" ).arg( tr( "QUADRATIC" ) ).arg( e->IsQuadratic() ? tr( "YES" ) : tr( "NO" ) ) );
+         // separator
+         myInfo->append( "" );
+         // gravity center
+         XYZ gc = gravityCenter( e );
+         myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( tr( "GRAVITY_CENTER" ) ).arg( gc.x() ).arg( gc.y() ).arg( gc.z() ) );
+       }
+       // separator
+       myInfo->append( "" );
+       // connectivity
+       SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
+       for ( int idx = 1; nodeIt->more(); idx++ ) {
+         const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+         // node number and ID
+         myInfo->append( QString( "<b>%1 %2/%3</b> - #%4" ).arg( tr( "NODE" ) ).arg( idx ).arg( e->NbNodes() ).arg( node->GetID() ) );
+         // node coordinates
+         myInfo->append( QString( "<b>%1:</b> (%2, %3, %4)" ).arg( tr( "COORDINATES" ) ).
+                         arg( node->X(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
+                         arg( node->Y(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ).
+                         arg( node->Z(), 0, precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+         // node connectivity
+         Connectivity connectivity = nodeConnectivity( node );
+         if ( !connectivity.isEmpty() ) {
+           myInfo->append( QString( "<b>%1:</b>" ).arg( tr( "CONNECTIVITY" ) ) );
+           QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
+           if ( !con.isEmpty() )
+             myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "0D_ELEMENTS" ) ).arg( con ) );
+           con = formatConnectivity( connectivity, SMDSAbs_Edge );
+           if ( !con.isEmpty() )
+             myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "EDGES" ) ).arg( con ) );
+           con = formatConnectivity( connectivity, SMDSAbs_Face );
+           if ( !con.isEmpty() )
+             myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "FACES" ) ).arg( con ) );
+           con = formatConnectivity( connectivity, SMDSAbs_Volume );
+           if ( !con.isEmpty() )
+             myInfo->append( QString( "- <b>%1:</b> %2" ).arg( tr( "VOLUMES" ) ).arg( con ) );
+         }
+         else {
+           myInfo->append( QString( "<b>%1</b>" ).arg( tr( "FREE_NODE" ) ).arg( id ) );
+         }
+       }
+      }
+      // separator
+      if ( ids.count() > 1 ) {
+       myInfo->append( "" );
+       myInfo->append( "------" );
+       myInfo->append( "" );
       }
     }
   }
 }
 
 /*!
-  \brief Clear mesh element information widget
+  \brief Internal clean-up (reset widget)
 */
-void SMESHGUI_SimpleElemInfo::clear()
+void SMESHGUI_SimpleElemInfo::clearInternal()
 {
   myInfo->clear();
 }
@@ -791,189 +914,43 @@ QWidget* SMESHGUI_TreeElemInfo::ItemDelegate::createEditor( QWidget* parent, con
 SMESHGUI_TreeElemInfo::SMESHGUI_TreeElemInfo( QWidget* parent )
 : SMESHGUI_ElemInfo( parent )
 {
-  myInfo = new QTreeWidget( this );
+  myInfo = new QTreeWidget( frame() );
   myInfo->setColumnCount( 2 );
   myInfo->setHeaderLabels( QStringList() << tr( "PROPERTY" ) << tr( "VALUE" ) );
   myInfo->header()->setStretchLastSection( true );
   myInfo->header()->setResizeMode( 0, QHeaderView::ResizeToContents );
   myInfo->setItemDelegate( new ItemDelegate( myInfo ) );
-  QVBoxLayout* l = new QVBoxLayout( this );
+  QVBoxLayout* l = new QVBoxLayout( frame() );
   l->setMargin( 0 );
   l->addWidget( myInfo );
 }
 
 /*!
   \brief Show mesh element information
-  \param long id mesh node / element ID
-  \param isElem show mesh element information if \c true or mesh node information if \c false
+  \param ids mesh nodes / elements identifiers
 */
-void SMESHGUI_TreeElemInfo::showInfo( long id, bool isElem )
+void SMESHGUI_TreeElemInfo::information( const QList<long>& ids )
 {
-  if ( myID == id && myIsElement == isElem ) return;
-
-  SMESHGUI_ElemInfo::showInfo( id, isElem );
+  clearInternal();
 
-  clear();
-  
-  if ( myActor ) {
+  if ( actor() ) {
     int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 );
-    if ( !isElem ) {
-      //
-      // show node info
-      //
-      const SMDS_MeshElement* e = myActor->GetObject()->GetMesh()->FindNode( id );
-      if ( !e ) return;
-      const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( e );
+    foreach ( long id, ids ) {
+      if ( !isElements() ) {
+       //
+       // show node info
+       //
+       const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindNode( id );
+       if ( !e ) return;
+       const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( e );
       
-      // node ID
-      QTreeWidgetItem* nodeItem = createItem( 0, -1 );
-      nodeItem->setText( 0, tr( "NODE" ) );
-      nodeItem->setText( 1, QString( "#%1" ).arg( id ) );
-      nodeItem->setExpanded( true );
-      // coordinates
-      QTreeWidgetItem* coordItem = createItem( nodeItem, 0 );
-      coordItem->setText( 0, tr( "COORDINATES" ) );
-      coordItem->setExpanded( true );
-      QTreeWidgetItem* xItem = createItem( coordItem );
-      xItem->setText( 0, "X" );
-      xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
-      QTreeWidgetItem* yItem = createItem( coordItem );
-      yItem->setText( 0, "Y" );
-      yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
-      QTreeWidgetItem* zItem = createItem( coordItem );
-      zItem->setText( 0, "Z" );
-      zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
-      // connectivity
-      QTreeWidgetItem* conItem = createItem( nodeItem, 0 );
-      conItem->setText( 0, tr( "CONNECTIVITY" ) );
-      conItem->setExpanded( true );
-      Connectivity connectivity = nodeConnectivity( node );
-      if ( !connectivity.isEmpty() ) {
-       QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
-       if ( !con.isEmpty() ) {
-         QTreeWidgetItem* i = createItem( conItem );
-         i->setText( 0, tr( "0D_ELEMENTS" ) );
-         i->setText( 1, con );
-       }
-       con = formatConnectivity( connectivity, SMDSAbs_Edge );
-       if ( !con.isEmpty() ) {
-         QTreeWidgetItem* i = createItem( conItem );
-         i->setText( 0, tr( "EDGES" ) );
-         i->setText( 1, con );
-       }
-       con = formatConnectivity( connectivity, SMDSAbs_Face );
-       if ( !con.isEmpty() ) {
-         QTreeWidgetItem* i = createItem( conItem );
-         i->setText( 0, tr( "FACES" ) );
-         i->setText( 1, con );
-       }
-       con = formatConnectivity( connectivity, SMDSAbs_Volume );
-       if ( !con.isEmpty() ) {
-         QTreeWidgetItem* i = createItem( conItem );
-         i->setText( 0, tr( "VOLUMES" ) );
-         i->setText( 1, con );
-       }
-      }
-      else {
-       conItem->setText( 1, tr( "FREE_NODE" ) );
-      }
-    }
-    else {
-      //
-      // show element info
-      // 
-      const SMDS_MeshElement* e = myActor->GetObject()->GetMesh()->FindElement( id );
-      if ( !e ) return;
-
-      // element ID && type
-      QString stype;
-      switch( e->GetType() ) {
-      case SMDSAbs_0DElement:
-       stype = tr( "0D ELEMENT" ); break;
-      case SMDSAbs_Edge:
-       stype = tr( "EDGE" ); break;
-      case SMDSAbs_Face:
-       stype = tr( "FACE" ); break;
-      case SMDSAbs_Volume:
-       stype = tr( "VOLUME" ); break;
-      default: 
-       break;
-      }
-      if ( stype.isEmpty() ) return;
-      QTreeWidgetItem* elemItem = createItem( 0, -1 );
-      elemItem->setText( 0, stype );
-      elemItem->setText( 1, QString( "#%1" ).arg( id ) );
-      elemItem->setExpanded( true );
-      // geometry type
-      QString gtype;
-      switch( e->GetEntityType() ) {
-      case SMDSEntity_Triangle:
-      case SMDSEntity_Quad_Triangle:
-       gtype = tr( "TRIANGLE" ); break;
-      case SMDSEntity_Quadrangle:
-      case SMDSEntity_Quad_Quadrangle:
-       gtype = tr( "QUADRANGLE" ); break;
-      case SMDSEntity_Polygon:
-      case SMDSEntity_Quad_Polygon:
-       gtype = tr( "POLYGON" ); break;
-      case SMDSEntity_Tetra:
-      case SMDSEntity_Quad_Tetra:
-       gtype = tr( "TETRAHEDRON" ); break;
-      case SMDSEntity_Pyramid:
-      case SMDSEntity_Quad_Pyramid:
-       gtype = tr( "PYRAMID" ); break;
-      case SMDSEntity_Hexa:
-      case SMDSEntity_Quad_Hexa:
-       gtype = tr( "HEXAHEDRON" ); break;
-      case SMDSEntity_Penta:
-      case SMDSEntity_Quad_Penta:
-       gtype = tr( "PRISM" ); break;
-      case SMDSEntity_Polyhedra:
-      case SMDSEntity_Quad_Polyhedra:
-       gtype = tr( "POLYHEDRON" ); break;
-      default: 
-       break;
-      }
-      if ( !gtype.isEmpty() ) {
-       QTreeWidgetItem* typeItem = createItem( elemItem, 0 );
-       typeItem->setText( 0, tr( "TYPE" ) );
-       typeItem->setText( 1, gtype );
-      }
-      // quadratic flag and gravity center (any element except 0D)
-      if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Last ) {
-       // quadratic flag
-       QTreeWidgetItem* quadItem = createItem( elemItem, 0 );
-       quadItem->setText( 0, tr( "QUADRATIC" ) );
-       quadItem->setText( 1, e->IsQuadratic() ? tr( "YES" ) : tr( "NO" ) );
-       // gravity center
-       XYZ gc = gravityCenter( e );
-       QTreeWidgetItem* gcItem = createItem( elemItem, 0 );
-       gcItem->setText( 0, tr( "GRAVITY_CENTER" ) );
-       gcItem->setExpanded( true );
-       QTreeWidgetItem* xItem = createItem( gcItem );
-       xItem->setText( 0, "X" );
-       xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
-       QTreeWidgetItem* yItem = createItem( gcItem );
-       yItem->setText( 0, "Y" );
-       yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
-       QTreeWidgetItem* zItem = createItem( gcItem );
-       zItem->setText( 0, "Z" );
-       zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
-      }
-      // connectivity
-      QTreeWidgetItem* conItem = createItem( elemItem, 0 );
-      conItem->setText( 0, tr( "CONNECTIVITY" ) );
-      conItem->setExpanded( true );
-      SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
-      for ( int idx = 1; nodeIt->more(); idx++ ) {
-       const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-       // node number and ID
-       QTreeWidgetItem* nodeItem = createItem( conItem, 0 );
-       nodeItem->setText( 0, QString( "%1 %2/%3" ).arg( tr( "NODE" ) ).arg( idx ).arg( e->NbNodes() ) );
-       nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() ) );
-       //nodeItem->setExpanded( true );
-       // node coordinates
-       QTreeWidgetItem* coordItem = createItem( nodeItem );
+       // node ID
+       QTreeWidgetItem* nodeItem = createItem( 0, -1 );
+       nodeItem->setText( 0, tr( "NODE" ) );
+       nodeItem->setText( 1, QString( "#%1" ).arg( id ) );
+       nodeItem->setExpanded( true );
+       // coordinates
+       QTreeWidgetItem* coordItem = createItem( nodeItem, 0 );
        coordItem->setText( 0, tr( "COORDINATES" ) );
        coordItem->setExpanded( true );
        QTreeWidgetItem* xItem = createItem( coordItem );
@@ -985,46 +962,189 @@ void SMESHGUI_TreeElemInfo::showInfo( long id, bool isElem )
        QTreeWidgetItem* zItem = createItem( coordItem );
        zItem->setText( 0, "Z" );
        zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
-       // node connectivity
-       QTreeWidgetItem* nconItem = createItem( nodeItem );
-       nconItem->setText( 0, tr( "CONNECTIVITY" ) );
-       nconItem->setExpanded( true );
+       // connectivity
+       QTreeWidgetItem* conItem = createItem( nodeItem, 0 );
+       conItem->setText( 0, tr( "CONNECTIVITY" ) );
+       conItem->setExpanded( true );
        Connectivity connectivity = nodeConnectivity( node );
        if ( !connectivity.isEmpty() ) {
          QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
          if ( !con.isEmpty() ) {
-           QTreeWidgetItem* i = createItem( nconItem );
+           QTreeWidgetItem* i = createItem( conItem );
            i->setText( 0, tr( "0D_ELEMENTS" ) );
            i->setText( 1, con );
          }
          con = formatConnectivity( connectivity, SMDSAbs_Edge );
          if ( !con.isEmpty() ) {
-           QTreeWidgetItem* i = createItem( nconItem );
+           QTreeWidgetItem* i = createItem( conItem );
            i->setText( 0, tr( "EDGES" ) );
            i->setText( 1, con );
          }
          con = formatConnectivity( connectivity, SMDSAbs_Face );
          if ( !con.isEmpty() ) {
-           QTreeWidgetItem* i = createItem( nconItem );
+           QTreeWidgetItem* i = createItem( conItem );
            i->setText( 0, tr( "FACES" ) );
            i->setText( 1, con );
          }
          con = formatConnectivity( connectivity, SMDSAbs_Volume );
          if ( !con.isEmpty() ) {
-           QTreeWidgetItem* i = createItem( nconItem );
+           QTreeWidgetItem* i = createItem( conItem );
            i->setText( 0, tr( "VOLUMES" ) );
            i->setText( 1, con );
          }
        }
+       else {
+         conItem->setText( 1, tr( "FREE_NODE" ) );
+       }
+      }
+      else {
+       //
+       // show element info
+       // 
+       const SMDS_MeshElement* e = actor()->GetObject()->GetMesh()->FindElement( id );
+       if ( !e ) return;
+       
+       // element ID && type
+       QString stype;
+       switch( e->GetType() ) {
+       case SMDSAbs_0DElement:
+         stype = tr( "0D ELEMENT" ); break;
+       case SMDSAbs_Edge:
+         stype = tr( "EDGE" ); break;
+       case SMDSAbs_Face:
+         stype = tr( "FACE" ); break;
+       case SMDSAbs_Volume:
+         stype = tr( "VOLUME" ); break;
+       default: 
+         break;
+       }
+       if ( stype.isEmpty() ) return;
+       QTreeWidgetItem* elemItem = createItem( 0, -1 );
+       elemItem->setText( 0, stype );
+       elemItem->setText( 1, QString( "#%1" ).arg( id ) );
+       elemItem->setExpanded( true );
+       // geometry type
+       QString gtype;
+       switch( e->GetEntityType() ) {
+       case SMDSEntity_Triangle:
+       case SMDSEntity_Quad_Triangle:
+         gtype = tr( "TRIANGLE" ); break;
+       case SMDSEntity_Quadrangle:
+       case SMDSEntity_Quad_Quadrangle:
+         gtype = tr( "QUADRANGLE" ); break;
+       case SMDSEntity_Polygon:
+       case SMDSEntity_Quad_Polygon:
+         gtype = tr( "POLYGON" ); break;
+       case SMDSEntity_Tetra:
+       case SMDSEntity_Quad_Tetra:
+         gtype = tr( "TETRAHEDRON" ); break;
+       case SMDSEntity_Pyramid:
+       case SMDSEntity_Quad_Pyramid:
+         gtype = tr( "PYRAMID" ); break;
+       case SMDSEntity_Hexa:
+       case SMDSEntity_Quad_Hexa:
+         gtype = tr( "HEXAHEDRON" ); break;
+       case SMDSEntity_Penta:
+       case SMDSEntity_Quad_Penta:
+         gtype = tr( "PRISM" ); break;
+       case SMDSEntity_Polyhedra:
+       case SMDSEntity_Quad_Polyhedra:
+         gtype = tr( "POLYHEDRON" ); break;
+       default: 
+         break;
+       }
+       if ( !gtype.isEmpty() ) {
+         QTreeWidgetItem* typeItem = createItem( elemItem, 0 );
+         typeItem->setText( 0, tr( "TYPE" ) );
+         typeItem->setText( 1, gtype );
+       }
+       // quadratic flag and gravity center (any element except 0D)
+       if ( e->GetEntityType() > SMDSEntity_0D && e->GetEntityType() < SMDSEntity_Last ) {
+         // quadratic flag
+         QTreeWidgetItem* quadItem = createItem( elemItem, 0 );
+         quadItem->setText( 0, tr( "QUADRATIC" ) );
+         quadItem->setText( 1, e->IsQuadratic() ? tr( "YES" ) : tr( "NO" ) );
+         // gravity center
+         XYZ gc = gravityCenter( e );
+         QTreeWidgetItem* gcItem = createItem( elemItem, 0 );
+         gcItem->setText( 0, tr( "GRAVITY_CENTER" ) );
+         gcItem->setExpanded( true );
+         QTreeWidgetItem* xItem = createItem( gcItem );
+         xItem->setText( 0, "X" );
+         xItem->setText( 1, QString::number( gc.x(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+         QTreeWidgetItem* yItem = createItem( gcItem );
+         yItem->setText( 0, "Y" );
+         yItem->setText( 1, QString::number( gc.y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+         QTreeWidgetItem* zItem = createItem( gcItem );
+         zItem->setText( 0, "Z" );
+         zItem->setText( 1, QString::number( gc.z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+       }
+       // connectivity
+       QTreeWidgetItem* conItem = createItem( elemItem, 0 );
+       conItem->setText( 0, tr( "CONNECTIVITY" ) );
+       conItem->setExpanded( true );
+       SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
+       for ( int idx = 1; nodeIt->more(); idx++ ) {
+         const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+         // node number and ID
+         QTreeWidgetItem* nodeItem = createItem( conItem, 0 );
+         nodeItem->setText( 0, QString( "%1 %2/%3" ).arg( tr( "NODE" ) ).arg( idx ).arg( e->NbNodes() ) );
+         nodeItem->setText( 1, QString( "#%1" ).arg( node->GetID() ) );
+         //nodeItem->setExpanded( true );
+         // node coordinates
+         QTreeWidgetItem* coordItem = createItem( nodeItem );
+         coordItem->setText( 0, tr( "COORDINATES" ) );
+         coordItem->setExpanded( true );
+         QTreeWidgetItem* xItem = createItem( coordItem );
+         xItem->setText( 0, "X" );
+         xItem->setText( 1, QString::number( node->X(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+         QTreeWidgetItem* yItem = createItem( coordItem );
+         yItem->setText( 0, "Y" );
+         yItem->setText( 1, QString::number( node->Y(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+         QTreeWidgetItem* zItem = createItem( coordItem );
+         zItem->setText( 0, "Z" );
+         zItem->setText( 1, QString::number( node->Z(), precision > 0 ? 'f' : 'g', qAbs( precision ) ) );
+         // node connectivity
+         QTreeWidgetItem* nconItem = createItem( nodeItem );
+         nconItem->setText( 0, tr( "CONNECTIVITY" ) );
+         nconItem->setExpanded( true );
+         Connectivity connectivity = nodeConnectivity( node );
+         if ( !connectivity.isEmpty() ) {
+           QString con = formatConnectivity( connectivity, SMDSAbs_0DElement );
+           if ( !con.isEmpty() ) {
+             QTreeWidgetItem* i = createItem( nconItem );
+             i->setText( 0, tr( "0D_ELEMENTS" ) );
+             i->setText( 1, con );
+           }
+           con = formatConnectivity( connectivity, SMDSAbs_Edge );
+           if ( !con.isEmpty() ) {
+             QTreeWidgetItem* i = createItem( nconItem );
+             i->setText( 0, tr( "EDGES" ) );
+             i->setText( 1, con );
+           }
+           con = formatConnectivity( connectivity, SMDSAbs_Face );
+           if ( !con.isEmpty() ) {
+             QTreeWidgetItem* i = createItem( nconItem );
+             i->setText( 0, tr( "FACES" ) );
+             i->setText( 1, con );
+           }
+           con = formatConnectivity( connectivity, SMDSAbs_Volume );
+           if ( !con.isEmpty() ) {
+             QTreeWidgetItem* i = createItem( nconItem );
+             i->setText( 0, tr( "VOLUMES" ) );
+             i->setText( 1, con );
+           }
+         }
+       }
       }
     }
   }
 }
 
 /*!
-  \brief Clear mesh element information widget
+  \brief Internal clean-up (reset widget)
 */
-void SMESHGUI_TreeElemInfo::clear()
+void SMESHGUI_TreeElemInfo::clearInternal()
 {
   myInfo->clear();
   myInfo->repaint();
@@ -1092,7 +1212,7 @@ SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page )
   myMode->addButton( new QRadioButton( tr( "ELEM_MODE" ), w ), ElemMode );
   myMode->button( NodeMode )->setChecked( true );
   myID = new QLineEdit( w );
-  myID->setValidator( new SMESHGUI_IdValidator( this, 1 ) );
+  myID->setValidator( new SMESHGUI_IdValidator( this ) );
 
   int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 );
   mode = qMin( 1, qMax( 0, mode ) );
@@ -1173,10 +1293,14 @@ void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO
        SMESH::GetNameOfSelectedElements( selector, IO, ID ) :
        SMESH::GetNameOfSelectedNodes( selector, IO, ID );
     }
-    if ( nb == 1 ) {
+    myElemInfo->setSource( myActor ) ;
+    if ( nb > 0 ) {
       myID->setText( ID.trimmed() );
-      myElemInfo->setSource( myActor ) ;
-      myElemInfo->showInfo( ID.toLong(), myMode->checkedId() == ElemMode );
+      QSet<long> ids;
+      QStringList idTxt = ID.split( " ", QString::SkipEmptyParts );
+      foreach ( ID, idTxt )
+       ids << ID.trimmed().toLong();
+      myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
     }
     else {
       myID->clear();
@@ -1247,15 +1371,15 @@ void SMESHGUI_MeshInfoDlg::updateSelection()
     }
   }
 
-  int oldID = myID->text().toLong();
+  QString oldID = myID->text().trimmed();
   SMESH_Actor* oldActor = myActor;
   myID->clear();
   
   connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) );
   updateInfo();
   
-  if ( oldActor == myActor && myActor && oldID ) {
-    myID->setText( QString::number( oldID ) );
+  if ( oldActor == myActor && myActor && !oldID.isEmpty() ) {
+    myID->setText( oldID );
     idChanged();
   }
 }
@@ -1328,10 +1452,21 @@ void SMESHGUI_MeshInfoDlg::idChanged()
   if ( myActor && selector ) {
     Handle(SALOME_InteractiveObject) IO = myActor->getIO();
     TColStd_MapOfInteger ID;
-    ID.Add( myID->text().toLong() );
+    QSet<long> ids;
+    QStringList idTxt = myID->text().split( " ", QString::SkipEmptyParts );
+    foreach ( QString tid, idTxt ) {
+      long id = tid.trimmed().toLong();
+      const SMDS_MeshElement* e = myMode->checkedId() == ElemMode ? 
+       myActor->GetObject()->GetMesh()->FindElement( id ) :
+       myActor->GetObject()->GetMesh()->FindNode( id );
+      if ( e ) {
+       ID.Add( id );
+       ids << id;
+      }
+    }
     selector->AddOrRemoveIndex( IO, ID, false );
     if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() )
       aViewWindow->highlight( IO, true, true );
-    myElemInfo->showInfo( myID->text().toLong(), myMode->checkedId() == ElemMode );
+    myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode );
   }
 }
index ae22e5ac0eb3947e95722d16d34c611d9550e74d..2028fb0507ee9d7e9514b7784036647819be3916 100644 (file)
@@ -32,6 +32,7 @@
 #include <QDialog>
 #include <QList>
 #include <QMap>
+#include <QSet>
 #include <QVector>
 
 #include <SALOMEconfig.h>
@@ -40,6 +41,7 @@
 class QButtonGroup;
 class QLabel;
 class QLineEdit;
+class QPushButton;
 class QTabWidget;
 class QTextBrowser;
 class QTreeWidget;
@@ -121,8 +123,9 @@ public:
   ~SMESHGUI_ElemInfo();
 
   void         setSource( SMESH_Actor* );
-  virtual void showInfo( long, bool );
-  virtual void clear() = 0;
+  void         showInfo( long, bool );
+  void         showInfo( QSet<long>, bool );
+  void         clear();
 
 protected:
   struct XYZ
@@ -137,14 +140,32 @@ protected:
   };
   typedef QMap< int, QList<int> > Connectivity;
 
+  QWidget*     frame() const;
+  SMESH_Actor* actor() const;
+  bool         isElements() const;
+
+  virtual void information( const QList<long>& ) = 0;
+  virtual void clearInternal();
+
   Connectivity nodeConnectivity( const SMDS_MeshNode* );
   QString      formatConnectivity( Connectivity, int );
   XYZ          gravityCenter( const SMDS_MeshElement* );
 
-protected:
-  SMESH_Actor* myActor;
-  long         myID;
-  int          myIsElement;
+private slots:
+  void         showPrevious();
+  void         showNext();
+  void         updateControls();
+
+private:
+  SMESH_Actor*     myActor;
+  QList<long>      myIDs;
+  int              myIsElement;
+  QWidget*         myFrame;
+  QWidget*         myExtra;
+  QLabel*          myCurrent;
+  QPushButton*     myPrev;
+  QPushButton*     myNext;
+  int              myIndex;
 };
 
 class SMESHGUI_EXPORT SMESHGUI_SimpleElemInfo : public SMESHGUI_ElemInfo
@@ -152,8 +173,9 @@ class SMESHGUI_EXPORT SMESHGUI_SimpleElemInfo : public SMESHGUI_ElemInfo
 public:
   SMESHGUI_SimpleElemInfo( QWidget* = 0 );
 
-  void          showInfo( long, bool );
-  void          clear();
+protected:
+  void          information( const QList<long>& );
+  void          clearInternal();
 
 private:
   QTextBrowser* myInfo;
@@ -166,8 +188,9 @@ class SMESHGUI_EXPORT SMESHGUI_TreeElemInfo : public SMESHGUI_ElemInfo
 public:
   SMESHGUI_TreeElemInfo( QWidget* = 0 );
 
-  void             showInfo( long, bool );
-  void             clear();
+protected:
+  void             information( const QList<long>& );
+  void             clearInternal();
 
 private:
   QTreeWidgetItem* createItem( QTreeWidgetItem* = 0, int = 100 );
index 43640501edc55d560f353831905bbacb412253f6..b1f9284c6497d6276433710b5d935f51611772ad 100644 (file)
@@ -418,7 +418,7 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI*
   }
   
   QColor distributionColor = mgr->colorValue("SMESH", "distribution_color",
-                                            QColor(255, 255, 255));
+                                             QColor(255, 255, 255));
   myMonoColorBtn->setColor(distributionColor);
   
   
@@ -509,18 +509,6 @@ bool SMESHGUI_Preferences_ScalarBarDlg::onApply()
   myScalarBarActor->SetLabelTextProperty( aLabelsTextPrp );
 
   myScalarBarActor->SetNumberOfLabels( myLabelsSpin->value() );
-  if( myColorsSpin->value() != myScalarBarActor->GetMaximumNumberOfColors() ) {
-    myScalarBarActor->SetMaximumNumberOfColors( myColorsSpin->value() );
-    SMESH::Controls::FunctorPtr fn = myActor->GetFunctor();       
-    SMESH::Controls::NumericalFunctor* aNumericalFunctor = dynamic_cast<SMESH::Controls::NumericalFunctor*>(fn.get());
-    if( aNumericalFunctor ) {
-      int nbIntervals = myColorsSpin->value();
-      std::vector<int> nbEvents;
-      std::vector<double> funValues;
-      aNumericalFunctor->GetHistogram(nbIntervals, nbEvents, funValues);
-      myScalarBarActor->SetDistribution(nbEvents);
-    }
-  }
 
   if ( myHorizRadioBtn->isChecked() )
     myScalarBarActor->SetOrientationToHorizontal();
@@ -550,9 +538,22 @@ bool SMESHGUI_Preferences_ScalarBarDlg::onApply()
   double aMax = myMaxEdit->text().toDouble();
   vtkLookupTable* myLookupTable =
     static_cast<vtkLookupTable*>(myScalarBarActor->GetLookupTable());
+  double oldMinMax[2] = { myLookupTable->GetRange()[0], myLookupTable->GetRange()[1] };
+  bool rangeChanges = ( fabs( oldMinMax[0] - aMin ) + fabs( oldMinMax[1] - aMax ) >
+                        0.001 * ( aMax-aMin + oldMinMax[1]-oldMinMax[0] ));
+  
+  bool nbColorsChanged = (myColorsSpin->value() != myScalarBarActor->GetMaximumNumberOfColors());
+  if(nbColorsChanged)
+    myScalarBarActor->SetMaximumNumberOfColors(myColorsSpin->value());
+  
+
   myLookupTable->SetRange( aMin, aMax );
   myLookupTable->SetNumberOfTableValues(myColorsSpin->value());
   myLookupTable->Build();
+
+  if( nbColorsChanged || rangeChanges)
+    myActor->UpdateDistribution();
+
   SMESH::RepaintCurrentView();
   return true;
 }
@@ -655,17 +656,17 @@ void SMESHGUI_Preferences_ScalarBarDlg::onSelectionChanged()
         myIniH = myScalarBarActor->GetHeight();
         setOriginAndSize( myIniX, myIniY, myIniW, myIniH );
 
-       myDistributionGrp->setChecked((bool)myScalarBarActor->GetDistributionVisibility());
-       int coloringType = myScalarBarActor->GetDistributionColoringType();
-       myScalarBarActor->GetDistributionColor( aTColor );
-       myMonoColorBtn->setColor( QColor( (int)( aTColor[0]*255 ), (int)( aTColor[1]*255 ), (int)( aTColor[2]*255 ) ) );
-       if ( coloringType == SMESH_MONOCOLOR_TYPE ) {
-         myDMonoColor->setChecked(true);
-         onDistributionChanged(myDistribColorGrp->id(myDMonoColor));    
-       } else {
-         myDMultiColor->setChecked(true);
-         onDistributionChanged(myDistribColorGrp->id(myDMultiColor));
-       }
+        myDistributionGrp->setChecked((bool)myScalarBarActor->GetDistributionVisibility());
+        int coloringType = myScalarBarActor->GetDistributionColoringType();
+        myScalarBarActor->GetDistributionColor( aTColor );
+        myMonoColorBtn->setColor( QColor( (int)( aTColor[0]*255 ), (int)( aTColor[1]*255 ), (int)( aTColor[2]*255 ) ) );
+        if ( coloringType == SMESH_MONOCOLOR_TYPE ) {
+          myDMonoColor->setChecked(true);
+          onDistributionChanged(myDistribColorGrp->id(myDMonoColor));    
+        } else {
+          myDMultiColor->setChecked(true);
+          onDistributionChanged(myDistribColorGrp->id(myDMultiColor));
+        }
         myRangeGrp->setEnabled( true );
         myFontGrp->setEnabled( true );
         myLabColorGrp->setEnabled( true );
index dfe7788315b6dea065c0b093f302042cc2b26d0b..331ad9f9272a721c1167208d54e797b7206df791 100644 (file)
@@ -214,7 +214,7 @@ namespace SMESH
       QString IOR = app->orb()->object_to_string( theObject );
       SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
       if ( study && !IOR.isEmpty() )
-       res = study->studyDS()->FindObjectIOR( IOR.toLatin1().constData() );
+        res = study->studyDS()->FindObjectIOR( IOR.toLatin1().constData() );
     }
     return res;
   }
index 856e88f32740868bc79b378612eac71dfd14f826..3eff547c5602ab4a03b97bf174cf13923f2b2571 100644 (file)
             <source>ICON_BUILD_COMPOUND</source>
             <translation>mesh_build_compound.png</translation>
         </message>
+        <message>
+            <source>ICON_COPY_MESH</source>
+            <translation>copy_mesh.png</translation>
+        </message>
         <message>
             <source>ICON_COMPUTE</source>
             <translation>mesh_compute.png</translation>
             <source>ICON_DLG_BUILD_COMPOUND_MESH</source>
             <translation>mesh_build_compound.png</translation>
         </message>
+        <message>
+            <source>ICON_DLG_COPY_MESH</source>
+            <translation>copy_mesh.png</translation>
+        </message>
         <message>
             <source>ICON_DLG_ELEM0D</source>
             <translation>mesh_vertex.png</translation>
             <source>ICON_VOLUME_3D</source>
             <translation>mesh_volume_3d.png</translation>
         </message>
+        <message>
+            <source>ICON_BARE_BORDER_VOLUME</source>
+            <translation>bare_border_volume.png</translation>
+        </message>
+        <message>
+            <source>ICON_BARE_BORDER_FACE</source>
+            <translation>bare_border_face.png</translation>
+        </message>
+        <message>
+            <source>ICON_OVER_CONSTRAINED_VOLUME</source>
+            <translation>over_constrained_volume.png</translation>
+        </message>
+        <message>
+            <source>ICON_OVER_CONSTRAINED_FACE</source>
+            <translation>over_constrained_face.png</translation>
+        </message>
         <message>
             <source>ICON_WARP</source>
             <translation>mesh_wrap.png</translation>
index 81e2619ee9592bd1cf799350dd141d950ff5f204..9352f1cef4a60f6e56de92142a69e405859a163b 100644 (file)
         <source>MEN_BUILD_COMPOUND</source>
         <translation>Build Compound</translation>
     </message>
+    <message>
+        <source>MEN_COPY_MESH</source>
+        <translation>Copy Mesh</translation>
+    </message>
     <message>
         <source>MEN_CLIP</source>
         <translation>Clipping</translation>
         <source>STB_FIND_ELEM</source>
         <translation>Find Element by Point</translation>
     </message>
+    <message>
+        <source>MEN_BARE_BORDER_VOLUME</source>
+        <translation>Volumes with bare border</translation>
+    </message>
+    <message>
+        <source>MEN_BARE_BORDER_FACE</source>
+        <translation>Faces with bare border</translation>
+    </message>
+    <message>
+        <source>MEN_OVER_CONSTRAINED_VOLUME</source>
+        <translation>Over-constrained volumes</translation>
+    </message>
+    <message>
+        <source>MEN_OVER_CONSTRAINED_FACE</source>
+        <translation>Over-constrained faces</translation>
+    </message>
     <message>
         <source>MEN_FREE_BORDER</source>
         <translation>Free Borders</translation>
@@ -1040,6 +1060,14 @@ Please enter correct values and try again</translation>
         <source>SMESH_BUILD_COMPOUND_TITLE</source>
         <translation>Create a Compound</translation>
     </message>
+    <message>
+        <source>SMESH_COPY_MESH_TITLE</source>
+        <translation>Copy Mesh</translation>
+    </message>
+    <message>
+        <source>SMESH_KEEP_IDS</source>
+        <translation>Preserve IDs of elements</translation>
+    </message>
     <message>
         <source>SMESH_BUT_ADD</source>
         <translation>A&amp;dd</translation>
@@ -1451,7 +1479,8 @@ add the exported data to its contents?</translation>
     </message>
     <message>
         <source>SMESH_HYP_12</source>
-        <translation>Geometry mismatches algorithm&apos;s expectation\nCheck algorithm documentation for supported geometry</translation>
+        <translation>Geometry mismatches algorithm&apos;s expectation
+Check algorithm documentation for supported geometry</translation>
     </message>
     <message>
         <source>SMESH_HYP_13</source>
@@ -2101,7 +2130,7 @@ add the exported data to its contents?</translation>
     <message>
         <source>SMESH_VERTICAL</source>
         <translation>Vertical</translation>
-    </message>    
+    </message>
     <message>
         <source>SMESH_DISTRIBUTION_COLORING_TYPE</source>
         <translation>Coloring Type</translation>
@@ -2274,6 +2303,10 @@ Please check preferences of Mesh module.
         <source>STB_BUILD_COMPOUND</source>
         <translation>Build Compound Mesh</translation>
     </message>
+    <message>
+        <source>STB_COPY_MESH</source>
+        <translation>Copy Mesh</translation>
+    </message>
     <message>
         <source>STB_CLIP</source>
         <translation>Clipping</translation>
@@ -2434,6 +2467,22 @@ Please check preferences of Mesh module.
         <source>STB_FACES</source>
         <translation>Faces</translation>
     </message>
+    <message>
+        <source>STB_BARE_BORDER_VOLUME</source>
+        <translation>Volumes with bare border</translation>
+    </message>
+    <message>
+        <source>STB_BARE_BORDER_FACE</source>
+        <translation>Faces with bare border</translation>
+    </message>
+    <message>
+        <source>STB_OVER_CONSTRAINED_VOLUME</source>
+        <translation>Over-constrained volumes</translation>
+    </message>
+    <message>
+        <source>STB_OVER_CONSTRAINED_FACE</source>
+        <translation>Over-constrained faces</translation>
+    </message>
     <message>
         <source>STB_FREE_BORDER</source>
         <translation>Free Borders</translation>
@@ -2614,7 +2663,7 @@ Please check preferences of Mesh module.
         <source>STB_SAVE_DISTRIBUTION</source>
         <translation>Save distribution to the file</translation>
     </message>
-        <message>
+    <message>
         <source>STB_SHOW_DISTRIBUTION</source>
         <translation>Show Distribution</translation>
     </message>
@@ -2810,6 +2859,10 @@ Please check preferences of Mesh module.
         <source>TOP_BUILD_COMPOUND</source>
         <translation>Build Compound Mesh</translation>
     </message>
+    <message>
+        <source>TOP_COPY_MESH</source>
+        <translation>Copy Mesh</translation>
+    </message>
     <message>
         <source>TOP_CLIP</source>
         <translation>Clipping</translation>
@@ -2970,6 +3023,22 @@ Please check preferences of Mesh module.
         <source>TOP_FACES</source>
         <translation>Faces</translation>
     </message>
+    <message>
+        <source>TOP_BARE_BORDER_VOLUME</source>
+        <translation>Volumes with bare border</translation>
+    </message>
+    <message>
+        <source>TOP_BARE_BORDER_FACE</source>
+        <translation>Faces with bare border</translation>
+    </message>
+    <message>
+        <source>TOP_OVER_CONSTRAINED_VOLUME</source>
+        <translation>Over-constrained volumes</translation>
+    </message>
+    <message>
+        <source>TOP_OVER_CONSTRAINED_FACE</source>
+        <translation>Over-constrained faces</translation>
+    </message>
     <message>
         <source>TOP_FREE_BORDER</source>
         <translation>Free Borders</translation>
@@ -3399,7 +3468,7 @@ Input value precision can be adjusted using
     <message>
         <source>SMESH_PLUGINS_OTHER</source>
         <translation>SMESH plugins</translation>
-    </message>  
+    </message>
 </context>
 <context>
     <name>SMESHGUI</name>
@@ -3565,7 +3634,7 @@ Please, create VTK viewer and try again</translation>
         <translation>Mesh information</translation>
     </message>
     <message>
-      <source>PREF_HIGHLIGHT_COLOR</source>
+        <source>PREF_HIGHLIGHT_COLOR</source>
         <translation>Highlight color</translation>
     </message>
     <message>
@@ -4320,6 +4389,22 @@ Please check input data and try again</translation>
         <source>BAD_ORIENTED_VOLUME</source>
         <translation>Bad oriented volume</translation>
     </message>
+    <message>
+        <source>BARE_BORDER_VOLUME</source>
+        <translation>Volumes with bare border</translation>
+    </message>
+    <message>
+        <source>BARE_BORDER_FACE</source>
+        <translation>Faces with bare border</translation>
+    </message>
+    <message>
+        <source>OVER_CONSTRAINED_VOLUME</source>
+        <translation>Over-constrained volumes</translation>
+    </message>
+    <message>
+        <source>OVER_CONSTRAINED_FACE</source>
+        <translation>Over-constrained faces</translation>
+    </message>
     <message>
         <source>BELONG_TO_CYLINDER</source>
         <translation>Belong to Cylinder</translation>
@@ -5607,7 +5692,7 @@ It is impossible to read point coordinates from file</translation>
     </message>
     <message>
         <source>QUADRANGLES_LAB</source>
-        <translation>Quadrandgles:</translation>
+        <translation>Quadrangles:</translation>
     </message>
     <message>
         <source>POLYGONS_LAB</source>
@@ -5795,10 +5880,6 @@ It is impossible to read point coordinates from file</translation>
         <source>NO</source>
         <translation>No</translation>
     </message>
-    <message>
-        <source>GRAVITY_CENTER</source>
-        <translation>GRAVITY CENTER</translation>
-    </message>
     <message>
         <source>PROPERTY</source>
         <translation>Property</translation>
@@ -5807,6 +5888,10 @@ It is impossible to read point coordinates from file</translation>
         <source>VALUE</source>
         <translation>Value</translation>
     </message>
+    <message>
+        <source>X_FROM_Y_ITEMS_SHOWN</source>
+        <translation>%1-%2 from %3 items shown</translation>
+    </message>
 </context>
 <context>
     <name>SMESHGUI_MinDistance</name>
@@ -5847,6 +5932,21 @@ It is impossible to read point coordinates from file</translation>
         <translation>Distance</translation>
     </message>
 </context>
+<context>
+    <name>SMESHGUI_CopyMeshDlg</name>
+    <message>
+        <source>OBJECT_NAME</source>
+        <translation>Source Object</translation>
+    </message>
+    <message>
+        <source>ELEM_IDS</source>
+        <translation>Source Element IDs</translation>
+    </message>
+    <message>
+        <source>NEW_NAME</source>
+        <translation>New Mesh Name</translation>
+    </message>
+</context>
 <context>
     <name>SMESHGUI_MeasureDlg</name>
     <message>
index 955e9396bbefa98a849e848400adb90826e74768..7ebd1df628976a247547740e9e6b0d7abd228129 100755 (executable)
@@ -3,6 +3,42 @@
 <TS version="2.0" language="fr_FR">
 <context>
     <name>@default</name>
+    <message>
+        <source>SMESH_EXPORT_MESH</source>
+        <translation>Exporter le maillage</translation>
+    </message>
+    <message>
+        <source>MED_FILES_FILTER</source>
+        <translation>Fichiers MED</translation>
+    </message>
+    <message>
+        <source>IDEAS_FILES_FILTER</source>
+        <translation>Fichiers IDEAS</translation>
+    </message>
+    <message>
+        <source>DAT_FILES_FILTER</source>
+        <translation>Fichiers DAT</translation>
+    </message>
+    <message>
+        <source>TEXT_FILES_FILTER</source>
+        <translation>Fichiers TXT</translation>
+    </message>
+    <message>
+        <source>MED_VX_FILES_FILTER</source>
+        <translation>Fichiers MED %1</translation>
+    </message>
+    <message>
+        <source>STL_ASCII_FILES_FILTER</source>
+        <translation>Fichiers STL ASCII</translation>
+    </message>
+    <message>
+        <source>STL_BIN_FILES_FILTER</source>
+        <translation>Fichiers STL binaires</translation>
+    </message>
+    <message>
+        <source>ALL_FILES_FILTER</source>
+        <translation>Tous les fichiers</translation>
+    </message>
     <message>
         <source>AREA_ELEMENTS</source>
         <translation>Aire</translation>
         <source>LOCAL_ALGO</source>
         <translation>Local</translation>
     </message>
+    <message>
+        <source>MAX_ELEMENT_LENGTH_2D</source>
+        <translation>Diamètre d&apos;éléments 2D</translation>
+    </message>
+    <message>
+        <source>MAX_ELEMENT_LENGTH_3D</source>
+        <translation>Diamètre d&apos;éléments 3D</translation>
+    </message>
     <message>
         <source>MEN_ADD</source>
         <translation>Ajouter</translation>
         <source>MEN_BUILD_COMPOUND</source>
         <translation>Construire un assemblage</translation>
     </message>
+    <message>
+        <source>MEN_COPY_MESH</source>
+        <translation>Copier le maillage</translation>
+    </message>
     <message>
         <source>MEN_CLIP</source>
         <translation>Plan de coupe</translation>
         <source>MEN_CTRL</source>
         <translation>Contrôles</translation>
     </message>
+    <message>
+        <source>MEN_NODE_CTRL</source>
+        <translation>Contrôles des nÅ“uds</translation>
+    </message>
+    <message>
+        <source>MEN_EDGE_CTRL</source>
+        <translation>Contrôles des arêtes</translation>
+    </message>
+    <message>
+        <source>MEN_FACE_CTRL</source>
+        <translation>Contrôles des faces</translation>
+    </message>
+    <message>
+        <source>MEN_VOLUME_CTRL</source>
+        <translation>Contrôles des volumes</translation>
+    </message>
     <message>
         <source>MEN_CUT</source>
         <translation>Découpe des quadrangles</translation>
     </message>
     <message>
         <source>MEN_DISPLAY_ONLY</source>
-       <translation>Afficher uniquement</translation>
+        <translation>Afficher uniquement</translation>
     </message>
     <message>
         <source>MEN_DISPMODE</source>
         <source>STB_FIND_ELEM</source>
         <translation>Trouver un Ã©lément par un point</translation>
     </message>
+    <message>
+        <source>MEN_BARE_BORDER_VOLUME</source>
+        <translation>Volumes avec frontière libre</translation>
+    </message>
+    <message>
+        <source>MEN_BARE_BORDER_FACE</source>
+        <translation>Faces avec frontière libre</translation>
+    </message>
+    <message>
+        <source>MEN_OVER_CONSTRAINED_VOLUME</source>
+        <translation>Volumes sur-contraints</translation>
+    </message>
+    <message>
+        <source>MEN_OVER_CONSTRAINED_FACE</source>
+        <translation>Faces sur-contraintes</translation>
+    </message>
     <message>
         <source>MEN_FREE_BORDER</source>
         <translation>Frontières libres</translation>
         <source>MEN_MAP</source>
         <translation>Projection de motif</translation>
     </message>
+    <message>
+        <source>MEN_MAX_ELEMENT_LENGTH_2D</source>
+        <translation>Diamètre des Ã©léments 2D</translation>
+    </message>
+    <message>
+        <source>MEN_MAX_ELEMENT_LENGTH_3D</source>
+        <translation>Diamètre des Ã©léments 3D</translation>
+    </message>
     <message>
         <source>MEN_MED</source>
         <translation>Fichier MED</translation>
         <source>MEN_MODIFY</source>
         <translation>Modification</translation>
     </message>
+    <message>
+        <source>MEN_MEASURE</source>
+        <translation>Outils de mesure</translation>
+    </message>
+    <message>
+        <source>MEN_MEASURE_MIN_DIST</source>
+        <translation>Distance minimale</translation>
+    </message>
+    <message>
+        <source>STB_MEASURE_MIN_DIST</source>
+        <translation>Calculate minimum distance between two objects</translation>
+    </message>
+    <message>
+        <source>TOP_MEASURE_MIN_DIST</source>
+        <translation>Minimum distance</translation>
+    </message>
+    <message>
+        <source>MEN_MEASURE_BND_BOX</source>
+        <translation>Boîte englobante</translation>
+    </message>
+    <message>
+        <source>STB_MEASURE_BND_BOX</source>
+        <translation>Calculate bounding box for the selected object(s)</translation>
+    </message>
+    <message>
+        <source>TOP_MEASURE_BND_BOX</source>
+        <translation>Bounding box</translation>
+    </message>
     <message>
         <source>MEN_MOVE</source>
         <translation>Déplacer un nÅ“ud</translation>
         <source>MEN_RESET</source>
         <translation>Restaurer</translation>
     </message>
+    <message>
+        <source>MEN_SAVE_DISTRIBUTION</source>
+        <translation>Exporter la distribution...</translation>
+    </message>
+    <message>
+        <source>MEN_SHOW_DISTRIBUTION</source>
+        <translation>Afficher la distribution</translation>
+    </message>
     <message>
         <source>MEN_REVOLUTION</source>
         <translation>Révolution</translation>
@@ -936,6 +1060,14 @@ Merci de les corriger, puis essayez de nouveau</translation>
         <source>SMESH_BUILD_COMPOUND_TITLE</source>
         <translation>Créer un assemblage</translation>
     </message>
+    <message>
+        <source>SMESH_COPY_MESH_TITLE</source>
+        <translation>Copier le maillage</translation>
+    </message>
+    <message>
+        <source>SMESH_KEEP_IDS</source>
+        <translation>Conserver les IDs des Ã©léments</translation>
+    </message>
     <message>
         <source>SMESH_BUT_ADD</source>
         <translation>A&amp;jouter</translation>
@@ -1200,13 +1332,15 @@ Voulez-vous continuer ?</translation>
     </message>
     <message>
         <source>SMESH_EXPORT_MED_V2_1</source>
-        <translation>Les Ã©léments polygonaux et polyèdriques seront omis dans le cas d&apos;exportation du maillage &quot;%1&quot; Ã  MED 2.1
+        <translation>Les Ã©léments polygonaux et polyèdriques seront omis 
+dans le cas d&apos;exportation du maillage &quot;%1&quot; Ã  MED 2.1
 Utilisez MED 2.2 pour l&apos;exportation correcte.
 Voulez-vous effectuer l&apos;exportation Ã  MED 2.1 ?</translation>
     </message>
     <message>
         <source>SMESH_EXPORT_MED_VERSION_COLLISION</source>
-        <translation>La version MED du fichier &quot;%1&quot; n&apos;est pas connue ou ne correspond pas Ã  la version choisie.
+        <translation>La version MED du fichier &quot;%1&quot; n&apos;est pas connue 
+ou ne correspond pas Ã  la version choisie.
 Réécrire le fichier ?</translation>
     </message>
     <message>
@@ -1226,7 +1360,8 @@ Réécrire le fichier ?</translation>
     </message>
     <message>
         <source>SMESH_EXPORT_UNV</source>
-        <translation>Les Ã©léments pyramides seront omis au cours de l&apos;exportation du maillage &quot;%1&quot; dans le fichier UNV</translation>
+        <translation>Les Ã©léments pyramides seront omis au cours de l&apos;exportation 
+du maillage &quot;%1&quot; dans le fichier UNV</translation>
     </message>
     <message>
         <source>SMESH_EXTRUSION</source>
@@ -1255,7 +1390,8 @@ Réécrire le fichier ?</translation>
     <message>
         <source>SMESH_FILE_EXISTS</source>
         <translation>Le fichier &quot;%1&quot; existe déjà.
-Voulez-vous le réécrire ou y ajouter les données exportées ?</translation>
+Voulez-vous le réécrire ou y ajouter 
+les données exportées ?</translation>
     </message>
     <message>
         <source>SMESH_FONT_ARIAL</source>
@@ -1742,6 +1878,14 @@ Référez-vous Ã  la documentation sur l&apos;algorithme et la géométrie suppo
         <source>SMESH_POSITION_SIZE_SCALARBAR</source>
         <translation>Origine &amp;&amp; Taille</translation>
     </message>
+    <message>
+        <source>SMESH_DISTRIBUTION_SCALARBAR</source>
+        <translation>Distribution</translation>
+    </message>
+    <message>
+        <source>SMESH_SHOW_DISTRIBUTION_SCALARBAR</source>
+        <translation>Afficher la distribution</translation>
+    </message>
     <message>
         <source>SMESH_PRECISION</source>
         <translation>Précision</translation>
@@ -1987,6 +2131,22 @@ Référez-vous Ã  la documentation sur l&apos;algorithme et la géométrie suppo
         <source>SMESH_VERTICAL</source>
         <translation>Verticale</translation>
     </message>
+    <message>
+        <source>SMESH_DISTRIBUTION_COLORING_TYPE</source>
+        <translation>Type de coloration</translation>
+    </message>
+    <message>
+        <source>SMESH_MONOCOLOR</source>
+        <translation>Monocouleur</translation>
+    </message>
+    <message>
+        <source>SMESH_DISTRIBUTION_COLOR</source>
+        <translation>Couleur de la distribution:</translation>
+    </message>
+    <message>
+        <source>SMESH_MULTICOLOR</source>
+        <translation>Multicouleur</translation>
+    </message>
     <message>
         <source>SMESH_VISU_PROBLEM</source>
         <translation>Impossible de visualiser le maillage, probablement Ã  cause d&apos;un manque de mémoire</translation>
@@ -2143,6 +2303,10 @@ Vérifiez la limite dans les préférences du module Mesh.
         <source>STB_BUILD_COMPOUND</source>
         <translation>Construire un maillage assemblé</translation>
     </message>
+    <message>
+        <source>STB_COPY_MESH</source>
+        <translation>Copie le maillage</translation>
+    </message>
     <message>
         <source>STB_CLIP</source>
         <translation>Pan de coupe</translation>
@@ -2823,6 +2987,22 @@ Vérifiez la limite dans les préférences du module Mesh.
         <source>TOP_FACES</source>
         <translation>Faces</translation>
     </message>
+    <message>
+        <source>TOP_BARE_BORDER_VOLUME</source>
+        <translation>Volumes avec frontière libre</translation>
+    </message>
+    <message>
+        <source>TOP_BARE_BORDER_FACE</source>
+        <translation>Faces avec frontière libre</translation>
+    </message>
+    <message>
+        <source>TOP_OVER_CONSTRAINED_VOLUME</source>
+        <translation>Volumes sur-contraints</translation>
+    </message>
+    <message>
+        <source>TOP_OVER_CONSTRAINED_FACE</source>
+        <translation>Faces sur-contraintes</translation>
+    </message>
     <message>
         <source>TOP_FREE_BORDER</source>
         <translation>Frontières libres</translation>
@@ -2871,6 +3051,14 @@ Vérifiez la limite dans les préférences du module Mesh.
         <source>TOP_MAP</source>
         <translation>Projection de motif</translation>
     </message>
+    <message>
+        <source>TOP_MAX_ELEMENT_LENGTH_2D</source>
+        <translation>Diamètre des Ã©léments 2D</translation>
+    </message>
+    <message>
+        <source>TOP_MAX_ELEMENT_LENGTH_3D</source>
+        <translation>Diamètre des Ã©léments 3D</translation>
+    </message>
     <message>
         <source>TOP_MED</source>
         <translation>Importer un fichier MED</translation>
@@ -2991,6 +3179,14 @@ Vérifiez la limite dans les préférences du module Mesh.
         <source>TOP_RESET</source>
         <translation>Restaurer</translation>
     </message>
+    <message>
+        <source>TOP_SAVE_DISTRIBUTION</source>
+        <translation>Exporter la distribution</translation>
+    </message>
+    <message>
+        <source>TOP_SHOW_DISTRIBUTION</source>
+        <translation>Afficher la distribution</translation>
+    </message>
     <message>
         <source>TOP_REVOLUTION</source>
         <translation>Révolution</translation>
@@ -3123,6 +3319,10 @@ Vérifiez la limite dans les préférences du module Mesh.
         <source>TOP_WIRE</source>
         <translation>Contours</translation>
     </message>
+    <message>
+        <source>UNKNOWN_CONTROL</source>
+        <translation>Inconnu</translation>
+    </message>
     <message>
         <source>VOLUME_3D_ELEMENTS</source>
         <translation>Aire</translation>
@@ -3225,10 +3425,14 @@ avec le paramètre &apos;%1&apos; des préférences du module Mesh.</translation
         <source>NB_NODES_REMOVED</source>
         <translation>%1 nÅ“ud(s) supprimés.</translation>
     </message>
+    <message>
+        <source>SMESH_SAVE_DISTRIBUTION</source>
+        <translation>Exporter la distribution</translation>
+    </message>
     <message>
         <source>SMESH_PLUGINS_OTHER</source>
         <translation>Extensions SMESH</translation>
-    </message>   
+    </message>
 </context>
 <context>
     <name>SMESHGUI</name>
@@ -3317,6 +3521,30 @@ Ouvrez une fenêtre VTK et essayez de nouveau</translation>
         <source>PREF_NOTIFY_MODE</source>
         <translation>Montrer la notification sur le résultat de calcul</translation>
     </message>
+    <message>
+        <source>PREF_NOTIFY_NEVER</source>
+        <translation>Jamais</translation>
+    </message>
+    <message>
+        <source>PREF_NOTIFY_ERROR</source>
+        <translation>Erreurs uniquement</translation>
+    </message>
+    <message>
+        <source>PREF_NOTIFY_ALWAYS</source>
+        <translation>Toujours</translation>
+    </message>
+    <message>
+        <source>PREF_ELEM_INFO</source>
+        <translation>Information des Ã©léments du maillage</translation>
+    </message>
+    <message>
+        <source>PREF_ELEM_INFO_SIMPLE</source>
+        <translation>Simple</translation>
+    </message>
+    <message>
+        <source>PREF_ELEM_INFO_TREE</source>
+        <translation>Arbre</translation>
+    </message>
     <message>
         <source>SMESH_PREF_GROUP_PRECISION</source>
         <translation>Précision des champs d&apos;entrée</translation>
@@ -3365,6 +3593,10 @@ Ouvrez une fenêtre VTK et essayez de nouveau</translation>
         <source>PREF_GROUP_SELECTION</source>
         <translation>Sélection</translation>
     </message>
+    <message>
+        <source>PREF_GROUP_INFO</source>
+        <translation>Information du maillage</translation>
+    </message>
     <message>
         <source>PREF_HIGHLIGHT_COLOR</source>
         <translation>Couleur de sélection</translation>
@@ -4121,6 +4353,22 @@ Vérifiez la validité des informations données</translation>
         <source>BAD_ORIENTED_VOLUME</source>
         <translation>Volume mal orienté</translation>
     </message>
+    <message>
+        <source>BARE_BORDER_VOLUME</source>
+        <translation>Volumes avec frontière libre</translation>
+    </message>
+    <message>
+        <source>BARE_BORDER_FACE</source>
+        <translation>Faces avec frontière libre</translation>
+    </message>
+    <message>
+        <source>OVER_CONSTRAINED_VOLUME</source>
+        <translation>Volumes sur-contraints</translation>
+    </message>
+    <message>
+        <source>OVER_CONSTRAINED_FACE</source>
+        <translation>Faces sur-contraintes</translation>
+    </message>
     <message>
         <source>BELONG_TO_CYLINDER</source>
         <translation>Appartient au cylindre</translation>
@@ -5173,6 +5421,14 @@ Il y a trop peu de points dans le fichier </translation>
         <source>CLIP_PLANES</source>
         <translation>Plans de découpe</translation>
     </message>
+    <message>
+        <source>MESHES_SUBMESHES_GROUPS</source>
+        <translation>Maillages, sous-maillages et groupes</translation>
+    </message>
+    <message>
+        <source>SELECT_ALL</source>
+        <translation>Tout sélectionner</translation>
+    </message>
     <message>
         <source>ROTATION_AROUND_X_Y2Z</source>
         <translation>Rotation autour de X (Y Ã  Z):</translation>
@@ -5343,4 +5599,361 @@ Il y a trop peu de points dans le fichier </translation>
         <translation>Le nom du groupe n&apos;est pas indiqué</translation>
     </message>
 </context>
+<context>
+    <name>SMESHGUI_MeshInfo</name>
+    <message>
+        <source>NAME_LAB</source>
+        <translation>Nom:</translation>
+    </message>
+    <message>
+        <source>OBJECT_LAB</source>
+        <translation>Objet:</translation>
+    </message>
+    <message>
+        <source>NODES_LAB</source>
+        <translation>NÅ“uds:</translation>
+    </message>
+    <message>
+        <source>ELEMENTS_LAB</source>
+        <translation>Eléments:</translation>
+    </message>
+    <message>
+        <source>TOTAL_LAB</source>
+        <translation>Total</translation>
+    </message>
+    <message>
+        <source>LINEAR_LAB</source>
+        <translation>Linéaire</translation>
+    </message>
+    <message>
+        <source>QUADRATIC_LAB</source>
+        <translation>Quadratique</translation>
+    </message>
+    <message>
+        <source>0D_LAB</source>
+        <translation>0D:</translation>
+    </message>
+    <message>
+        <source>1D_LAB</source>
+        <translation>1D (arêtes):</translation>
+    </message>
+    <message>
+        <source>2D_LAB</source>
+        <translation>2D (faces):</translation>
+    </message>
+    <message>
+        <source>TRIANGLES_LAB</source>
+        <translation>Triangles:</translation>
+    </message>
+    <message>
+        <source>QUADRANGLES_LAB</source>
+        <translation>Quadrangles:</translation>
+    </message>
+    <message>
+        <source>POLYGONS_LAB</source>
+        <translation>Polygones:</translation>
+    </message>
+    <message>
+        <source>3D_LAB</source>
+        <translation>3D (volumes):</translation>
+    </message>
+    <message>
+        <source>TETRAHEDRONS_LAB</source>
+        <translation>Tétrahédrons:</translation>
+    </message>
+    <message>
+        <source>HEXAHEDONRS_LAB</source>
+        <translation>Hexahédrons:</translation>
+    </message>
+    <message>
+        <source>PYRAMIDS_LAB</source>
+        <translation>Pyramides:</translation>
+    </message>
+    <message>
+        <source>PRISMS_LAB</source>
+        <translation>Prismes:</translation>
+    </message>
+    <message>
+        <source>POLYHEDRONS_LAB</source>
+        <translation>Polyhédrons:</translation>
+    </message>
+    <message>
+        <source>OBJECT_MESH</source>
+        <translation>Maillage</translation>
+    </message>
+    <message>
+        <source>OBJECT_SUBMESH</source>
+        <translation>Sous-maillage</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP</source>
+        <translation>Groupe</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP_NODES</source>
+        <translation>Groupe de nÅ“uds</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP_EDGES</source>
+        <translation>Groupe d&apos;arêtes</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP_FACES</source>
+        <translation>Groupe de faces</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP_VOLUMES</source>
+        <translation>Groupe de volumes</translation>
+    </message>
+    <message>
+        <source>OBJECT_GROUP_0DELEMS</source>
+        <translation>Groupe d&apos;éléments 0D</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeshInfoDlg</name>
+    <message>
+        <source>MESH_INFO</source>
+        <translation>Infiormations de maillage</translation>
+    </message>
+    <message>
+        <source>BASE_INFO</source>
+        <translation>Informations de base</translation>
+    </message>
+    <message>
+        <source>ELEM_INFO</source>
+        <translation>Informations des Ã©léments</translation>
+    </message>
+    <message>
+        <source>NODE_MODE</source>
+        <translation>NÅ“ud</translation>
+    </message>
+    <message>
+        <source>ELEM_MODE</source>
+        <translation>Elément</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_ElemInfo</name>
+    <message>
+        <source>COORDINATES</source>
+        <translation>COORDONNÉES</translation>
+    </message>
+    <message>
+        <source>CONNECTIVITY</source>
+        <translation>CONNECTIVITÉ</translation>
+    </message>
+    <message>
+        <source>GRAVITY_CENTER</source>
+        <translation>CENTRE DE GRAVITÉ</translation>
+    </message>
+    <message>
+        <source>NODE</source>
+        <translation>NÅ“ud</translation>
+    </message>
+    <message>
+        <source>0D_ELEMENT</source>
+        <translation>ELÉMENTS 0D</translation>
+    </message>
+    <message>
+        <source>0D_ELEMENTS</source>
+        <translation>ELÉMENTS 0D</translation>
+    </message>
+    <message>
+        <source>EDGE</source>
+        <translation>ARÊTE</translation>
+    </message>
+    <message>
+        <source>EDGES</source>
+        <translation>ARÊTES</translation>
+    </message>
+    <message>
+        <source>FACE</source>
+        <translation>FACE</translation>
+    </message>
+    <message>
+        <source>FACES</source>
+        <translation>FACES</translation>
+    </message>
+    <message>
+        <source>VOLUME</source>
+        <translation>VOLUME</translation>
+    </message>
+    <message>
+        <source>VOLUMES</source>
+        <translation>VOLUMES</translation>
+    </message>
+    <message>
+        <source>FREE_NODE</source>
+        <translation>NÅ“ud libre (pas de connectivité)</translation>
+    </message>
+    <message>
+        <source>TYPE</source>
+        <translation>TYPE</translation>
+    </message>
+    <message>
+        <source>TRIANGLE</source>
+        <translation>Triangle</translation>
+    </message>
+    <message>
+        <source>QUADRANGLE</source>
+        <translation>Quadrangle</translation>
+    </message>
+    <message>
+        <source>POLYGON</source>
+        <translation>Polygône</translation>
+    </message>
+    <message>
+        <source>TETRAHEDRON</source>
+        <translation>Tétrahédron</translation>
+    </message>
+    <message>
+        <source>HEXAHEDRON</source>
+        <translation>Hexahédron</translation>
+    </message>
+    <message>
+        <source>PYRAMID</source>
+        <translation>Pyramide</translation>
+    </message>
+    <message>
+        <source>PRISM</source>
+        <translation>Prisme</translation>
+    </message>
+    <message>
+        <source>POLYHEDRON</source>
+        <translation>Polyhédron</translation>
+    </message>
+    <message>
+        <source>QUADRATIC</source>
+        <translation>QUADRATIQUE</translation>
+    </message>
+    <message>
+        <source>YES</source>
+        <translation>Oui</translation>
+    </message>
+    <message>
+        <source>NO</source>
+        <translation>Non</translation>
+    </message>
+    <message>
+        <source>PROPERTY</source>
+        <translation>Propriété</translation>
+    </message>
+    <message>
+        <source>VALUE</source>
+        <translation>Valeur</translation>
+    </message>
+    <message>
+        <source>X_FROM_Y_ITEMS_SHOWN</source>
+        <translation>%1-%2 sur %3 Ã©léments affichés</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MinDistance</name>
+    <message>
+        <source>FIRST_TARGET</source>
+        <translation>Premier Ã©lément</translation>
+    </message>
+    <message>
+        <source>SECOND_TARGET</source>
+        <translation>Deuxième Ã©lément</translation>
+    </message>
+    <message>
+        <source>NODE</source>
+        <translation>NÅ“ud</translation>
+    </message>
+    <message>
+        <source>ELEMENT</source>
+        <translation>Elément</translation>
+    </message>
+    <message>
+        <source>OBJECT</source>
+        <translation>Objet</translation>
+    </message>
+    <message>
+        <source>ORIGIN</source>
+        <translation>Origine</translation>
+    </message>
+    <message>
+        <source>COMPUTE</source>
+        <translation>Calculer</translation>
+    </message>
+    <message>
+        <source>RESULT</source>
+        <translation>Distance entre les Ã©léments</translation>
+    </message>
+    <message>
+        <source>DISTANCE</source>
+        <translation>Distance</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_CopyMeshDlg</name>
+    <message>
+        <source>OBJECT_NAME</source>
+        <translation>Objet source</translation>
+    </message>
+    <message>
+        <source>ELEM_IDS</source>
+        <translation>IDs des Ã©léments sources</translation>
+    </message>
+    <message>
+        <source>NEW_NAME</source>
+        <translation>Nom du nouveau maillage</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_MeasureDlg</name>
+    <message>
+        <source>MEASUREMENTS</source>
+        <translation>Outils de mesure</translation>
+    </message>
+    <message>
+        <source>MIN_DIST</source>
+        <translation>Distance minimale</translation>
+    </message>
+    <message>
+        <source>BND_BOX</source>
+        <translation>Boîte englobante</translation>
+    </message>
+</context>
+<context>
+    <name>SMESHGUI_BoundingBox</name>
+    <message>
+        <source>SOURCE</source>
+        <translation>Source</translation>
+    </message>
+    <message>
+        <source>OBJECTS</source>
+        <translation>Objets</translation>
+    </message>
+    <message>
+        <source>NODES</source>
+        <translation>NÅ“uds</translation>
+    </message>
+    <message>
+        <source>ELEMENTS</source>
+        <translation>Eléments</translation>
+    </message>
+    <message>
+        <source>COMPUTE</source>
+        <translation>Calculer</translation>
+    </message>
+    <message>
+        <source>RESULT</source>
+        <translation>Boîte englobante</translation>
+    </message>
+    <message>
+        <source>SELECTED_NB_OBJ</source>
+        <translation>%1 %2 sélectionnés</translation>
+    </message>
+    <message>
+        <source>NB_NODES</source>
+        <translation>nÅ“uds</translation>
+    </message>
+    <message>
+        <source>NB_ELEMENTS</source>
+        <translation>éléments</translation>
+    </message>
+</context>
 </TS>
index dfb378f245374942c3cbcde707e2a473220d9af9..26a480a4e02e927e437389f03c73a783ba0caab1 100644 (file)
@@ -247,7 +247,8 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
 
   // SMESH_Mesh method?
   map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( objID );
-  if ( id_mesh != myMeshes.end() ) {
+  if ( id_mesh != myMeshes.end() )
+  {
     // check for mesh editor object
     if ( aCommand->GetMethod() == "GetMeshEditor" ) { // MeshEditor creation
       _pyID editorID = aCommand->GetResultValue();
@@ -268,7 +269,8 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
 
   // SMESH_MeshEditor method?
   map< _pyID, Handle(_pyMeshEditor) >::iterator id_editor = myMeshEditors.find( objID );
-  if ( id_editor != myMeshEditors.end() ) {
+  if ( id_editor != myMeshEditors.end() )
+  {
     id_editor->second->Process( aCommand );
     TCollection_AsciiString processedCommand = aCommand->GetString();
     // some commands of SMESH_MeshEditor create meshes
@@ -277,6 +279,15 @@ Handle(_pyCommand) _pyGen::AddCommand( const TCollection_AsciiString& theCommand
       aCommand->GetString() = processedCommand; // discard changes made by _pyMesh
       myMeshes.insert( make_pair( mesh->GetID(), mesh ));
     }
+    if ( aCommand->GetMethod() == "MakeBoundaryMesh") {
+      _pyID meshID = aCommand->GetResultValue(0);
+      if ( !myMeshes.count( meshID ) )
+      {
+        Handle(_pyMesh) mesh = new _pyMesh( aCommand, meshID );
+        aCommand->GetString() = processedCommand; // discard changes made by _pyMesh
+        myMeshes.insert( make_pair( meshID, mesh ));
+      }
+    }
     return aCommand;
   }
   // SMESH_Hypothesis method?
@@ -352,7 +363,7 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand )
     myMeshes.insert( make_pair( mesh->GetID(), mesh ));
     return;
   }
-  if ( method == "CreateMeshesFromUNV" || method == "CreateMeshesFromSTL")
+  if ( method == "CreateMeshesFromUNV" || method == "CreateMeshesFromSTL" || method == "CopyMesh" )
   {
     Handle(_pyMesh) mesh = new _pyMesh( theCommand, theCommand->GetResultValue() );
     myMeshes.insert( make_pair( mesh->GetID(), mesh ));
@@ -1118,14 +1129,15 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
       "ConvertToQuadratic","ConvertFromQuadratic","RenumberNodes","RenumberElements",
       "RotationSweep","RotationSweepObject","RotationSweepObject1D","RotationSweepObject2D",
       "ExtrusionSweep","AdvancedExtrusion","ExtrusionSweepObject","ExtrusionSweepObject1D","ExtrusionSweepObject2D",
-      "ExtrusionAlongPath","ExtrusionAlongPathObject","ExtrusionAlongPathObject1D","ExtrusionAlongPathObject2D",
+      "ExtrusionAlongPath","ExtrusionAlongPathObject","ExtrusionAlongPathX",
+      "ExtrusionAlongPathObject1D","ExtrusionAlongPathObject2D",
       "Mirror","MirrorObject","Translate","TranslateObject","Rotate","RotateObject",
       "FindCoincidentNodes",/*"FindCoincidentNodesOnPart",*/"MergeNodes","FindEqualElements",
       "MergeElements","MergeEqualElements","SewFreeBorders","SewConformFreeBorders",
       "SewBorderToSide","SewSideElements","ChangeElemNodes","GetLastCreatedNodes",
       "GetLastCreatedElems",
       "MirrorMakeMesh","MirrorObjectMakeMesh","TranslateMakeMesh",
-      "TranslateObjectMakeMesh","RotateMakeMesh","RotateObjectMakeMesh"
+      "TranslateObjectMakeMesh","RotateMakeMesh","RotateObjectMakeMesh","MakeBoundaryMesh"
       ,"" }; // <- mark of the end
     sameMethods.Insert( names );
   }
@@ -1166,6 +1178,13 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand)
     }
   }
 
+  // set "ExtrusionAlongPathX()" instead of "ExtrusionAlongPathObjX()"
+  if ( !isPyMeshMethod && method == "ExtrusionAlongPathObjX")
+  {
+    isPyMeshMethod=true;
+    theCommand->SetMethod("ExtrusionAlongPathX");
+  }
+
   // set "FindCoincidentNodesOnPart()" instead of "FindCoincidentNodesOnPartBut()"
   if ( !isPyMeshMethod && method == "FindCoincidentNodesOnPartBut")
   {
index 3fd8ff22f55a148a5f5850cee01970b20d3f9c9d..a8e4205b26c4121d3ce52d0d8ec3b5349216e31c 100644 (file)
@@ -232,7 +232,10 @@ namespace SMESH
     if(!aSObject->_is_nil() || CORBA::is_nil( theArg ))
       return *this << aSObject;
     SMESH::long_array_var anElementsId = theArg->GetIDs();
-    return *this << anElementsId;
+    SMESH::SMESH_Mesh_var mesh = theArg->GetMesh();
+    SMESH::array_of_ElementType_var types =  theArg->GetTypes();
+    SMESH::ElementType type = types->length() ? types[0] : SMESH::ALL;
+    return *this << mesh << ".GetIDSource(" << anElementsId << ", " << type << ")";
   }
 
   TPythonDump& 
@@ -266,43 +269,47 @@ namespace SMESH
     if ( theArg ) {
       FunctorType aFunctorType = theArg->GetFunctorType();
       switch(aFunctorType){
-      case FT_AspectRatio:      myStream<< "anAspectRatio";     break;
-      case FT_AspectRatio3D:    myStream<< "anAspectRatio3D";   break;
-      case FT_Warping:          myStream<< "aWarping";          break;
-      case FT_MinimumAngle:     myStream<< "aMinimumAngle";     break;
-      case FT_Taper:            myStream<< "aTaper";            break;
-      case FT_Skew:             myStream<< "aSkew";             break;
-      case FT_Area:             myStream<< "aArea";             break;
-      case FT_Volume3D:         myStream<< "aVolume3D";         break;
-      case FT_MaxElementLength2D:myStream<< "aMaxElementLength2D";break;
-      case FT_MaxElementLength3D:myStream<< "aMaxElementLength3D";break;
-      case FT_FreeBorders:      myStream<< "aFreeBorders";      break;
-      case FT_FreeEdges:        myStream<< "aFreeEdges";        break;
-      case FT_FreeNodes:        myStream<< "aFreeNodes";        break;
-      case FT_FreeFaces:        myStream<< "aFreeFaces";        break;
-      case FT_MultiConnection:  myStream<< "aMultiConnection";  break;
-      case FT_MultiConnection2D:myStream<< "aMultiConnection2D";break;
-      case FT_Length:           myStream<< "aLength";           break;
-      case FT_Length2D:         myStream<< "aLength";           break;
-      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_CoplanarFaces:    myStream<< "aCoplanarFaces";    break;
-      case FT_RangeOfIds:       myStream<< "aRangeOfIds";       break;
-      case FT_BadOrientedVolume:myStream<< "aBadOrientedVolume";break;
-      case FT_LinearOrQuadratic:myStream<< "aLinearOrQuadratic";break;
-      case FT_GroupColor:       myStream<< "aGroupColor";       break;
-      case FT_ElemGeomType:     myStream<< "anElemGeomType";    break;
-      case FT_LessThan:         myStream<< "aLessThan";         break;
-      case FT_MoreThan:         myStream<< "aMoreThan";         break;
-      case FT_EqualTo:          myStream<< "anEqualTo";         break;
-      case FT_LogicalNOT:       myStream<< "aLogicalNOT";       break;
-      case FT_LogicalAND:       myStream<< "aLogicalAND";       break;
-      case FT_LogicalOR:        myStream<< "aLogicalOR";        break;
+      case FT_AspectRatio:           myStream<< "anAspectRatio";          break;
+      case FT_AspectRatio3D:         myStream<< "anAspectRatio3D";        break;
+      case FT_Warping:               myStream<< "aWarping";               break;
+      case FT_MinimumAngle:          myStream<< "aMinimumAngle";          break;
+      case FT_Taper:                 myStream<< "aTaper";                 break;
+      case FT_Skew:                  myStream<< "aSkew";                  break;
+      case FT_Area:                  myStream<< "aArea";                  break;
+      case FT_Volume3D:              myStream<< "aVolume3D";              break;
+      case FT_MaxElementLength2D:    myStream<< "aMaxElementLength2D";    break;
+      case FT_MaxElementLength3D:    myStream<< "aMaxElementLength3D";    break;
+      case FT_FreeBorders:           myStream<< "aFreeBorders";           break;
+      case FT_FreeEdges:             myStream<< "aFreeEdges";             break;
+      case FT_FreeNodes:             myStream<< "aFreeNodes";             break;
+      case FT_FreeFaces:             myStream<< "aFreeFaces";             break;
+      case FT_MultiConnection:       myStream<< "aMultiConnection";       break;
+      case FT_MultiConnection2D:     myStream<< "aMultiConnection2D";     break;
+      case FT_Length:                myStream<< "aLength";                break;
+      case FT_Length2D:              myStream<< "aLength2D";              break;
+      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_CoplanarFaces:         myStream<< "aCoplanarFaces";         break;
+      case FT_RangeOfIds:            myStream<< "aRangeOfIds";            break;
+      case FT_BadOrientedVolume:     myStream<< "aBadOrientedVolume";     break;
+      case FT_BareBorderVolume:      myStream<< "aBareBorderVolume";      break;
+      case FT_BareBorderFace:        myStream<< "aBareBorderFace";        break;
+      case FT_OverConstrainedVolume: myStream<< "aOverConstrainedVolume"; break;
+      case FT_OverConstrainedFace:   myStream<< "aOverConstrainedFace";   break;
+      case FT_LinearOrQuadratic:     myStream<< "aLinearOrQuadratic";     break;
+      case FT_GroupColor:            myStream<< "aGroupColor";            break;
+      case FT_ElemGeomType:          myStream<< "anElemGeomType";         break;
+      case FT_LessThan:              myStream<< "aLessThan";              break;
+      case FT_MoreThan:              myStream<< "aMoreThan";              break;
+      case FT_EqualTo:               myStream<< "anEqualTo";              break;
+      case FT_LogicalNOT:            myStream<< "aLogicalNOT";            break;
+      case FT_LogicalAND:            myStream<< "aLogicalAND";            break;
+      case FT_LogicalOR:             myStream<< "aLogicalOR";             break;
       case FT_Undefined:
-      default:                  myStream<< "anUndefined";       break;
+      default:                       myStream<< "anUndefined";            break;
       }
       myStream<<theArg;
     }
index d2a7ae648d7b2510cbef06115cb41d1a3276743c..f222d8db617dbdfeefe91610f299c2c0d53c4ff6 100644 (file)
@@ -34,6 +34,7 @@
 #include "SMDS_MeshNode.hxx"
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_ElemIterator.hxx"
+#include "SMDS_VolumeTool.hxx"
 
 #include "SMESHDS_Mesh.hxx"
 
@@ -600,7 +601,8 @@ SMESH::Histogram* NumericalFunctor_i::GetHistogram(CORBA::Short nbIntervals)
 {
   std::vector<int> nbEvents;
   std::vector<double> funValues;
-  myNumericalFunctorPtr->GetHistogram(nbIntervals,nbEvents,funValues);
+  std::vector<int> elements;
+  myNumericalFunctorPtr->GetHistogram(nbIntervals,nbEvents,funValues,elements);
 
   nbIntervals = CORBA::Short( std::min( nbEvents.size(), funValues.size() - 1));
   SMESH::Histogram_var histogram = new SMESH::Histogram;
@@ -937,6 +939,66 @@ FunctorType BadOrientedVolume_i::GetFunctorType()
   return SMESH::FT_BadOrientedVolume;
 }
 
+/*
+  Class       : BareBorderVolume_i
+  Description : Verify whether a mesh volume has a free facet without a face on it
+*/
+BareBorderVolume_i::BareBorderVolume_i()
+{
+  Controls::PredicatePtr control( new Controls::BareBorderVolume() );
+  myFunctorPtr = myPredicatePtr = control;
+};
+
+FunctorType BareBorderVolume_i::GetFunctorType()
+{
+  return SMESH::FT_BareBorderVolume;
+}
+
+/*
+  Class       : BareBorderFace_i
+  Description : Verify whether a mesh face has a free border without an edge on it
+*/
+BareBorderFace_i::BareBorderFace_i()
+{
+  Controls::PredicatePtr control( new Controls::BareBorderFace() );
+  myFunctorPtr = myPredicatePtr = control;
+};
+
+FunctorType BareBorderFace_i::GetFunctorType()
+{
+  return SMESH::FT_BareBorderFace;
+}
+
+/*
+  Class       : OverConstrainedVolume_i
+  Description : Verify whether a mesh volume has only one facet shared with other volumes
+*/
+OverConstrainedVolume_i::OverConstrainedVolume_i()
+{
+  Controls::PredicatePtr control( new Controls::OverConstrainedVolume() );
+  myFunctorPtr = myPredicatePtr = control;
+};
+
+FunctorType OverConstrainedVolume_i::GetFunctorType()
+{
+  return SMESH::FT_OverConstrainedVolume;
+}
+
+/*
+  Class       : OverConstrainedFace_i
+  Description : Verify whether a mesh face has only one border shared with other faces
+*/
+OverConstrainedFace_i::OverConstrainedFace_i()
+{
+  Controls::PredicatePtr control( new Controls::OverConstrainedFace() );
+  myFunctorPtr = myPredicatePtr = control;
+};
+
+FunctorType OverConstrainedFace_i::GetFunctorType()
+{
+  return SMESH::FT_OverConstrainedFace;
+}
+
 /*
   Class       : BelongToGeom_i
   Description : Predicate for selection on geometrical support
@@ -2036,6 +2098,38 @@ BadOrientedVolume_ptr FilterManager_i::CreateBadOrientedVolume()
   return anObj._retn();
 }
 
+BareBorderVolume_ptr FilterManager_i::CreateBareBorderVolume()
+{
+  SMESH::BareBorderVolume_i* aServant = new SMESH::BareBorderVolume_i();
+  SMESH::BareBorderVolume_var anObj = aServant->_this();
+  TPythonDump()<<aServant<<" = "<<this<<".CreateBareBorderVolume()";
+  return anObj._retn();
+}
+
+BareBorderFace_ptr FilterManager_i::CreateBareBorderFace()
+{
+  SMESH::BareBorderFace_i* aServant = new SMESH::BareBorderFace_i();
+  SMESH::BareBorderFace_var anObj = aServant->_this();
+  TPythonDump()<<aServant<<" = "<<this<<".CreateBareBorderFace()";
+  return anObj._retn();
+}
+
+OverConstrainedVolume_ptr FilterManager_i::CreateOverConstrainedVolume()
+{
+  SMESH::OverConstrainedVolume_i* aServant = new SMESH::OverConstrainedVolume_i();
+  SMESH::OverConstrainedVolume_var anObj = aServant->_this();
+  TPythonDump()<<aServant<<" = "<<this<<".CreateOverConstrainedVolume()";
+  return anObj._retn();
+}
+
+OverConstrainedFace_ptr FilterManager_i::CreateOverConstrainedFace()
+{
+  SMESH::OverConstrainedFace_i* aServant = new SMESH::OverConstrainedFace_i();
+  SMESH::OverConstrainedFace_var anObj = aServant->_this();
+  TPythonDump()<<aServant<<" = "<<this<<".CreateOverConstrainedFace()";
+  return anObj._retn();
+}
+
 LessThan_ptr FilterManager_i::CreateLessThan()
 {
   SMESH::LessThan_i* aServant = new SMESH::LessThan_i();
@@ -2476,6 +2570,62 @@ static inline bool getCriteria( Predicate_i*                thePred,
       theCriteria[ i ].Type          = FT_BadOrientedVolume;
       theCriteria[ i ].TypeOfElement = aPred->GetElementType();
 
+      return true;
+    }
+  case FT_BareBorderVolume:
+    {
+      BareBorderVolume_i* aPred = dynamic_cast<BareBorderVolume_i*>( thePred );
+
+      CORBA::ULong i = theCriteria->length();
+      theCriteria->length( i + 1 );
+
+      theCriteria[ i ] = createCriterion();
+
+      theCriteria[ i ].Type          = FT_BareBorderVolume;
+      theCriteria[ i ].TypeOfElement = aPred->GetElementType();
+
+      return true;
+    }
+  case FT_BareBorderFace:
+    {
+      BareBorderFace_i* aPred = dynamic_cast<BareBorderFace_i*>( thePred );
+
+      CORBA::ULong i = theCriteria->length();
+      theCriteria->length( i + 1 );
+
+      theCriteria[ i ] = createCriterion();
+
+      theCriteria[ i ].Type          = FT_BareBorderFace;
+      theCriteria[ i ].TypeOfElement = aPred->GetElementType();
+
+      return true;
+    }
+  case FT_OverConstrainedVolume:
+    {
+      OverConstrainedVolume_i* aPred = dynamic_cast<OverConstrainedVolume_i*>( thePred );
+
+      CORBA::ULong i = theCriteria->length();
+      theCriteria->length( i + 1 );
+
+      theCriteria[ i ] = createCriterion();
+
+      theCriteria[ i ].Type          = FT_OverConstrainedVolume;
+      theCriteria[ i ].TypeOfElement = aPred->GetElementType();
+
+      return true;
+    }
+  case FT_OverConstrainedFace:
+    {
+      OverConstrainedFace_i* aPred = dynamic_cast<OverConstrainedFace_i*>( thePred );
+
+      CORBA::ULong i = theCriteria->length();
+      theCriteria->length( i + 1 );
+
+      theCriteria[ i ] = createCriterion();
+
+      theCriteria[ i ].Type          = FT_OverConstrainedFace;
+      theCriteria[ i ].TypeOfElement = aPred->GetElementType();
+
       return true;
     }
   case FT_LessThan:
@@ -2723,6 +2873,26 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria
           aPredicate = aFilterMgr->CreateBadOrientedVolume();
         }
         break;
+      case SMESH::FT_BareBorderVolume:
+        {
+          aPredicate = aFilterMgr->CreateBareBorderVolume();
+        }
+        break;
+      case SMESH::FT_BareBorderFace:
+        {
+          aPredicate = aFilterMgr->CreateBareBorderFace();
+        }
+        break;
+      case SMESH::FT_OverConstrainedVolume:
+        {
+          aPredicate = aFilterMgr->CreateOverConstrainedVolume();
+        }
+        break;
+      case SMESH::FT_OverConstrainedFace:
+        {
+          aPredicate = aFilterMgr->CreateOverConstrainedFace();
+        }
+        break;
       case SMESH::FT_LinearOrQuadratic:
         {
           SMESH::LinearOrQuadratic_ptr tmpPred = aFilterMgr->CreateLinearOrQuadratic();
@@ -2963,7 +3133,11 @@ static inline LDOMString toString( CORBA::Long theType )
     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_BadOrientedVolume:return "Bad Oriented Volume";
+    case FT_BareBorderVolume: return "Volumes with bare border";
+    case FT_BareBorderFace  : return "Faces with bare border";
+    case FT_OverConstrainedVolume: return "Over-constrained Volumes";
+    case FT_OverConstrainedFace  : return "Over-constrained Faces";
     case FT_RangeOfIds      : return "Range of IDs";
     case FT_FreeBorders     : return "Free borders";
     case FT_FreeEdges       : return "Free edges";
@@ -3017,6 +3191,10 @@ static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr )
   //  else if ( theStr.equals( "Length2D"                     ) ) return FT_Length2D;
   else if ( theStr.equals( "Range of IDs"                 ) ) return FT_RangeOfIds;
   else if ( theStr.equals( "Bad Oriented Volume"          ) ) return FT_BadOrientedVolume;
+  else if ( theStr.equals( "Volumes with bare border"     ) ) return FT_BareBorderVolume;
+  else if ( theStr.equals( "Faces with bare border"       ) ) return FT_BareBorderFace;
+  else if ( theStr.equals( "Over-constrained Volumes"     ) ) return FT_OverConstrainedVolume;
+  else if ( theStr.equals( "Over-constrained Faces"       ) ) return FT_OverConstrainedFace;
   else if ( theStr.equals( "Less than"                    ) ) return FT_LessThan;
   else if ( theStr.equals( "More than"                    ) ) return FT_MoreThan;
   else if ( theStr.equals( "Equal to"                     ) ) return FT_EqualTo;
index bef8c2252bbcd31da25d2639f6c3d6cc35ae83f4..9ca20ddb4b32167001eecb11edc797310c9948f0 100644 (file)
@@ -44,6 +44,7 @@ class SMESHDS_Mesh;
 namespace SMESH
 {
 
+  // ================================================================================
   namespace Controls
   {
 
@@ -123,8 +124,10 @@ namespace SMESH
       Controls::ElementsOnShapePtr    myElementsOnShapePtr; // only if myIsSubshape == false
     };
     typedef boost::shared_ptr<LyingOnGeom> LyingOnGeomPtr;
-  }
-  
+
+  } // namespace Controls
+
+  // ================================================================================
   /*
     FUNCTORS
   */
@@ -387,6 +390,54 @@ namespace SMESH
     FunctorType                     GetFunctorType();
   };
   
+  /*
+    Class       : BareBorderVolume_i
+    Description : Verify whether a mesh volume has a free facet without a face on it
+  */
+  class SMESH_I_EXPORT BareBorderVolume_i: public virtual POA_SMESH::BareBorderVolume,
+                                           public virtual Predicate_i
+  {
+  public:
+    BareBorderVolume_i();
+    FunctorType                     GetFunctorType();
+  };
+  
+  /*
+    Class       : BareBorderFace_i
+    Description : Verify whether a mesh face has a free border without an edge on it
+  */
+  class SMESH_I_EXPORT BareBorderFace_i: public virtual POA_SMESH::BareBorderFace,
+                                           public virtual Predicate_i
+  {
+  public:
+    BareBorderFace_i();
+    FunctorType                     GetFunctorType();
+  };
+  
+  /*
+    Class       : OverConstrainedVolume_i
+    Description : Verify whether a mesh volume has only one facet shared with other volumes
+  */
+  class SMESH_I_EXPORT OverConstrainedVolume_i: public virtual POA_SMESH::OverConstrainedVolume,
+                                           public virtual Predicate_i
+  {
+  public:
+    OverConstrainedVolume_i();
+    FunctorType                     GetFunctorType();
+  };
+  
+  /*
+    Class       : OverConstrainedFace_i
+    Description : Verify whether a mesh face has only one border shared with other faces
+  */
+  class SMESH_I_EXPORT OverConstrainedFace_i: public virtual POA_SMESH::OverConstrainedFace,
+                                           public virtual Predicate_i
+  {
+  public:
+    OverConstrainedFace_i();
+    FunctorType                     GetFunctorType();
+  };
+  
   /*
     Class       : BelongToGeom_i
     Description : Predicate for selection on geometrical support
@@ -954,6 +1005,10 @@ namespace SMESH
     
     RangeOfIds_ptr            CreateRangeOfIds();
     BadOrientedVolume_ptr     CreateBadOrientedVolume();
+    BareBorderFace_ptr        CreateBareBorderFace();
+    BareBorderVolume_ptr      CreateBareBorderVolume();
+    OverConstrainedFace_ptr   CreateOverConstrainedFace();
+    OverConstrainedVolume_ptr CreateOverConstrainedVolume();
     LinearOrQuadratic_ptr     CreateLinearOrQuadratic();
     GroupColor_ptr            CreateGroupColor();
     ElemGeomType_ptr          CreateElemGeomType();
index 47e0fad99c6b3408bb26a257707cc5cd3bebdc29..6b4fac320715721468f0da0efc622a0fff92b734 100644 (file)
 
 #include "SMDS_EdgePosition.hxx"
 #include "SMDS_FacePosition.hxx"
-#include "SMDS_VertexPosition.hxx"
-#include "SMDS_SpacePosition.hxx"
 #include "SMDS_PolyhedralVolumeOfNodes.hxx"
+#include "SMDS_SetIterator.hxx"
+#include "SMDS_SpacePosition.hxx"
+#include "SMDS_VertexPosition.hxx"
 
 #include CORBA_SERVER_HEADER(SMESH_Group)
 #include CORBA_SERVER_HEADER(SMESH_Filter)
@@ -901,7 +902,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName
   aServant->ImportUNVFile( theFileName );
 
   // Dump creation of groups
-  aServant->GetGroups();
+  SMESH::ListOfGroups_var groups = aServant->GetGroups();
 
   aServant->GetImpl().GetMeshDS()->Modified();
   return aMesh._retn();
@@ -982,7 +983,7 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName,
   }
   // Dump creation of groups
   for ( int i = 0; i < aResult->length(); ++i )
-    aResult[ i ]->GetGroups();
+    SMESH::ListOfGroups_var groups = aResult[ i ]->GetGroups();
 
   return aResult._retn();
 }
@@ -2025,7 +2026,23 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
                 }
               } 
             }//elems loop
-            
+
+            // copy orphan nodes
+            SMDS_NodeIteratorPtr  itNodes = anInitMeshDS->nodesIterator();
+            while ( itNodes->more() )
+            {
+              const SMDS_MeshNode* aNode = itNodes->next();
+              if ( aNode->NbInverseElements() == 0 )
+              {
+                const SMDS_MeshNode* aNewNode =
+                  aNewMeshDS->AddNode(aNode->X(), aNode->Y(), aNode->Z());
+                nodesMap.insert( make_pair(aNode->GetID(), aNewNode->GetID()) );
+                if( theCommonGroups )
+                  anIDsNodes[anNbNodes++] = aNewNode->GetID();
+              }
+            }
+
+
             aListOfGroups = anInitImpl->GetGroups();
             SMESH::SMESH_GroupBase_ptr aGroup;
 
@@ -2211,6 +2228,212 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray,
   return aNewMesh._retn();
 }
 
+//================================================================================
+/*!
+ * \brief Create a mesh by copying a part of another mesh
+ *  \param meshPart - a part of mesh to copy
+ *  \param toCopyGroups - to create in the new mesh groups
+ *                        the copied elements belongs to
+ *  \param toKeepIDs - to preserve IDs of the copied elements or not
+ *  \retval SMESH::SMESH_Mesh_ptr - the new mesh
+ */
+//================================================================================
+
+SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
+                                            const char*               meshName,
+                                            CORBA::Boolean            toCopyGroups,
+                                            CORBA::Boolean            toKeepIDs)
+{
+  Unexpect aCatch(SALOME_SalomeException);
+
+  TPythonDump* pyDump = new TPythonDump; // prevent dump from CreateMesh()
+
+  // 1. Get source mesh
+
+  if ( CORBA::is_nil( meshPart ))
+    THROW_SALOME_CORBA_EXCEPTION( "bad IDSource", SALOME::BAD_PARAM );
+
+  SMESH::SMESH_Mesh_var srcMesh = meshPart->GetMesh();
+  SMESH_Mesh_i*       srcMesh_i = SMESH::DownCast<SMESH_Mesh_i*>( srcMesh );
+  if ( !srcMesh_i )
+    THROW_SALOME_CORBA_EXCEPTION( "bad mesh of IDSource", SALOME::BAD_PARAM );
+  
+  SMESHDS_Mesh* srcMeshDS = srcMesh_i->GetImpl().GetMeshDS();
+
+  // 2. Make a new mesh
+
+  SMESH::SMESH_Mesh_var newMesh = CreateMesh(GEOM::GEOM_Object::_nil());
+  SMESH_Mesh_i*       newMesh_i = SMESH::DownCast<SMESH_Mesh_i*>( newMesh );
+  if ( !newMesh_i )
+    THROW_SALOME_CORBA_EXCEPTION( "can't create a mesh", SALOME::INTERNAL_ERROR );
+  SALOMEDS::SObject_var meshSO = ObjectToSObject(myCurrentStudy, newMesh );
+  if ( !meshSO->_is_nil() )
+  {
+    SetName( meshSO, meshName, "Mesh" );
+    SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
+  }
+  SMESHDS_Mesh* newMeshDS = newMesh_i->GetImpl().GetMeshDS();
+  ::SMESH_MeshEditor editor( &newMesh_i->GetImpl() );
+
+  // 3. Get elements to copy
+
+  SMDS_ElemIteratorPtr srcElemIt;
+  TIDSortedElemSet srcElems;
+  SMESH::array_of_ElementType_var srcElemTypes = meshPart->GetTypes();
+  if ( SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
+  {
+    srcElemIt = srcMeshDS->elementsIterator();
+  }
+  else
+  {
+    SMESH::long_array_var ids = meshPart->GetIDs();
+    if ( srcElemTypes->length() == 1 && srcElemTypes[0] == SMESH::NODE ) // group of nodes
+    {
+      for (int i=0; i < ids->length(); i++)
+        if ( const SMDS_MeshElement * elem = srcMeshDS->FindNode( ids[i] ))
+          srcElems.insert( elem );
+    }
+    else
+    {
+      for (int i=0; i < ids->length(); i++)
+        if ( const SMDS_MeshElement * elem = srcMeshDS->FindElement( ids[i] ))
+          srcElems.insert( elem );
+    }
+    if ( srcElems.empty() )
+      return newMesh._retn();
+
+    typedef SMDS_SetIterator< SMDS_pElement, TIDSortedElemSet::const_iterator > ElIter;
+    srcElemIt = SMDS_ElemIteratorPtr( new ElIter( srcElems.begin(), srcElems.end() ));
+  }
+
+  // 4. Copy elements
+
+  typedef map<SMDS_pElement, SMDS_pElement, TIDCompare> TE2EMap;
+  TE2EMap e2eMapByType[ SMDSAbs_NbElementTypes ];
+  TE2EMap& n2nMap = e2eMapByType[ SMDSAbs_Node ];
+  int iN;
+  const SMDS_MeshNode *nSrc, *nTgt;
+  vector< const SMDS_MeshNode* > nodes;
+  while ( srcElemIt->more() )
+  {
+    const SMDS_MeshElement * elem = srcElemIt->next();
+    nodes.resize( elem->NbNodes());
+    SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
+    if ( toKeepIDs ) {
+      for ( iN = 0; nIt->more(); ++iN )
+      {
+        nSrc = static_cast<const SMDS_MeshNode*>( nIt->next() );
+        nTgt = newMeshDS->FindNode( nSrc->GetID());
+        if ( !nTgt )
+          nTgt = newMeshDS->AddNodeWithID( nSrc->X(), nSrc->Y(), nSrc->Z(), nSrc->GetID());
+        nodes[ iN ] = nTgt;
+      }
+    }
+    else {
+      for ( iN = 0; nIt->more(); ++iN )
+      {
+        nSrc = static_cast<const SMDS_MeshNode*>( nIt->next() );
+        TE2EMap::iterator n2n = n2nMap.insert( make_pair( nSrc, SMDS_pNode(0) )).first;
+        if ( !n2n->second )
+          n2n->second = newMeshDS->AddNode( nSrc->X(), nSrc->Y(), nSrc->Z() );
+        nodes[ iN ] = (const SMDS_MeshNode*) n2n->second;
+      }
+    }
+    if ( elem->GetType() != SMDSAbs_Node )
+    {
+      int ID = toKeepIDs ? elem->GetID() : 0;
+      const SMDS_MeshElement * newElem = editor.AddElement( nodes,
+                                                            elem->GetType(),
+                                                            elem->IsPoly(),
+                                                            ID);
+      if ( toCopyGroups && !toKeepIDs )
+        e2eMapByType[ elem->GetType() ].insert( make_pair( elem, newElem ));
+    }
+  }
+
+  // 5. Copy groups
+
+  int nbNewGroups = 0;
+  if ( toCopyGroups )
+  {
+    SMESH_Mesh::GroupIteratorPtr gIt = srcMesh_i->GetImpl().GetGroups();
+    while ( gIt->more() )
+    {
+      SMESH_Group* group = gIt->next();
+      const SMESHDS_GroupBase* groupDS = group->GetGroupDS();
+
+      // Check group type. We copy nodal groups containing nodes of copied element
+      SMDSAbs_ElementType groupType = groupDS->GetType();
+      if ( groupType != SMDSAbs_Node &&
+           newMeshDS->GetMeshInfo().NbElements( groupType ) == 0 )
+        continue; // group type differs from types of meshPart
+
+      // Find copied elements in the group
+      vector< const SMDS_MeshElement* > groupElems;
+      SMDS_ElemIteratorPtr eIt = groupDS->GetElements();
+      if ( toKeepIDs )
+      {
+        const SMDS_MeshElement* foundElem;
+        if ( groupType == SMDSAbs_Node )
+        {
+          while ( eIt->more() )
+            if (( foundElem = newMeshDS->FindNode( eIt->next()->GetID() )))
+              groupElems.push_back( foundElem );
+        }
+        else
+        {
+          while ( eIt->more() )
+            if (( foundElem = newMeshDS->FindElement( eIt->next()->GetID() )))
+              groupElems.push_back( foundElem );
+        }
+      }
+      else
+      {
+        TE2EMap & e2eMap = e2eMapByType[ groupDS->GetType() ];
+        if ( e2eMap.empty() ) continue;
+        int minID = e2eMap.begin()->first->GetID();
+        int maxID = e2eMap.rbegin()->first->GetID();
+        TE2EMap::iterator e2e;
+        while ( eIt->more() && groupElems.size() < e2eMap.size())
+        {
+          const SMDS_MeshElement* e = eIt->next();
+          if ( e->GetID() < minID || e->GetID() > maxID ) continue;
+          if ((e2e = e2eMap.find( e )) != e2eMap.end())
+            groupElems.push_back( e2e->second );
+        }
+      }
+      // Make a new group
+      if ( !groupElems.empty() )
+      {
+        SMESH::SMESH_Group_var newGroupObj =
+          newMesh->CreateGroup( SMESH::ElementType(groupType), group->GetName() );
+        if ( SMESH_GroupBase_i* newGroup_i = SMESH::DownCast<SMESH_GroupBase_i*>( newGroupObj))
+        {
+          SMESHDS_GroupBase * newGroupDS = newGroup_i->GetGroupDS();
+          SMDS_MeshGroup& smdsGroup = ((SMESHDS_Group*)newGroupDS)->SMDSGroup();
+          for ( unsigned i = 0; i < groupElems.size(); ++i )
+            smdsGroup.Add( groupElems[i] );
+
+          nbNewGroups++;
+        }
+      }
+    }
+  }
+
+  *pyDump << newMesh << " = " << this
+          << ".CopyMesh( " << meshPart << ", "
+          << "'" << meshName << "', "
+          << toCopyGroups << ", "
+          << toKeepIDs << ")";
+
+  delete pyDump; pyDump = 0; // allow dump in GetGroups()
+
+  if ( nbNewGroups > 0 ) // dump created groups
+    SMESH::ListOfGroups_var groups = newMesh->GetGroups();
+
+  return newMesh._retn();
+}
+
 //================================================================================
 /*!
  *  SMESH_Gen_i::GetMEDVersion
index b2c90805c642e4b8d65fdaa6413da1fb1e06ad2e..b4003818d2840f3aa460bae4bcaccb7d884d18d9 100644 (file)
@@ -236,6 +236,12 @@ public:
   SMESH::SMESH_Mesh_ptr CreateMeshesFromSTL( const char* theFileName )
     throw ( SALOME::SALOME_Exception );
 
+  // Copy a part of mesh
+  SMESH::SMESH_Mesh_ptr CopyMesh(SMESH::SMESH_IDSource_ptr meshPart,
+                                 const char*               meshName,
+                                 CORBA::Boolean            toCopyGroups,
+                                 CORBA::Boolean            toKeepIDs);
+
   // Compute mesh on a shape
   CORBA::Boolean Compute( SMESH::SMESH_Mesh_ptr theMesh,
                           GEOM::GEOM_Object_ptr theShapeObject )
index d6185e1078a877d377fd1eafbf3e1d0abd4de411..5144d33a9dc4b0c98694573bb2d38021d85fe044 100644 (file)
@@ -2685,6 +2685,8 @@ ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr  Object,
                        SMESH::ElementType         ElemType,
                        SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
 {
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
   SMESH::long_array_var anElementsId = Object->GetIDs();
   SMESH::ListOfGroups * aGroups = extrusionAlongPathX(anElementsId,
                                                       Path,
@@ -2698,16 +2700,12 @@ ExtrusionAlongPathObjX(SMESH::SMESH_IDSource_ptr  Object,
                                                       (SMDSAbs_ElementType)ElemType,
                                                       Error);
 
-  if ( !myPreviewMode ) {
+  if (!myPreviewMode) {
     bool isDumpGroups = aGroups && aGroups->length() > 0;
-    TPythonDump aPythonDump;
-    if(isDumpGroups) {
-      aPythonDump << "("<<aGroups;
-    }
-    if(isDumpGroups)
-      aPythonDump << ", error)";
+    if (isDumpGroups)
+      aPythonDump << "(" << *aGroups << ", error)";
     else
-      aPythonDump <<"error";
+      aPythonDump << "error";
 
     aPythonDump << " = " << this << ".ExtrusionAlongPathObjX( "
                 << Object      << ", "
@@ -2745,6 +2743,8 @@ ExtrusionAlongPathX(const SMESH::long_array&   IDsOfElements,
                     SMESH::ElementType         ElemType,
                     SMESH::SMESH_MeshEditor::Extrusion_Error& Error)
 {
+  TPythonDump aPythonDump; // it is here to prevent dump of GetGroups()
+
   SMESH::ListOfGroups * aGroups = extrusionAlongPathX(IDsOfElements,
                                                       Path,
                                                       NodeStart,
@@ -2757,14 +2757,10 @@ ExtrusionAlongPathX(const SMESH::long_array&   IDsOfElements,
                                                       (SMDSAbs_ElementType)ElemType,
                                                       Error);
 
-  if ( !myPreviewMode ) {
+  if (!myPreviewMode) {
     bool isDumpGroups = aGroups && aGroups->length() > 0;
-    TPythonDump aPythonDump;
-    if(isDumpGroups) {
-      aPythonDump << "("<<aGroups;
-    }
-    if(isDumpGroups)
-      aPythonDump << ", error)";
+    if (isDumpGroups)
+      aPythonDump << "(" << *aGroups << ", error)";
     else
       aPythonDump <<"error";
 
@@ -2780,6 +2776,7 @@ ExtrusionAlongPathX(const SMESH::long_array&   IDsOfElements,
                 << ( HasRefPoint ? RefPoint.x : 0 ) << ", "
                 << ( HasRefPoint ? RefPoint.y : 0 ) << ", "
                 << ( HasRefPoint ? RefPoint.z : 0 ) << " ), "
+                << MakeGroups << ", "
                 << ElemType << " )";
   }
   return aGroups;
@@ -5353,7 +5350,7 @@ SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
     SMESH_Group* smesh_group = 0;
     if ( strlen(groupName) )
     {
-      group_var = mesh_i->CreateGroup( SMESH::ElementType(elemType),groupName);
+      group_var = mesh_i->CreateGroup( SMESH::ElementType(int(elemType)-1),groupName);
       if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( group_var ))
         smesh_group = group_i->GetSmeshGroup();
     }
@@ -5369,6 +5366,8 @@ SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
     storeResult( aMeshEditor );
   }
 
+  const char* dimName[] = { "BND_2DFROM3D", "BND_1DFROM3D", "BND_1DFROM2D" };
+
   // result of MakeBoundaryMesh() is a tuple (mesh, group)
   if ( mesh_var->_is_nil() )
     pyDump << myMesh_i->_this() << ", ";
@@ -5380,9 +5379,9 @@ SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource,
     pyDump << group_var << " = ";
   pyDump << this << ".MakeBoundaryMesh( "
          << idSource << ", "
-         << dim << ", "
-         << groupName << ", "
-         << meshName<< ", "
+         << "SMESH." << dimName[int(dim)] << ", "
+         << "'" << groupName << "', "
+         << "'" << meshName<< "', "
          << toCopyElements << ", "
          << toCopyExistingBondary << ")";
 
index 043a2e3128e465fc6663df3e9b6d5098b420d689..f50a0c8e4fe21bbbe24821d74df16d71c8349bcc 100644 (file)
@@ -76,17 +76,13 @@ f4 = MakePlane(sphere_centre, MakeVectorDXDYDZ( 1, 0, -1), plan_trim)
 
 
 #sphere_decoupee = MakePartition(solids, sphere_outils, [], [], ShapeType["SOLID"])
-solids = geompy.SubShapeAll(sphere_troue,geompy.ShapeType["SOLID"])
-sphere_decoupee = MakePartition(solids, [f1], [], [], ShapeType["SOLID"])
-solids = geompy.SubShapeAll(sphere_decoupee,geompy.ShapeType["SOLID"])
-sphere_decoupee = MakePartition(solids, [f2], [], [], ShapeType["SOLID"])
-solids = geompy.SubShapeAll(sphere_decoupee,geompy.ShapeType["SOLID"])
-sphere_decoupee = MakePartition(solids, [f3], [], [], ShapeType["SOLID"])
-solids = geompy.SubShapeAll(sphere_decoupee,geompy.ShapeType["SOLID"])
-sphere_decoupee = MakePartition(solids, [f4], [], [], ShapeType["SOLID"])
-solids = geompy.SubShapeAll(sphere_decoupee,geompy.ShapeType["SOLID"])
-
-sphere_partie = geompy.MakeCompound(solids)
+
+sphere_decoupee = MakePartition([sphere_troue],    [f1], [], [], ShapeType["SOLID"])
+sphere_decoupee = MakePartition([sphere_decoupee], [f2], [], [], ShapeType["SOLID"])
+sphere_decoupee = MakePartition([sphere_decoupee], [f3], [], [], ShapeType["SOLID"])
+sphere_decoupee = MakePartition([sphere_decoupee], [f4], [], [], ShapeType["SOLID"])
+
+sphere_partie = geompy.MakeCompound([sphere_decoupee])
 
 sphere_partie   = GetBlockNearPoint(sphere_decoupee, MakeVertex(-sphere_rayon, 0, 0))
 sphere_bloc     = RemoveExtraEdges(sphere_partie)
@@ -113,17 +109,12 @@ cube_plein   = MakeBox(-cube_cote, -cube_cote, -cube_cote,  +cube_cote, +cube_co
 cube_trou    = MakeCut(cube_plein, sphere_pleine)
 #cube_decoupe = MakePartition([cube_trou], sphere_outils, [], [], ShapeType["SOLID"])
 
-solids = geompy.SubShapeAll(cube_trou,geompy.ShapeType["SOLID"])
-cube_decoupe = MakePartition(solids, [f1], [], [], ShapeType["SOLID"])
-solids = geompy.SubShapeAll(cube_decoupe,geompy.ShapeType["SOLID"])
-cube_decoupe = MakePartition(solids, [f2], [], [], ShapeType["SOLID"])
-solids = geompy.SubShapeAll(cube_decoupe,geompy.ShapeType["SOLID"])
-cube_decoupe = MakePartition(solids, [f3], [], [], ShapeType["SOLID"])
-solids = geompy.SubShapeAll(cube_decoupe,geompy.ShapeType["SOLID"])
-cube_decoupe = MakePartition(solids, [f4], [], [], ShapeType["SOLID"])
-solids = geompy.SubShapeAll(cube_decoupe,geompy.ShapeType["SOLID"])
-
-cube_decoupe = geompy.MakeCompound(solids)
+cube_decoupe = MakePartition([cube_trou],    [f1], [], [], ShapeType["SOLID"])
+cube_decoupe = MakePartition([cube_decoupe], [f2], [], [], ShapeType["SOLID"])
+cube_decoupe = MakePartition([cube_decoupe], [f3], [], [], ShapeType["SOLID"])
+cube_decoupe = MakePartition([cube_decoupe], [f4], [], [], ShapeType["SOLID"])
+
+cube_decoupe = geompy.MakeCompound([cube_decoupe])
 
 
 cube_partie  = GetBlockNearPoint(cube_decoupe, MakeVertex(-cube_cote, 0, 0))
index f07cf3c238c6233320669275e00497354a4e50b0..3e52108c653cc8a1f550b5125cf9913cef07f1c3 100644 (file)
 #
 #  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
-
 #  File   : smesh.py
 #  Author : Francis KLOSS, OCC
 #  Module : SMESH
-#
+
 """
  \namespace smesh
  \brief Module smesh
@@ -358,7 +357,7 @@ def ParseDirStruct(Dir):
         pntStr = Dir.pointStruct
         if isinstance(pntStr, PointStructStr6):
             Parameters = str(pntStr.x1Str) + var_separator + str(pntStr.x2Str) + var_separator
-            Parameters += str(pntStr.y1Str) + var_separator + str(pntStr.y2Str) + var_separator 
+            Parameters += str(pntStr.y1Str) + var_separator + str(pntStr.y2Str) + var_separator
             Parameters += str(pntStr.z1Str) + var_separator + str(pntStr.z2Str)
             Point = PointStruct(pntStr.x2 - pntStr.x1, pntStr.y2 - pntStr.y1, pntStr.z2 - pntStr.z1)
         else:
@@ -387,13 +386,13 @@ def ParseAngles(list):
         else:
             Result.append(parameter)
             pass
-        
+
         Parameters = Parameters + str(parameter)
         Parameters = Parameters + var_separator
         pass
     Parameters = Parameters[:len(Parameters)-1]
     return Result, Parameters
-    
+
 def IsEqual(val1, val2, tol=PrecisionConfusion):
     if abs(val1 - val2) < tol:
         return True
@@ -491,7 +490,7 @@ def CheckPlugin(plugin):
         print "Warning: BLSURFPlugin module unavailable"
         return False
     return True
-    
+
 # end of l1_auxiliary
 ## @}
 
@@ -570,7 +569,7 @@ class smeshDC(SMESH._objref_SMESH_Gen):
     #  @return SMESH.AxisStruct
     #  @ingroup l1_auxiliary
     def GetAxisStruct(self,theObj):
-        edges = self.geompyD.SubShapeAll( theObj, geompyDC.ShapeType["EDGE"] )
+        edges = self.geompyD.ExtractShapes( theObj, geompyDC.ShapeType["EDGE"] )
         if len(edges) > 1:
             vertex1, vertex2 = self.geompyD.SubShapeAll( edges[0], geompyDC.ShapeType["VERTEX"] )
             vertex3, vertex4 = self.geompyD.SubShapeAll( edges[1], geompyDC.ShapeType["VERTEX"] )
@@ -663,27 +662,6 @@ class smeshDC(SMESH._objref_SMESH_Gen):
         aMesh = Mesh(self, self.geompyD, aSmeshMesh)
         return aMesh
 
-    ## From SMESH_Gen interface
-    #  @return the list of integer values
-    #  @ingroup l1_auxiliary
-    def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
-        return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
-
-    ## From SMESH_Gen interface. Creates a pattern
-    #  @return an instance of SMESH_Pattern
-    #
-    #  <a href="../tui_modifying_meshes_page.html#tui_pattern_mapping">Example of Patterns usage</a>
-    #  @ingroup l2_modif_patterns
-    def GetPattern(self):
-        return SMESH._objref_SMESH_Gen.GetPattern(self)
-
-    ## Sets number of segments per diagonal of boundary box of geometry by which
-    #  default segment length of appropriate 1D hypotheses is defined.
-    #  Default value is 10
-    #  @ingroup l1_auxiliary
-    def SetBoundaryBoxSegmentation(self, nbSegments):
-        SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
-
     ## Concatenate the given meshes into one mesh.
     #  @return an instance of Mesh class
     #  @param meshes the meshes to combine into one mesh
@@ -707,6 +685,41 @@ class smeshDC(SMESH._objref_SMESH_Gen):
         aMesh = Mesh(self, self.geompyD, aSmeshMesh)
         return aMesh
 
+    ## Create a mesh by copying a part of another mesh.
+    #  @param meshPart a part of mesh to copy, either a Mesh, a sub-mesh or a group;
+    #                  to copy nodes or elements not contained in any mesh object,
+    #                  pass result of Mesh.GetIDSource( list_of_ids, type ) as meshPart
+    #  @param meshName a name of the new mesh
+    #  @param toCopyGroups to create in the new mesh groups the copied elements belongs to
+    #  @param toKeepIDs to preserve IDs of the copied elements or not
+    #  @return an instance of Mesh class
+    def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False):
+        if (isinstance( meshPart, Mesh )):
+            meshPart = meshPart.GetMesh()
+        mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs )
+        return Mesh(self, self.geompyD, mesh)
+
+    ## From SMESH_Gen interface
+    #  @return the list of integer values
+    #  @ingroup l1_auxiliary
+    def GetSubShapesId( self, theMainObject, theListOfSubObjects ):
+        return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects)
+
+    ## From SMESH_Gen interface. Creates a pattern
+    #  @return an instance of SMESH_Pattern
+    #
+    #  <a href="../tui_modifying_meshes_page.html#tui_pattern_mapping">Example of Patterns usage</a>
+    #  @ingroup l2_modif_patterns
+    def GetPattern(self):
+        return SMESH._objref_SMESH_Gen.GetPattern(self)
+
+    ## Sets number of segments per diagonal of boundary box of geometry by which
+    #  default segment length of appropriate 1D hypotheses is defined.
+    #  Default value is 10
+    #  @ingroup l1_auxiliary
+    def SetBoundaryBoxSegmentation(self, nbSegments):
+        SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments)
+
     # Filtering. Auxiliary functions:
     # ------------------------------
 
@@ -735,6 +748,8 @@ class smeshDC(SMESH._objref_SMESH_Gen):
     #  @param UnaryOp  FT_LogicalNOT or FT_Undefined
     #  @param BinaryOp a binary logical operation FT_LogicalAND, FT_LogicalOR or
     #                  FT_Undefined (must be for the last criterion of all criteria)
+    #  @param Tolerance the tolerance used by FT_BelongToGeom, FT_BelongToSurface,
+    #         FT_LyingOnGeom, FT_CoplanarFaces criteria
     #  @return SMESH.Filter.Criterion
     #  @ingroup l1_controls
     def GetCriterion(self,elementType,
@@ -742,10 +757,12 @@ class smeshDC(SMESH._objref_SMESH_Gen):
                      Compare = FT_EqualTo,
                      Treshold="",
                      UnaryOp=FT_Undefined,
-                     BinaryOp=FT_Undefined):
+                     BinaryOp=FT_Undefined,
+                     Tolerance=1e-07):
         aCriterion = self.GetEmptyCriterion()
         aCriterion.TypeOfElement = elementType
         aCriterion.Type = self.EnumToLong(CritType)
+        aCriterion.Tolerance = Tolerance
 
         aTreshold = Treshold
 
@@ -810,7 +827,9 @@ class smeshDC(SMESH._objref_SMESH_Gen):
                 return None
             pass
         elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_BadOrientedVolume, FT_FreeNodes,
-                          FT_FreeFaces, FT_LinearOrQuadratic]:
+                          FT_FreeFaces, FT_LinearOrQuadratic,
+                          FT_BareBorderFace, FT_BareBorderVolume,
+                          FT_OverConstrainedFace, FT_OverConstrainedVolume]:
             # At this point the treshold is unnecessary
             if aTreshold ==  FT_LogicalNOT:
                 aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT)
@@ -845,14 +864,17 @@ class smeshDC(SMESH._objref_SMESH_Gen):
     #  @param Compare  belongs to {FT_LessThan, FT_MoreThan, FT_EqualTo}
     #  @param Treshold the threshold value (range of id ids as string, shape, numeric)
     #  @param UnaryOp  FT_LogicalNOT or FT_Undefined
+    #  @param Tolerance the tolerance used by FT_BelongToGeom, FT_BelongToSurface,
+    #         FT_LyingOnGeom, FT_CoplanarFaces criteria
     #  @return SMESH_Filter
     #  @ingroup l1_controls
     def GetFilter(self,elementType,
                   CritType=FT_Undefined,
                   Compare=FT_EqualTo,
                   Treshold="",
-                  UnaryOp=FT_Undefined):
-        aCriterion = self.GetCriterion(elementType, CritType, Compare, Treshold, UnaryOp, FT_Undefined)
+                  UnaryOp=FT_Undefined,
+                  Tolerance=1e-07):
+        aCriterion = self.GetCriterion(elementType, CritType, Compare, Treshold, UnaryOp, FT_Undefined,Tolerance)
         aFilterMgr = self.CreateFilterManager()
         aFilter = aFilterMgr.CreateFilter()
         aCriteria = []
@@ -913,7 +935,7 @@ class smeshDC(SMESH._objref_SMESH_Gen):
             obj = obj.GetMesh()
         d = {}
         if hasattr(obj, "_narrow") and obj._narrow(SMESH.SMESH_IDSource):
-            values = obj.GetMeshInfo() 
+            values = obj.GetMeshInfo()
             for i in range(SMESH.Entity_Last._v):
                 if i < len(values): d[SMESH.EntityType._item(i)]=values[i]
             pass
@@ -924,7 +946,7 @@ class smeshDC(SMESH._objref_SMESH_Gen):
     #  If @a src2 is None, and @a id2 = 0, distance from @a src1 / @a id1 to the origin is computed.
     #  If @a src2 is None, and @a id2 != 0, it is assumed that both @a id1 and @a id2 belong to @a src1.
     #
-    #  @param src1 first source object 
+    #  @param src1 first source object
     #  @param src2 second source object
     #  @param id1 node/element id from the first source
     #  @param id2 node/element id from the second (or first) source
@@ -940,13 +962,13 @@ class smeshDC(SMESH._objref_SMESH_Gen):
         else:
             result = result.value
         return result
-    
+
     ## Get measure structure specifying minimum distance data between two objects
     #
     #  If @a src2 is None, and @a id2 = 0, distance from @a src1 / @a id1 to the origin is computed.
     #  If @a src2 is None, and @a id2 != 0, it is assumed that both @a id1 and @a id2 belong to @a src1.
     #
-    #  @param src1 first source object 
+    #  @param src1 first source object
     #  @param src2 second source object
     #  @param id1 node/element id from the first source
     #  @param id2 node/element id from the second (or first) source
@@ -985,7 +1007,7 @@ class smeshDC(SMESH._objref_SMESH_Gen):
         result = aMeasurements.MinDistance(src1, src2)
         aMeasurements.Destroy()
         return result
-    
+
     ## Get bounding box of the specified object(s)
     #  @param objects single source object or list of source objects
     #  @return tuple of six values (minX, minY, minZ, maxX, maxY, maxZ)
@@ -1330,8 +1352,8 @@ class Mesh:
         shape = geom
         if shape==0:
             shape = self.geom
-        nbSolids = len( self.geompyD.SubShapeAll( shape, geompyDC.ShapeType["SOLID"] ))
-        nbShells = len( self.geompyD.SubShapeAll( shape, geompyDC.ShapeType["SHELL"] ))
+        nbSolids = len( self.geompyD.ExtractShapes( shape, geompyDC.ShapeType["SOLID"] ))
+        nbShells = len( self.geompyD.ExtractShapes( shape, geompyDC.ShapeType["SHELL"] ))
         if nbSolids == 0 or nbSolids == nbShells:
             return Mesh_Prism3D(self,  geom)
         return Mesh_RadialPrism3D(self,  geom)
@@ -1412,14 +1434,14 @@ class Mesh:
                     except:
                         shapeText = " on subshape #%s" % (err.subShapeID)
                 errText = ""
-                stdErrors = ["OK",                 #COMPERR_OK            
+                stdErrors = ["OK",                 #COMPERR_OK
                              "Invalid input mesh", #COMPERR_BAD_INPUT_MESH
-                             "std::exception",     #COMPERR_STD_EXCEPTION 
-                             "OCC exception",      #COMPERR_OCC_EXCEPTION 
-                             "SALOME exception",   #COMPERR_SLM_EXCEPTION 
-                             "Unknown exception",  #COMPERR_EXCEPTION     
-                             "Memory allocation problem", #COMPERR_MEMORY_PB     
-                             "Algorithm failed",   #COMPERR_ALGO_FAILED   
+                             "std::exception",     #COMPERR_STD_EXCEPTION
+                             "OCC exception",      #COMPERR_OCC_EXCEPTION
+                             "SALOME exception",   #COMPERR_SLM_EXCEPTION
+                             "Unknown exception",  #COMPERR_EXCEPTION
+                             "Memory allocation problem", #COMPERR_MEMORY_PB
+                             "Algorithm failed",   #COMPERR_ALGO_FAILED
                              "Unexpected geometry"]#COMPERR_BAD_SHAPE
                 if err.code > 0:
                     if err.code < len(stdErrors): errText = stdErrors[err.code]
@@ -1744,6 +1766,8 @@ class Mesh:
     #  @param Compare belongs to {FT_LessThan, FT_MoreThan, FT_EqualTo}
     #  @param Treshold the threshold value (range of id ids as string, shape, numeric)
     #  @param UnaryOp FT_LogicalNOT or FT_Undefined
+    #  @param Tolerance the tolerance used by FT_BelongToGeom, FT_BelongToSurface,
+    #         FT_LyingOnGeom, FT_CoplanarFaces criteria
     #  @return SMESH_Group
     #  @ingroup l2_grps_create
     def MakeGroup(self,
@@ -1752,8 +1776,9 @@ class Mesh:
                   CritType=FT_Undefined,
                   Compare=FT_EqualTo,
                   Treshold="",
-                  UnaryOp=FT_Undefined):
-        aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Treshold, UnaryOp, FT_Undefined)
+                  UnaryOp=FT_Undefined,
+                  Tolerance=1e-07):
+        aCriterion = self.smeshpyD.GetCriterion(elementType, CritType, Compare, Treshold, UnaryOp, FT_Undefined,Tolerance)
         group = self.MakeGroupByCriterion(groupName, aCriterion)
         return group
 
@@ -1855,15 +1880,15 @@ class Mesh:
     #  @ingroup l2_grps_operon
     def UnionGroups(self, group1, group2, name):
         return self.mesh.UnionGroups(group1, group2, name)
-        
+
     ## Produces a union list of groups
-    #  New group is created. All mesh elements that are present in 
+    #  New group is created. All mesh elements that are present in
     #  initial groups are added to the new one
     #  @return an instance of SMESH_Group
     #  @ingroup l2_grps_operon
     def UnionListOfGroups(self, groups, name):
       return self.mesh.UnionListOfGroups(groups, name)
-      
+
     ## Prodices an intersection of two groups
     #  A new group is created. All mesh elements that are common
     #  for the two initial groups are added to the new one.
@@ -1871,9 +1896,9 @@ class Mesh:
     #  @ingroup l2_grps_operon
     def IntersectGroups(self, group1, group2, name):
         return self.mesh.IntersectGroups(group1, group2, name)
-        
+
     ## Produces an intersection of groups
-    #  New group is created. All mesh elements that are present in all 
+    #  New group is created. All mesh elements that are present in all
     #  initial groups simultaneously are added to the new one
     #  @return an instance of SMESH_Group
     #  @ingroup l2_grps_operon
@@ -1887,17 +1912,17 @@ class Mesh:
     #  @ingroup l2_grps_operon
     def CutGroups(self, main_group, tool_group, name):
         return self.mesh.CutGroups(main_group, tool_group, name)
-        
+
     ## Produces a cut of groups
-    #  A new group is created. All mesh elements that are present in main groups 
+    #  A new group is created. All mesh elements that are present in main groups
     #  but do not present in tool groups are added to the new one
     #  @return an instance of SMESH_Group
     #  @ingroup l2_grps_operon
     def CutListOfGroups(self, main_groups, tool_groups, name):
       return self.mesh.CutListOfGroups(main_groups, tool_groups, name)
-      
+
     ## Produces a group of elements with specified element type using list of existing groups
-    #  A new group is created. System 
+    #  A new group is created. System
     #  1) extract all nodes on which groups elements are built
     #  2) combine all elements of specified dimension laying on these nodes
     #  @return an instance of SMESH_Group
@@ -1969,6 +1994,13 @@ class Mesh:
     def GetMeshEditor(self):
         return self.mesh.GetMeshEditor()
 
+    ## Wrap a list of IDs of elements or nodes into SMESH_IDSource which
+    #  can be passed as argument to accepting mesh, group or sub-mesh
+    #  @return an instance of SMESH_IDSource
+    #  @ingroup l1_auxiliary
+    def GetIDSource(self, ids, elemType):
+        return self.GetMeshEditor().MakeIDSource(ids, elemType)
+
     ## Gets MED Mesh
     #  @return an instance of SALOME_MED::MESH
     #  @ingroup l1_auxiliary
@@ -2346,7 +2378,7 @@ class Mesh:
     def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False):
         aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2)
         return aMeasure.value
-    
+
     ## Get measure structure specifying minimum distance data between two objects
     #  @param id1 first node/element id
     #  @param id2 second node/element id (if 0, distance from @a id1 to the origin is computed)
@@ -2367,12 +2399,12 @@ class Mesh:
             pass
         else:
             id2 = None
-        
+
         aMeasurements = self.smeshpyD.CreateMeasurements()
         aMeasure = aMeasurements.MinDistance(id1, id2)
         aMeasurements.Destroy()
         return aMeasure
-    
+
     ## Get bounding box of the specified object(s)
     #  @param objects single source object or list of source objects or list of nodes/elements IDs
     #  @param isElem if @a objects is a list of IDs, @c True value in this parameters specifies that @a objects are elements,
@@ -2421,7 +2453,7 @@ class Mesh:
         aMeasure = aMeasurements.BoundingBox(srclist)
         aMeasurements.Destroy()
         return aMeasure
-    
+
     # Mesh edition (SMESH_MeshEditor functionality):
     # ---------------------------------------------
 
@@ -2651,10 +2683,10 @@ class Mesh:
     #  @ingroup l2_modif_throughp
     def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL):
         return self.editor.FindElementsByPoint(x, y, z, elementType)
-        
+
     # Return point state in a closed 2D mesh in terms of TopAbs_State enumeration.
     # TopAbs_UNKNOWN state means that either mesh is wrong or the analysis fails.
-     
+
     def GetPointState(self, x, y, z):
         return self.editor.GetPointState(x, y, z)
 
@@ -2722,7 +2754,7 @@ class Mesh:
             IDsOfElements = self.GetElementsId()
         self.mesh.SetParameters(Parameters)
         Functor = 0
-       if ( isinstance( theCriterion, SMESH._objref_NumericalFunctor ) ):
+        if ( isinstance( theCriterion, SMESH._objref_NumericalFunctor ) ):
             Functor = theCriterion
         else:
             Functor = self.smeshpyD.GetFunctor(theCriterion)
@@ -3044,7 +3076,7 @@ class Mesh:
     #  @param meshName - a name of new mesh to store created boundary elements in,
     #                     "" means not to create the new mesh
     #  @param toCopyElements - if true, the checked elements will be copied into the new mesh
-    #  @param toCopyExistingBondary - if true, not only new but also pre-existing 
+    #  @param toCopyExistingBondary - if true, not only new but also pre-existing
     #                                boundary elements will be copied into the new mesh
     #  @return tuple (mesh, group) where bondary elements were added to
     #  @ingroup l2_modif_edit
@@ -3213,7 +3245,7 @@ class Mesh:
 
     ## Generates new elements by extrusion of the elements with given ids
     #  @param IDsOfElements the list of elements ids for extrusion
-    #  @param StepVector vector, defining the direction and value of extrusion
+    #  @param StepVector vector or DirStruct, defining the direction and value of extrusion
     #  @param NbOfSteps the number of steps
     #  @param MakeGroups forces the generation of new groups from existing ones
     #  @return the list of created groups (SMESH_GroupBase) if MakeGroups=True, empty list otherwise
@@ -3347,7 +3379,10 @@ class Mesh:
         Parameters = AnglesParameters + var_separator + RefPointParameters
         self.mesh.SetParameters(Parameters)
 
-        if isinstance(Base,list):
+        if (isinstance(Path, Mesh)):
+            Path = Path.GetMesh()
+
+        if isinstance(Base, list):
             IDsOfElements = []
             if Base == []: IDsOfElements = self.GetElementsId()
             else: IDsOfElements = Base
@@ -3355,7 +3390,8 @@ class Mesh:
                                                    HasAngles, Angles, LinearVariation,
                                                    HasRefPoint, RefPoint, MakeGroups, ElemType)
         else:
-            if isinstance(Base,Mesh):
+            if isinstance(Base, Mesh): Base = Base.GetMesh()
+            if isinstance(Base, SMESH._objref_SMESH_Mesh) or isinstance(Base, SMESH._objref_SMESH_Group) or isinstance(Base, SMESH._objref_SMESH_subMesh):
                 return self.editor.ExtrusionAlongPathObjX(Base, Path, NodeStart,
                                                           HasAngles, Angles, LinearVariation,
                                                           HasRefPoint, RefPoint, MakeGroups, ElemType)
@@ -3700,7 +3736,7 @@ class Mesh:
         if ( isinstance( theObject, Mesh )):
             theObject = theObject.GetMesh()
         if ( isinstance( theObject, list )):
-            theObject = self.editor.MakeIDSource(theObject, SMESH.ALL)
+            theObject = self.GetIDSource(theObject, SMESH.ALL)
 
         thePoint, Parameters = ParsePointStruct(thePoint)
         self.mesh.SetParameters(Parameters)
@@ -3721,7 +3757,7 @@ class Mesh:
         if (isinstance(theObject, Mesh)):
             theObject = theObject.GetMesh()
         if ( isinstance( theObject, list )):
-            theObject = self.editor.MakeIDSource(theObject,SMESH.ALL)
+            theObject = self.GetIDSource(theObject,SMESH.ALL)
 
         mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact,
                                          MakeGroups, NewMeshName)
@@ -3855,7 +3891,7 @@ class Mesh:
         if not isinstance( exceptNodes, list):
             exceptNodes = [ exceptNodes ]
         if exceptNodes and isinstance( exceptNodes[0], int):
-            exceptNodes = [ self.editor.MakeIDSource( exceptNodes, SMESH.NODE)]
+            exceptNodes = [ self.GetIDSource( exceptNodes, SMESH.NODE)]
         return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,exceptNodes)
 
     ## Merges nodes
@@ -3951,14 +3987,14 @@ class Mesh:
 
      ## Creates a hole in a mesh by doubling the nodes of some particular elements
     #  @param theNodes identifiers of nodes to be doubled
-    #  @param theModifiedElems identifiers of elements to be updated by the new (doubled) 
-    #         nodes. If list of element identifiers is empty then nodes are doubled but 
+    #  @param theModifiedElems identifiers of elements to be updated by the new (doubled)
+    #         nodes. If list of element identifiers is empty then nodes are doubled but
     #         they not assigned to elements
     #  @return TRUE if operation has been completed successfully, FALSE otherwise
     #  @ingroup l2_modif_edit
     def DoubleNodes(self, theNodes, theModifiedElems):
         return self.editor.DoubleNodes(theNodes, theModifiedElems)
-        
+
     ## Creates a hole in a mesh by doubling the nodes of some particular elements
     #  This method provided for convenience works as DoubleNodes() described above.
     #  @param theNodeId identifiers of node to be doubled
@@ -3967,7 +4003,7 @@ class Mesh:
     #  @ingroup l2_modif_edit
     def DoubleNode(self, theNodeId, theModifiedElems):
         return self.editor.DoubleNode(theNodeId, theModifiedElems)
-        
+
     ## Creates a hole in a mesh by doubling the nodes of some particular elements
     #  This method provided for convenience works as DoubleNodes() described above.
     #  @param theNodes group of nodes to be doubled
@@ -3989,18 +4025,18 @@ class Mesh:
     #  @ingroup l2_modif_edit
     def DoubleNodeGroups(self, theNodes, theModifiedElems):
         return self.editor.DoubleNodeGroups(theNodes, theModifiedElems)
-    
+
     ## Creates a hole in a mesh by doubling the nodes of some particular elements
     #  @param theElems - the list of elements (edges or faces) to be replicated
     #         The nodes for duplication could be found from these elements
     #  @param theNodesNot - list of nodes to NOT replicate
-    #  @param theAffectedElems - the list of elements (cells and edges) to which the 
+    #  @param theAffectedElems - the list of elements (cells and edges) to which the
     #         replicated nodes should be associated to.
     #  @return TRUE if operation has been completed successfully, FALSE otherwise
     #  @ingroup l2_modif_edit
     def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems):
         return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems)
-        
+
     ## Creates a hole in a mesh by doubling the nodes of some particular elements
     #  @param theElems - the list of elements (edges or faces) to be replicated
     #         The nodes for duplication could be found from these elements
@@ -4012,7 +4048,7 @@ class Mesh:
     #  @ingroup l2_modif_edit
     def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape):
         return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape)
-    
+
     ## Creates a hole in a mesh by doubling the nodes of some particular elements
     #  This method provided for convenience works as DoubleNodes() described above.
     #  @param theElems - group of of elements (edges or faces) to be replicated
@@ -4036,7 +4072,7 @@ class Mesh:
     #  @ingroup l2_modif_edit
     def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape):
         return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape)
-        
+
     ## Creates a hole in a mesh by doubling the nodes of some particular elements
     #  This method provided for convenience works as DoubleNodes() described above.
     #  @param theElems - list of groups of elements (edges or faces) to be replicated
@@ -4059,7 +4095,7 @@ class Mesh:
     #  @ingroup l2_modif_edit
     def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape):
         return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape)
-        
+
     ## Double nodes on shared faces between groups of volumes and create flat elements on demand.
     # The list of groups must describe a partition of the mesh volumes.
     # The nodes of the internal faces at the boundaries of the groups are doubled.
@@ -4079,27 +4115,27 @@ class Mesh:
         else:
             val = 0
         return val
-        
+
     ## Get length of 1D element.
     #  @param elemId mesh element ID
     #  @return element's length value
     #  @ingroup l1_measurements
     def GetLength(self, elemId):
-        return self._valueFromFunctor(SMESH.FT_Length, elemId)    
+        return self._valueFromFunctor(SMESH.FT_Length, elemId)
 
     ## Get area of 2D element.
     #  @param elemId mesh element ID
     #  @return element's area value
     #  @ingroup l1_measurements
     def GetArea(self, elemId):
-        return self._valueFromFunctor(SMESH.FT_Area, elemId)    
+        return self._valueFromFunctor(SMESH.FT_Area, elemId)
 
     ## Get volume of 3D element.
     #  @param elemId mesh element ID
     #  @return element's volume value
     #  @ingroup l1_measurements
     def GetVolume(self, elemId):
-        return self._valueFromFunctor(SMESH.FT_Volume3D, elemId)    
+        return self._valueFromFunctor(SMESH.FT_Volume3D, elemId)
 
     ## Get maximum element length.
     #  @param elemId mesh element ID
@@ -4110,7 +4146,7 @@ class Mesh:
             ftype = SMESH.FT_MaxElementLength3D
         else:
             ftype = SMESH.FT_MaxElementLength2D
-        return self._valueFromFunctor(ftype, elemId)    
+        return self._valueFromFunctor(ftype, elemId)
 
     ## Get aspect ratio of 2D or 3D element.
     #  @param elemId mesh element ID
@@ -4121,7 +4157,7 @@ class Mesh:
             ftype = SMESH.FT_AspectRatio3D
         else:
             ftype = SMESH.FT_AspectRatio
-        return self._valueFromFunctor(ftype, elemId)    
+        return self._valueFromFunctor(ftype, elemId)
 
     ## Get warping angle of 2D element.
     #  @param elemId mesh element ID
@@ -4340,8 +4376,11 @@ class Mesh_Algorithm:
                 pass
             self.mesh.smeshpyD.SetName(hypo, hyp + a)
             pass
+        geomName=""
+        if self.geom:
+            geomName = GetName(self.geom)
         status = self.mesh.mesh.AddHypothesis(self.geom, hypo)
-        TreatHypoStatus( status, GetName(hypo), GetName(self.geom), 0 )
+        TreatHypoStatus( status, GetName(hypo), geomName, 0 )
         return hypo
 
     ## Returns entry of the shape to mesh in the study
@@ -4424,7 +4463,7 @@ class Mesh_Segment(Mesh_Algorithm):
             pass
         hyp.SetUsePreestimatedLength( length == 0.0 )
         return hyp
-        
+
     ## Defines "NumberOfSegments" hypothesis to cut an edge in a fixed number of segments
     #  @param n for the number of segments that cut an edge
     #  @param s for the scale factor (optional)
@@ -4625,7 +4664,7 @@ class Mesh_Segment(Mesh_Algorithm):
         store_geom = self.geom
         if type(vertex) is types.IntType:
             if vertex == 0 or vertex == 1:
-                vertex = self.mesh.geompyD.SubShapeAllSorted(self.geom, geompyDC.ShapeType["VERTEX"])[vertex]
+                vertex = self.mesh.geompyD.ExtractShapes(self.geom, geompyDC.ShapeType["VERTEX"],True)[vertex]
                 self.geom = vertex
                 pass
             pass
@@ -4884,20 +4923,31 @@ class Mesh_Triangle(Mesh_Algorithm):
         self.Parameters().SetOptionValue(optionName,level)
 
     ## Sets QuadAllowed flag.
-    #  Only for algoType == NETGEN || NETGEN_2D || BLSURF
+    #  Only for algoType == NETGEN(NETGEN_1D2D) || NETGEN_2D || BLSURF
     #  @ingroup l3_hypos_netgen l3_hypos_blsurf
     def SetQuadAllowed(self, toAllow=True):
         if self.algoType == NETGEN_2D:
-            if toAllow: # add QuadranglePreference
-                self.Hypothesis("QuadranglePreference", UseExisting=1, CompareMethod=self.CompareEqualHyp)
-            else:       # remove QuadranglePreference
+            if not self.params:
+                # use simple hyps
+                hasSimpleHyps = False
+                simpleHyps = ["QuadranglePreference","LengthFromEdges","MaxElementArea"]
                 for hyp in self.mesh.GetHypothesisList( self.geom ):
-                    if hyp.GetName() == "QuadranglePreference":
-                        self.mesh.RemoveHypothesis( self.geom, hyp )
+                    if hyp.GetName() in simpleHyps:
+                        hasSimpleHyps = True
+                        if hyp.GetName() == "QuadranglePreference":
+                            if not toAllow: # remove QuadranglePreference
+                                self.mesh.RemoveHypothesis( self.geom, hyp )
+                                pass
+                            return
                         pass
                     pass
+                if hasSimpleHyps:
+                    if toAllow: # add QuadranglePreference
+                        self.Hypothesis("QuadranglePreference", UseExisting=1, CompareMethod=self.CompareEqualHyp)
+                        pass
+                    return
                 pass
-            return
+            pass
         if self.Parameters():
             self.params.SetQuadAllowed(toAllow)
             return
@@ -4906,30 +4956,25 @@ class Mesh_Triangle(Mesh_Algorithm):
     #
     #  @ingroup l3_hypos_netgen
     def Parameters(self, which=SOLE):
-        if self.params:
-            return self.params
-        if self.algoType == NETGEN:
-            if which == SIMPLE:
-                self.params = self.Hypothesis("NETGEN_SimpleParameters_2D", [],
+        if not self.params:
+            if self.algoType == NETGEN:
+                if which == SIMPLE:
+                    self.params = self.Hypothesis("NETGEN_SimpleParameters_2D", [],
+                                                  "libNETGENEngine.so", UseExisting=0)
+                else:
+                    self.params = self.Hypothesis("NETGEN_Parameters_2D", [],
+                                                  "libNETGENEngine.so", UseExisting=0)
+            elif self.algoType == MEFISTO:
+                print "Mefisto algo support no multi-parameter hypothesis"
+            elif self.algoType == NETGEN_2D:
+                self.params = self.Hypothesis("NETGEN_Parameters_2D_ONLY", [],
                                               "libNETGENEngine.so", UseExisting=0)
+            elif self.algoType == BLSURF:
+                self.params = self.Hypothesis("BLSURF_Parameters", [],
+                                              "libBLSURFEngine.so", UseExisting=0)
             else:
-                self.params = self.Hypothesis("NETGEN_Parameters_2D", [],
-                                              "libNETGENEngine.so", UseExisting=0)
-            return self.params
-        elif self.algoType == MEFISTO:
-            print "Mefisto algo support no multi-parameter hypothesis"
-            return None
-        elif self.algoType == NETGEN_2D:
-            print "NETGEN_2D_ONLY algo support no multi-parameter hypothesis"
-            print "NETGEN_2D_ONLY uses 'MaxElementArea' and 'LengthFromEdges' ones"
-            return None
-        elif self.algoType == BLSURF:
-            self.params = self.Hypothesis("BLSURF_Parameters", [],
-                                          "libBLSURFEngine.so", UseExisting=0)
-            return self.params
-        else:
-            print "Mesh_Triangle with algo type %s does not have such a parameter, check algo type"%self.algoType
-        return None
+                print "Mesh_Triangle with algo type %s does not have such a parameter, check algo type"%self.algoType
+        return self.params
 
     ## Sets MaxSize
     #
@@ -5026,14 +5071,14 @@ class Mesh_Quadrangle(Mesh_Algorithm):
     #  @param quadType defines the algorithm of transition between differently descretized
     #                  sides of a geometrical face:
     #  - QUAD_STANDARD - both triangles and quadrangles are possible in the transition
-    #                    area along the finer meshed sides. 
+    #                    area along the finer meshed sides.
     #  - QUAD_TRIANGLE_PREF - only triangles are built in the transition area along the
     #                    finer meshed sides.
     #  - QUAD_QUADRANGLE_PREF - only quadrangles are built in the transition area along
     #                    the finer meshed sides, iff the total quantity of segments on
     #                    all four sides of the face is even (divisible by 2).
     #  - QUAD_QUADRANGLE_PREF_REVERSED - same as QUAD_QUADRANGLE_PREF but the transition
-    #                    area is located along the coarser meshed sides. 
+    #                    area is located along the coarser meshed sides.
     #  - QUAD_REDUCED - only quadrangles are built and the transition between the sides
     #                    is made gradually, layer by layer. This type has a limitation on
     #                    the number of segments: one pair of opposite sides must have the
@@ -5166,33 +5211,34 @@ class Mesh_Tetrahedron(Mesh_Algorithm):
     #
     #  @ingroup l3_hypos_netgen
     def Parameters(self, which=SOLE):
-        if self.params:
-            return self.params
+        if not self.params:
 
-        if self.algoType == FULL_NETGEN:
-            if which == SIMPLE:
-                self.params = self.Hypothesis("NETGEN_SimpleParameters_3D", [],
-                                              "libNETGENEngine.so", UseExisting=0)
-            else:
-                self.params = self.Hypothesis("NETGEN_Parameters", [],
+            if self.algoType == FULL_NETGEN:
+                if which == SIMPLE:
+                    self.params = self.Hypothesis("NETGEN_SimpleParameters_3D", [],
+                                                  "libNETGENEngine.so", UseExisting=0)
+                else:
+                    self.params = self.Hypothesis("NETGEN_Parameters", [],
+                                                  "libNETGENEngine.so", UseExisting=0)
+
+            if self.algoType == NETGEN:
+                self.params = self.Hypothesis("NETGEN_Parameters_3D", [],
                                               "libNETGENEngine.so", UseExisting=0)
-            return self.params
 
-        if self.algoType == GHS3D:
-            self.params = self.Hypothesis("GHS3D_Parameters", [],
-                                          "libGHS3DEngine.so", UseExisting=0)
-            return self.params
+            elif self.algoType == GHS3D:
+                self.params = self.Hypothesis("GHS3D_Parameters", [],
+                                              "libGHS3DEngine.so", UseExisting=0)
 
-        if self.algoType == GHS3DPRL:
-            self.params = self.Hypothesis("GHS3DPRL_Parameters", [],
-                                          "libGHS3DPRLEngine.so", UseExisting=0)
-            return self.params
+            elif self.algoType == GHS3DPRL:
+                self.params = self.Hypothesis("GHS3DPRL_Parameters", [],
+                                              "libGHS3DPRLEngine.so", UseExisting=0)
+            else:
+                print "Algo supports no multi-parameter hypothesis"
 
-        print "Algo supports no multi-parameter hypothesis"
-        return None
+        return self.params
 
     ## Sets MaxSize
-    #  Parameter of FULL_NETGEN
+    #  Parameter of FULL_NETGEN and NETGEN
     #  @ingroup l3_hypos_netgen
     def SetMaxSize(self, theSize):
         self.Parameters().SetMaxSize(theSize)
@@ -5204,7 +5250,7 @@ class Mesh_Tetrahedron(Mesh_Algorithm):
         self.Parameters().SetSecondOrder(theVal)
 
     ## Sets Optimize flag
-    #  Parameter of FULL_NETGEN
+    #  Parameter of FULL_NETGEN and NETGEN
     #  @ingroup l3_hypos_netgen
     def SetOptimize(self, theVal):
         self.Parameters().SetOptimize(theVal)
@@ -5911,7 +5957,7 @@ omniORB.registerObjref(StdMeshers._objref_StdMeshers_LocalLength._NP_RepositoryI
 
 #Wrapper class for StdMeshers_LayerDistribution hypothesis
 class LayerDistribution(StdMeshers._objref_StdMeshers_LayerDistribution):
-    
+
     def SetLayerDistribution(self, hypo):
         StdMeshers._objref_StdMeshers_LayerDistribution.SetParameters(self,hypo.GetParameters())
         hypo.ClearParameters();
@@ -5922,9 +5968,9 @@ omniORB.registerObjref(StdMeshers._objref_StdMeshers_LayerDistribution._NP_Repos
 
 #Wrapper class for StdMeshers_SegmentLengthAroundVertex hypothesis
 class SegmentLengthAroundVertex(StdMeshers._objref_StdMeshers_SegmentLengthAroundVertex):
-    
+
     ## Set Length parameter value
-    #  @param length numerical value or name of variable from notebook    
+    #  @param length numerical value or name of variable from notebook
     def SetLength(self, length):
         length,parameters = ParseParameters(StdMeshers._objref_StdMeshers_SegmentLengthAroundVertex.GetLastParameters(self),1,1,length)
         StdMeshers._objref_StdMeshers_SegmentLengthAroundVertex.SetParameters(self,parameters)
@@ -5936,7 +5982,7 @@ omniORB.registerObjref(StdMeshers._objref_StdMeshers_SegmentLengthAroundVertex._
 
 #Wrapper class for StdMeshers_Arithmetic1D hypothesis
 class Arithmetic1D(StdMeshers._objref_StdMeshers_Arithmetic1D):
-    
+
     ## Set Length parameter value
     #  @param length   numerical value or name of variable from notebook
     #  @param isStart  true is length is Start Length, otherwise false
@@ -5947,15 +5993,15 @@ class Arithmetic1D(StdMeshers._objref_StdMeshers_Arithmetic1D):
         length,parameters = ParseParameters(StdMeshers._objref_StdMeshers_Arithmetic1D.GetLastParameters(self),2,nb,length)
         StdMeshers._objref_StdMeshers_Arithmetic1D.SetParameters(self,parameters)
         StdMeshers._objref_StdMeshers_Arithmetic1D.SetLength(self,length,isStart)
-        
+
 #Registering the new proxy for Arithmetic1D
 omniORB.registerObjref(StdMeshers._objref_StdMeshers_Arithmetic1D._NP_RepositoryId, Arithmetic1D)
 
 #Wrapper class for StdMeshers_Deflection1D hypothesis
 class Deflection1D(StdMeshers._objref_StdMeshers_Deflection1D):
-    
+
     ## Set Deflection parameter value
-    #  @param deflection numerical value or name of variable from notebook    
+    #  @param deflection numerical value or name of variable from notebook
     def SetDeflection(self, deflection):
         deflection,parameters = ParseParameters(StdMeshers._objref_StdMeshers_Deflection1D.GetLastParameters(self),1,1,deflection)
         StdMeshers._objref_StdMeshers_Deflection1D.SetParameters(self,parameters)
@@ -5966,7 +6012,7 @@ omniORB.registerObjref(StdMeshers._objref_StdMeshers_Deflection1D._NP_Repository
 
 #Wrapper class for StdMeshers_StartEndLength hypothesis
 class StartEndLength(StdMeshers._objref_StdMeshers_StartEndLength):
-    
+
     ## Set Length parameter value
     #  @param length  numerical value or name of variable from notebook
     #  @param isStart true is length is Start Length, otherwise false
@@ -5977,54 +6023,54 @@ class StartEndLength(StdMeshers._objref_StdMeshers_StartEndLength):
         length,parameters = ParseParameters(StdMeshers._objref_StdMeshers_StartEndLength.GetLastParameters(self),2,nb,length)
         StdMeshers._objref_StdMeshers_StartEndLength.SetParameters(self,parameters)
         StdMeshers._objref_StdMeshers_StartEndLength.SetLength(self,length,isStart)
-        
+
 #Registering the new proxy for StartEndLength
 omniORB.registerObjref(StdMeshers._objref_StdMeshers_StartEndLength._NP_RepositoryId, StartEndLength)
 
 #Wrapper class for StdMeshers_MaxElementArea hypothesis
 class MaxElementArea(StdMeshers._objref_StdMeshers_MaxElementArea):
-    
+
     ## Set Max Element Area parameter value
     #  @param area  numerical value or name of variable from notebook
     def SetMaxElementArea(self, area):
         area ,parameters = ParseParameters(StdMeshers._objref_StdMeshers_MaxElementArea.GetLastParameters(self),1,1,area)
         StdMeshers._objref_StdMeshers_MaxElementArea.SetParameters(self,parameters)
         StdMeshers._objref_StdMeshers_MaxElementArea.SetMaxElementArea(self,area)
-        
+
 #Registering the new proxy for MaxElementArea
 omniORB.registerObjref(StdMeshers._objref_StdMeshers_MaxElementArea._NP_RepositoryId, MaxElementArea)
 
 
 #Wrapper class for StdMeshers_MaxElementVolume hypothesis
 class MaxElementVolume(StdMeshers._objref_StdMeshers_MaxElementVolume):
-    
+
     ## Set Max Element Volume parameter value
     #  @param volume numerical value or name of variable from notebook
     def SetMaxElementVolume(self, volume):
         volume ,parameters = ParseParameters(StdMeshers._objref_StdMeshers_MaxElementVolume.GetLastParameters(self),1,1,volume)
         StdMeshers._objref_StdMeshers_MaxElementVolume.SetParameters(self,parameters)
         StdMeshers._objref_StdMeshers_MaxElementVolume.SetMaxElementVolume(self,volume)
-        
+
 #Registering the new proxy for MaxElementVolume
 omniORB.registerObjref(StdMeshers._objref_StdMeshers_MaxElementVolume._NP_RepositoryId, MaxElementVolume)
 
 
 #Wrapper class for StdMeshers_NumberOfLayers hypothesis
 class NumberOfLayers(StdMeshers._objref_StdMeshers_NumberOfLayers):
-    
+
     ## Set Number Of Layers parameter value
     #  @param nbLayers  numerical value or name of variable from notebook
     def SetNumberOfLayers(self, nbLayers):
         nbLayers ,parameters = ParseParameters(StdMeshers._objref_StdMeshers_NumberOfLayers.GetLastParameters(self),1,1,nbLayers)
         StdMeshers._objref_StdMeshers_NumberOfLayers.SetParameters(self,parameters)
         StdMeshers._objref_StdMeshers_NumberOfLayers.SetNumberOfLayers(self,nbLayers)
-        
+
 #Registering the new proxy for NumberOfLayers
 omniORB.registerObjref(StdMeshers._objref_StdMeshers_NumberOfLayers._NP_RepositoryId, NumberOfLayers)
 
 #Wrapper class for StdMeshers_NumberOfSegments hypothesis
 class NumberOfSegments(StdMeshers._objref_StdMeshers_NumberOfSegments):
-    
+
     ## Set Number Of Segments parameter value
     #  @param nbSeg numerical value or name of variable from notebook
     def SetNumberOfSegments(self, nbSeg):
@@ -6032,14 +6078,14 @@ class NumberOfSegments(StdMeshers._objref_StdMeshers_NumberOfSegments):
         nbSeg , parameters = ParseParameters(lastParameters,1,1,nbSeg)
         StdMeshers._objref_StdMeshers_NumberOfSegments.SetParameters(self,parameters)
         StdMeshers._objref_StdMeshers_NumberOfSegments.SetNumberOfSegments(self,nbSeg)
-        
+
     ## Set Scale Factor parameter value
     #  @param factor numerical value or name of variable from notebook
     def SetScaleFactor(self, factor):
         factor, parameters = ParseParameters(StdMeshers._objref_StdMeshers_NumberOfSegments.GetLastParameters(self),2,2,factor)
         StdMeshers._objref_StdMeshers_NumberOfSegments.SetParameters(self,parameters)
         StdMeshers._objref_StdMeshers_NumberOfSegments.SetScaleFactor(self,factor)
-        
+
 #Registering the new proxy for NumberOfSegments
 omniORB.registerObjref(StdMeshers._objref_StdMeshers_NumberOfSegments._NP_RepositoryId, NumberOfSegments)
 
@@ -6110,7 +6156,7 @@ if not noNETGENPlugin:
             NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.SetLocalLength(self, length)
 
         ## Set Max Element Area parameter value
-        #  @param area numerical value or name of variable from notebook    
+        #  @param area numerical value or name of variable from notebook
         def SetMaxElementArea(self, area):
             lastParameters = NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_2D.GetLastParameters(self)
             area, parameters = ParseParameters(lastParameters,2,2,area)
@@ -6131,7 +6177,7 @@ if not noNETGENPlugin:
     #Wrapper class for NETGENPlugin_SimpleHypothesis_3D hypothesis
     class NETGEN_SimpleParameters_3D(NETGEN_SimpleParameters_2D,NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_3D):
         ## Set Max Element Volume parameter value
-        #  @param volume numerical value or name of variable from notebook    
+        #  @param volume numerical value or name of variable from notebook
         def SetMaxElementVolume(self, volume):
             lastParameters = NETGENPlugin._objref_NETGENPlugin_SimpleHypothesis_3D.GetLastParameters(self)
             volume, parameters = ParseParameters(lastParameters,3,3,volume)
index b3dac25ab5a604d2ae43fbcbc4c81420e5cb440c..9f4759a596a6bdb55067c9305f56b9c6ce27b6e8 100644 (file)
@@ -120,6 +120,7 @@ namespace // INTERNAL STUFF
   enum _ListenerDataType
     {
       WAIT_HYP_MODIF=1, // data indicating awaiting for valid parameters of src hyp
+      LISTEN_SRC_MESH, // data storing submesh depending on source mesh state
       SRC_HYP // data storing ImportSource hyp
     };
   //================================================================================
@@ -130,10 +131,29 @@ namespace // INTERNAL STUFF
   struct _ListenerData : public SMESH_subMeshEventListenerData
   {
     const StdMeshers_ImportSource1D* _srcHyp;
-    _ListenerData(const StdMeshers_ImportSource1D* h):
+    _ListenerData(const StdMeshers_ImportSource1D* h, _ListenerDataType type=SRC_HYP):
       SMESH_subMeshEventListenerData(/*isDeletable=*/true), _srcHyp(h)
     {
-      myType = SRC_HYP; 
+      myType = type; 
+    }
+  };
+  //================================================================================
+  /*!
+   * \brief Comparator of sub-meshes
+   */
+  struct _SubLess
+  {
+    bool operator()(const SMESH_subMesh* sm1, const SMESH_subMesh* sm2 ) const
+    {
+      if ( sm1 == sm2 ) return false;
+      if ( !sm1 || !sm2 ) return sm1 < sm2;
+      const TopoDS_Shape& s1 = sm1->GetSubShape();
+      const TopoDS_Shape& s2 = sm2->GetSubShape();
+      TopAbs_ShapeEnum t1 = s1.IsNull() ? TopAbs_SHAPE : s1.ShapeType();
+      TopAbs_ShapeEnum t2 = s2.IsNull() ? TopAbs_SHAPE : s2.ShapeType();
+      if ( t1 == t2)
+        return (sm1 < sm2);
+      return t1 < t2; // to have: face < edge
     }
   };
   //================================================================================
@@ -146,10 +166,10 @@ namespace // INTERNAL STUFF
     StdMeshers_Import_1D::TNodeNodeMap _n2n;
     StdMeshers_Import_1D::TElemElemMap _e2e;
 
-    set< SMESH_subMesh*> _subM; // submeshes relating to this srcMesh
-    set< SMESH_subMesh*> _copyMeshSubM; // submeshes requesting mesh copying
-    set< SMESH_subMesh*> _copyGroupSubM; // submeshes requesting mesh copying
-    set< SMESH_subMesh*> _computedSubM;
+    set< SMESH_subMesh*, _SubLess > _subM; // submeshes relating to this srcMesh
+    set< SMESH_subMesh*, _SubLess > _copyMeshSubM; // submeshes requesting mesh copying
+    set< SMESH_subMesh*, _SubLess > _copyGroupSubM; // submeshes requesting mesh copying
+    set< SMESH_subMesh*, _SubLess > _computedSubM;
 
     SMESHDS_SubMesh*     _importMeshSubDS; // submesh storing a copy of _srcMesh
     int                  _importMeshSubID; // id of _importMeshSubDS
@@ -196,10 +216,30 @@ namespace // INTERNAL STUFF
       if ( toCopyGroups ) _copyGroupSubM.insert( sm );
       else                _copyGroupSubM.erase( sm );
     }
+    void addComputed( SMESH_subMesh* sm )
+    {
+      SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true,
+                                                               /*complexShapeFirst=*/true);
+      while ( smIt->more() )
+      {
+        sm = smIt->next();
+        switch ( sm->GetSubShape().ShapeType() )
+        {
+        case TopAbs_EDGE:
+        case TopAbs_FACE:
+          _subM.insert( sm );
+          if ( !sm->IsEmpty() )
+            _computedSubM.insert( sm );
+        case TopAbs_VERTEX:
+          break;
+        default:;
+        }
+      }
+    }
   };
   //================================================================================
   /*!
-   * Listener notified on events of an imported submesh
+   * Listener notified on events relating to imported submesh
    */
   class _Listener : public SMESH_subMeshEventListener
   {
@@ -212,198 +252,248 @@ namespace // INTERNAL STUFF
     // return poiter to a static listener
     static _Listener* get() { static _Listener theListener; return &theListener; }
 
-    //--------------------------------------------------------------------------------
-    /*!
-     * \brief Find or create ImportData for given meshes
-     */
-    static _ImportData* getImportData(const SMESH_Mesh* srcMesh,
-                                       SMESH_Mesh*       tgtMesh)
-    {
-      list< _ImportData >& dList = get()->_tgtMesh2ImportData[tgtMesh];
-      list< _ImportData >::iterator d = dList.begin();
-      for ( ; d != dList.end(); ++d )
-        if ( d->_srcMesh == srcMesh )
-          return &*d;
-      dList.push_back(_ImportData(srcMesh));
-      return &dList.back();
-    }
+    static _ImportData* getImportData(const SMESH_Mesh* srcMesh, SMESH_Mesh* tgtMesh);
 
-    //--------------------------------------------------------------------------------
-    /*!
-     * \brief Remember an imported mesh and groups 
-     *  \param smDS - submesh DS holding the imported mesh
-     *  \param sm - submesh computed by Import algo
-     *  \param srcMeshDS - source mesh
-     *  \param srcHyp - ImportSource hypothesis
-     */
-    static _ImportData* storeImportSubmesh(SMESH_subMesh*                   importSub,
-                                           const SMESH_Mesh*                srcMesh,
-                                           const StdMeshers_ImportSource1D* srcHyp)
-    {
-      // set listener to hear events of the submesh computed by "Import" algo
-      importSub->SetEventListener( get(), new _ListenerData(srcHyp), importSub );
-
-      // set a listener to hear events of the source mesh
-      SMESH_subMesh* smToNotify = importSub;
-      SMESH_subMesh* smToListen = srcMesh->GetSubMeshContaining(1);
-      importSub->SetEventListener
-        ( new SMESH_subMeshEventListener(/*isDeletable=*/true),
-          SMESH_subMeshEventListenerData::MakeData( smToNotify ),
-          smToListen );
-
-      // remeber the submesh
-      _ImportData* iData = _Listener::getImportData( srcMesh, importSub->GetFather());
-      iData->_subM.insert( importSub );
-      iData->trackHypParams( importSub, srcHyp );
-      if ( !importSub->IsEmpty() )
-        iData->_computedSubM.insert( importSub );
-      if ( !iData->_copyMeshSubM.empty() && iData->_importMeshSubID < 1 )
-      {
-        SMESH_Mesh* tgtMesh = importSub->GetFather();
-        iData->_importMeshSubID = getSubmeshIDForCopiedMesh( srcMesh->GetMeshDS(),tgtMesh);
-        iData->_importMeshSubDS = tgtMesh->GetMeshDS()->NewSubMesh( iData->_importMeshSubID );
-      }
-      if ( !importSub->IsEmpty() )
-        iData->_computedSubM.insert( importSub );
+    static void storeImportSubmesh(SMESH_subMesh*                   importSub,
+                                   const SMESH_Mesh*                srcMesh,
+                                   const StdMeshers_ImportSource1D* srcHyp);
 
-      return iData;
-    }
-    //--------------------------------------------------------------------------------
-    /*!
-     * \brief mark sm as missing src hyp with valid groups
-     */
+    virtual void ProcessEvent(const int                       event,
+                              const int                       eventType,
+                              SMESH_subMesh*                  subMesh,
+                              SMESH_subMeshEventListenerData* data,
+                              const SMESH_Hypothesis*         hyp);
+    void removeSubmesh( SMESH_subMesh* sm, _ListenerData* data );
+    void clearSubmesh ( SMESH_subMesh* sm, _ListenerData* data, bool clearAllSub );
+
+    // mark sm as missing src hyp with valid groups
     static void waitHypModification(SMESH_subMesh* sm)
     {
       sm->SetEventListener
         (get(), SMESH_subMeshEventListenerData::MakeData( sm, WAIT_HYP_MODIF ), sm);
     }
+  };
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief Find or create ImportData for given meshes
+   */
+  _ImportData* _Listener::getImportData(const SMESH_Mesh* srcMesh,
+                                        SMESH_Mesh*       tgtMesh)
+  {
+    list< _ImportData >& dList = get()->_tgtMesh2ImportData[tgtMesh];
+    list< _ImportData >::iterator d = dList.begin();
+    for ( ; d != dList.end(); ++d )
+      if ( d->_srcMesh == srcMesh )
+        return &*d;
+    dList.push_back(_ImportData(srcMesh));
+    return &dList.back();
+  }
 
-    //--------------------------------------------------------------------------------
-    /*!
-     * \brief Remove imported mesh and/or groups as soon as no more imported submeshes
-     *               remain computed
-     *  \param sm - submesh loosing Import algo
-     *  \param data - data holding imported groups
-     */
-    void removeSubmesh( SMESH_subMesh* sm, _ListenerData* data )
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief Remember an imported sub-mesh and set needed even listeners
+   *  \param importSub - submesh computed by Import algo
+   *  \param srcMesh - source mesh
+   *  \param srcHyp - ImportSource hypothesis
+   */
+  void _Listener::storeImportSubmesh(SMESH_subMesh*                   importSub,
+                                     const SMESH_Mesh*                srcMesh,
+                                     const StdMeshers_ImportSource1D* srcHyp)
+  {
+    // set listener to hear events of the submesh computed by "Import" algo
+    importSub->SetEventListener( get(), new _ListenerData(srcHyp), importSub );
+
+    // set a listener to hear events of the source mesh
+    SMESH_subMesh* smToNotify = importSub;
+    SMESH_subMesh* smToListen = srcMesh->GetSubMeshContaining(1);
+    SMESH_subMeshEventListenerData* data = new _ListenerData(srcHyp, LISTEN_SRC_MESH);
+    data->mySubMeshes.push_back( smToNotify );
+    importSub->SetEventListener( get(), data, smToListen );
+
+    // remeber the submesh importSub and its sub-submeshes
+    _ImportData* iData = _Listener::getImportData( srcMesh, importSub->GetFather());
+    iData->trackHypParams( importSub, srcHyp );
+    iData->addComputed( importSub );
+    if ( !iData->_copyMeshSubM.empty() && iData->_importMeshSubID < 1 )
     {
-      list< _ImportData > &  dList = _tgtMesh2ImportData[ sm->GetFather() ];
-      list< _ImportData >::iterator d = dList.begin();
-      for ( ; d != dList.end(); ++d )
-        if ( (*d)._subM.erase( sm ))
+      SMESH_Mesh* tgtMesh = importSub->GetFather();
+      iData->_importMeshSubID = getSubmeshIDForCopiedMesh( srcMesh->GetMeshDS(),tgtMesh);
+      iData->_importMeshSubDS = tgtMesh->GetMeshDS()->NewSubMesh( iData->_importMeshSubID );
+    }
+  }
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief Remove imported mesh and/or groups if needed
+   *  \param sm - submesh loosing Import algo
+   *  \param data - data holding imported groups
+   */
+  void _Listener::removeSubmesh( SMESH_subMesh* sm, _ListenerData* data )
+  {
+    list< _ImportData > &  dList = _tgtMesh2ImportData[ sm->GetFather() ];
+    list< _ImportData >::iterator d = dList.begin();
+    for ( ; d != dList.end(); ++d )
+      if ( (*d)._subM.erase( sm ))
+      {
+        d->_computedSubM.erase( sm );
+        bool rmMesh   = d->_copyMeshSubM.erase( sm ) && d->_copyMeshSubM.empty();
+        bool rmGroups = (d->_copyGroupSubM.erase( sm ) && d->_copyGroupSubM.empty()) || rmMesh;
+        if ( rmMesh )
+          d->removeImportedMesh( sm->GetFather()->GetMeshDS() );
+        if ( rmGroups && data )
+          d->removeGroups( sm, data->_srcHyp );
+      }
+  }
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief Clear submeshes and remove imported mesh and/or groups if necessary
+   *  \param sm - cleared submesh
+   *  \param data - data holding imported groups
+   */
+  void _Listener::clearSubmesh(SMESH_subMesh* sm, _ListenerData* data, bool clearAllSub)
+  {
+    list< _ImportData > &  dList = _tgtMesh2ImportData[ sm->GetFather() ];
+    list< _ImportData >::iterator d = dList.begin();
+    for ( ; d != dList.end(); ++d )
+    {
+      if ( !d->_subM.count( sm )) continue;
+      if ( (*d)._computedSubM.erase( sm ) )
+      {
+        bool copyMesh = !d->_copyMeshSubM.empty();
+        if ( copyMesh || clearAllSub )
         {
-          d->_computedSubM.erase( sm );
-          bool rmMesh   = d->_copyMeshSubM.erase( sm ) && d->_copyMeshSubM.empty();
-          bool rmGroups = (d->_copyGroupSubM.erase( sm ) && d->_copyGroupSubM.empty()) || rmMesh;
-          if ( rmMesh )
-            d->removeImportedMesh( sm->GetFather()->GetMeshDS() );
-          if ( rmGroups && data )
+          // remove imported mesh and groups
+          d->removeImportedMesh( sm->GetFather()->GetMeshDS() );
+
+          if ( data )
             d->removeGroups( sm, data->_srcHyp );
+
+          // clear the rest submeshes
+          if ( !d->_computedSubM.empty() )
+          {
+            set< SMESH_subMesh*, _SubLess> subs;
+            subs.swap( d->_computedSubM ); // avoid recursion via events
+            while ( !subs.empty() )
+            {
+              SMESH_subMesh* subM = *subs.begin(); subs.erase( subs.begin() );
+              _ListenerData* hypData = (_ListenerData*) subM->GetEventListenerData( get() );
+              if ( hypData )
+                d->removeGroups( sm, hypData->_srcHyp );
+
+              subM->ComputeStateEngine( SMESH_subMesh::CLEAN );
+              if ( subM->GetSubShape().ShapeType() == TopAbs_FACE )
+                subM->ComputeSubMeshStateEngine( SMESH_subMesh::CLEAN );
+            }
+          }
         }
+        sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
+        if ( sm->GetSubShape().ShapeType() == TopAbs_FACE )
+          sm->ComputeSubMeshStateEngine( SMESH_subMesh::CLEAN );
+      }
+      if ( data )
+        d->trackHypParams( sm, data->_srcHyp );
+      d->_n2n.clear();
+      d->_e2e.clear();
     }
-    //--------------------------------------------------------------------------------
-    /*!
-     * \brief Remove imported mesh and/or groups and
-     * clear all submeshes with common source mesh
-     *  \param sm - cleared submesh
-     *  \param data - data holding imported groups
-     */
-    void clearSubmesh( SMESH_subMesh* sm, _ListenerData* data )
+  }
+  //--------------------------------------------------------------------------------
+  /*!
+   * \brief Remove imported mesh and/or groups
+   */
+  void _Listener::ProcessEvent(const int                       event,
+                               const int                       eventType,
+                               SMESH_subMesh*                  subMesh,
+                               SMESH_subMeshEventListenerData* data,
+                               const SMESH_Hypothesis*         /*hyp*/)
+  {
+    if ( data && data->myType == WAIT_HYP_MODIF )
     {
-      list< _ImportData > &  dList = _tgtMesh2ImportData[ sm->GetFather() ];
-      list< _ImportData >::iterator d = dList.begin();
-      for ( ; d != dList.end(); ++d )
+      // event of Import submesh
+      if ( SMESH_subMesh::MODIF_HYP  == event &&
+           SMESH_subMesh::ALGO_EVENT == eventType )
       {
-        if ( !d->_subM.count( sm )) continue;
-        if ( (*d)._computedSubM.erase( sm ) )
-        {
-          bool copyMesh = !d->_copyMeshSubM.empty();
-          if ( copyMesh )
+        // re-call SetEventListener() to take into account valid parameters
+        // of ImportSource hypothesis
+        SMESH_Gen* gen = subMesh->GetFather()->GetGen();
+        if ( SMESH_Algo* algo = gen->GetAlgo(*subMesh->GetFather(), subMesh->GetSubShape()))
+          algo->SetEventListener( subMesh );
+      }
+    }
+    else if ( data && data->myType == LISTEN_SRC_MESH )
+    {
+      // event of source mesh
+      if ( SMESH_subMesh::COMPUTE_EVENT == eventType )
+      {
+        switch ( event ) {
+        case SMESH_subMesh::CLEAN:
+          // source mesh cleaned -> clean target mesh
+          clearSubmesh( data->mySubMeshes.front(), (_ListenerData*) data, /*all=*/true );
+          break;
+        case SMESH_subMesh::SUBMESH_COMPUTED: {
+          // source mesh computed -> reset FAILED state of Import submeshes to
+          // READY_TO_COMPUTE
+          SMESH_Mesh* srcMesh = subMesh->GetFather();
+          if ( srcMesh->NbEdges() > 0 || srcMesh->NbFaces() > 0 )
           {
-            // clear submeshes
-            if ( !d->_computedSubM.empty() )
+            SMESH_Mesh* m = data->mySubMeshes.front()->GetFather();
+            if ( SMESH_subMesh* sm1 = m->GetSubMeshContaining(1))
             {
-              set< SMESH_subMesh*> subs;
-              subs.swap( d->_computedSubM ); // avoid recursion via events
-              while ( !subs.empty() )
-              {
-                SMESH_subMesh* subM = *subs.begin(); subs.erase( subs.begin() );
-                _ListenerData* hypData = (_ListenerData*) subM->GetEventListenerData( get() );
-                if ( hypData )
-                  d->removeGroups( sm, hypData->_srcHyp );
-                
-                subM->ComputeStateEngine( SMESH_subMesh::CLEAN );
-              }
+              sm1->ComputeStateEngine(SMESH_subMesh::SUBMESH_COMPUTED );
+              sm1->ComputeSubMeshStateEngine( SMESH_subMesh::SUBMESH_COMPUTED );
             }
-            // remove imported mesh and groups
-            d->removeImportedMesh( sm->GetFather()->GetMeshDS() );
-
-            if ( data )
-              d->removeGroups( sm, data->_srcHyp );
           }
+          break;
+        }
+        default:;
         }
-        if ( data )
-          d->trackHypParams( sm, data->_srcHyp );
-        d->_n2n.clear();
-        d->_e2e.clear();
       }
     }
-    //--------------------------------------------------------------------------------
-    /*!
-     * \brief Remove imported mesh and/or groups
-     */
-    virtual void ProcessEvent(const int                       event,
-                              const int                       eventType,
-                              SMESH_subMesh*                  subMesh,
-                              SMESH_subMeshEventListenerData* data,
-                              const SMESH_Hypothesis*         /*hyp*/)
+    else // event of Import submesh
     {
-      if ( data && data->myType == WAIT_HYP_MODIF )
+      // find out what happens: import hyp modified or removed
+      bool removeImport = false, modifHyp = false;
+      if ( SMESH_subMesh::ALGO_EVENT == eventType )
+        modifHyp = true;
+      if ( subMesh->GetAlgoState() != SMESH_subMesh::HYP_OK )
       {
-        if ( SMESH_subMesh::MODIF_HYP  == event &&
-             SMESH_subMesh::ALGO_EVENT == eventType )
-        {
-          SMESH_Gen* gen = subMesh->GetFather()->GetGen();
-          if ( SMESH_Algo* algo = gen->GetAlgo(*subMesh->GetFather(), subMesh->GetSubShape()))
-            algo->SetEventListener( subMesh );
-        }
+        removeImport = true;
       }
-      else
+      else if ( SMESH_subMesh::REMOVE_ALGO == event ||
+                SMESH_subMesh::REMOVE_FATHER_ALGO == event )
       {
         SMESH_Gen* gen = subMesh->GetFather()->GetGen();
         SMESH_Algo* algo = gen->GetAlgo(*subMesh->GetFather(),subMesh->GetSubShape() );
+        removeImport = ( strncmp( "Import", algo->GetName(), 6 ) != 0 );
+      }
 
-        if ( subMesh->GetAlgoState() != SMESH_subMesh::HYP_OK ||
-             strncmp( "Import", algo->GetName(), 6 ) != 0 )
-        {
-          // treate removal of Import algo from subMesh
-          removeSubmesh( subMesh, (_ListenerData*) data );
-        }
-        else if ( subMesh->IsEmpty() )
-        {
-          // treate modification of ImportSource hypothesis
-          clearSubmesh( subMesh, (_ListenerData*) data );
-        }
-        else if ( SMESH_subMesh::CHECK_COMPUTE_STATE == event &&
-                  SMESH_subMesh::COMPUTE_EVENT       == eventType )
-        {
-          // check compute state of all submeshes impoting from same src mesh;
-          // this is to take into account 1D computed submeshes hidden by 2D import algo;
-          // else source mesh is not copied as _subM.size != _computedSubM.size()
-          list< _ImportData > &  dList = _tgtMesh2ImportData[ subMesh->GetFather() ];
-          list< _ImportData >::iterator d = dList.begin();
-          for ( ; d != dList.end(); ++d )
-            if ( d->_subM.count( subMesh ))
-            {
-              set<SMESH_subMesh*>::iterator smIt = d->_subM.begin();
-              for( ; smIt != d->_subM.end(); ++smIt )
-                if ( (*smIt)->IsMeshComputed() )
-                  d->_computedSubM.insert( *smIt);
-            }
-        }
+      if ( removeImport )
+      {
+        // treate removal of Import algo from subMesh
+        removeSubmesh( subMesh, (_ListenerData*) data );
+      }
+      else if ( modifHyp )
+      {
+        // treate modification of ImportSource hypothesis
+        clearSubmesh( subMesh, (_ListenerData*) data, /*all=*/false );
+      }
+      else if ( SMESH_subMesh::CHECK_COMPUTE_STATE == event &&
+                SMESH_subMesh::COMPUTE_EVENT       == eventType )
+      {
+        // check compute state of all submeshes impoting from same src mesh;
+        // this is to take into account 1D computed submeshes hidden by 2D import algo;
+        // else source mesh is not copied as _subM.size != _computedSubM.size()
+        list< _ImportData > &  dList = _tgtMesh2ImportData[ subMesh->GetFather() ];
+        list< _ImportData >::iterator d = dList.begin();
+        for ( ; d != dList.end(); ++d )
+          if ( d->_subM.count( subMesh ))
+          {
+            set<SMESH_subMesh*>::iterator smIt = d->_subM.begin();
+            for( ; smIt != d->_subM.end(); ++smIt )
+              if ( (*smIt)->IsMeshComputed() )
+                d->_computedSubM.insert( *smIt);
+          }
       }
     }
-  }; // class _Listener
+  }
 
   //================================================================================
   /*!
@@ -495,7 +585,7 @@ namespace // INTERNAL STUFF
     _ImportData* iData = _Listener::getImportData(srcMesh,tgtMesh);
 
     SMESH_subMesh* importedSM = tgtMesh->GetSubMesh( tgtShape );
-    iData->_computedSubM.insert( importedSM );
+    iData->addComputed( importedSM );
     if ( iData->_computedSubM.size() != iData->_subM.size() )
       return 0; // not all submeshes computed yet
 
@@ -543,8 +633,8 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th
   subShapeIDs.insert( shapeID );
 
   // get nodes on vertices
-  list < SMESH_MeshEditor::TNodeXYZ > vertexNodes;
 list < SMESH_MeshEditor::TNodeXYZ >::iterator vNIt;
+  list < SMESH_MeshEditor::TNodeXYZ > vertexNodes; 
+ list < SMESH_MeshEditor::TNodeXYZ >::iterator vNIt;
   TopExp_Explorer vExp( theShape, TopAbs_VERTEX );
   for ( ; vExp.More(); vExp.Next() )
   {
index 5d89cd1282e9a291ca504e885b00f682b763355f..2d98c671f03081b9505f09acc712ca027771c906 100644 (file)
@@ -153,8 +153,8 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
   const bool toCheckOri = (helper.NbAncestors( geomFace, theMesh, TopAbs_SOLID ) == 1 );
 
   Handle(Geom_Surface) surface = BRep_Tool::Surface( geomFace );
-  if ( helper.GetSubShapeOri( tgtMesh->ShapeToMesh(), geomFace) == TopAbs_REVERSED )
-    surface->UReverse();
+  const bool reverse = 
+    ( helper.GetSubShapeOri( tgtMesh->ShapeToMesh(), geomFace) == TopAbs_REVERSED );
   gp_Pnt p; gp_Vec du, dv;
 
   set<int> subShapeIDs;
@@ -262,7 +262,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
         {
           uv = helper.GetNodeUV( geomFace, newNodes[++iNode] );
           surface->D1( uv.X(),uv.Y(), p, du,dv );
-          geomNorm = du ^ dv;
+          geomNorm = reverse ? dv^du : du^dv;
         }
         while ( geomNorm.SquareMagnitude() < 1e-6 && iNode+1 < face->NbCornerNodes());
 
@@ -341,7 +341,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
       int nbFaces = link2Nb->second;
       if ( nbFaces == 1 )
       {
-        // check if the link lie on face boundary
+        // check if a not shared link lie on face boundary
         bool nodesOnBoundary = true;
         list< TopoDS_Shape > bndShapes;
         for ( int is1stN = 0; is1stN < 2 && nodesOnBoundary; ++is1stN )
@@ -356,6 +356,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
                 if ( Abs(u-f) < 2 * faceTol || Abs(u-l) < 2 * faceTol )
                   // duplicated node on vertex
                   return error("Source elements overlap one another");
+                tgtSM->RemoveNode( n, /*isNodeDeleted=*/false );
                 tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)n, edges[iE], u );
                 break;
               }
@@ -371,10 +372,10 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
           }
         }
         if ( !nodesOnBoundary )
-          break; // free internal link
+          break; // error: free internal link
         if ( bndShapes.front().ShapeType() == TopAbs_EDGE &&
              bndShapes.front() != bndShapes.back() )
-          break; // link nodes on different geom edges
+          break; // error: link nodes on different geom edges
 
         // find geom edge the link is on
         if ( bndShapes.back().ShapeType() != TopAbs_EDGE )
@@ -389,7 +390,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
               geomEdge.Nullify();
           }
           if ( geomEdge.IsNull() )
-            break; // vertices belong to different edges -> free internal link
+            break; // vertices belong to different edges -> error: free internal link
           bndShapes.push_back( geomEdge );
         }
 
@@ -407,15 +408,13 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
 
           TopoDS_Edge geomEdge = TopoDS::Edge(bndShapes.back());
           helper.CheckNodeU( geomEdge, link._medium, u, 10*faceTol, /*force=*/true );
+          tgtSM->RemoveNode( link._medium, /*isNodeDeleted=*/false );
           tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)link._medium, geomEdge, u );
         }
         else
         {
           edge = tgtMesh->AddEdge( newNodes[0], newNodes[1]);
         }
-        // remove nodes from submesh of theShape
-        for ( unsigned i = 0; i < newNodes.size(); ++i )
-          tgtSM->RemoveNode( newNodes[i], /*isNodeDeleted=*/false );
         if ( !edge )
           return false;
 
index 86edbacfda44b4c686139bcbf8486f20d54ecd49..7749da81cde82538d63d274f4a758802cdc149d3 100644 (file)
@@ -1082,6 +1082,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
   TopTools_IndexedMapOfShape vMap1, vMap2;
   TopExp::MapShapes( theShape1, TopAbs_VERTEX, vMap1 );
   TopExp::MapShapes( theShape2, TopAbs_VERTEX, vMap2 );
+  TopoDS_Vertex VV1[2], VV2[2];
 
   if ( vMap1.Extent() != vMap2.Extent() )
     RETURN_BAD_RESULT("Different nb of vertices");
@@ -1095,6 +1096,32 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
     return FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap);
   }
 
+  // Try to associate by common vertices of an edge
+  for ( int i = 1; i <= vMap1.Extent(); ++i )
+  {
+    const TopoDS_Shape& v1 = vMap1(i);
+    if ( vMap2.Contains( v1 ))
+    {
+      // find an egde sharing v1 and sharing at the same time another common vertex
+      PShapeIteratorPtr edgeIt = SMESH_MesherHelper::GetAncestors( v1, *theMesh1, TopAbs_EDGE);
+      bool edgeFound = false;
+      while ( edgeIt->more() && !edgeFound )
+      {
+        TopoDS_Edge edge = TopoDS::Edge( edgeIt->next()->Oriented(TopAbs_FORWARD));
+        TopExp::Vertices(edge, VV1[0], VV1[1]);
+        if ( !VV1[0].IsSame( VV1[1] ))
+          edgeFound = ( vMap2.Contains( VV1[ v1.IsSame(VV1[0]) ? 1:0]));
+      }
+      if ( edgeFound )
+      {
+        InsertAssociation( VV1[0], VV1[0], theMap, bidirect );
+        InsertAssociation( VV1[1], VV1[1], theMap, bidirect );
+        if (FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap ))
+          return true;
+      }
+    }
+  }
+
   // Find transformation to make the shapes be of similar size at same location
 
   Bnd_Box box[2];
@@ -1116,7 +1143,6 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the
 
   // Find 2 closest vertices
 
-  TopoDS_Vertex VV1[2], VV2[2];
   // get 2 linked vertices of shape 1 not belonging to an inner wire of a face
   TopoDS_Shape edge = theShape1;
   TopExp_Explorer expF( theShape1, TopAbs_FACE ), expE;
index 25b472c3eed3d427ee6152666f49627d9f60f2b7..4b9731812d578edd6ef48583a2028d46dc2a9062 100644 (file)
@@ -82,10 +82,10 @@ namespace
     SMESH_MeshEditor::TNodeXYZ Pj( Nrem );
 
     // an apex node to make common to all merged pyramids
+    if (PrmI->GetVtkType() != VTK_PYRAMID) throw SALOME_Exception(LOCALIZED("not a pyramid"));
     SMDS_MeshNode* CommonNode = const_cast<SMDS_MeshNode*>(PrmI->GetNode(4));
     if ( CommonNode == Nrem ) return; // already merged
     int nbI = CommonNode->NbInverseElements( SMDSAbs_Volume );
-    //cerr << __LINE__ << " " << nbI << " " << nbJ << endl;
     SMESH_MeshEditor::TNodeXYZ Pi( CommonNode );
     gp_XYZ Pnew = ( nbI*Pi + nbJ*Pj ) / (nbI+nbJ);
     CommonNode->setXYZ( Pnew.X(), Pnew.Y(), Pnew.Z() );
@@ -116,7 +116,6 @@ namespace
     }
 
     // set the common apex node to pyramids and triangles merged with J
-    //cerr <<  __LINE__ << " NbInverseElements " << Nrem->NbInverseElements() << endl;
     SMDS_ElemIteratorPtr itJ = Nrem->GetInverseElementIterator();
     while ( itJ->more() )
     {
@@ -124,22 +123,15 @@ namespace
       if ( elem->GetType() == SMDSAbs_Volume ) // pyramid
       {
         vector< const SMDS_MeshNode* > nodes( elem->begin_nodes(), elem->end_nodes() );
-        //cerr << __LINE__ << " volId " << elem->GetID() << " nbNodes " << nodes.size() << endl;
         nodes[4] = CommonNode;
         MESSAGE("ChangeElementNodes");
         meshDS->ChangeElementNodes( elem, &nodes[0], nodes.size());
       }
       else if ( tempTrias.count(elem) ) // tmp triangles
       {
-        //cerr << __LINE__ << " triaId " << elem->GetID() << endl;
         ((SMDS_VtkFace*) elem )->ChangeApex( CommonNode );
       }
-//      else
-//        {
-//          cerr <<  __LINE__ << " other " << elem->GetVtkType() << endl;
-//        }
     }
-    //cerr <<  __LINE__ << " NbInverseElements " << Nrem->NbInverseElements() << endl;
     ASSERT( Nrem->NbInverseElements() == 0 );
     meshDS->RemoveFreeNode( Nrem,
                             meshDS->MeshElements( Nrem->getshapeId()),
@@ -157,6 +149,8 @@ namespace
                          const SMDS_MeshElement* PrmJ,
                          const bool              hasShape)
   {
+    if (PrmI->GetVtkType() != VTK_PYRAMID) throw SALOME_Exception(LOCALIZED("not a pyramid"));
+    if (PrmJ->GetVtkType() != VTK_PYRAMID) throw SALOME_Exception(LOCALIZED("not a pyramid"));
     const SMDS_MeshNode* nApexI = PrmI->GetNode(4);
     const SMDS_MeshNode* nApexJ = PrmJ->GetNode(4);
     if ( nApexI == nApexJ ||
@@ -264,6 +258,7 @@ namespace
                      TRemTrias &                tempTrias,
                      set<const SMDS_MeshNode*>& nodesToMove)
   {
+    if (PrmI->GetVtkType() != VTK_PYRAMID) throw SALOME_Exception(LOCALIZED("not a pyramid"));
     TIDSortedElemSet adjacentPyrams, mergedPyrams;
     for(int k=0; k<4; k++) // loop on 4 base nodes of PrmI
     {
@@ -302,6 +297,8 @@ namespace
 StdMeshers_QuadToTriaAdaptor::StdMeshers_QuadToTriaAdaptor():
   myElemSearcher(0), myNbTriangles(0)
 {
+  myResMap.clear();
+  myTempTriangles.clear();
 }
 
 //================================================================================
@@ -1003,6 +1000,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh)
     return true;
 
   SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+  if (myPyramids[0]->GetVtkType() != VTK_PYRAMID) throw SALOME_Exception(LOCALIZED("not a pyramid"));
   int i, j, k, myShapeID = myPyramids[0]->GetNode(4)->getshapeId();
 
   if ( !myElemSearcher )
@@ -1016,6 +1014,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh)
   for ( i = 0; i <  myPyramids.size(); ++i )
   {
     const SMDS_MeshElement* PrmI = myPyramids[i];
+    if (PrmI->GetVtkType() != VTK_PYRAMID) throw SALOME_Exception(LOCALIZED("not a pyramid"));
     MergeAdjacent( PrmI, aMesh, myTempTriangles, nodesToMove );
   }
 
@@ -1023,6 +1022,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh)
   for ( i = 0; i <  myPyramids.size(); ++i )
   {
     const SMDS_MeshElement* PrmI = myPyramids[i];
+    if (PrmI->GetVtkType() != VTK_PYRAMID) throw SALOME_Exception(LOCALIZED("not a pyramid"));
 
     // compare PrmI with all the rest pyramids
 
@@ -1051,6 +1051,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh)
       for ( j = 0; j < suspectPyrams.size(); ++j )
       {
         const SMDS_MeshElement* PrmJ = suspectPyrams[j];
+        //if (PrmJ->GetVtkType() != VTK_PYRAMID) throw SALOME_Exception(LOCALIZED("not a pyramid"));
         if ( PrmJ == PrmI || PrmJ->NbCornerNodes() != 5 )
           continue;
         if ( myShapeID != PrmJ->GetNode(4)->getshapeId())
@@ -1135,12 +1136,12 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh)
 
   } // loop on all pyramids
 
-  if( !nodesToMove.empty() && !meshDS->IsEmbeddedMode() )
-  {
-    set<const SMDS_MeshNode*>::iterator n = nodesToMove.begin();
-    for ( ; n != nodesToMove.end(); ++n )
-      meshDS->MoveNode( *n, (*n)->X(), (*n)->Y(), (*n)->Z() );
-  }
+//  if( !nodesToMove.empty() && !meshDS->IsEmbeddedMode() )
+//  {
+//    set<const SMDS_MeshNode*>::iterator n = nodesToMove.begin();
+//    for ( ; n != nodesToMove.end(); ++n )
+//      meshDS->MoveNode( *n, (*n)->X(), (*n)->Y(), (*n)->Z() );
+//  }
 
   // rebind triangles of pyramids sharing the same base quadrangle to the first
   // entrance of the base quadrangle
@@ -1148,31 +1149,30 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh)
   for ( ++q2t; q2t != myResMap.end(); ++q2t, ++q2tPrev )
   {
     if ( q2t->first == q2tPrev->first )
-      {
-        //cerr << __LINE__ << " splice" << endl;
-        q2tPrev->second.splice( q2tPrev->second.end(), q2t->second );
-      }
+      q2tPrev->second.splice( q2tPrev->second.end(), q2t->second );
   }
   // delete removed triangles and count resulting nb of triangles
   for (q2t = myResMap.begin(); q2t != myResMap.end(); ++q2t)
     {
       TTriaList & trias = q2t->second;
-      vector<const SMDS_MeshFace*> faceToErase;
+      set<const SMDS_MeshFace*> faceToErase;
       faceToErase.clear();
-      //cerr << __LINE__ << " " << trias.size() << endl;
       for (TTriaList::iterator tri = trias.begin(); tri != trias.end(); ++tri)
         {
-          //cerr <<  "  " << __LINE__ << endl;
           const SMDS_MeshFace* face = *tri;
           if (myTempTriangles.count(face) && (myTempTriangles[face] == false))
-            faceToErase.push_back(face);
+            faceToErase.insert(face);
           else
             myNbTriangles++;
         }
-      for (vector<const SMDS_MeshFace*>::iterator it = faceToErase.begin(); it != faceToErase.end(); ++it)
+      for (set<const SMDS_MeshFace*>::iterator it = faceToErase.begin(); it != faceToErase.end(); ++it)
         {
           const SMDS_MeshFace *face = dynamic_cast<const SMDS_MeshFace*>(*it);
-          if (face) trias.remove(face);
+          if (face)
+            {
+              trias.remove(face);
+              myTempTriangles.erase(face);
+            }
           meshDS->RemoveFreeElement(face, 0, false);
         }
     }