From: vsr Date: Thu, 25 Nov 2010 12:44:43 +0000 (+0000) Subject: Merge from V5_1_main branch 24/11/2010 X-Git-Tag: V6_2_0a1~11 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=d8f644ca3d4ce62f2ef41d4aacb52f5bb1221df3;p=modules%2Fsmesh.git Merge from V5_1_main branch 24/11/2010 --- diff --git a/clean_configure b/clean_configure index 366520874..05e43a7ff 100755 --- a/clean_configure +++ b/clean_configure @@ -28,6 +28,6 @@ find bin -name Makefile.in | xargs rm -f find doc -name Makefile.in | xargs rm -f find idl -name Makefile.in | xargs rm -f find resources -name Makefile.in | xargs rm -f -find salome_adm -name Makefile.in | xargs rm -f +find adm_local -name Makefile.in | xargs rm -f find src -name Makefile.in | xargs rm -f rm -f Makefile.in diff --git a/configure.ac b/configure.ac index aeb288943..7b39b99c8 100644 --- a/configure.ac +++ b/configure.ac @@ -24,7 +24,7 @@ # Modified by : Alexander BORODIN (OCN) - autotools usage # Created from configure.in.base # -AC_INIT([Salome2 Project SMESH module], [6.1.0], [webmaster.salome@opencascade.com], [SalomeSMESH]) +AC_INIT([Salome2 Project SMESH module], [6.2.0], [webmaster.salome@opencascade.com], [SalomeSMESH]) AC_CONFIG_AUX_DIR(adm_local/unix/config_files) AC_CANONICAL_HOST AC_CANONICAL_TARGET @@ -355,6 +355,13 @@ echo CHECK_HTML_GENERATORS +echo +echo --------------------------------------------- +echo testing sphinx +echo --------------------------------------------- +echo +CHECK_SPHINX + echo echo --------------------------------------------- echo Testing Kernel @@ -390,11 +397,11 @@ echo echo Configure if test "${gui_ok}" = "yes"; then - variables="cc_ok fortran_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok OpenGL_ok qt_ok vtk_ok hdf5_ok omniORB_ok occ_ok doxygen_ok graphviz_ok qwt_ok Kernel_ok Geom_ok Med_ok gui_ok" + variables="cc_ok fortran_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok OpenGL_ok qt_ok vtk_ok hdf5_ok omniORB_ok occ_ok doxygen_ok graphviz_ok sphinx_ok qwt_ok Kernel_ok Geom_ok Med_ok gui_ok" elif test "${SalomeGUI_need}" != "no"; then - variables="cc_ok fortran_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok hdf5_ok omniORB_ok occ_ok doxygen_ok graphviz_ok Kernel_ok Geom_ok Med_ok gui_ok" + variables="cc_ok fortran_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok hdf5_ok omniORB_ok occ_ok doxygen_ok graphviz_ok sphinx_ok Kernel_ok Geom_ok Med_ok gui_ok" else - variables="cc_ok fortran_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok hdf5_ok omniORB_ok occ_ok doxygen_ok graphviz_ok Kernel_ok Geom_ok Med_ok" + variables="cc_ok fortran_ok boost_ok lex_yacc_ok python_ok swig_ok threads_ok hdf5_ok omniORB_ok occ_ok doxygen_ok graphviz_ok sphinx_ok Kernel_ok Geom_ok Med_ok" fi for var in $variables @@ -435,6 +442,19 @@ echo # chmod +x ./bin/salome/*; \ #]) +AC_CONFIG_COMMANDS([hack_libtool],[ +sed -i "s%^CC=\"\(.*\)\"%hack_libtool (){ \n\ + if test \"\$(echo \$[@] | grep -E '\\\-L/usr/lib(/../lib)?(64)? ')\" == \"\" \n\ + then\n\ + cmd=\"\1 \$[@]\"\n\ + else\n\ + cmd=\"\1 \"\`echo \$[@] | sed -r -e 's|(.*)-L/usr/lib(/../lib)?(64)? (.*)|\\\1\\\4 -L/usr/lib\\\3|g'\`\n\ + fi\n\ + \$cmd\n\ +}\n\ +CC=\"hack_libtool\"%g" libtool +],[]) + # This list is initiated using autoscan and must be updated manually # when adding a new file .in to manage. When you execute # autoscan, the Makefile list is generated in the output file configure.scan. @@ -448,6 +468,7 @@ AC_OUTPUT([ \ bin/Makefile \ SMESH_version.h \ doc/Makefile \ + doc/docutils/Makefile \ doc/salome/Makefile \ doc/salome/gui/Makefile \ doc/salome/gui/SMESH/Makefile \ @@ -479,6 +500,7 @@ AC_OUTPUT([ \ src/StdMeshers/Makefile \ src/StdMeshersGUI/Makefile \ src/StdMeshers_I/Makefile \ + src/SMESH_PY/Makefile \ resources/Makefile \ resources/SMESHCatalog.xml \ idl/Makefile \ diff --git a/doc/Makefile.am b/doc/Makefile.am index f40fb81a5..6cf4c8ea2 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -24,7 +24,7 @@ # $Header$ # source path # -SUBDIRS = salome +SUBDIRS = salome docutils usr_docs: (cd salome && $(MAKE) $(AM_MAKEFLAGS) usr_docs) diff --git a/doc/docutils/Makefile.am b/doc/docutils/Makefile.am new file mode 100644 index 000000000..a757dd6f7 --- /dev/null +++ b/doc/docutils/Makefile.am @@ -0,0 +1,91 @@ +# -*- coding: iso-8859-1 -*- +# 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 + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +pydocdir = $(docdir)/tui/SMESH/docutils + +.PHONY : latex + +if SPHINX_IS_OK + +html/index.html:$(RSTFILES) + make htm + +endif + +SPHINXOPTS = +SOURCEDIR = $(srcdir) +SPHINXBUILD = sphinx-build +PAPEROPT_a4 = -D latex_paper_size=a4 +ALLSPHINXOPTS = -d doctrees $(PAPEROPT_a4) $(SPHINXOPTS) $(SOURCEDIR) + +SPHINX_PYTHONPATH = $(prefix)/lib/python$(PYTHON_VERSION)/site-packages/salome:$(prefix)/lib64/python$(PYTHON_VERSION)/site-packages/salome:$(KERNEL_ROOT_DIR)/bin/salome:$(KERNEL_ROOT_DIR)/lib/python$(PYTHON_VERSION)/site-packages/salome:$(KERNEL_ROOT_DIR)/lib64/python$(PYTHON_VERSION)/site-packages/salome:$(OMNIORB_ROOT)/lib/python$(PYTHON_VERSION)/site-packages:$(OMNIORB_ROOT)/lib64/python$(PYTHON_VERSION)/site-packages + +SPHINX_LD_LIBRARY_PATH = $(KERNEL_ROOT_DIR)/lib/salome:$(OMNIORB_ROOT)/lib + +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 + @echo + @echo "Build finished. The HTML pages are in html." + +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 + @echo + @echo "Build finished; the LaTeX files are in latex." + @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ + "run these through (pdf)latex." + +html: + mkdir -p $@ + +RSTFILES= \ + index.rst \ + overview.rst \ + docapi.rst + +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; \ + cp -rf $$b"html"/* $(pydocdir) ; \ + if test -f $$b"latex"/smeshpy.pdf; then cp -f $$b"latex"/smeshpy.pdf $(pydocdir) ; fi; + +uninstall-local: + -test -d $(pydocdir) && chmod -R +w $(pydocdir) && rm -rf $(pydocdir)/* + +clean-local: + -rm -rf html latex doctrees + if test -d "html"; then rm -rf html ; fi + +disthook : + -test -d html && cp -Rp html $(distdir) diff --git a/doc/docutils/conf.py b/doc/docutils/conf.py new file mode 100644 index 000000000..84a74a570 --- /dev/null +++ b/doc/docutils/conf.py @@ -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 = '5.1.4' +# The full version, including alpha/beta/rc tags. +release = '5.1.4' + +# 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 +# " v 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/. +html_copy_source = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a 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/docapi.rst b/doc/docutils/docapi.rst new file mode 100644 index 000000000..b39c124dc --- /dev/null +++ b/doc/docutils/docapi.rst @@ -0,0 +1,17 @@ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + Documentation of the programming interface (API) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +This section describes the python packages and modules of the +``salome.smesh`` python package. The main part is generated from the +code documentation included in source python files. + +:mod:`salome.smesh` -- Package containing the SMESH python utilities +==================================================================== + +:mod:`smeshstudytools` -- Tools to access SMESH objects in the study +-------------------------------------------------------------------- + +.. automodule:: salome.smesh.smeshstudytools + :members: diff --git a/doc/docutils/index.rst b/doc/docutils/index.rst new file mode 100644 index 000000000..fece6eff2 --- /dev/null +++ b/doc/docutils/index.rst @@ -0,0 +1,14 @@ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + Documentation of the SMESH python packages +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +Main documentation +================== + +.. toctree:: + :maxdepth: 3 + + overview.rst + docapi.rst + diff --git a/doc/docutils/overview.rst b/doc/docutils/overview.rst new file mode 100644 index 000000000..5ab13766a --- /dev/null +++ b/doc/docutils/overview.rst @@ -0,0 +1,24 @@ + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +General presentation of the SMESH python package +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +The SMESH python package contains (today) helpser functions to +manipulate mesh elements and interact with this elements. + +Note that these functions either encapsulate the python programming +interface of SMESH core (the CORBA or SWIG interface for example) or +extend existing utilities as the ``smesh.py`` module. + +The functions are distributed in the python package +``salome.smesh``. + +The specification of the programming interface of this package is +detailled in the part :doc:`Documentation of the programming interface +(API)` of this documentation. + +.. note:: + The main package ``salome`` contains other sub-packages that are + distributed with the other SALOME modules. For example, the KERNEL + module provides the python package ``salome.kernel`` and GEOM the + package ``salome.geom``. diff --git a/doc/salome/gui/SMESH/Makefile.am b/doc/salome/gui/SMESH/Makefile.am index 187295302..1bb1e9bee 100755 --- a/doc/salome/gui/SMESH/Makefile.am +++ b/doc/salome/gui/SMESH/Makefile.am @@ -31,42 +31,40 @@ guidoc_DATA = images/head.png usr_docs: doxyfile_py doxyfile - echo "===========================================" ; \ - echo "Generating Python interface documentation"; \ - echo "===========================================" ; \ - $(DOXYGEN) doxyfile_py ; \ - echo "===========================================" ; \ - echo "Replacing smeshDC by smesh" ; \ - echo "===========================================" ; \ - files=`find smeshpy_doc -type f` ; \ - for filen in $${files} ; do \ - sed -e "s/\/smesh/g" -e "s/smesh\.smesh/smesh/g" \ - -e "s/smesh::smesh/smesh/g" $${filen} > $${filen}_ ; \ - mv -f $${filen}_ $${filen} ; \ - done ; \ - echo "===========================================" ; \ - echo "Generating GUI documentation" ; \ - echo "===========================================" ; \ - $(DOXYGEN) doxyfile ; + echo "===========================================" ; \ + echo "Replacing smeshDC by smesh" ; \ + echo "===========================================" ; \ + sed -e "/class smeshDC/d" -e "s/^ *#/#/g" -e "s/^ *def /def /g" \ + -e "s/smeshDC/smesh/g" $(top_srcdir)/src/SMESH_SWIG/smeshDC.py > \ + $(top_builddir)/src/SMESH_SWIG/smesh.py ; \ + echo "===========================================" ; \ + echo "Generating Python interface documentation"; \ + echo "===========================================" ; \ + $(DOXYGEN) doxyfile_py ; \ + echo "===========================================" ; \ + echo "Generating GUI documentation" ; \ + echo "===========================================" ; \ + $(DOXYGEN) doxyfile ; \ + rm -f $(top_builddir)/src/SMESH_SWIG/smesh.py docs: usr_docs clean-local: - @for filen in `find . -maxdepth 1` ; do \ + @for filen in `find . -maxdepth 1` ; do \ case $${filen} in \ ./Makefile | ./doxyfile | ./doxyfile_py ) ;; \ - . | .. ) ;; \ + . | .. | ./static ) ;; \ *) echo "Removing $${filen}" ; rm -rf $${filen} ;; \ esac ; \ done ; install-data-local: usr_docs $(INSTALL) -d $(DESTDIR)$(docdir)/gui/SMESH - @for filen in `find . -maxdepth 1` ; do \ + @for filen in `find . -maxdepth 1` ; do \ case $${filen} in \ ./Makefile | ./doxyfile | ./doxyfile_py ) ;; \ ./doxyfile.bak | ./doxyfile_py.bak ) ;; \ - . | .. ) ;; \ + . | .. | ./static ) ;; \ *) echo "Installing $${filen}" ; cp -rp $${filen} $(DESTDIR)$(docdir)/gui/SMESH ;; \ esac ; \ done ; diff --git a/doc/salome/gui/SMESH/doxyfile.in b/doc/salome/gui/SMESH/doxyfile.in index ce268972f..535cc57c7 100755 --- a/doc/salome/gui/SMESH/doxyfile.in +++ b/doc/salome/gui/SMESH/doxyfile.in @@ -70,3 +70,4 @@ GENERATE_RTF = NO #External reference options #--------------------------------------------------------------------------- TAGFILES = smeshpy_doc.tag=smeshpy_doc +SEARCHENGINE = YES diff --git a/doc/salome/gui/SMESH/doxyfile_py.in b/doc/salome/gui/SMESH/doxyfile_py.in index 6d45aa6b5..6053cdfd0 100755 --- a/doc/salome/gui/SMESH/doxyfile_py.in +++ b/doc/salome/gui/SMESH/doxyfile_py.in @@ -98,8 +98,8 @@ EXAMPLE_RECURSIVE = NO #--------------------------------------------------------------------------- #Input related options #--------------------------------------------------------------------------- -INPUT = @top_srcdir@/src/SMESH_SWIG -FILE_PATTERNS = smeshDC.py +INPUT = @top_builddir@/src/SMESH_SWIG +FILE_PATTERNS = smesh.py IMAGE_PATH = @srcdir@/images RECURSIVE = NO EXAMPLE_PATH = @top_srcdir@/src/SMESH_SWIG @@ -157,3 +157,4 @@ DOT_CLEANUP = YES #External reference options #--------------------------------------------------------------------------- GENERATE_TAGFILE = smeshpy_doc.tag +SEARCHENGINE = YES \ No newline at end of file diff --git a/doc/salome/gui/SMESH/images/2d_from_3d_dlg.png b/doc/salome/gui/SMESH/images/2d_from_3d_dlg.png new file mode 100644 index 000000000..a03530978 Binary files /dev/null and b/doc/salome/gui/SMESH/images/2d_from_3d_dlg.png differ diff --git a/doc/salome/gui/SMESH/images/2d_from_3d_ico.png b/doc/salome/gui/SMESH/images/2d_from_3d_ico.png new file mode 100644 index 000000000..b0842d3e7 Binary files /dev/null and b/doc/salome/gui/SMESH/images/2d_from_3d_ico.png differ diff --git a/doc/salome/gui/SMESH/images/2d_from_3d_menu.png b/doc/salome/gui/SMESH/images/2d_from_3d_menu.png index ec5117214..acb7b349e 100644 Binary files a/doc/salome/gui/SMESH/images/2d_from_3d_menu.png and b/doc/salome/gui/SMESH/images/2d_from_3d_menu.png differ diff --git a/doc/salome/gui/SMESH/images/a-averagelength.png b/doc/salome/gui/SMESH/images/a-averagelength.png index 70e2afd26..c8ca5ac77 100755 Binary files a/doc/salome/gui/SMESH/images/a-averagelength.png and b/doc/salome/gui/SMESH/images/a-averagelength.png differ diff --git a/doc/salome/gui/SMESH/images/a-clipping2.png b/doc/salome/gui/SMESH/images/a-clipping2.png index bfac4cea5..9d1249c68 100755 Binary files a/doc/salome/gui/SMESH/images/a-clipping2.png and b/doc/salome/gui/SMESH/images/a-clipping2.png differ diff --git a/doc/salome/gui/SMESH/images/advanced_mesh_infos.png b/doc/salome/gui/SMESH/images/advanced_mesh_infos.png index 2dc9f8f48..d8bdbc6e5 100755 Binary files a/doc/salome/gui/SMESH/images/advanced_mesh_infos.png and b/doc/salome/gui/SMESH/images/advanced_mesh_infos.png differ diff --git a/doc/salome/gui/SMESH/images/bnd_box.png b/doc/salome/gui/SMESH/images/bnd_box.png new file mode 100644 index 000000000..6761a76ff Binary files /dev/null and b/doc/salome/gui/SMESH/images/bnd_box.png differ diff --git a/doc/salome/gui/SMESH/images/bnd_box_preview.png b/doc/salome/gui/SMESH/images/bnd_box_preview.png new file mode 100644 index 000000000..902101cf3 Binary files /dev/null and b/doc/salome/gui/SMESH/images/bnd_box_preview.png differ diff --git a/doc/salome/gui/SMESH/images/creategroup.png b/doc/salome/gui/SMESH/images/creategroup.png index 2fb825cc8..eefc9e275 100755 Binary files a/doc/salome/gui/SMESH/images/creategroup.png and b/doc/salome/gui/SMESH/images/creategroup.png differ diff --git a/doc/salome/gui/SMESH/images/duplicate01.png b/doc/salome/gui/SMESH/images/duplicate01.png new file mode 100644 index 000000000..b35c7785f Binary files /dev/null and b/doc/salome/gui/SMESH/images/duplicate01.png differ diff --git a/doc/salome/gui/SMESH/images/duplicate02.png b/doc/salome/gui/SMESH/images/duplicate02.png new file mode 100644 index 000000000..1b5cfabc5 Binary files /dev/null and b/doc/salome/gui/SMESH/images/duplicate02.png differ diff --git a/doc/salome/gui/SMESH/images/duplicate_nodes.png b/doc/salome/gui/SMESH/images/duplicate_nodes.png new file mode 100644 index 000000000..61ff32bcd Binary files /dev/null and b/doc/salome/gui/SMESH/images/duplicate_nodes.png differ diff --git a/doc/salome/gui/SMESH/images/editgroup.png b/doc/salome/gui/SMESH/images/editgroup.png index ac9e8a2c1..2d8cb8dd0 100755 Binary files a/doc/salome/gui/SMESH/images/editgroup.png and b/doc/salome/gui/SMESH/images/editgroup.png differ diff --git a/doc/salome/gui/SMESH/images/elem_info.png b/doc/salome/gui/SMESH/images/elem_info.png new file mode 100644 index 000000000..9937d6d88 Binary files /dev/null and b/doc/salome/gui/SMESH/images/elem_info.png differ diff --git a/doc/salome/gui/SMESH/images/eleminfo1.png b/doc/salome/gui/SMESH/images/eleminfo1.png index a93a622f1..4d12b54b1 100755 Binary files a/doc/salome/gui/SMESH/images/eleminfo1.png and b/doc/salome/gui/SMESH/images/eleminfo1.png differ diff --git a/doc/salome/gui/SMESH/images/eleminfo2.png b/doc/salome/gui/SMESH/images/eleminfo2.png index c417b6d25..26cfae365 100755 Binary files a/doc/salome/gui/SMESH/images/eleminfo2.png and b/doc/salome/gui/SMESH/images/eleminfo2.png differ diff --git a/doc/salome/gui/SMESH/images/formula5.png b/doc/salome/gui/SMESH/images/formula5.png new file mode 100644 index 000000000..823ba068d Binary files /dev/null and b/doc/salome/gui/SMESH/images/formula5.png differ diff --git a/doc/salome/gui/SMESH/images/hexotic_parameters.png b/doc/salome/gui/SMESH/images/hexotic_parameters.png index c06ff3bb2..5f4bb3df5 100644 Binary files a/doc/salome/gui/SMESH/images/hexotic_parameters.png and b/doc/salome/gui/SMESH/images/hexotic_parameters.png differ diff --git a/doc/salome/gui/SMESH/images/hyp_source_edges.png b/doc/salome/gui/SMESH/images/hyp_source_edges.png new file mode 100644 index 000000000..2305e178b Binary files /dev/null and b/doc/salome/gui/SMESH/images/hyp_source_edges.png differ diff --git a/doc/salome/gui/SMESH/images/hyp_source_faces.png b/doc/salome/gui/SMESH/images/hyp_source_faces.png new file mode 100644 index 000000000..fe9e6c62c Binary files /dev/null and b/doc/salome/gui/SMESH/images/hyp_source_faces.png differ diff --git a/doc/salome/gui/SMESH/images/hypo_quad_params_dialog.png b/doc/salome/gui/SMESH/images/hypo_quad_params_dialog.png new file mode 100644 index 000000000..3cd442a8d Binary files /dev/null and b/doc/salome/gui/SMESH/images/hypo_quad_params_dialog.png differ diff --git a/doc/salome/gui/SMESH/images/image42.png b/doc/salome/gui/SMESH/images/image42.png new file mode 100755 index 000000000..d0120fa1e Binary files /dev/null and b/doc/salome/gui/SMESH/images/image42.png differ diff --git a/doc/salome/gui/SMESH/images/image43.png b/doc/salome/gui/SMESH/images/image43.png new file mode 100755 index 000000000..7b6b895a1 Binary files /dev/null and b/doc/salome/gui/SMESH/images/image43.png differ diff --git a/doc/salome/gui/SMESH/images/image49.png b/doc/salome/gui/SMESH/images/image49.png index 74926d244..6e5b3176b 100755 Binary files a/doc/salome/gui/SMESH/images/image49.png and b/doc/salome/gui/SMESH/images/image49.png differ diff --git a/doc/salome/gui/SMESH/images/image79.jpg b/doc/salome/gui/SMESH/images/image79.jpg index 6d164167f..0efc73695 100755 Binary files a/doc/salome/gui/SMESH/images/image79.jpg and b/doc/salome/gui/SMESH/images/image79.jpg differ diff --git a/doc/salome/gui/SMESH/images/image99.gif b/doc/salome/gui/SMESH/images/image99.gif index 4959ed825..2672e99f3 100755 Binary files a/doc/salome/gui/SMESH/images/image99.gif and b/doc/salome/gui/SMESH/images/image99.gif differ diff --git a/doc/salome/gui/SMESH/images/max_element_length_2d.png b/doc/salome/gui/SMESH/images/max_element_length_2d.png new file mode 100755 index 000000000..012d552f5 Binary files /dev/null and b/doc/salome/gui/SMESH/images/max_element_length_2d.png differ diff --git a/doc/salome/gui/SMESH/images/max_element_length_3d.png b/doc/salome/gui/SMESH/images/max_element_length_3d.png new file mode 100755 index 000000000..fdf1b7688 Binary files /dev/null and b/doc/salome/gui/SMESH/images/max_element_length_3d.png differ diff --git a/doc/salome/gui/SMESH/images/mergenodes.png b/doc/salome/gui/SMESH/images/mergenodes.png index 024bc22e8..54cb3d17a 100755 Binary files a/doc/salome/gui/SMESH/images/mergenodes.png and b/doc/salome/gui/SMESH/images/mergenodes.png differ diff --git a/doc/salome/gui/SMESH/images/mergenodes_auto.png b/doc/salome/gui/SMESH/images/mergenodes_auto.png index b2920867c..71511d22e 100644 Binary files a/doc/salome/gui/SMESH/images/mergenodes_auto.png and b/doc/salome/gui/SMESH/images/mergenodes_auto.png differ diff --git a/doc/salome/gui/SMESH/images/meshtopass.png b/doc/salome/gui/SMESH/images/meshtopass.png index 9a5c62e24..1c426783e 100755 Binary files a/doc/salome/gui/SMESH/images/meshtopass.png and b/doc/salome/gui/SMESH/images/meshtopass.png differ diff --git a/doc/salome/gui/SMESH/images/min_distance.png b/doc/salome/gui/SMESH/images/min_distance.png new file mode 100644 index 000000000..765522e88 Binary files /dev/null and b/doc/salome/gui/SMESH/images/min_distance.png differ diff --git a/doc/salome/gui/SMESH/images/min_distance_preview.png b/doc/salome/gui/SMESH/images/min_distance_preview.png new file mode 100644 index 000000000..c5373d99f Binary files /dev/null and b/doc/salome/gui/SMESH/images/min_distance_preview.png differ diff --git a/doc/salome/gui/SMESH/images/moving_nodes1.png b/doc/salome/gui/SMESH/images/moving_nodes1.png index 2bae38850..295b3a38f 100755 Binary files a/doc/salome/gui/SMESH/images/moving_nodes1.png and b/doc/salome/gui/SMESH/images/moving_nodes1.png differ diff --git a/doc/salome/gui/SMESH/images/moving_nodes2.png b/doc/salome/gui/SMESH/images/moving_nodes2.png index b65e57ae9..a89e8b36b 100755 Binary files a/doc/salome/gui/SMESH/images/moving_nodes2.png and b/doc/salome/gui/SMESH/images/moving_nodes2.png differ diff --git a/doc/salome/gui/SMESH/images/netgen2d.png b/doc/salome/gui/SMESH/images/netgen2d.png deleted file mode 100644 index 29e09ef13..000000000 Binary files a/doc/salome/gui/SMESH/images/netgen2d.png and /dev/null differ diff --git a/doc/salome/gui/SMESH/images/netgen2d3d.png b/doc/salome/gui/SMESH/images/netgen2d3d.png new file mode 100644 index 000000000..e3949e249 Binary files /dev/null and b/doc/salome/gui/SMESH/images/netgen2d3d.png differ diff --git a/doc/salome/gui/SMESH/images/netgen2d3d_simple.png b/doc/salome/gui/SMESH/images/netgen2d3d_simple.png new file mode 100644 index 000000000..50ca0a060 Binary files /dev/null and b/doc/salome/gui/SMESH/images/netgen2d3d_simple.png differ diff --git a/doc/salome/gui/SMESH/images/netgen3d_local_size.png b/doc/salome/gui/SMESH/images/netgen3d_local_size.png new file mode 100644 index 000000000..f7bcd18b9 Binary files /dev/null and b/doc/salome/gui/SMESH/images/netgen3d_local_size.png differ diff --git a/doc/salome/gui/SMESH/images/netgen3d_simple.png b/doc/salome/gui/SMESH/images/netgen3d_simple.png deleted file mode 100644 index 959ec02c8..000000000 Binary files a/doc/salome/gui/SMESH/images/netgen3d_simple.png and /dev/null differ diff --git a/doc/salome/gui/SMESH/images/remove_nodes_icon.png b/doc/salome/gui/SMESH/images/remove_nodes_icon.png new file mode 100644 index 000000000..0818837ef Binary files /dev/null and b/doc/salome/gui/SMESH/images/remove_nodes_icon.png differ diff --git a/doc/salome/gui/SMESH/images/remove_orphan_nodes_icon.png b/doc/salome/gui/SMESH/images/remove_orphan_nodes_icon.png new file mode 100644 index 000000000..16df2e592 Binary files /dev/null and b/doc/salome/gui/SMESH/images/remove_orphan_nodes_icon.png differ diff --git a/doc/salome/gui/SMESH/images/removeorphannodes.png b/doc/salome/gui/SMESH/images/removeorphannodes.png new file mode 100644 index 000000000..fdf839559 Binary files /dev/null and b/doc/salome/gui/SMESH/images/removeorphannodes.png differ diff --git a/doc/salome/gui/SMESH/images/split_into_tetra.png b/doc/salome/gui/SMESH/images/split_into_tetra.png index bc88b1169..fce071e7d 100644 Binary files a/doc/salome/gui/SMESH/images/split_into_tetra.png and b/doc/salome/gui/SMESH/images/split_into_tetra.png differ diff --git a/doc/salome/gui/SMESH/input/1d_meshing_hypo.doc b/doc/salome/gui/SMESH/input/1d_meshing_hypo.doc index aba2b6598..367a0d0b5 100644 --- a/doc/salome/gui/SMESH/input/1d_meshing_hypo.doc +++ b/doc/salome/gui/SMESH/input/1d_meshing_hypo.doc @@ -5,7 +5,7 @@
  • \ref arithmetic_1d_anchor "Arithmetic 1D"
  • -
  • \ref average_length_anchor "Average Length"
  • +
  • \ref average_length_anchor "Local Length"
  • \ref max_length_anchor "Max Size"
  • \ref deflection_1d_anchor "Deflection 1D"
  • \ref number_of_segments_anchor "Number of segments"
  • @@ -57,9 +57,9 @@ locations and 1D mesh elements are constructed on segments.
    \anchor average_length_anchor -

    Average Length hypothesis

    +

    Local Length hypothesis

    -Average Length hypothesis can be applied for meshing of edges +Local Length hypothesis can be applied for meshing of edges composing your geometrical object. Definition of this hypothesis consists of setting the \b length of segments, which will split these edges, and the \b precision of rounding. The points on the edges @@ -79,10 +79,10 @@ integer. Default value is 1e-07. \image html a-averagelength.png -\image html b-erage_length.png "Average length hypothesis - all 1D mesh elements are roughly equal" +\image html b-erage_length.png "Local Length hypothesis - all 1D mesh elements are roughly equal" See Also a sample TUI Script of a -\ref tui_average_length "Defining Average Length" hypothesis +\ref tui_average_length "Defining Local Length" hypothesis operation.
    \anchor max_length_anchor @@ -157,7 +157,7 @@ operation. Start and End Length hypothesis allows to divide a geometrical edge into segments so that the first and the last segments have a specified -length. The length medium segments changes with automatically chosen +length. The length of medium segments changes with automatically chosen geometric progression. Then mesh nodes are constructed at segment ends location and 1D mesh elements are constructed on them. diff --git a/doc/salome/gui/SMESH/input/2d_meshing_hypo.doc b/doc/salome/gui/SMESH/input/2d_meshing_hypo.doc index 892cc9f74..d72e4d504 100644 --- a/doc/salome/gui/SMESH/input/2d_meshing_hypo.doc +++ b/doc/salome/gui/SMESH/input/2d_meshing_hypo.doc @@ -43,27 +43,58 @@ length calculated as an average edge length for a given wire. \anchor hypo_quad_params_anchor

    Quadrangle parameters

    -Quadrangle parameters is a hypothesis for -Quadrangle (Mapping), which allows using this algorithm for meshing of -triangular faces.In this case it is necessary to select the Base vertex -used as a degenerated edge. +\image html hypo_quad_params_dialog.png "Quadrangle parameters creation/edition dialog" + +Quadrangle parameters is a hypothesis for Quadrangle (Mapping). + +Base vertex parameter allows using Quadrangle (Mapping) +algorithm for meshing of triangular faces. In this case it is +necessary to select the vertex, which will be used as the fourth edge +(degenerated). \image html hypo_quad_params_1.png "A face built from 3 edges" \image html hypo_quad_params_res.png "The resulting mesh" -This hypothesis can be also used to mesh a segment of a circular face. -Please, consider that there is a limitation on the selectiion of the degenerated +This parameter can be also used to mesh a segment of a circular face. +Please, consider that there is a limitation on the selection of the vertex for the faces built with the angle > 180 degrees (see the picture). \image html hypo_quad_params_2.png "3/4 of a circular face" -In this case, selection of a wrong vertex for the Quadrangle parameters -hypothesis will generate a wrong mesh. The picture below +In this case, selection of a wrong vertex for the Base vertex +parameter will generate a wrong mesh. The picture below shows the good (left) and the bad (right) results of meshing. \image html hypo_quad_params_res_2.png "The resulting meshes" +Type parameter is used on faces with a different number of +segments on opposite sides to define the algorithm of transition +between them. The following types are available: + +
      +
    • Standard is the default case, when both triangles and quadrangles + are possible in the transition area along the finer meshed sides.
    • +
    • Triangle preference forces building only triangles in the + transition area along the finer meshed sides. + This type corresponds to Triangle Preference additional + hypothesis, which is obsolete now.
    • +
    • Quadrangle preference forces building only quadrangles in the + transition area along the finer meshed sides. This hypothesis has a + restriction: the total quantity of segments on all + four sides of the face must be even (divisible by 2).
    • + This type corresponds to Quadrangle Preference + additional hypothesis, which is obsolete now. +
    • Quadrangle preference (reversed) works in the same way and +with the same restriction as Quadrangle preference, but + the transition area is located along the coarser meshed sides.
    • +
    • Reduced type forces building only quadrangles 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 same number of segments, the other pair must have an even difference + between the numbers of segments on the sides.
    • +
    + See Also a sample TUI Script of a \ref tui_quadrangle_parameters "Quadrangle Parameters" hypothesis. diff --git a/doc/salome/gui/SMESH/input/about_filters.doc b/doc/salome/gui/SMESH/input/about_filters.doc new file mode 100644 index 000000000..22d88635f --- /dev/null +++ b/doc/salome/gui/SMESH/input/about_filters.doc @@ -0,0 +1,31 @@ +/*! + +\page filters_page About filters + +\b Filters allow picking only the mesh elements satisfying to a +specific condition or a set of conditions. Filters can be used to create +or edit mesh groups, remove elements from the mesh object, control +mesh quality by different parameters, etc. + +Several filters can be combined together by using logical operators \a +AND and \a OR. In addition, applied filter criterion can be reverted +using logical operator \a NOT. + +Mesh filters use the functionality of \ref quality_page "mesh quality controls" +to filter mesh nodes / elements by specific characteristic (Area, Length, etc). + +The functinality of mesh filters is available in both GUI and TUI +modes: + +- In GUI, filters are available in some dialog boxes via an additional +"Set Filters" button, clicking on which opens the dialog box +allowing to specify the list of filter criterions to be applied to the +current selection. See \subpage selection_filter_library_page page to learn more +about selection filters and their usage in GUI. + +- In Python scripts, filters can be used to choose only some mesh + entities (nodes and/or elements) for the operations, which require the + list of entities as input parameter (create/modify group, remove + nodes/elements, etc). The page \ref tui_filters_page provides + examples of the filters usage in Python scripts. +*/ diff --git a/doc/salome/gui/SMESH/input/about_hypo.doc b/doc/salome/gui/SMESH/input/about_hypo.doc index 0e8ac1007..5f989ec3d 100644 --- a/doc/salome/gui/SMESH/input/about_hypo.doc +++ b/doc/salome/gui/SMESH/input/about_hypo.doc @@ -17,7 +17,7 @@ them, you operate numerical values): edges):
    • \ref arithmetic_1d_anchor "Arithmetic 1D"
    • -
    • \ref average_length_anchor "Average Length"
    • +
    • \ref average_length_anchor "Local Length"
    • \ref max_length_anchor "Max Size"
    • \ref deflection_1d_anchor "Deflection 1D"
    • \ref number_of_segments_anchor "Number of segments"
    • @@ -29,8 +29,6 @@ them, you operate numerical values):
    • \ref max_element_area_anchor "Max Element Area"
    • \ref length_from_edges_anchor "Length from Edges"
    • \ref hypo_quad_params_anchor "Quadrangle Parameters"
    • -
    • \ref quadrangle_preference_anchor "Quadrangle Preference"
    • -
    • \ref triangle_preference_anchor "Triangle Preference"
  • 3D Hypothesis (for meshing of volumes):
    • diff --git a/doc/salome/gui/SMESH/input/about_quality_controls.doc b/doc/salome/gui/SMESH/input/about_quality_controls.doc index 0d7ab61b0..8f78c38c5 100644 --- a/doc/salome/gui/SMESH/input/about_quality_controls.doc +++ b/doc/salome/gui/SMESH/input/about_quality_controls.doc @@ -13,24 +13,25 @@ the meshing elements and these calculated values is shown with the help of a scalar bar, which is displayed near the presentation of your mesh. -There are 0D, 1D, 2D and 3D quality controls. +There are four types of quality controls, corresponding to node, edge, +face and volume entity type. -0D mesh quality controls: +Node quality controls:
        -
      • \ref free_nodes_page "Free nodes"
      • +
      • \subpage free_nodes_page "Free nodes"
      -1D mesh quality controls: +Edge quality controls:
        +
      • \subpage free_edges_page "Free edges"
      • \subpage free_borders_page "Free borders"
      • -
      • \subpage borders_at_multi_connection_page "Borders at multi-connection"
      • \subpage length_page "Length"
      • +
      • \subpage borders_at_multi_connection_page "Borders at multi-connection"
      -2D mesh quality controls: +Face quality controls:
        -
      • \subpage free_nodes_page "Free nodes"
      • -
      • \subpage free_edges_page "Free edges"
      • +
      • \subpage free_faces_page "Free faces"
      • \subpage length_2d_page "Length 2D"
      • \subpage borders_at_multi_connection_2d_page "Borders at multi-connection 2D"
      • \subpage area_page "Area"
      • @@ -39,13 +40,14 @@ There are 0D, 1D, 2D and 3D quality controls.
      • \subpage minimum_angle_page "Minimum angle"
      • \subpage warping_page "Warping"
      • \subpage skew_page "Skew"
      • +
      • \subpage max_element_length_2d_page "Max element length 2D"
      -3D mesh quality controls: +Volume quality controls:
      • \subpage aspect_ratio_3d_page "Aspect ratio 3D"
      • \subpage volume_page "Volume"
      • -
      • \subpage free_faces_page "Free faces"
      • +
      • \subpage max_element_length_3d_page "Max element length 3D"
      */ diff --git a/doc/salome/gui/SMESH/input/adding_nodes_and_elements.doc b/doc/salome/gui/SMESH/input/adding_nodes_and_elements.doc index 5c99e8e79..c0168994b 100644 --- a/doc/salome/gui/SMESH/input/adding_nodes_and_elements.doc +++ b/doc/salome/gui/SMESH/input/adding_nodes_and_elements.doc @@ -27,23 +27,23 @@ following associated submenu will appear: From this submenu select the type of element which you would like to add to your mesh. -\note All dialogs for adding new node or element to the mesh (except for -the dialog for 0D elements) provide a possibility to add it -automatically to the specified group or to create it anew using -Add to group box, that allows to choose an existing group for -the created node or element or to give the name to a new group. By -default, the Add to group check box is switched off. If user +\note All dialogs for new node or element adding to the mesh (except for +the dialog for 0D elements) provide the possibility to automatically add +a node or element to the specified group or to create the anew using +Add to group box, that allows choosing an existing group for +the created node or element or giving the name to a new group. By +default, the Add to group check box is switched off. If the user swiches this check box on, the combo box listing all currently existing groups of the corresponding type becomes available. By -default, no any group is selected. In such a case, when user presses +default, no group is selected. In this case, when the user presses Apply or Apply & Close button, the warning message box -informing the user about the necessity to input new group name is -shown. The combo box lists both \ref standalone_group "standalone groups" -and \ref group_on_geom "groups on geometry". If the user has -chosen the group on geometry, he is warned and proposed to -\ref convert_to_standalone "convert this group to the standalone". -If user refuses converting operation, an operation is cancelled and -new node/element is not created! +informs the user about the necessity to input new group name. The +combo box lists both \ref standalone_group "standalone groups" +and \ref group_on_geom "groups on geometry". If the user chooses a +group on geometry, he is warned and proposed to +\ref convert_to_standalone "convert this group to standalone". +If the user rejects conversion operation, it is cancelled and +a new node/element is not created! diff --git a/doc/salome/gui/SMESH/input/adding_quadratic_elements.doc b/doc/salome/gui/SMESH/input/adding_quadratic_elements.doc index 83736c85d..921948630 100644 --- a/doc/salome/gui/SMESH/input/adding_quadratic_elements.doc +++ b/doc/salome/gui/SMESH/input/adding_quadratic_elements.doc @@ -18,23 +18,23 @@ one of the following: \image html image152.png -\note All dialogs for adding quadratic element to the mesh -provide a possibility to add new element -automatically to the specified group or to create it anew using -Add to group box, that allows to choose an existing group for -the created node or element or to give the name to a new group. By -default, the Add to group check box is switched off. If user +\note All dialogs for quadratic element adding to the mesh +provide the possibility to automatically add an element +to the specified group or to create the group anew using +Add to group box, that allows choosing an existing group for +the created node or element or giving the name to a new group. By +default, the Add to group check box is switched off. If the user swiches this check box on, the combo box listing all currently existing groups of the corresponding type becomes available. By -default, no any group is selected. In such a case, when user presses +default, no group is selected. In this case, when the user presses Apply or Apply & Close button, the warning message box -informing the user about the necessity to input new group name is -shown. The combo box lists both \ref standalone_group "standalone groups" -and \ref group_on_geom "groups on geometry". If the user has -chosen the group on geometry, he is warned and proposed to -\ref convert_to_standalone "convert this group to the standalone". -If user refuses converting operation, an operation is cancelled and -new node/element is not created! +informs the user about the necessity to input a new group name. The +combo box lists both \ref standalone_group "standalone groups" +and \ref group_on_geom "groups on geometry". If the user chooses a +group on geometry, he is warned and proposed to +\ref convert_to_standalone "convert this group to standalone". +If the user rejects conversion operation, it is cancelled and +a new quadratic element is not created. To create any Quadratic Element specify the nodes which will form your diff --git a/doc/salome/gui/SMESH/input/additional_hypo.doc b/doc/salome/gui/SMESH/input/additional_hypo.doc index 1205e19b0..81eab0be8 100644 --- a/doc/salome/gui/SMESH/input/additional_hypo.doc +++ b/doc/salome/gui/SMESH/input/additional_hypo.doc @@ -41,17 +41,20 @@ It allows Netgen 2D to build quadrangular meshes at any conditions. It allows Quadrangle (Mapping) to build quadrangular meshes even if the number of nodes at the opposite edges of a meshed face is not equal, -otherwise this mesh will contain some triangular elements. +otherwise this mesh will contain some triangular elements. This use +case is obsolete now. Use Quadrangle Parameters hypothesis with +type Quadrangle Preference set instead.
      This hypothesis has one restriction on its work: the total quantity of segments on all four sides of the face must be even (divisible by 2). -

      Triangle Preference

      +

      Triangle Preference (obsolete)

      This additional hypothesis can be used only together with Quadrangle (Mapping) algorithm. It allows to build triangular mesh faces in the refinement area if the number of nodes at the opposite edges of a meshed face is not equal, otherwise refinement area will contain some quadrangular elements. - +This hypothesis is obsolete now. Use Quadrangle Parameters +hypothesis with type Triangle Preference set instead. */ diff --git a/doc/salome/gui/SMESH/input/area.doc b/doc/salome/gui/SMESH/input/area.doc index bef0c0f8a..f650a3fd6 100644 --- a/doc/salome/gui/SMESH/input/area.doc +++ b/doc/salome/gui/SMESH/input/area.doc @@ -11,7 +11,8 @@ quadrangles).
      1. Display your mesh in the viewer.
      2. -
      3. Choose Controls > Area or click "Area" button. +
      4. Choose Controls > Face Controls > Area or click +"Area" button. \image html image35.png
        "Area" button
        diff --git a/doc/salome/gui/SMESH/input/aspect_ratio.doc b/doc/salome/gui/SMESH/input/aspect_ratio.doc index 070d377cc..c6c3dbdee 100644 --- a/doc/salome/gui/SMESH/input/aspect_ratio.doc +++ b/doc/salome/gui/SMESH/input/aspect_ratio.doc @@ -13,10 +13,10 @@ nodes is calculated by the formula: \image html formula4.png -- The Aspect Ratio of a \b quadrangle 2D element consisting of - 4 nodes is the worst (i.e. the greatest) value from all triangles - which can be built taking three nodes of the quadrangle. There are - four triangles to consider: +- The Aspect Ratio of a \b quadrangle 2D element consisting of 4 +nodes is calculated by the formula: + +\image html formula5.png \image html image138.gif @@ -24,8 +24,8 @@ nodes is calculated by the formula:
        1. Display your mesh in the viewer.
        2. -
        3. Choose Controls > Aspect Ratio or click "Aspect -Ratio" button in the toolbar. +
        4. Choose Controls > Face Controls > Aspect Ratio or click +"Aspect Ratio" button in the toolbar. \image html image37.png
          "Aspect Ratio" button
          diff --git a/doc/salome/gui/SMESH/input/aspect_ratio_3d.doc b/doc/salome/gui/SMESH/input/aspect_ratio_3d.doc index 751e41102..6e8b70808 100644 --- a/doc/salome/gui/SMESH/input/aspect_ratio_3d.doc +++ b/doc/salome/gui/SMESH/input/aspect_ratio_3d.doc @@ -21,8 +21,8 @@ by the formula:
          1. Display your mesh in the viewer.
          2. -
          3. Choose Controls > Aspect Ratio 3D or click "Aspect Ratio 3D" -button of the toolbar. +
          4. Choose Controls > Volume Controls > Aspect Ratio 3D or click +"Aspect Ratio 3D" button of the toolbar. \image html image144.png
            "Aspect Ratio 3D" button
            diff --git a/doc/salome/gui/SMESH/input/basic_meshing_algos.doc b/doc/salome/gui/SMESH/input/basic_meshing_algos.doc index e957a9713..274ab7438 100644 --- a/doc/salome/gui/SMESH/input/basic_meshing_algos.doc +++ b/doc/salome/gui/SMESH/input/basic_meshing_algos.doc @@ -62,6 +62,7 @@ license to be used within the Mesh module. There is also a number of more specific algorithms:
            • \subpage projection_algos_page "for meshing by projection of another mesh"
            • +
            • \subpage import_algos_page "for meshing by importing elements from another mesh"
            • \subpage radial_prism_algo_page "for meshing geometrical objects with cavities"
            • \subpage segments_around_vertex_algo_page "for defining the local size of elements around a certain node"
            • \subpage prism_3d_algo_page "for meshing prismatic shapes"
            • diff --git a/doc/salome/gui/SMESH/input/clipping.doc b/doc/salome/gui/SMESH/input/clipping.doc index f3b19f374..df3e39495 100644 --- a/doc/salome/gui/SMESH/input/clipping.doc +++ b/doc/salome/gui/SMESH/input/clipping.doc @@ -9,11 +9,14 @@ To start, click on the \em New button. \image html a-clipping2.png -Now you can define the parameters of your cross-section: \b Orientation -(X-Y, X-Z or Y-Z); \b Distance between the opposite extremities of the -object, if it is set to 0.5 the object is split in two halves; and -\b Rotation (in angle degrees) around X (Y to Z) and around Y (X to -Z). If the Show preview button is on, you can see the clipping plane +Now you can define the parameters of your cross-section: list of +meshes, sub-meshes and groups the cross-section will be applied to +(Select all button allows to select and deselect all available +objects at once), \b Orientation (X-Y, X-Z or Y-Z); \b Distance between the +opposite extremities of the boundary box of selected objects, if it is set +to 0.5 the boundary box is split in two halves; and \b Rotation (in angle +degrees) around X (Y to Z) and around Y (X to Z). +If the Show preview button is on, you can see the clipping plane in the 3D Viewer. \image html image79.jpg "The plane and the cut object" diff --git a/doc/salome/gui/SMESH/input/creating_groups.doc b/doc/salome/gui/SMESH/input/creating_groups.doc index 29b17f1ae..85d633a22 100644 --- a/doc/salome/gui/SMESH/input/creating_groups.doc +++ b/doc/salome/gui/SMESH/input/creating_groups.doc @@ -26,7 +26,7 @@ SALOME Platform distinguishes between the two Group types: \anchor standalone_group

              "Standalone Group"

              Standalone Group consists of mesh elements, which you can define in -two possible ways. +the following ways:
              • Choosing them manually with the mouse in the 3D Viewer. You can click on an element in the 3D viewer and it will be highlighted. After @@ -36,6 +36,9 @@ the list.
              • definite filter to selection of the elements of your group. See more about filters on the \ref selection_filter_library_page "Selection filter library" page. +
              • By adding all existing entities of the chosen type to the +group. For this turn on the Select All check box. In this +mode all controls, which allow selecting the entities manually or by filters, are disabled.
              To remove a selected element or elements from the list click the \b Remove button. The Sort List button allows to sort the list of IDs of diff --git a/doc/salome/gui/SMESH/input/double_nodes_page.doc b/doc/salome/gui/SMESH/input/double_nodes_page.doc new file mode 100644 index 000000000..063bcba5e --- /dev/null +++ b/doc/salome/gui/SMESH/input/double_nodes_page.doc @@ -0,0 +1,70 @@ +/*! + +\page double_nodes_page Duplicate Nodes + +\n This operation allows to duplicate nodes of your mesh. +Duplication consists in replacement of an existing mesh element by another one. +Lower level elements of the duplicated ones are cloned +automatically. + +To duplicate nodes: +
                +
              1. From the \b Modification menu choose \b Transformation -> \b Duplicate +\b Nodes item or click "Duplicate Nodes" button in the toolbar. +
                +\image html duplicate_nodes.png "Duplicate Nodes button" +
              2. +
              3. Check in the dialog box one of two radio buttons corresponding to +the type of nodes duplication operation you would like to perform.
              4. +
              5. Fill the other fields available in the dialog box (depends on the chosen + operation mode).
              6. +
              7. Click the \b Apply or Apply and Close button to perform the operation of nodes + duplication.
              8. +
              + +\n "Duplicate Nodes" dialog has two working modes: +
                +
              • \ref mode_without_elem_anchor "Without the duplication of border elements"
              • +
              • \ref mode_with_elem_anchor "With the duplication of border elements"
              • +
              + +
              +\anchor mode_without_elem_anchor +

              Without duplication of border elements

              + +In this mode the dialog looks like: + +\image html duplicate01.png + +Parameters to be defined in this mode: +
                +
              • Group of nodes to duplicate (mandatory): these nodes will be duplicated.
              • +
              • Group of elements to replace nodes with new ones (optional): the duplicated nodes + will be associated with these elements.
              • +
              • Construct group with newly created nodes option (checked by default): + if checked - the group with just created nodes will be built.
              • +
              + +
              +\anchor mode_with_elem_anchor +

              With duplication of border elements

              + +In this mode the dialog looks like: + +\image html duplicate02.png + +Parameters to be defined in this mode: +
                +
              • Group of elements to duplicate (mandatory): these elements will be duplicated.
              • +
              • Group of nodes at not to duplicate (optional): group of nodes at crack bottom + which will not be duplicated.
              • +
              • Group of elements to replace nodes with new ones (mandatory): the duplicated nodes + will be associated with these elements.
              • +
              • Construct group with newly created elements option (checked by default): + if checked - the group with just created elements will be built.
              • +
              + + +
              See Also a sample TUI Script of a \ref tui_duplicate_nodes "Duplicate nodes" operation. + +*/ diff --git a/doc/salome/gui/SMESH/input/grouping_elements.doc b/doc/salome/gui/SMESH/input/grouping_elements.doc index 638d70112..3ec4117c4 100644 --- a/doc/salome/gui/SMESH/input/grouping_elements.doc +++ b/doc/salome/gui/SMESH/input/grouping_elements.doc @@ -33,7 +33,7 @@ The created groups can be later:
            An important tool, providing filters for creation of \b Standalone -groups is \subpage selection_filter_library_page. +groups is \ref selection_filter_library_page. */ diff --git a/doc/salome/gui/SMESH/input/index.doc b/doc/salome/gui/SMESH/input/index.doc index 7e18d2b68..5301ce8de 100644 --- a/doc/salome/gui/SMESH/input/index.doc +++ b/doc/salome/gui/SMESH/input/index.doc @@ -12,10 +12,13 @@ previously created or imported by the Geometry component;
          5. \subpage viewing_meshes_overview_page "viewing created meshes" in the VTK viewer;
          6. \subpage grouping_elements_page "creating groups of mesh elements";
          7. -
          8. applying to meshes \subpage quality_page "Quality Controls" , -allowing to highlight important elements: +
          9. applying to meshes \subpage quality_page "Quality Controls", +allowing to highlight important elements; +
          10. filtering sub-sets of mesh entities (nodes elements) using +\subpage filters_page "Filters" functionality;
          11. \subpage modifying_meshes_page "modifying meshes" with a vast -array of dedicated operations.
          12. +array of dedicated operations; +
          13. different \subpage measurements_page "measurements" of the mesh objects;
          14. easily setting parameters via the variables predefined in \subpage using_notebook_mesh_page "Salome notebook".
    @@ -23,6 +26,10 @@ array of dedicated operations. Almost all mesh module functionalities are accessible via \subpage smeshpy_interface_page "Mesh module Python interface". +Also it can be useful to have a look at the +\subpage smeshpypkg_page "documentation on SMESH python package". + + \image html image7.jpg "Example of MESH module usage for engineering tasks" */ diff --git a/doc/salome/gui/SMESH/input/length_2d.doc b/doc/salome/gui/SMESH/input/length_2d.doc index def8afa95..4ed5b69e6 100644 --- a/doc/salome/gui/SMESH/input/length_2d.doc +++ b/doc/salome/gui/SMESH/input/length_2d.doc @@ -10,8 +10,8 @@ of your mesh.
    1. Display your mesh in the viewer.
    2. -
    3. Choose Controls > Length 2D or click "Length 2D" -button in the toolbar. +
    4. Choose Controls > Face Controls > Length 2D or click +"Length 2D" button in the toolbar. \image html image34.png
      "Length 2D" button
      diff --git a/doc/salome/gui/SMESH/input/make_2dmesh_from_3d.doc b/doc/salome/gui/SMESH/input/make_2dmesh_from_3d.doc index f4b5b2ba5..e52078629 100644 --- a/doc/salome/gui/SMESH/input/make_2dmesh_from_3d.doc +++ b/doc/salome/gui/SMESH/input/make_2dmesh_from_3d.doc @@ -1,22 +1,58 @@ /*! -\page make_2dmesh_from_3d_page Generate the skin elements (2D) of a mesh having 3D elements +\page make_2dmesh_from_3d_page Generate boundary elements -\n This functionality allows to generate 2D mesh elements as a skin -on the existing 3D mesh elements. +\n This functionality allows to generate mesh elements on the borders of +elements of a higher dimension. -To generate 2D mesh: +To generate border elements:
        -
      1. From the Modification menu choose "Create 2D mesh from 3D" -item, or choose from the popup menu. +
      2. From the Modification menu choose "Create boundary elements" +item, or click "Create boundary elements" button in the toolbar -\image html 2d_from_3d_menu.png +\image html 2d_from_3d_ico.png "Create boundary elements icon" -The algorithm detects boundary volume faces without connections to -other volumes and creates 2D mesh elements on face nodes. If the mesh -already contains 2D elements on the detected nodes, new elements are not -created. The the resulting dialog shows mesh information statistics -about the newly created 2D mesh elements. +The following dialog box will appear: +\image html 2d_from_3d_dlg.png "Create boundary elements dialog box". +
      3. +
      4. Check in the dialog box one of three radio buttons corresponding to +the type of operation you would like to perform.
      5. +
      6. Fill the other fields available in the dialog box.
      7. +
      8. Click the \b Apply or Apply and Close button to perform the operation.
      +\n "Create boundary elements" dialog allows creation of boundary elements +of three types. +
        +
      • 2D from 3D creates mesh faces on free facets of volume elements
      • +
      • 1D from 2D creates mesh edges on free edges of mesh faces
      • +
      • 1D from 3D creates mesh edges on all borders of free facets of volume elements
      • +
      +Here a free facet means a facet shared by only one volume, a free edge +means an edge shared by only one mesh face. + +In this dialog: +
        +
      • specify the Mesh, submesh or group, the boundary which of +will be analyzed.
      • +
      • specify the Target mesh, where the boundary elements will + be created. +
          +
        • This mesh adds elements in the selected mesh or the mesh + the selected submesh or group belongs to.
        • +
        • New mesh adds elements to a new mesh. The new mesh appears + in the Object Browser with the name that you can change in the adjacent box.
        • +
      • +
      • activate Copy source mesh checkbox to copy 2D or 3D + elements (depending on the operation type), which belong to the analyzed +Mesh, submesh or group field, to the new mesh.
      • +
      • deactivate Copy missing elements only checkbox to copy + boundary elements already present in the analyzed mesh to the + new mesh.
      • +
      • activate Create group checkbox to create a group to which the + missing boundary elements are added. The new group appears + in the Object Browser with the name that you can change in the adjacent box.
      • +
      +
      See Also a sample TUI Script of a \ref tui_make_2dmesh_from_3d "Create boundary elements" operation. + */ diff --git a/doc/salome/gui/SMESH/input/max_element_length_2d.doc b/doc/salome/gui/SMESH/input/max_element_length_2d.doc new file mode 100644 index 000000000..933ac55ee --- /dev/null +++ b/doc/salome/gui/SMESH/input/max_element_length_2d.doc @@ -0,0 +1,29 @@ +/*! + +\page max_element_length_2d_page Element Diameter 2D + +\n This quality control criterion consists of calculation of length of +the edges and diagonals combining the meshing elements (triangles and quadrangles) +of your mesh. + +To apply the Element Diameter 2D quality criterion to your mesh: +
        +
      1. Display your mesh in the viewer.
      2. + +
      3. Choose Controls > Face Controls > Element Diameter 2D or click +"Element Diameter 2D" button in the toolbar. + +\image html image42.png +
        "Element Diameter 2D" button
        + +Your mesh will be displayed in the viewer with its elements colored according to the +applied mesh quality control criterion: + +\image html max_element_length_2d.png +
      4. +
      + +
      See Also a sample TUI Script of a +\ref tui_max_element_length_2d "Element Diameter 2D quality control" operation. + +*/ \ No newline at end of file diff --git a/doc/salome/gui/SMESH/input/max_element_length_3d.doc b/doc/salome/gui/SMESH/input/max_element_length_3d.doc new file mode 100644 index 000000000..9326ad837 --- /dev/null +++ b/doc/salome/gui/SMESH/input/max_element_length_3d.doc @@ -0,0 +1,30 @@ +/*! + +\page max_element_length_3d_page Element Diameter 3D + +\n This quality control criterion consists of calculation of length of +the edges and diagonals combining the 3D meshing elements +(tetrahedrons, pyramids, pentahendrons, hexahedrons and polyhedrons) +of your mesh. + +To apply the Element Diameter 3D quality criterion to your mesh: +
        +
      1. Display your mesh in the viewer.
      2. + +
      3. Choose Controls > Volume Controls > Element Diameter 3D or click +"Element Diameter 3D" button in the toolbar. + +\image html image43.png +
        "Element Diameter 3D" button
        + +Your mesh will be displayed in the viewer with its elements colored according to the +applied mesh quality control criterion: + +\image html max_element_length_3d.png +
      4. +
      + +
      See Also a sample TUI Script of a +\ref tui_max_element_length_3d "Element Diameter 3D quality control" operation. + +*/ \ No newline at end of file diff --git a/doc/salome/gui/SMESH/input/measurements.doc b/doc/salome/gui/SMESH/input/measurements.doc new file mode 100644 index 000000000..27894a49a --- /dev/null +++ b/doc/salome/gui/SMESH/input/measurements.doc @@ -0,0 +1,71 @@ +/*! + +\page measurements_page Measurements + +Mesh module provides possibility to perform different measurements +of the selected mesh data. + +All the measurement operations are available via \b Measurements +top-level menu. An access to the measurements operations is +implemented via single dialog box, where each operation is represented +as a separate tab page. + +\section min_distance_anchor Minimum Distance + +This operation allows measuring a distance between two objects. +Currently only node-to-node and node-to-origin operations are +available, but this operation will be extended in future to support +other mesh objects - elements, meshes, sub-meshes and groups. + +To start Minimum Distance operation, select Minimum Distance +item from \b Measurements menu. + +\image html min_distance.png + +In the dialog box choose the first target and second target mode by +switching the corresponding radio buttons, then select the objects +between which the distance is to be calculated (or enter directly IDs +in case of nodes/elements) and press \em Compute button. + +The following types of targets are supported: +- \em Node: single mesh node; +- \em Element: single mesh element (not available in this version); +- \em Object: mesh, sub-mesh or group object (not available in this +version); +- \em Origin: origin of the global co-ordinate system. + +The result will +be shown in the bottom area of the dialog box. In addition, the simple +preview will be shown in the 3D viewer. + +\image html min_distance_preview.png + +\section bounding_box_anchor Bounding Box + +This operation allows to calculate the bounding box of the selected +object(s). + +To start Bounding Box operation, select Bounding Box +item from \b Measurements menu. + +\image html bnd_box.png + +In the dialog box choose desired type of the object by switching the +corresponding radio button, select the desired object(s) and press +\em Compute button. + +The following types of input are available: +- \em Objects: select one or more mesh, sub-mesh, group objects; +- \em Nodes: select set of mesh nodes; +- \em Elements: select set of mesh elements. + +The result of calculation will be shown in the bottom area of the +dialog box. In addition, the simple preview will be shown in the 3D +viewer. + +\image html bnd_box_preview.png + +See Also a sample TUI Script of a +\ref tui_measurements_page "Measurement operations". + +*/ diff --git a/doc/salome/gui/SMESH/input/merging_nodes.doc b/doc/salome/gui/SMESH/input/merging_nodes.doc index eb17e0a14..3b1bbeaaf 100644 --- a/doc/salome/gui/SMESH/input/merging_nodes.doc +++ b/doc/salome/gui/SMESH/input/merging_nodes.doc @@ -2,17 +2,18 @@ \page merging_nodes_page Merging nodes -\n This functionality allows user to detect groups of coincident nodes -with desirable tolerance, edit these groups and merge. +This functionality allows user to detect groups of coincident nodes +with specified tolerance; each group of the coincident nodes can be +then converted to the single node. \image html mergenodes_ico.png "Merge nodes button" To merge nodes of your mesh:
        -
      1. From the \b Modification choose \b Transformation and from its +
      2. From the \b Modification choose \b Transformation and from its sub-menu select the Merge nodes item. The following dialog box shall appear:
      3. - +
        \image html mergenodes_auto.png
          @@ -21,13 +22,16 @@ shall appear: processed.
        • \b Tolerance is a maximum distance between nodes sufficient for merging.
        • +
        • Exclude Groups group box allows to ignore the nodes which +belong to the specified mesh groups.
      4. Automatic mode:
        • In the \b Automatic Mode all Nodes within the indicated tolerance -will be merged.
        • +will be merged. The nodes which belong to the groups specified in the +Exclude Groups will be not taken into account.

      5. If the \b Manual Mode is selected, additional controls are available: @@ -44,8 +48,9 @@ viewer with pressed "Shift" key.
      6. Select all checkbox selects all groups.
+
\image html mergenodes.png - +
  • Edit selected group list allows editing the selected group: diff --git a/doc/salome/gui/SMESH/input/mesh_infos.doc b/doc/salome/gui/SMESH/input/mesh_infos.doc index 7b855c42c..919f6768e 100644 --- a/doc/salome/gui/SMESH/input/mesh_infos.doc +++ b/doc/salome/gui/SMESH/input/mesh_infos.doc @@ -1,62 +1,67 @@ /*! -\page mesh_infos_page Mesh infos +\page mesh_infos_page Mesh Information -\n There are three information boxes: Standard Mesh -Infos, Advanced Mesh Infos and Mesh Element Info. +The user can obtain an information about the selected mesh object +(mesh, sub-mesh or group) using Mesh Information dialog box. -
    -\anchor standard_mesh_infos_anchor -

    Standard Mesh Infos

    - -The Standard Mesh Infos box gives only the information on the -number of elements of maximum dimension and the number of nodes in the -mesh. However, from this Info you can learn about groups selected on -this mesh. -\n To view the Standard Mesh Infos, select your mesh or submesh -in the Object Browser and select Standard Mesh Infos -from the \b Mesh menu or click "Standard Mesh Infos" button -in the toolbar. - -\image html image49.png -
    "Standard Mesh Infos" button
    - -The following information will be displayed: - -\image html a-standmeshinfo.png +The Mesh Information dialog box provides two tab pages: +- Base Info - to show base information about selected mesh +object +- Element Info - to show detail information about selected mesh +node or element. -
    \anchor advanced_mesh_infos_anchor -

    Advanced Mesh Infos

    +

    Base Info

    -The Advanced Mesh Infos box gives more information about the mesh, -including the total number of faces and volumes and their geometrical -types. -\n To view the Advanced Mesh Infos, select your mesh or submesh -in the Object Browser and select Advanced Mesh Infos -from the \b Mesh menu or click "Advanced Mesh Infos" button -in the toolbar. +The Base Info tab page of the dialog box provides general +information on the selected object - mesh, sub-mesh or mesh group: +name, type, total number of nodes and elements separately for each +type: 0D elements, edges, faces and volumes. + +To view the Mesh Information, select your mesh, sub-mesh or +group in the Object Browser and invoke Mesh Information +item from the \b Mesh menu or click "Mesh Information" button +in the toolbar. -\image html image50.gif -
    "Advanced Mesh Infos" button
    +\image html image49.png +
    "Mesh Information" button
    The following information will be displayed: \image html advanced_mesh_infos.png +
    "Base Info" page
    -
    \anchor mesh_element_info_anchor -

    Mesh Element Info

    +

    Mesh Element Information

    -The Mesh Element Info dialog box gives basic information about the type, coordinates and connectivity of the selected mesh node or element. -\n It is possible to input the Element ID or to select the Element in -the Viewer. +The Element Info tab page of the dialog box gives basic +information about the type, coordinates and connectivity of the +selected mesh node or element. -\image html eleminfo1.png +To view the Mesh Element Information, select your mesh, sub-mesh or +group in the Object Browser and invoke Mesh Element Information +item from the \b Mesh menu or click "Mesh Element Information" button +in the toolbar. + +\image html elem_info.png +
    "Mesh Element Information" button
    +The following information will be displayed: + +\image html eleminfo1.png +
    "Element Info" page, node
    +
    \image html eleminfo2.png +
    "Element Info" page, element
    + +The use can either input the ID of a node or element he wants to +analyze directly in the dialog box or select the node or element in +the 3D viewer. -In case you get Mesh Infos via a TUI script the information is displayed in Python Console. -See the \ref tui_viewing_mesh_infos "TUI Example", +In case you get Mesh Information via a TUI script, the information is +displayed in the Python Console. +See the \ref tui_viewing_mesh_infos "TUI Example". -*/ \ No newline at end of file +*/ + diff --git a/doc/salome/gui/SMESH/input/mesh_through_point.doc b/doc/salome/gui/SMESH/input/mesh_through_point.doc index cd0d68ea9..968bfbc0b 100644 --- a/doc/salome/gui/SMESH/input/mesh_through_point.doc +++ b/doc/salome/gui/SMESH/input/mesh_through_point.doc @@ -1,34 +1,37 @@ /*! -\page mesh_through_point_page Mesh through point +\page mesh_through_point_page Moving nodes -\n In mesh you can define a node at a certain point either by creation -of a new node, by movement of the node closest to the point or by +\n In mesh you can define a node at a certain point either +by movement of the node closest to the point or by movement of any node to the point. -To create a mesh passing through a point: +To displace a node:
      -
    1. From the \b Modification menu choose the Mesh through point item or -click "Mesh to pass through a point" button in the toolbar. +
    2. From the \b Modification menu choose the Move node item or +click "Move Node" button in the toolbar. -\image html mesh_node_to_point.png -
      "Mesh to pass through a point" button
      +\image html image67.png +
      "Move Node" button
      The following dialog box shall appear: \image html meshtopass.png
    3. -
    4. Enter the coordinates of the point.
    5. -
    6. Choose one of several methods: you can either \b Create a new node at -the indicated point or Move the existing node to the point. In the -latter case you can check in Automatic search of the closest node or -select the necessary node manually. \b Preview check-box allows to see -the results of the operation.
    7. -
    8. Click the \b Apply or \b OK button.
    9. +
    10. Enter the coordinates of the destination point.
    11. +
    12. Check in Find closest to destination option or +select the necessary node manually (X, Y, Z, dX, dY, dZ fields allow +to see original coordinates and displacement of the node to move). +\b Preview check-box allows to see the results of the operation.
    13. +
    14. Click the \b Apply or Apply and Close button.
    +\image html moving_nodes1.png "The initial mesh" + +\image html moving_nodes2.png "The modified mesh" +
    See Also a sample TUI Script of a -\ref tui_mesh_through_point "Mesh through point" operation. +\ref tui_moving_nodes "Moving Nodes" operation. */ \ No newline at end of file diff --git a/doc/salome/gui/SMESH/input/minimum_angle.doc b/doc/salome/gui/SMESH/input/minimum_angle.doc index af631b0ec..4236d6562 100644 --- a/doc/salome/gui/SMESH/input/minimum_angle.doc +++ b/doc/salome/gui/SMESH/input/minimum_angle.doc @@ -10,7 +10,8 @@ element (triangle or quadrangle).
    1. Display your mesh in the viewer.
    2. -
    3. Choose Controls > Minimum angle or click "Minimum Angle" button. +
    4. Choose Controls > Face Controls > Minimum angle or click +"Minimum Angle" button. \image html image38.png
      "Minimum Angle" button
      diff --git a/doc/salome/gui/SMESH/input/modifying_meshes.doc b/doc/salome/gui/SMESH/input/modifying_meshes.doc index 05180eb4b..ddddfad50 100644 --- a/doc/salome/gui/SMESH/input/modifying_meshes.doc +++ b/doc/salome/gui/SMESH/input/modifying_meshes.doc @@ -18,7 +18,9 @@ elements of the mesh.
    5. its elements.
    6. \subpage rotation_page "Rotate" by the indicated axis and angle the mesh or some of its elements.
    7. -
    8. \subpage scale_page "Scale Transform" the mesh or some of its elements.
    9. +
    10. \subpage scale_page "Scale Transform" the mesh or some of its +elements.
    11. +
    12. \subpage double_nodes_page "Duplicate nodes".
    13. Create a \subpage symmetry_page "symmetrical copy" of the mesh through a point or a vector of symmetry.
    14. Unite meshes by \subpage sewing_meshes_page "sewing" free borders, @@ -27,10 +29,8 @@ conform free borders, border to side or side elements.
    15. within the indicated tolerance.
    16. \subpage merging_elements_page "Merge Elements", considered coincident within the indicated tolerance.
    17. -
    18. \subpage moving_nodes_page "Move Nodes" to an arbitrary location +
    19. \subpage mesh_through_point_page "Move Nodes" to an arbitrary location with consequent transformation of all adjacent elements and edges.
    20. -
    21. \subpage mesh_through_point_page "Make node at a point", existing -or created anew.
    22. \subpage diagonal_inversion_of_elements_page "Invert an edge" between neighboring triangles.
    23. \subpage uniting_two_triangles_page "Unite two triangles".
    24. \subpage uniting_set_of_triangles_page "Unite several adjacent triangles".
    25. @@ -47,8 +47,7 @@ of the selected node or edge.
    26. Apply \subpage pattern_mapping_page "pattern mapping".
    27. \subpage convert_to_from_quadratic_mesh_page "Convert regular mesh to quadratic", or vice versa.
    28. -
    29. \subpage make_2dmesh_from_3d_page "Create 2D mesh from 3D".
    30. - +
    31. \subpage make_2dmesh_from_3d_page "Generate boundary elements".
    32. \note It is possible to use the variables defined in the SALOME \b NoteBook diff --git a/doc/salome/gui/SMESH/input/moving_nodes.doc b/doc/salome/gui/SMESH/input/moving_nodes.doc deleted file mode 100644 index d44ddc249..000000000 --- a/doc/salome/gui/SMESH/input/moving_nodes.doc +++ /dev/null @@ -1,36 +0,0 @@ -/*! - -\page moving_nodes_page Moving nodes - -\n In MESH you can change the location of any node of your mesh. In -this case all adjacent elements (edges) will be also transformed right -after the displaced node. - -To displace a node: -
        -
      1. From the \b Modification menu choose the Move node item or -click "Move Node" button in the toolbar. - -\image html image67.png -
        "Move Node" button
        - -The following dialog box shall appear: - -\image html movenodes.png - -
      2. -
      3. Enter the ID of the required node in the Node ID field or -select this node in the 3D viewer. The coordinates of your node will -be automatically displayed in the \b Coordinates set of fields.
      4. -
      5. Set new coordinates for your node in the \b Coordinates set of fields.
      6. -
      7. Click the \b Apply or Apply and Close button.
      8. -
      - -\image html moving_nodes1.png "The initial mesh" - -\image html moving_nodes2.png "The node has been moved, transforming all adjacent edges" - -
      See Also a sample TUI Script of a -\ref tui_moving_nodes "Moving Nodes" operation. - -*/ \ No newline at end of file diff --git a/doc/salome/gui/SMESH/input/netgen_2d_3d_hypo.doc b/doc/salome/gui/SMESH/input/netgen_2d_3d_hypo.doc index bbb7c59ff..4690bf966 100644 --- a/doc/salome/gui/SMESH/input/netgen_2d_3d_hypo.doc +++ b/doc/salome/gui/SMESH/input/netgen_2d_3d_hypo.doc @@ -5,11 +5,9 @@ Netgen 2D and Netgen 3D hypotheses work only with Netgen 1D-2D and Netgen 1D-2D-3D algorithms. These algorithms do not require definition of lower-level hypotheses and algorithms (2D and 1D for -meshing 3D objects and 1D for meshing 2D objects). They prove to be -useful if lower-level meshing is homogeneous for all wires and faces -of the meshed object. +meshing 3D objects and 1D for meshing 2D objects). -\image html netgen2d.png +\image html netgen2d3d.png - Name - allows to define the name for the algorithm (Netgen 2D (or 3D) Parameters by default). @@ -32,7 +30,18 @@ not possible. - Optimize - if this box is checked in, the algorithm will try to create regular (possessing even sides) elements. -\image html netgen3d_simple.png +\image html netgen3d_local_size.png + +- Local sizes - allows to define size of elements on and +around specified geometrical edges and vertices. To define the local +size it is necessary to select a geometrical edge or vertex in the +object browser or in the viewer, and to click On Edge or On +Vertex correspondingly. Name of the geometrical object and +a default Value will be added in the table where the +Value can be changed. +- Remove - deletes a selected row from the table. + +\image html netgen2d3d_simple.png Netgen 2D simple parameters and Netgen 3D simple parameters allow defining the size of elements for each @@ -42,8 +51,8 @@ dimension. - Number of Segments has the same sense as \ref number_of_segments_anchor "Number of segments" hypothesis with equidistant distribution. -- Average Length has the same sense as \ref -average_length_anchor "Average Length" hypothesis. +- Local Length has the same sense as \ref +average_length_anchor "Local Length" hypothesis. \b 2D group allows defining the size of 2D elements - Length from edges if checked in, acts like \ref diff --git a/doc/salome/gui/SMESH/input/pattern_mapping.doc b/doc/salome/gui/SMESH/input/pattern_mapping.doc index 1a48a4644..ef7f8ba66 100644 --- a/doc/salome/gui/SMESH/input/pattern_mapping.doc +++ b/doc/salome/gui/SMESH/input/pattern_mapping.doc @@ -5,33 +5,31 @@

      About patterns

      The pattern describes a mesh to generate: positions of nodes within a -geometrical domain and nodal connectivity of elements. As well, a -pattern specifies the so-called key-points, i.e. nodes that will be -located at geometrical vertices. Pattern description is stored in +geometrical domain and nodal connectivity of elements. A +pattern also specifies the so-called key-points, i.e. the nodes that will be +located at geometrical vertices. The pattern description is stored in \.smp file. The smp file contains 4 sections: --# The first line holds the total number of the pattern nodes (N). --# The next N lines describe nodes coordinates. Each line holds 2 -coordinates of a node for 2D pattern or 3 cordinates for 3D pattern. -Note, that for 3D pattern only relateive values in range [0;1] are -valid for coordinates of the nodes. --# A key-points line: indices of nodes to be mapped on geometrical -vertices (for 2D pattern only). An index n refers to a node described -on an n-th line of section 2. The first node index is zero. For 3D -pattern key points are not specified. --# The rest lines describe nodal connectivity of elements, one line -for an element. A line holds indices of nodes forming an element. An -index n refers to a node described on an n-th line of the section -2. The first node index is zero. There must be 3 or 4 indices on a -line for 2D pattern (only 2d elements are allowed) and 4, 5, 6 or 8 -indices for 3D pattern (only 3d elements are allowed). - -The 2D pattern must contain at least one element and at least one -key-point. All key-points must lay on boundaries. - -The 3D pattern must contain at least one element. +-# The first line indicates the total number of pattern nodes (N). +-# The next N lines describe nodes coordinates. Each line contains 2 +node coordinates for a 2D pattern or 3 node cordinates for a 3D pattern. +Note, that node coordinates of a 3D pattern can be defined only by relative values in range [0;1]. +-# The key-points line contains the indices of the nodes to be mapped on geometrical +vertices (for a 2D pattern only). Index n refers to the node described +on the n-th line of section 2. The index of the first node zero. For a 3D pattern the key points are not specified. +-# The remaining lines describe nodal connectivity of elements, one line +for each element. Each line holds indices of nodes forming an element. +Index n refers to the node described on the n-th line of section 2. +The first node index is zero. There must be 3 or 4 indices on each +line for a 2D pattern (only 2d elements are allowed) and 4, 5, 6 or 8 +indices for a 3D pattern (only 3d elements are allowed). + +A 2D pattern must contain at least one element and at least one +key-point. All key-points must lie on boundaries. + +A 3D pattern must contain at least one element. An example of a simple 2D pattern smp file: @@ -60,7 +58,7 @@ An example of a simple 2D pattern smp file: 8 1 2 \endcode -The image below provides a preview of above described pattern: +The image below provides a preview of the above pattern: \image html pattern2d.png @@ -99,91 +97,120 @@ From the \b Modification menu choose the Pattern Mapping item or click \image html image98.png
      "Pattern mapping" button
      -The following dialog box shall appear: +The following dialog box will appear: + +\n For a 2D pattern \image html patternmapping1.png -
      2D Pattern Mapping dialog box
      +In this dialog you should specify: + +
        +
      • \b Pattern, which can be loaded from .smp pattern file previously +created manually or generated automatically from an existing mesh or submesh.
      • +
      • \b Face with the number of vertices equal to the number of + key-points in the pattern; the number of key-points on internal + boundaries of the pattern must also be equal to the number of vertices + on internal boundaries of the face;
      • +
      • \b Vertex to which the first key-point should be mapped;
      • +Alternatively, it is possible to select Refine selected mesh elements +checkbox and apply the pattern to +
      • Mesh Face instead of a geometric Face
      • +
      • and select \b Node instead of vertex.
      • + +Additionally it is possible to: +
      • Reverse the order of key-points By default, the vertices of + a face are ordered counterclockwise.
      • +
      • Enable to Create polygons near boundary
      • +
      • and Create polyhedrons near boundary
      • +
      + +\n For a 3D pattern \image html patternmapping2.png -
      3D Pattern Mapping dialog box
      +In this dialog you should specify: +
        +
      • \b Pattern, which can be loaded from .smp pattern file previously +created manually or generated automatically from an existing mesh or submesh.
      • +
      • A 3D block (Solid) object;
      • +
      • Two vertices that specify the order of nodes in the resulting mesh.
      • +Alternatively, it is possible to select Refine selected mesh elements +checkbox and apply the pattern to +
      • One or several Mesh volumes instead of a geometric 3D +object
      • +
      • and select two /b Nodes instead of vertices.
      • +Additionally it is possible to: +
      • Enable to Create polygons near boundary
      • +
      • and Create polyhedrons near boundary
      • +
      + +\n Automatic Generation + +To generate a pattern automatically from an existing mesh or submesh, +click \b New button. + +The following dialog box will appear: -To apply a pattern to a geometrical object, you should specify: +\image html a-patterntype1.png --# For 2D pattern - - A face having the number of vertices equal to the number of - key-points in the pattern; the number of key-points on internal - boundaries of a pattern must also be equal to the number of vertices - on internal boundaries of a face; - - A vertex to which the first key-point should be mapped; - - Reverse or not the order of key-points. (The order of vertices of - a face is counterclockwise looking from outside). --# For 3D pattern - - 3D block (Solid) object; - - Two vertices that specify the order of nodes in the resulting - mesh. - -Then you either load a .smp pattern file previously created manually -by clicking on the "Load pattern" button, or click on the \b -New button for automatic generation of the pattern. - -For an automatic generation you just specify a geometrical face (for -2D) or solid (for 3d) having a mesh built on it. Mesh nodes lying on -face vertices become key-points of 2D pattern. Additionally, for 2D -pattern you may choose the way of getting nodes coordinates by -projecting nodes on the face instead of using -"positions on face" generated by mesher (if there is any). Faces -having a seam edge can't be used for automatic pattern creation. - -When creating a pattern from an existing mesh, there are two possible -cases: - -- A sub-mesh on face/solid is selected. A pattern is created from the 2d/3d -elements bound to a face/solid by mesher. For 2D pattern, node coordinates are either -"positions on face" computed by mesher, or coordinates got by node -projection on a geometrical surface, according to the user choice. For -3D pattern, nodes coordinates correspond to the nodes computed by mesher. -- A mesh where the main shape is a face/solid, is selected. A pattern is -created from all the 2d/3d elements in a mesh. In addition, for 2D -pattern, if all mesh elements are build by mesher, the user can select -the way of getting nodes coordinates, else all nodes are projected on -a face surface. +In this dialog you should specify: -\image html a-patterntype.png +
        +
      • Mesh or Submesh, which is a meshed geometrical face (for a +2D pattern) or a meshed solid (for a 3D pattern). Mesh nodes lying on +the face vertices become key-points of the pattern.
      • +
      • A custom Pattern Name
      • +
      • Additionally, for a 2D pattern you may choose to +Project nodes on the face to get node coordinates instead of using +"positions on face" generated by the mesher (if there is any). The faces +having a seam edge cannot be used for automatic pattern creation.
      • +
      -
      2D Pattern Creation dialog box
      +When a pattern is created from an existing mesh, two cases are possible: -\image html a-patterntype1.png +- A sub-mesh on a face/solid is selected. The pattern is created from the 2d/3d +elements bound to the face/solid by the mesher. For a 2D pattern, the node coordinates are either +"positions on face" computed by the mesher, or coordinates got by node +projection on a geometrical surface, according to the user choice. For +a 3D pattern, the node coordinates correspond to the nodes computed by +the mesher. +- A mesh, where the main shape is a face/solid, is selected. The pattern is +created from all 2d/3d elements in a mesh. In addition, if all mesh +elements of a 2D pattern are built by the mesher, the user can select +how to get node coordinates, otherwise all nodes are projected on +a face surface. -
      3D Pattern Creation dialog box

      Mapping algorithm

      -The mapping algorithm for 2D case is as follows: - -- Key-points are set in the order that they are encountered when - walking along a pattern boundary so that elements are on the left. The - first key-point is preserved. -- Find geometrical vertices corresponding to key-points by vertices - order in a face boundary; here, "Reverse order of key-points" flag is - taken into account. \image html image95.gif -- Boundary nodes of a pattern are mapped onto edges of a face: a - node located between certain key-points on a pattern boundary is - mapped on a geometrical edge limited by corresponding geometrical - vertices. Node position on an edge reflects its distance from two - key-points. \image html image96.gif -- Coordinates of a non-boundary node in a parametric space of a face - are defined as following. In a parametric space of a pattern, a node - lays at the intersection of two iso-lines, each of which intersects a - pattern boundary at least at two points. Knowing mapped positions of - boundary nodes, we find where isoline-boundary intersection points are - mapped to, and hence we can find mapped isolines direction and then, - two node positions on two mapped isolines. The eventual mapped - position of a node is found as an average of positions on mapped - isolines. \image html image97.gif - -For 3D case the algorithm is similar. +The mapping algorithm for a 2D case is as follows: + +- The key-points are set counterclockwise in the order corresponding + to their location on the pattern boundary. The first key-point is preserved. +- The geometrical vertices corresponding to the key-points are found + on face boundary. Here, "Reverse order of key-points" flag is set. +\image html image95.gif +- The boundary nodes of the pattern are mapped onto the edges of the face: a + node located between two key-points on the pattern boundary is + mapped on the geometrical edge limited by the corresponding geometrical + vertices. The node position on the edge depends on its distance from the + key-points. +\image html image96.gif +- The cordinates of a non-boundary node in the parametric space of the face + are defined in the following way. In the parametric space of the + pattern, the node lies at the intersection of two iso-lines. Both + of them intersect the pattern boundary at two + points at least. If the mapped positions of boundary nodes are known, it is + possible to find, where the points at the intersection of isolines + and boundaries are mapped. Then it is possible to find + the direction of mapped isolinesection and, filally, the poitions of + two nodes on two mapped isolines. The eventual mapped + position of the node is found as an average of the positions on mapped + isolines. +\image html image97.gif + +The 3D algorithm is similar. See Also a sample TUI Script of a \ref tui_pattern_mapping "Pattern Mapping" operation. diff --git a/doc/salome/gui/SMESH/input/removing_nodes_and_elements.doc b/doc/salome/gui/SMESH/input/removing_nodes_and_elements.doc index 6cd891573..0a48ee65e 100644 --- a/doc/salome/gui/SMESH/input/removing_nodes_and_elements.doc +++ b/doc/salome/gui/SMESH/input/removing_nodes_and_elements.doc @@ -6,6 +6,7 @@
      • \ref removing_nodes_anchor "Nodes"
      • +
      • \ref removing_orphan_nodes_anchor "Orphan Nodes"
      • \ref removing_elements_anchor "Elements"
      • \ref clear_mesh_anchor "Clear Mesh Data"
      @@ -18,11 +19,11 @@
      1. Select your mesh in the Object Browser or in the 3D viewer.
      2. -
      3. From the Modification menu choose Remove and from the associated -submenu select the Remove nodes, or just click "Remove nodes" +
      4. From the Modification menu choose Remove and from the associated +submenu select the Nodes, or just click "Remove nodes" button in the toolbar. -\image html image88.gif +\image html remove_nodes_icon.png
        "Remove nodes" button
        The following dialog box will appear: @@ -46,6 +47,30 @@ about filters in the \ref selection_filter_library_page "Selection filter librar \note Be careful while removing nodes because if you remove a definite node of your mesh all adjacent elements will be also deleted. +
        +\anchor removing_orphan_nodes_anchor +

        Removing orphan nodes

        + +There is a quick way to remove all orphan (free) nodes. + +To remove orphan nodes: +
          +
        1. Select your mesh in the Object Browser or in the 3D viewer.
        2. + +
        3. From the Modification menu choose Remove and from the associated +submenu select Orphan Nodes, or just click "Remove orphan nodes" +button in the toolbar. + +\image html remove_orphan_nodes_icon.png +
          "Remove orphan nodes" button
          + +The following Warning message box will appear: + +\image html removeorphannodes.png + +Confirm nodes removal by pressing "Yes" button. +
        +
        \anchor removing_elements_anchor

        Removing elements

        @@ -54,8 +79,8 @@ node of your mesh all adjacent elements will be also deleted.
        1. Select your mesh in the Object Browser or in the 3D viewer.
        2. -
        3. From the \b Modification menu choose \b Remove and from the -associated submenu select the Remove elements, or just click +
        4. From the Modification menu choose Remove and from the +associated submenu select the Elements, or just click "Remove elements" button in the toolbar. \image html remove_elements_icon.png @@ -94,7 +119,7 @@ about filters in the \ref selection_filter_library_page "Selection filter librar
        5. From the Modification menu choose Remove and from the associated submenu select the Clear Mesh Data, or just click "Clear Mesh Data" button in the toolbar. You can also right-click on the mesh in the -Object Browser and select Clear Mesh Data in the pop-up menu. +Object Browser and select Clear Mesh Data in the pop-up menu.
        \image html mesh_clear.png diff --git a/doc/salome/gui/SMESH/input/selection_filter_library.doc b/doc/salome/gui/SMESH/input/selection_filter_library.doc index 94dd3844c..1f612994f 100644 --- a/doc/salome/gui/SMESH/input/selection_filter_library.doc +++ b/doc/salome/gui/SMESH/input/selection_filter_library.doc @@ -156,6 +156,17 @@ See also a length, which is more, less or equal (within a given Tolerance) to the predefined Threshold Value. See also a \ref length_2d_page "Length 2D quality control". +
      5. +Coplanar faces selects mesh faces neighboring the one selected +by ID in Threshold Value field, if the angle between the +normal to the neighboring face and the normal to the selected face is less then the +angular tolerance (defined in degrees). Selection continues among all neighbor faces of already +selected ones.
        +
      6. +Element Diameter 2D selects triangles and quadrangles combining of the edges and +diagonals with a value of length, which is more, less or equal +(within a given Tolerance) to the predefined Threshold Value. See also a +\ref max_element_length_2d_page "Element Diameter 2D quality control".
      7. @@ -169,6 +180,11 @@ Additional criteria to select mesh Volumes are the following: \ref volume_page "Volume quality control"), which is more, less or equal (within a given Tolerance) to the predefined Threshold Value.
      8. +Element Diameter 3D selects 3D mesh elements combining of the edges and +diagonals with a value of length, which is more, less or equal +(within a given Tolerance) to the predefined Threshold Value. See also a +\ref max_element_length_3d_page "Element Diameter 3D quality control". +
      9. Bad oriented volume selects mesh volumes, which are incorrectly oriented from the point of view of MED convention.
      10. diff --git a/doc/salome/gui/SMESH/input/skew.doc b/doc/salome/gui/SMESH/input/skew.doc index 5235b4ddd..036c70d83 100644 --- a/doc/salome/gui/SMESH/input/skew.doc +++ b/doc/salome/gui/SMESH/input/skew.doc @@ -14,7 +14,8 @@ criterion can be applied to elements composed of 4 and 3 nodes
        1. Display your mesh in the viewer.
        2. -
        3. Choose Controls > Skew or click "Skew" button of the toolbar. +
        4. Choose Controls > Face Controls > Skew or click +"Skew" button of the toolbar. \image html image40.png
          "Skew" button
          diff --git a/doc/salome/gui/SMESH/input/smeshpy_interface.doc b/doc/salome/gui/SMESH/input/smeshpy_interface.doc index e0fe78ec9..8b63ddfa3 100644 --- a/doc/salome/gui/SMESH/input/smeshpy_interface.doc +++ b/doc/salome/gui/SMESH/input/smeshpy_interface.doc @@ -133,9 +133,11 @@ the following links: - \subpage tui_viewing_meshes_page - \subpage tui_defining_hypotheses_page - \subpage tui_quality_controls_page +- \subpage tui_filters_page - \subpage tui_grouping_elements_page - \subpage tui_modifying_meshes_page - \subpage tui_transforming_meshes_page - \subpage tui_notebook_smesh_page +- \subpage tui_measurements_page */ diff --git a/doc/salome/gui/SMESH/input/smeshpypkg.doc b/doc/salome/gui/SMESH/input/smeshpypkg.doc new file mode 100644 index 000000000..06bf94a23 --- /dev/null +++ b/doc/salome/gui/SMESH/input/smeshpypkg.doc @@ -0,0 +1,14 @@ +/*! + +\page smeshpypkg_page Programming Interface of the SMESH python package + +Sorry, but the documentation is not available yet in doxygen format. + +Fortunately, a documentation exists in restructured format and then +can be generated here using sphinx, in the expectative of the doxygen +version. + +Please refer to this +documentation of the SMESH python packages. + +*/ diff --git a/doc/salome/gui/SMESH/input/split_to_tetra.doc b/doc/salome/gui/SMESH/input/split_to_tetra.doc index 4817a3f2f..4b09b2199 100644 --- a/doc/salome/gui/SMESH/input/split_to_tetra.doc +++ b/doc/salome/gui/SMESH/input/split_to_tetra.doc @@ -37,7 +37,7 @@ volumes of the currently displayed mesh or submesh.
        5. \b Split hexahedron
            -
          • Into 5 tetrahedra and Into 6 tetrahedra allows to +
          • Into 5 tetrahedra, Into 5 tetrahedra and Into 24 tetrahedra allows to specify the number of tetrahedra a hexahedron will be split into. If the specified method does not allow to get a conform mesh, a generic solution is applied: an additional node is created at the gravity center of a hexahedron, serving an apex of tetrahedra, all quadrangle sides of the hexahedron are split into two triangles each serving a base of a new tetrahedron.
          • diff --git a/doc/salome/gui/SMESH/input/taper.doc b/doc/salome/gui/SMESH/input/taper.doc index d2c4dd2b4..86472eabe 100644 --- a/doc/salome/gui/SMESH/input/taper.doc +++ b/doc/salome/gui/SMESH/input/taper.doc @@ -13,8 +13,8 @@ for elements consisting of 4 nodes.
            1. Display your mesh in the viewer.
            2. -
            3. Choose Controls > Taper or click "Taper" button in -the toolbar. +
            4. Choose Controls > Face Controls > Taper or click +"Taper" button in the toolbar. \image html image36.png
              "Taper" button
              diff --git a/doc/salome/gui/SMESH/input/tui_defining_hypotheses.doc b/doc/salome/gui/SMESH/input/tui_defining_hypotheses.doc index 1aa91d9d5..1581e7c2f 100644 --- a/doc/salome/gui/SMESH/input/tui_defining_hypotheses.doc +++ b/doc/salome/gui/SMESH/input/tui_defining_hypotheses.doc @@ -128,7 +128,7 @@ hexa.Compute()
              \anchor tui_average_length -

              Average Length

              +

              Local Length

              \code from geompy import * @@ -549,11 +549,10 @@ mesh.Compute() \endcode \anchor tui_quadrangle_parameters -

              Quadrangle Parameters example

              +

              Quadrangle Parameters example 1 (meshing a face with 3 edges)

              \code -import geompy -import smesh -import StdMeshers +from smesh import * +SetCurrentStudy(salome.myStudy) # Get 1/4 part from the disk face. Box_1 = geompy.MakeBoxDXDYDZ(100, 100, 100) @@ -566,17 +565,112 @@ geompy.addToStudy( Common_1, "Common_1" ) # Set the Geometry for meshing Mesh_1 = smesh.Mesh(Common_1) + +# Define 1D hypothesis and compute the mesh +Regular_1D = Mesh_1.Segment() +Nb_Segments_1 = Regular_1D.NumberOfSegments(10) +Nb_Segments_1.SetDistrType( 0 ) + # Create Quadrangle parameters and define the Base Vertex. +Quadrangle_2D = Mesh_1.Quadrangle().TriangleVertex( 8 ) + +Mesh_1.Compute() +\endcode + +

              Quadrangle Parameters example 2 (using different types)

              +\code +import geompy +import smesh +import StdMeshers + +# Make quadrangle face and explode it on edges. +Vertex_1 = geompy.MakeVertex(0, 0, 0) +Vertex_2 = geompy.MakeVertex(40, 0, 0) +Vertex_3 = geompy.MakeVertex(40, 30, 0) +Vertex_4 = geompy.MakeVertex(0, 30, 0) +Quadrangle_Face_1 = geompy.MakeQuad4Vertices(Vertex_1, Vertex_4, Vertex_3, Vertex_2) +[Edge_1,Edge_2,Edge_3,Edge_4] = geompy.SubShapeAllSorted(Quadrangle_Face_1, geompy.ShapeType["EDGE"]) +geompy.addToStudy( Vertex_1, "Vertex_1" ) +geompy.addToStudy( Vertex_2, "Vertex_2" ) +geompy.addToStudy( Vertex_3, "Vertex_3" ) +geompy.addToStudy( Vertex_4, "Vertex_4" ) +geompy.addToStudy( Quadrangle_Face_1, "Quadrangle Face_1" ) +geompy.addToStudyInFather( Quadrangle_Face_1, Edge_2, "Edge_2" ) + +# Set the Geometry for meshing +Mesh_1 = smesh.Mesh(Quadrangle_Face_1) + +# Create Quadrangle parameters and +# define the Type as Quadrangle Preference Quadrangle_Parameters_1 = smesh.CreateHypothesis('QuadrangleParams') -Quadrangle_Parameters_1.SetTriaVertex( 8 ) +Quadrangle_Parameters_1.SetQuadType( StdMeshers.QUAD_QUADRANGLE_PREF ) -# Define 1D hypothesis and cmpute the mesh +# Define other hypotheses and algorithms Regular_1D = Mesh_1.Segment() -Nb_Segments_1 = Regular_1D.NumberOfSegments(10) +Nb_Segments_1 = Regular_1D.NumberOfSegments(4) Nb_Segments_1.SetDistrType( 0 ) status = Mesh_1.AddHypothesis(Quadrangle_Parameters_1) Quadrangle_2D = Mesh_1.Quadrangle() -Mesh_1.Compute() + +# Define submesh on one edge to provide different number of segments +Regular_1D_1 = Mesh_1.Segment(geom=Edge_2) +Nb_Segments_2 = Regular_1D_1.NumberOfSegments(10) +Nb_Segments_2.SetDistrType( 0 ) +SubMesh_1 = Regular_1D_1.GetSubMesh() + +# Compute mesh (with Quadrangle Preference type) +isDone = Mesh_1.Compute() + +# Change type to Reduced and compute again +Quadrangle_Parameters_1.SetQuadType( StdMeshers.QUAD_REDUCED ) +isDone = Mesh_1.Compute() +\endcode + +\anchor tui_import +

              "Use Existing Elements" example

              +\code + +from smesh import * +SetCurrentStudy(salome.myStudy) + +# Make a patritioned box + +box = geompy.MakeBoxDXDYDZ(100,100,100) + +N = geompy.MakeVectorDXDYDZ( 1,0,0 ) +O = geompy.MakeVertex( 50,0,0 ) +plane = geompy.MakePlane( O, N, 200 ) # plane YOZ + +shape2boxes = geompy.MakeHalfPartition( box, plane ) +boxes = geompy.SubShapeAllSorted(shape2boxes, geompy.ShapeType["SOLID"]) + +geompy.addToStudy( boxes[0], "boxes[0]") +geompy.addToStudy( boxes[1], "boxes[1]") +midFace0 = geompy.SubShapeAllSorted(boxes[0], geompy.ShapeType["FACE"])[5] +geompy.addToStudyInFather( boxes[0], midFace0, "middle Face") +midFace1 = geompy.SubShapeAllSorted(boxes[1], geompy.ShapeType["FACE"])[0] +geompy.addToStudyInFather( boxes[1], midFace1, "middle Face") + +# Mesh one of boxes with quadrangles. It is a source mesh + +srcMesh = Mesh(boxes[0], "source mesh") # box coloser to CS origin +nSeg1 = srcMesh.Segment().NumberOfSegments(4) +srcMesh.Quadrangle() +srcMesh.Compute() +srcFaceGroup = srcMesh.GroupOnGeom( midFace0, "src faces", FACE ) + +# Import faces from midFace0 to the target mesh + +tgtMesh = Mesh(boxes[1], "target mesh") +importAlgo = tgtMesh.UseExisting2DElements(midFace1) +import2hyp = importAlgo.SourceFaces( [srcFaceGroup] ) +tgtMesh.Segment().NumberOfSegments(3) +tgtMesh.Quadrangle() +tgtMesh.Compute() + +# Import the whole source mesh with groups +import2hyp.SetCopySourceMesh(True,True) +tgtMesh.Compute() \endcode \n Other meshing algorithms: diff --git a/doc/salome/gui/SMESH/input/tui_filters.doc b/doc/salome/gui/SMESH/input/tui_filters.doc new file mode 100755 index 000000000..6677b2ab5 --- /dev/null +++ b/doc/salome/gui/SMESH/input/tui_filters.doc @@ -0,0 +1,594 @@ +/*! + +\page tui_filters_page Filters usage + +Filters allow picking only the mesh elements satisfying to a +specific condition or a set of conditions. Filters can be used to create +or edit mesh groups, remove elements from the mesh object, control +mesh quality by different parameters, etc. + +Several filters can be combined together by using logical operators \a +AND and \a OR. In addition, applied filter criterion can be reverted +using logical operator \a NOT. + +Mesh filters use the functionality of mesh quality controls to filter +mesh nodes / elements by a specific characteristic (Area, Length, etc). + +This page provides a short description of the existing mesh filters, +describes required parameters and gives simple examples of usage in +Python scripts. + +\sa \ref tui_quality_controls_page + +\section filter_aspect_ratio Aspect ratio + +Filter 2D mesh elements (faces) according to the aspect ratio value: +- element type should be \a smesh.FACE +- functor type should be \a smesh.FT_AspectRatio +- threshold is floating point value (aspect ratio) + +\code +# create mesh +from SMESH_mechanic import * +# get faces with aspect ratio > 6.5 +filter = smesh.GetFilter(smesh.FACE, smesh.FT_AspectRatio, smesh.FT_MoreThan, 6.5) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces with aspect ratio > 6.5:", len(ids) +\endcode + +\sa \ref tui_aspect_ratio + +\section filter_aspect_ratio_3d Aspect ratio 3D + +Filter 3D mesh elements (volumes) according to the aspect ratio value: +- element type is \a smesh.VOLUME +- functor type is \a smesh.FT_AspectRatio3D +- threshold is floating point value (aspect ratio) + +\code +# create mesh with volumes +from SMESH_mechanic import * +mesh.Tetrahedron( algo=smesh.NETGEN ) +mesh.Compute() +# get volumes with aspect ratio < 2.0 +filter = smesh.GetFilter(smesh.VOLUME, smesh.FT_AspectRatio3D, smesh.FT_LessThan, 2.0) +ids = mesh.GetIdsFromFilter(filter) +print "Number of volumes with aspect ratio < 2.0:", len(ids) +\endcode + +\sa \ref tui_aspect_ratio_3d + +\section filter_warping_angle Warping angle + +Filter 2D mesh elements (faces) according to the warping angle value: +- element type is \a smesh.FACE +- functor type is \a smesh.FT_Warping +- threshold is floating point value (warping angle) + +\code +# create mesh +from SMESH_mechanic import * +# get faces with warping angle = 2.0e-13 with tolerance 5.0e-14 +criterion = smesh.GetCriterion(smesh.FACE, smesh.FT_Warping, smesh.FT_EqualTo, 2.0e-13) +criterion.Tolerance = 5.0e-14 +filter = smesh.CreateFilterManager().CreateFilter() +filter.SetCriteria([criterion]) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces with warping angle = 2.0e-13 (tolerance 5.0e-14):", len(ids) +\endcode + +\sa \ref tui_warping + +\section filter_minimum_angle Minimum angle + +Filter 2D mesh elements (faces) according to the minimum angle value: +- element type is \a smesh.FACE +- functor type is \a smesh.FT_MinimumAngle +- threshold is floating point value (minimum angle) + +\code +# create mesh +from SMESH_mechanic import * +# get faces with minimum angle > 75 +filter = smesh.GetFilter(smesh.FACE, smesh.FT_MinimumAngle, smesh.FT_MoreThan, 75) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces with minimum angle > 75:", len(ids) +\endcode + +\sa \ref tui_minimum_angle + +\section filter_taper Taper + +Filter 2D mesh elements (faces) according to the taper value: +- element type is \a smesh.FACE +- functor type is \a smesh.FT_Taper +- threshold is floating point value (taper) + +\code +# create mesh +from SMESH_mechanic import * +# get faces with taper < 1.e-15 +filter = smesh.GetFilter(smesh.FACE, smesh.FT_Taper, smesh.FT_LessThan, 1.e-15) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces with taper < 1.e-15:", len(ids) +\endcode + +\sa \ref tui_taper + +\section filter_skew Skew + +Filter 2D mesh elements (faces) according to the skew value: +- element type is \a smesh.FACE +- functor type is \a smesh.FT_Skew +- threshold is floating point value (skew) + +\code +# create mesh +from SMESH_mechanic import * +# get faces with skew > 50 +filter = smesh.GetFilter(smesh.FACE, smesh.FT_Skew, smesh.FT_MoreThan, 50) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces with skew > 50:", len(ids) +\endcode + +\sa \ref tui_skew + +\section filter_area Area + +Filter 2D mesh elements (faces) according to the area value: +- element type is \a smesh.FACE +- functor type is \a smesh.FT_Area +- threshold is floating point value (area) + +\code +# create mesh +from SMESH_mechanic import * +# get faces with area > 60 and < 90 +criterion1 = smesh.GetCriterion(smesh.FACE, smesh.FT_Area, smesh.FT_MoreThan, 60,\ + smesh.FT_Undefined, smesh.FT_LogicalAND) +criterion2 = smesh.GetCriterion(smesh.FACE, smesh.FT_Area, smesh.FT_LessThan, 90) +filter = smesh.CreateFilterManager().CreateFilter() +filter.SetCriteria([criterion1,criterion2]) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces with area in range (60,90):", len(ids) +\endcode + +\sa \ref tui_area + +\section filter_volume Volume + +Filter 3D mesh elements (volumes) according to the volume value: +- element type is \a smesh.VOLUME +- functor type is \a smesh.FT_Volume3D +- threshold is floating point value (volume) + +\code +# create mesh with volumes +from SMESH_mechanic import * +mesh.Tetrahedron( algo=smesh.NETGEN ) +mesh.Compute() +# get volumes faces with volume > 100 +filter = smesh.GetFilter(smesh.VOLUME, smesh.FT_Volume3D, smesh.FT_MoreThan, 100) +ids = mesh.GetIdsFromFilter(filter) +print "Number of volumes with volume > 100:", len(ids) +\endcode + +\sa \ref tui_volume + +\section filter_free_borders Free borders + +Filter 1D mesh elements (edges) which represent free borders of a mesh: +- element type is \a smesh.EDGE +- functor type is \a smesh.FT_FreeBorders +- threshold value is not required + +\code +# create mesh +import geompy, smesh, StdMeshers +face = geompy.MakeFaceHW(100, 100, 1) +geompy.addToStudy( face, "quadrangle" ) +mesh = smesh.Mesh(face) +mesh.Segment().NumberOfSegments(10) +mesh.Triangle().MaxElementArea(25) +mesh.Compute() +# get all free borders +filter = smesh.GetFilter(smesh.EDGE, smesh.FT_FreeBorders) +ids = mesh.GetIdsFromFilter(filter) +print "Number of edges on free borders:", len(ids) +\endcode + +\sa \ref tui_free_borders + +\section filter_free_edges Free edges + +Filter 2D mesh elements (faces) consisting of edges belonging to one +element of mesh only: +- element type is \a smesh.FACE +- functor type is \a smesh.FT_FreeEdges +- threshold value is not required + +\code +# create mesh +import geompy, smesh, StdMeshers +face = geompy.MakeFaceHW(100, 100, 1) +geompy.addToStudy( face, "quadrangle" ) +mesh = smesh.Mesh(face) +mesh.Segment().NumberOfSegments(10) +mesh.Triangle().MaxElementArea(25) +mesh.Compute() +# get all faces with free edges +filter = smesh.GetFilter(smesh.FACE, smesh.FT_FreeEdges) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces with free edges:", len(ids) +\endcode + +\sa \ref tui_free_edges + +\section filter_free_nodes Free nodes + +Filter free nodes: +- element type is \a smesh.NODE +- functor type is \a smesh.FT_FreeNodes +- threshold value is not required + +\code +# create mesh +from SMESH_mechanic import * +# add node +mesh.AddNode(0,0,0) +# get all free nodes +filter = smesh.GetFilter(smesh.EDGE, smesh.FT_FreeNodes) +ids = mesh.GetIdsFromFilter(filter) +print "Number of free nodes:", len(ids) +\endcode + +\sa \ref tui_free_nodes + +\section filter_free_faces Free faces + +Filter free faces: +- element type is \a smesh.FACE +- functor type is \a smesh.FT_FreeFaces +- threshold value is not required + +\code +# create mesh +from SMESH_mechanic import * +# get all free faces +filter = smesh.GetFilter(smesh.EDGE, smesh.FT_FreeFaces) +ids = mesh.GetIdsFromFilter(filter) +print "Number of free faces:", len(ids) +\endcode + +\sa \ref tui_free_faces + +\section filter_borders_multiconnection Borders at multi-connection + +Filter border 1D mesh elements (edges) according to the specified number of +connections (faces belonging the border edges) +- element type is \a smesh.EDGE +- functor type is \a smesh.FT_MultiConnection +- threshold is integer value (number of connections) + +\code +# create mesh +from SMESH_mechanic import * +# get border edges with number of connected faces = 5 +filter = smesh.GetFilter(smesh.EDGE, smesh.FT_MultiConnection, 5) +ids = mesh.GetIdsFromFilter(filter) +print "Number of border edges with 5 faces connected:", len(ids) +\endcode + +\sa \ref tui_borders_at_multiconnection + +\section filter_borders_multiconnection_2d Borders at multi-connection 2D + +Filter 2D mesh elements (faces) which consist of edges belonging +to the specified number of mesh elements +- element type is \a smesh.FACE +- functor type is \a smesh.FT_MultiConnection2D +- threshold is integer value (number of connections) + +\code +# create mesh +from SMESH_mechanic import * +# get faces which consist of edges belonging to 2 mesh elements +filter = smesh.GetFilter(smesh.FACE, smesh.FT_MultiConnection2D, 2) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces consisting of edges belonging to 2 faces:", len(ids) +\endcode + +\sa \ref tui_borders_at_multiconnection_2d + +\section filter_length Length + +Filter 1D mesh elements (edges) according to the edge length value: +- element type should be \a smesh.EDGE +- functor type should be \a smesh.FT_Length +- threshold is floating point value (length) + +\code +# create mesh +from SMESH_mechanic import * +# get edges with length > 14 +filter = smesh.GetFilter(smesh.EDGE, smesh.FT_Length, smesh.FT_MoreThan, 14) +ids = mesh.GetIdsFromFilter(filter) +print "Number of edges with length > 14:", len(ids) +\endcode + +\sa \ref tui_length_1d + +\section filter_length_2d Length 2D + +Filter 2D mesh elements (faces) corresponding to the maximum length. +value of its edges: +- element type should be \a smesh.FACE +- functor type should be \a smesh.FT_Length2D +- threshold is floating point value (edge length) + +\code +# create mesh +from SMESH_mechanic import * +# get all faces that have edges with length > 14 +filter = smesh.GetFilter(smesh.FACE, smesh.FT_Length2D, smesh.FT_MoreThan, 14) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces with maximum edge length > 14:", len(ids) +\endcode + +\sa \ref tui_length_2d + +\section filter_max_element_length_2d Element Diameter 2D + +Filter 2D mesh elements (faces) corresponding to the maximum length +value of its edges and diagonals: +- element type should be \a smesh.FACE +- functor type should be \a smesh.FT_MaxElementLength2D +- threshold is floating point value (edge/diagonal length) + +\code +# create mesh +from SMESH_mechanic import * +# get all faces that have elements with length > 10 +filter = smesh.GetFilter(smesh.FACE, smesh.FT_MaxElementLength2D, smesh.FT_MoreThan, 10) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces with maximum element length > 10:", len(ids) +\endcode + +\sa \ref tui_max_element_length_2d + +\section filter_max_element_length_3d Element Diameter 3D + +Filter 3D mesh elements (volumes) corresponding to the maximum length +value of its edges and diagonals: +- element type should be \a smesh.VOLUME +- functor type should be \a smesh.FT_MaxElementLength3D +- threshold is floating point value (edge/diagonal length) + +\code +# create mesh with volumes +from SMESH_mechanic import * +mesh.Tetrahedron( algo=smesh.NETGEN ) +mesh.Compute() +# get all volumes that have elements with length > 10 +filter = smesh.GetFilter(smesh.VOLUME, smesh.FT_MaxElementLength3D, smesh.FT_MoreThan, 10) +ids = mesh.GetIdsFromFilter(filter) +print "Number of volumes with maximum element length > 10:", len(ids) +\endcode + +\sa \ref tui_max_element_length_3d + +\section filter_belong_to_geom Belong to Geom + +Filter mesh entities (nodes or elements) which all nodes lie on the +shape defined by threshold value: +- element type can be any entity type, from \a smesh.NODE to \a smesh.VOLUME +- functor type should be \a smesh.FT_BelongToGeom +- threshold is geometrical object + +\code +# create mesh +from SMESH_mechanic import * +# get all faces which nodes lie on the face sub_face3 +filter = smesh.GetFilter(smesh.FACE, smesh.FT_BelongToGeom, sub_face3) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces which nodes lie on sub_face3:", len(ids) +\endcode + +\section filter_lying_on_geom Lying on Geom + +Filter mesh entities (nodes or elements) at least one node of which lies on the +shape defined by threshold value: +- element type can be any entity type, from \a smesh.NODE to \a smesh.VOLUME +- functor type should be \a smesh.FT_LyingOnGeom +- threshold is geometrical object + +\code +# create mesh +from SMESH_mechanic import * +# get all faces at least one node of each lies on the face sub_face3 +filter = smesh.GetFilter(smesh.FACE, smesh.FT_LyingOnGeom, sub_face3) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces at least one node of each lies on sub_face3:", len(ids) +\endcode + +\section filter_belong_to_plane Belong to Plane + +Filter mesh entities (nodes or elements) which all nodes belong to the +plane defined by threshold value with the given tolerance: +- element type can be: \a smesh.NODE, \a smesh.EDGE, \a smesh.FACE +- functor type should be \a smesh.FT_BelongToPlane +- threshold is geometrical object (plane) +- default tolerance is 1.0e-7 + +\code +# create mesh +from SMESH_mechanic import * +# create plane +import geompy +plane_1 = geompy.MakePlane(p3,seg1,2000) +geompy.addToStudy(plane_1, "plane_1") +# get all nodes which lie on the plane \a plane_1 +filter = smesh.GetFilter(smesh.NODE, smesh.FT_BelongToPlane, plane_1) +ids = mesh.GetIdsFromFilter(filter) +print "Number of nodes which lie on the plane plane_1:", len(ids) +\endcode + +\section filter_belong_to_cylinder Belong to Cylinder + +Filter mesh entities (nodes or elements) which all nodes belong to the +cylindrical face defined by threshold value with the given tolerance: +- element type can be: \a smesh.NODE, \a smesh.EDGE, \a smesh.FACE +- functor type should be \a smesh.FT_BelongToCylinder +- threshold is geometrical object (cylindrical face) +- default tolerance is 1.0e-7 + +\code +# create mesh +from SMESH_mechanic import * +# get all faces which lie on the cylindrical face \a sub_face1 +filter = smesh.GetFilter(smesh.FACE, smesh.FT_BelongToCylinder, sub_face1) +ids = mesh.GetIdsFromFilter(filter) +print "Number of faces which lie on the cylindrical surface sub_face1:", len(ids) +\endcode + +\section filter_belong_to_surface Belong to Surface + +Filter mesh entities (nodes or elements) which all nodes belong to the +arbitrary surface defined by threshold value with the given tolerance: +- element type can be: \a smesh.NODE, \a smesh.EDGE, \a smesh.FACE +- functor type should be \a smesh.FT_BelongToGenSurface +- threshold is geometrical object (arbitrary surface) +- default tolerance is 1.0e-7 + +\code +# create mesh +from SMESH_mechanic import * +# create b-spline +spline_1 = geompy.MakeInterpol([p4,p6,p3,p1]) +surface_1 = geompy.MakePrismVecH( spline_1, vz, 70.0 ) +geompy.addToStudy(surface_1, "surface_1") +# get all nodes which lie on the surface \a surface_1 +filter = smesh.GetFilter(smesh.NODE, smesh.FT_BelongToGenSurface, surface_1) +ids = mesh.GetIdsFromFilter(filter) +print "Number of nodes which lie on the surface surface_1:", len(ids) +\endcode + +\section filter_range_of_ids Range of IDs + +Filter mesh entities elements (nodes or elements) according to the +specified identifiers range: +- element type can be any entity type, from \a smesh.NODE to \a smesh.VOLUME +- functor type is \a smesh.FT_RangeOfIds +- threshold is string listing required IDs and/or ranges of IDs, e.g."1,2,3,50-60,63,67,70-78" + +\code +# create mesh +from SMESH_mechanic import * +# get nodes with identifiers [5-10] and [15-30] +criterion1 = smesh.GetCriterion(smesh.NODE, smesh.FT_RangeOfIds, Treshold="5-10",\ + BinaryOp=smesh.FT_LogicalOR) +criterion2 = smesh.GetCriterion(smesh.NODE, smesh.FT_RangeOfIds, Treshold="15-30") +filter = smesh.CreateFilterManager().CreateFilter() +filter.SetCriteria([criterion1,criterion2]) +ids = mesh.GetIdsFromFilter(filter) +print "Number of nodes in ranges [5-10] and [15-30]:", len(ids) +\endcode + +\section filter_bad_oriented_volume Badly oriented volume + +Filter 3D mesh elements (volumes), which are incorrectly oriented from +the point of view of MED convention. +- element type should be \a smesh.VOLUME +- functor type is \a smesh.FT_BadOrientedVolume +- threshold is not required + +\code +# create mesh with volumes +from SMESH_mechanic import * +mesh.Tetrahedron( algo=smesh.NETGEN ) +mesh.Compute() +# get all badly oriented volumes +filter = smesh.GetFilter(smesh.VOLUME, smesh.FT_BadOrientedVolume) +ids = mesh.GetIdsFromFilter(filter) +print "Number of badly oriented volumes:", len(ids) +\endcode + +\section filter_linear_or_quadratic Linear / quadratic + +Filter linear / quadratic mesh elements: +- element type should be any element type, e.g.: \a smesh.EDGE, \a smesh.FACE, \a smesh.VOLUME +- functor type is \a smesh.FT_LinearOrQuadratic +- threshold is not required +- if unary operator is set to smesh.FT_LogicalNOT, the quadratic +elements are selected, otherwise (by default) linear elements are selected + +\code +# create mesh +from SMESH_mechanic import * +# get number of linear and quadratic edges +filter_linear = smesh.GetFilter(smesh.EDGE, smesh.FT_LinearOrQuadratic) +filter_quadratic = smesh.GetFilter(smesh.EDGE, smesh.FT_LinearOrQuadratic, smesh.FT_LogicalNOT) +ids_linear = mesh.GetIdsFromFilter(filter_linear) +ids_quadratic = mesh.GetIdsFromFilter(filter_quadratic) +print "Number of linear edges:", len(ids_linear), "; number of quadratic edges:", len(ids_quadratic) +# convert mesh to quadratic +print "Convert to quadratic..." +mesh.ConvertToQuadratic(True) +# get number of linear and quadratic edges +ids_linear = mesh.GetIdsFromFilter(filter_linear) +ids_quadratic = mesh.GetIdsFromFilter(filter_quadratic) +print "Number of linear edges:", len(ids_linear), "; number of quadratic edges:", len(ids_quadratic) +\endcode + +\section filter_group_color Group color + +Filter mesh entities, belonging to the group with the color defined by the threshold value. +- element type can be any entity type, from \a smesh.NODE to \a smesh.VOLUME +- functor type is \a smesh.FT_GroupColor +- threshold should be of SALOMEDS.Color type + +\code +# create mesh +from SMESH_mechanic import * +# create group of edges +all_edges = mesh.GetElementsByType(smesh.EDGE) +grp = mesh.MakeGroupByIds("edges group", smesh.EDGE, all_edges[:len(all_edges)/4]) +import SALOMEDS +c = SALOMEDS.Color(0.1, 0.5, 1.0) +grp.SetColor(c) +# get number of the edges not belonging to the group with the given color +filter = smesh.GetFilter(smesh.EDGE, smesh.FT_GroupColor, c, smesh.FT_LogicalNOT) +ids = mesh.GetIdsFromFilter(filter) +print "Number of edges not beloging to the group with color (0.1, 0.5, 1.0):", len(ids) +\endcode + +\section filter_geom_type Geometry type + +Filter mesh elements by the geometric type defined with the threshold +value. The list of available geometric types depends on the element +entity type. +- element type should be any element type, e.g.: \a smesh.EDGE, \a smesh.FACE, \a smesh.VOLUME +- functor type should be \a smesh.FT_ElemGeomType +- threshold is of smesh.GeometryType value + +\code +# create mesh with volumes +from SMESH_mechanic import * +mesh.Tetrahedron( algo=smesh.NETGEN ) +mesh.Compute() +# get all triangles, quadrangles, tetrahedrons, pyramids +filter_tri = smesh.GetFilter(smesh.FACE, smesh.FT_ElemGeomType, smesh.Geom_TRIANGLE) +filter_qua = smesh.GetFilter(smesh.FACE, smesh.FT_ElemGeomType, smesh.Geom_QUADRANGLE) +filter_tet = smesh.GetFilter(smesh.VOLUME, smesh.FT_ElemGeomType, smesh.Geom_TETRA) +filter_pyr = smesh.GetFilter(smesh.VOLUME, smesh.FT_ElemGeomType, smesh.Geom_PYRAMID) +ids_tri = mesh.GetIdsFromFilter(filter_tri) +ids_qua = mesh.GetIdsFromFilter(filter_qua) +ids_tet = mesh.GetIdsFromFilter(filter_tet) +ids_pyr = mesh.GetIdsFromFilter(filter_pyr) +print "Number of triangles:", len(ids_tri) +print "Number of quadrangles:", len(ids_qua) +print "Number of tetrahedrons:", len(ids_tet) +print "Number of pyramids:", len(ids_pyr) +\endcode + +*/ diff --git a/doc/salome/gui/SMESH/input/tui_grouping_elements.doc b/doc/salome/gui/SMESH/input/tui_grouping_elements.doc index b77edd21e..1aa73a484 100644 --- a/doc/salome/gui/SMESH/input/tui_grouping_elements.doc +++ b/doc/salome/gui/SMESH/input/tui_grouping_elements.doc @@ -1,4 +1,4 @@ - /*! +/*! \page tui_grouping_elements_page Grouping Elements @@ -19,7 +19,11 @@ aFilter = smesh.GetFilter(smesh.FACE, smesh.FT_Area, smesh.FT_MoreThan, 100.) anIds = mesh.GetIdsFromFilter(aFilter) # create a group consisting of faces with area > 100 -aGroup = mesh.MakeGroupByIds("Area > 100", smesh.FACE, anIds) +aGroup1 = mesh.MakeGroupByIds("Area > 100", smesh.FACE, anIds) + +# create a group that contains all nodes from the mesh +aGroup2 = mesh.CreateEmptyGroup(smesh.NODE, "all nodes") +aGroup2.AddFrom(mesh.mesh) salome.sg.updateObjBrowser(1) \endcode diff --git a/doc/salome/gui/SMESH/input/tui_measurements.doc b/doc/salome/gui/SMESH/input/tui_measurements.doc new file mode 100644 index 000000000..aabf0b317 --- /dev/null +++ b/doc/salome/gui/SMESH/input/tui_measurements.doc @@ -0,0 +1,84 @@ +/*! + +\page tui_measurements_page Measurements + +\section tui_min_distance Minimum Distance + +\code + +import smesh +from SMESH_mechanic import mesh as mesh1 +from SMESH_test1 import mesh as mesh2 + +mesh1.Compute() +mesh2.Compute() + +# compute min distance from mesh1 to the origin (not available yet) +smesh.MinDistance(mesh1) + +# compute min distance from node 10 of mesh1 to the origin +smesh.MinDistance(mesh1, id1=10) +# ... or +mesh1.MinDistance(10) + +# compute min distance between nodes 10 and 20 of mesh1 +smesh.MinDistance(mesh1, id1=10, id2=20) +# ... or +mesh1.MinDistance(10, 20) + +# compute min distance from element 100 of mesh1 to the origin (not available yet) +smesh.MinDistance(mesh1, id1=100, isElem1=True) +# ... or +mesh1.MinDistance(100, isElem1=True) + +# compute min distance between elements 100 and 200 of mesh1 (not available yet) +smesh.MinDistance(mesh1, id1=100, id2=200, isElem1=True, isElem2=True) +# ... or +mesh1.MinDistance(100, 200, True, True) + +# compute min distance from element 100 to node 20 of mesh1 (not available yet) +smesh.MinDistance(mesh1, id1=100, id2=20, isElem1=True) +# ... or +mesh1.MinDistance(100, 20, True) + +# compute min distance from mesh1 to mesh2 (not available yet) +smesh.MinDistance(mesh1, mesh2) + +# compute min distance from node 10 of mesh1 to node 20 of mesh2 +smesh.MinDistance(mesh1, mesh2, 10, 20) + +# compute min distance from node 10 of mesh1 to element 200 of mesh2 (not available yet) +smesh.MinDistance(mesh1, mesh2, 10, 200, isElem2=True) + +# etc... + +\endcode + +\section tui_bounding_box Bounding Box + +\code + +import smesh +from SMESH_mechanic import mesh as mesh1 +from SMESH_test1 import mesh as mesh2 + +mesh1.Compute() +mesh2.Compute() + +# compute bounding box for mesh1 +mesh1.BoundingBox() + +# compute bounding box for list of nodes of mesh1 +mesh1.BoundingBox([363, 364, 370, 371, 372, 373, 379, 380, 381]) + +# compute bounding box for list of elements of mesh1 +mesh1.BoundingBox([363, 364, 370, 371, 372, 373, 379, 380, 381], isElem=True) + +# compute common bounding box of mesh1 and mesh2 +smesh.BoundingBox([mesh1, mesh2]) + +# etc... + +\endcode + +*/ diff --git a/doc/salome/gui/SMESH/input/tui_modifying_meshes.doc b/doc/salome/gui/SMESH/input/tui_modifying_meshes.doc index 2e8f75291..fe0da8e61 100644 --- a/doc/salome/gui/SMESH/input/tui_modifying_meshes.doc +++ b/doc/salome/gui/SMESH/input/tui_modifying_meshes.doc @@ -282,35 +282,40 @@ else: print "KO Elements removing." \endcode
              -\anchor tui_renumbering_nodes_and_elements -

              Renumbering Nodes and Elements

              +\anchor tui_removing_orphan_nodes +

              Removing Orphan Nodes

              \code import SMESH_mechanic mesh = SMESH_mechanic.mesh -mesh.RenumberNodes() - -mesh.RenumberElements() +# add orphan nodes +mesh.AddNode(0,0,0) +mesh.AddNode(1,1,1) +# remove just created orphan nodes +res = mesh.RemoveOrphanNodes() +if res == 1: print "Removed %d nodes!" % res +else: print "KO nodes removing." \endcode
              -\anchor tui_moving_nodes -

              Moving Nodes

              +\anchor tui_renumbering_nodes_and_elements +

              Renumbering Nodes and Elements

              \code import SMESH_mechanic mesh = SMESH_mechanic.mesh -# move node #38 -mesh.MoveNode(38, 20., 10., 0.) +mesh.RenumberNodes() + +mesh.RenumberElements() \endcode
              -\anchor tui_mesh_through_point -

              Mesh through point

              +\anchor tui_moving_nodes +

              Moving Nodes

              \code from geompy import * @@ -344,16 +349,11 @@ n = mesh.FindNodeClosestTo( -1,-1,-1 ) if not n == node000: raise "FindNodeClosestTo() returns " + str( n ) + " != " + str( node000 ) -# check if any node will be found for a point inside a box -n = mesh.FindNodeClosestTo( 100, 100, 100 ) -if not n > 0: - raise "FindNodeClosestTo( 100, 100, 100 ) fails" - # move node000 to a new location x,y,z = -10, -10, -10 -n = mesh.MeshToPassThroughAPoint( x,y,z ) -if not n == node000: - raise "FindNodeClosestTo() returns " + str( n ) + " != " + str( node000 ) +n = mesh.MoveNode( n,x,y,z ) +if not n: + raise "MoveNode() returns " + n # check the coordinates of the node000 xyz = mesh.GetNodeXYZ( node000 ) diff --git a/doc/salome/gui/SMESH/input/tui_quality_controls.doc b/doc/salome/gui/SMESH/input/tui_quality_controls.doc index 57d52c69e..fc496dcde 100644 --- a/doc/salome/gui/SMESH/input/tui_quality_controls.doc +++ b/doc/salome/gui/SMESH/input/tui_quality_controls.doc @@ -2,9 +2,7 @@ \page tui_quality_controls_page Quality Controls -
              -\anchor tui_free_borders -

              Free Borders

              +\section tui_free_borders Free Borders \code import salome @@ -48,9 +46,7 @@ aGroup.Add(anIds) salome.sg.updateObjBrowser(1) \endcode -
              -\anchor tui_borders_at_multiconnection -

              Borders at Multiconnection

              +\section tui_borders_at_multiconnection Borders at Multiconnection \code import salome @@ -97,9 +93,7 @@ aGroup.Add(anIds) salome.sg.updateObjBrowser(1) \endcode -
              -\anchor tui_length_1d -

              Length 1D

              +\section tui_length_1d Length 1D \code import salome @@ -145,9 +139,7 @@ aGroup.Add(anIds) salome.sg.updateObjBrowser(1) \endcode -
              -\anchor tui_free_edges -

              Free Edges

              +\section tui_free_edges Free Edges \code import SMESH_mechanic @@ -189,9 +181,7 @@ for i in range(len(aBorders)): salome.sg.updateObjBrowser(1) \endcode -
              -\anchor tui_free_nodes -

              Free Nodes

              +\section tui_free_nodes Free Nodes \code import salome @@ -242,10 +232,7 @@ print "" salome.sg.updateObjBrowser(1) \endcode - -
              -\anchor tui_free_faces -

              Free Faces

              +\section tui_free_faces Free Faces \code import salome @@ -322,10 +309,7 @@ aGroup.Add(aFaceIds) salome.sg.updateObjBrowser(1) \endcode - -
              -\anchor tui_length_2d -

              Length 2D

              +\section tui_length_2d Length 2D \code import salome @@ -372,9 +356,7 @@ aGroup.Add(anIds) salome.sg.updateObjBrowser(1) \endcode -
              -\anchor tui_borders_at_multiconnection_2d -

              Borders at Multiconnection 2D

              +\section tui_borders_at_multiconnection_2d Borders at Multiconnection 2D \code import salome @@ -421,9 +403,7 @@ aGroup.Add(anIds) salome.sg.updateObjBrowser(1) \endcode -
              -\anchor tui_area -

              Area

              +\section tui_area Area \code import SMESH_mechanic @@ -456,9 +436,7 @@ aGroup.Add(anIds) salome.sg.updateObjBrowser(1) \endcode -
              -\anchor tui_taper -

              Taper

              +\section tui_taper Taper \code import SMESH_mechanic @@ -491,9 +469,7 @@ aGroup.Add(anIds) salome.sg.updateObjBrowser(1) \endcode -
              -\anchor tui_aspect_ratio -

              Aspect Ratio

              +\section tui_aspect_ratio Aspect Ratio \code import SMESH_mechanic @@ -526,9 +502,7 @@ aGroup.Add(anIds) salome.sg.updateObjBrowser(1) \endcode -
              -\anchor tui_minimum_angle -

              Minimum Angle

              +\section tui_minimum_angle Minimum Angle \code import SMESH_mechanic @@ -562,9 +536,7 @@ aGroup.Add(anIds) salome.sg.updateObjBrowser(1) \endcode -
              -\anchor tui_warping -

              Warping

              +\section tui_warping Warping \code import SMESH_mechanic @@ -598,9 +570,7 @@ aGroup.Add(anIds) salome.sg.updateObjBrowser(1) \endcode -
              -\anchor tui_skew -

              Skew

              +\section tui_skew Skew \code import SMESH_mechanic @@ -633,9 +603,40 @@ aGroup.Add(anIds) salome.sg.updateObjBrowser(1) \endcode -
              -\anchor tui_aspect_ratio_3d -

              Aspect Ratio 3D

              +\section tui_max_element_length_2d Element Diameter 2D + +\code +import SMESH_mechanic + +smesh = SMESH_mechanic.smesh +mesh = SMESH_mechanic.mesh +salome = SMESH_mechanic.salome + +# Criterion : ELEMENT DIAMETER 2D > 10 +mel_2d_margin = 10 + +aFilter = smesh.GetFilter(smesh.FACE, smesh.FT_MaxElementLength2D, smesh.FT_MoreThan, mel_2d_margin) + +anIds = mesh.GetIdsFromFilter(aFilter) + +# print the result +print "Criterion: Element Diameter 2D Ratio > ", mel_2d_margin, " Nb = ", len(anIds) +j = 1 +for i in range(len(anIds)): + if j > 20: j = 1; print "" + print anIds[i], + j = j + 1 + pass +print "" + +# create a group +aGroup = mesh.CreateEmptyGroup(smesh.FACE, "Element Diameter 2D > " + `mel_2d_margin`) +aGroup.Add(anIds) + +salome.sg.updateObjBrowser(1) +\endcode + +\section tui_aspect_ratio_3d Aspect Ratio 3D \code import SMESH_mechanic_tetra @@ -669,9 +670,7 @@ aGroup.Add(anIds) salome.sg.updateObjBrowser(1) \endcode -
              -\anchor tui_volume -

              Volume

              +\section tui_volume Volume \code import SMESH_mechanic_tetra @@ -706,4 +705,37 @@ aGroup.Add(anIds) salome.sg.updateObjBrowser(1) \endcode +\section tui_max_element_length_3d Element Diameter 3D + +\code +import SMESH_mechanic_tetra + +smesh = SMESH_mechanic_tetra.smesh +mesh = SMESH_mechanic_tetra.mesh +salome = SMESH_mechanic_tetra.salome + +# Criterion : ELEMENT DIAMETER 3D > 10 +mel_3d_margin = 10 + +aFilter = smesh.GetFilter(smesh.FACE, smesh.FT_MaxElementLength3D, smesh.FT_MoreThan, mel_3d_margin) + +anIds = mesh.GetIdsFromFilter(aFilter) + +# print the result +print "Criterion: Element Diameter 3D Ratio > ", mel_3d_margin, " Nb = ", len(anIds) +j = 1 +for i in range(len(anIds)): + if j > 20: j = 1; print "" + print anIds[i], + j = j + 1 + pass +print "" + +# create a group +aGroup = mesh.CreateEmptyGroup(smesh.FACE, "Element Diameter 3D > " + `mel_3d_margin`) +aGroup.Add(anIds) + +salome.sg.updateObjBrowser(1) +\endcode + */ diff --git a/doc/salome/gui/SMESH/input/tui_transforming_meshes.doc b/doc/salome/gui/SMESH/input/tui_transforming_meshes.doc index c55b2a492..22f11886f 100644 --- a/doc/salome/gui/SMESH/input/tui_transforming_meshes.doc +++ b/doc/salome/gui/SMESH/input/tui_transforming_meshes.doc @@ -350,4 +350,238 @@ mesh.Compute() mesh.SewSideElements([69, 70, 71, 72], [91, 92, 89, 90], 8, 38, 23, 58) \endcode +
              +\anchor tui_duplicate_nodes +

              Duplicate nodes

              + +\code +import salome +import smesh +import SMESH_test1 + +mesh = SMESH_test1.mesh + +# Compute mesh +mesh.Compute() + +# Without the duplication of border elements + +# Nodes to duplicate +nodes1 = mesh.CreateEmptyGroup( smesh.NODE, 'nodes1' ) +nodes1.Add( [ 289, 278, 302, 285 ] ) + +# Group of faces to replace nodes with new ones +faces1 = mesh.CreateEmptyGroup( smesh.FACE, 'faces1' ) +faces1.Add( [ 519, 556, 557 ] ) + +# Duplicate nodes +print "\nMesh before the first nodes duplication:" +print "Nodes : ", mesh.NbNodes() +print "Edges : ", mesh.NbEdges() +print "Triangles : ", mesh.NbTriangles() + +groupOfCreatedNodes = mesh.DoubleNodeGroup(nodes1, faces1, theMakeGroup=True) +print "New nodes:", groupOfCreatedNodes.GetIDs() + +print "\nMesh after the first nodes duplication:" +print "Nodes : ", mesh.NbNodes() +print "Edges : ", mesh.NbEdges() +print "Triangles : ", mesh.NbTriangles() + +# With the duplication of border elements + +# Edges to duplicate +edges = mesh.CreateEmptyGroup( smesh.EDGE, 'edges' ) +edges.Add( [ 29, 30, 31 ] ) + +# Nodes not to duplicate +nodes2 = mesh.CreateEmptyGroup( smesh.NODE, 'nodes2' ) +nodes2.Add( [ 32, 5 ] ) + +# Group of faces to replace nodes with new ones +faces2 = mesh.CreateEmptyGroup( smesh.FACE, 'faces2' ) +faces2.Add( [ 576, 578, 580 ] ) + +# Duplicate nodes +print "\nMesh before the second nodes duplication:" +print "Nodes : ", mesh.NbNodes() +print "Edges : ", mesh.NbEdges() +print "Triangles : ", mesh.NbTriangles() + +groupOfNewEdges = mesh.DoubleNodeElemGroup( edges, nodes2, faces2, theMakeGroup=True ) +print "New edges:", groupOfNewEdges.GetIDs() + +print "\nMesh after the second nodes duplication:" +print "Nodes : ", mesh.NbNodes() +print "Edges : ", mesh.NbEdges() +print "Triangles : ", mesh.NbTriangles() + +# Update object browser +if salome.sg.hasDesktop(): + salome.sg.updateObjBrowser(0) +\endcode + +
              +\anchor tui_make_2dmesh_from_3d +

              Create boundary elements

              + +\code +# The objective of these samples is to illustrate the following use cases: +# 1) The mesh MESH1 with 3D cells has no or only a part of its skin (2D cells): +# 1.1) Add the 2D skin (missing 2D cells) to MESH1 (what is done now by the algorithm). +# 1.2) Create a new 3D Mesh MESH2 that consists of MESH1 and added 2D skin cells. +# 1.3) Create a new 2D Mesh MESH3 that consists only of 2D skin cells. +# 2) The mesh MESH1 with 3D cells has all its skin (2D cells): +# Create a new 2D Mesh MESH3 that consists only of 2D skin cells. +# +# In all cases an option to create a group containing these 2D skin cells is available. + +from smesh import * + +box = geompy.MakeBoxDXDYDZ(1,1,1) +geompy.addToStudy(box,"box") +boxFace = geompy.SubShapeAll(box, geompy.ShapeType["FACE"])[0] +geompy.addToStudyInFather(box,boxFace,"boxFace") + +MESH1 = Mesh(box,"MESH1") +MESH1.AutomaticHexahedralization() + +init_nb_edges = MESH1.NbEdges() +init_nb_faces = MESH1.NbFaces() +init_nb_volumes = MESH1.NbVolumes() + +# ========================================================================================= +# 1) The mesh MESH1 with 3D cells has no or only a part of its skin (2D cells) +# ========================================================================================= +# remove some faces +all_faces = MESH1.GetElementsByType(SMESH.FACE) +rm_faces = all_faces[:init_nb_faces/5] + all_faces[4*init_nb_faces/5:] +MESH1.RemoveElements(rm_faces) +assert(MESH1.NbFaces() == init_nb_faces-len(rm_faces)) + +# 1.1) Add the 2D skin (missing 2D cells) to MESH1 +# ------------------------------------------------- +# add missing faces +# 1.1.1) to the whole mesh +m,g = MESH1.MakeBoundaryMesh(MESH1) +assert(init_nb_faces == MESH1.NbFaces()) +assert(init_nb_edges == MESH1.NbEdges()) +assert(m) +assert(not g) + +# 1.1.2) to some elements +MESH1.RemoveElements(rm_faces) +MESH1.MakeBoundaryMesh([]) +assert(init_nb_faces != MESH1.NbFaces()) +volumes = MESH1.GetElementsByType(SMESH.VOLUME) +for v in volumes: + MESH1.MakeBoundaryMesh([v]) +assert(init_nb_faces == MESH1.NbFaces()) +assert(init_nb_edges == MESH1.NbEdges()) + +# 1.1.3) to a group of elements +volGroup1 = MESH1.CreateEmptyGroup(SMESH.VOLUME, "volGroup1") +volGroup1.Add( volumes[: init_nb_volumes/2]) +volGroup2 = MESH1.CreateEmptyGroup(SMESH.VOLUME, "volGroup2") +volGroup1.Add( volumes[init_nb_volumes/2:]) +MESH1.RemoveElements(rm_faces) +MESH1.MakeBoundaryMesh(volGroup1) +MESH1.MakeBoundaryMesh(volGroup2) +assert(init_nb_faces == MESH1.NbFaces()) +assert(init_nb_edges == MESH1.NbEdges()) + +# 1.1.4) to a submesh. +# The submesh has no volumes, so it is required to check if it passes without crash and does not create +# missing faces +faceSubmesh = MESH1.GetSubMesh( boxFace, "boxFace" ) +MESH1.RemoveElements(rm_faces) +MESH1.MakeBoundaryMesh(faceSubmesh) +assert(init_nb_faces != MESH1.NbFaces()) + +# check group creation +MESH1.RemoveElements(rm_faces) +groupName = "added to mesh" +m,group = MESH1.MakeBoundaryMesh(MESH1,groupName=groupName) +assert(group) +assert(group.GetName() == groupName) +assert(group.Size() == len(rm_faces)) + + +# 1.2) Create a new 3D Mesh MESH2 that consists of MESH1 and added 2D skin cells. +# ------------------------------------------------------------------------------ +MESH1.RemoveElements(rm_faces) +meshName = "MESH2" +MESH2,group = MESH1.MakeBoundaryMesh(MESH1,meshName=meshName,toCopyElements=True) +assert(MESH2) +assert(MESH2.GetName() == meshName) +assert(MESH2.NbVolumes() == MESH1.NbVolumes()) +assert(MESH2.NbFaces() == len(rm_faces)) + +# check group creation +MESH1.RemoveElements(rm_faces) +MESH2,group = MESH1.MakeBoundaryMesh(MESH1,meshName="MESH2_0", + groupName=groupName,toCopyElements=True) +assert(group) +assert(group.GetName() == groupName) +assert(group.Size() == len(rm_faces)) +assert(group.GetMesh()._is_equivalent(MESH2.GetMesh())) + +# 1.3) Create a new 2D Mesh MESH3 that consists only of 2D skin cells. +# ----------------------------------------------------------------------- +MESH1.RemoveElements(rm_faces) +meshName = "MESH3" +MESH3,group = MESH1.MakeBoundaryMesh(MESH1,meshName=meshName,toCopyExistingBondary=True) +assert(MESH3) +assert(not group) +assert(MESH3.GetName() == meshName) +assert(MESH3.NbVolumes() == 0) +assert(MESH3.NbFaces() == init_nb_faces) + +# check group creation +MESH1.RemoveElements(rm_faces) +MESH3,group = MESH1.MakeBoundaryMesh(MESH1,meshName=meshName, + groupName=groupName, toCopyExistingBondary=True) +assert(group) +assert(group.GetName() == groupName) +assert(group.Size() == len(rm_faces)) +assert(group.GetMesh()._is_equivalent(MESH3.GetMesh())) +assert(MESH3.NbFaces() == init_nb_faces) + +# ================================================================== +# 2) The mesh MESH1 with 3D cells has all its skin (2D cells) +# Create a new 2D Mesh MESH3 that consists only of 2D skin cells. +# ================================================================== +MESH1.MakeBoundaryMesh(MESH1) +MESH3,group = MESH1.MakeBoundaryMesh(MESH1,meshName=meshName,toCopyExistingBondary=True) +assert(MESH3) +assert(not group) +assert(MESH3.NbVolumes() == 0) +assert(MESH3.NbFaces() == init_nb_faces) + +# check group creation +MESH3,group = MESH1.MakeBoundaryMesh(MESH1,meshName=meshName, + groupName=groupName, toCopyExistingBondary=True) +assert(group) +assert(group.GetName() == groupName) +assert(group.Size() == 0) +assert(group.GetMesh()._is_equivalent(MESH3.GetMesh())) +assert(MESH3.NbFaces() == init_nb_faces) + +# ================ +# Make 1D from 2D +# ================ + +MESH1.Clear() +MESH1.Compute() +MESH1.RemoveElements( MESH1.GetElementsByType(SMESH.EDGE)) + +rm_faces = faceSubmesh.GetIDs()[:2] # to remove few adjacent faces +nb_missing_edges = 2 + 2*len(rm_faces) + +MESH1.RemoveElements(rm_faces) +mesh,group = MESH1.MakeBoundaryMesh(MESH1, BND_1DFROM2D) +assert( MESH1.NbEdges() == nb_missing_edges ) + + +\endcode */ diff --git a/doc/salome/gui/SMESH/input/use_existing_algos.doc b/doc/salome/gui/SMESH/input/use_existing_algos.doc new file mode 100644 index 000000000..b2273a4f0 --- /dev/null +++ b/doc/salome/gui/SMESH/input/use_existing_algos.doc @@ -0,0 +1,58 @@ +/*! + +\page import_algos_page Use Existing Elements Algorithms + +\n Use Existing Elements algorithms allow to define the mesh of a geometrical +object by the importing suitably located mesh elements from another +mesh. The mesh elements to import from the other mesh are to be contained in +groups. If several groups are used to mesh one geometry, validity of +nodal connectivity of result mesh must be assured by connectivity of +the source mesh; no geometrical checks are performed to merge +different nodes at same locations. +
              The source elements must totally cover the meshed geometry. +The source elements lying partially over the geometry will not be used. +
              +These algorithms can be used to mesh a very complex geometry part by +part, by storing meshes of parts in files and then fusing them +together using these algorithms. +
              + +Use Existing 1D Elements algorithm allows to define the mesh of +a geometrical edge (or group of edges) +by the importing of mesh edges of another mesh contained in a group (or groups). +\n To apply this algorithm select the edge to be meshed (indicated in +the field \b Geometry of Create mesh dialog box), +Use existing 1D elements in the list of 1D algorithms and click the +"Add Hypothesis" button. +The following dialog box will appear: + +\image html hyp_source_edges.png + +In this menu you can define the \b Name of the algorithm, the +Groups of Edges to import elements from, To copy mesh +the selected Groups of Edges belong to as a whole and To +copy groups along with the whole mesh. +
              + +Use Existing 2D Elements algorithm allows to define the mesh of +a geometrical face (or group of faces) +by the importing of mesh faces of another mesh contained in a group (or groups). +\n To apply this algorithm select the edge to be meshed (indicated in +the field \b Geometry of Create mesh dialog box), +Use existing 2D elements in the list of 2D algorithms and click the +"Add Hypothesis" button. +The following dialog box will appear: + +\image html hyp_source_faces.png + +In this menu you can define the \b Name of the algorithm, the +Groups of Faces to import elements from, To copy mesh +the selected Groups of Fcaes belong to as a whole and To +copy groups along with the whole mesh. +
              + +
              See Also a sample TUI Script of a +\ref tui_import "Use Existing Elements Algorithms". + +*/ + diff --git a/doc/salome/gui/SMESH/input/volume.doc b/doc/salome/gui/SMESH/input/volume.doc index ba99c193e..4d74fcbf0 100644 --- a/doc/salome/gui/SMESH/input/volume.doc +++ b/doc/salome/gui/SMESH/input/volume.doc @@ -9,8 +9,8 @@
              1. Display your mesh in the viewer.
              2. -
              3. Choose Controls > Volume or click "Volume" button -in the toolbar. +
              4. Choose Controls > Volume Controls > Volume or click +"Volume" button in the toolbar. \image html image145.png
                "Volume" button
                diff --git a/doc/salome/gui/SMESH/input/warping.doc b/doc/salome/gui/SMESH/input/warping.doc index 83bfaa3ac..86ba0c905 100644 --- a/doc/salome/gui/SMESH/input/warping.doc +++ b/doc/salome/gui/SMESH/input/warping.doc @@ -24,8 +24,8 @@ projection height ?h? to the half edge length ?l?.
                1. Display your mesh in the viewer.
                2. -
                3. Choose Controls > Warping Angle or click "Warping angle" -button of the toolbar. +
                4. Choose Controls > Face Controls > Warping Angle or click +"Warping angle" button of the toolbar. \image html image39.png
                  "Warping angle" button
                  diff --git a/idl/Makefile.am b/idl/Makefile.am index 5a88808b3..491c38667 100644 --- a/idl/Makefile.am +++ b/idl/Makefile.am @@ -32,7 +32,8 @@ BASEIDL_FILES = \ SMESH_Filter.idl \ SMESH_Group.idl \ SMESH_Pattern.idl \ - SMESH_MeshEditor.idl + SMESH_MeshEditor.idl \ + SMESH_Measurements.idl # This variable defines the files to be installed dist_salomeidl_DATA = $(BASEIDL_FILES) @@ -49,7 +50,8 @@ nodist_libSalomeIDLSMESH_la_SOURCES = \ SMESH_FilterSK.cc \ SMESH_GroupSK.cc \ SMESH_PatternSK.cc \ - SMESH_MeshEditorSK.cc + SMESH_MeshEditorSK.cc \ + SMESH_MeasurementsSK.cc # header files must be exported: other modules have to use this library nodist_salomeinclude_HEADERS = $(BASEIDL_FILES:%.idl=%.hh) diff --git a/idl/SMESH_BasicHypothesis.idl b/idl/SMESH_BasicHypothesis.idl index 871f07714..88b0ab751 100644 --- a/idl/SMESH_BasicHypothesis.idl +++ b/idl/SMESH_BasicHypothesis.idl @@ -753,6 +753,16 @@ module StdMeshers /*! * StdMeshers_QuadrangleParams: interface of "Quadrangle Params" hypothesis */ + enum QuadType + { + QUAD_STANDARD, + QUAD_TRIANGLE_PREF, + QUAD_QUADRANGLE_PREF, + QUAD_QUADRANGLE_PREF_REVERSED, + QUAD_REDUCED, + QUAD_NB_TYPES /* this is not a type of quadrangulation */ + }; + interface StdMeshers_QuadrangleParams : SMESH::SMESH_Hypothesis { /*! @@ -774,6 +784,58 @@ module StdMeshers * Get the entry of the main object */ string GetObjectEntry(); + + /*! + * Set the type of quadrangulation + */ + void SetQuadType( in QuadType type ); + + /*! + * Get the type of quadrangulation + */ + QuadType GetQuadType(); + }; + + /*! + * interface of "Source edges" hypothesis. + * This hypothesis specifies groups of edges of other mesh to be imported + * in this mesh + */ + interface StdMeshers_ImportSource1D : SMESH::SMESH_Hypothesis + { + /*! + * Set edges to import from other mesh + */ + void SetSourceEdges(in SMESH::ListOfGroups groups); + SMESH::string_array GetSourceEdges(); + + /*! + * Set to import the whole other mesh or not, and if yes, to + * copy groups of not. By default the mesh is not copied. + */ + void SetCopySourceMesh(in boolean toCopyMesh, in boolean toCopyGroups); + void GetCopySourceMesh(out boolean toCopyMesh,out boolean toCopyGroups); + }; + + /*! + * interface of "Source faces" hypothesis. + * This hypothesis specifies groups of faces of other mesh to be imported + * in this mesh + */ + interface StdMeshers_ImportSource2D : SMESH::SMESH_Hypothesis + { + /*! + * Set faces to import from other mesh + */ + void SetSourceFaces(in SMESH::ListOfGroups groups); + SMESH::string_array GetSourceFaces(); + + /*! + * Set to import the whole other mesh or not, and if yes, to + * copy groups of not. By default the mesh is not copied. + */ + void SetCopySourceMesh(in boolean toCopyMesh,in boolean toCopyGroups); + void GetCopySourceMesh(out boolean toCopyMesh,out boolean toCopyGroups); }; /*! @@ -876,6 +938,19 @@ module StdMeshers { }; + /*! + * StdMeshers_Import_1D2D: interface of "Use existing 2D elements" algorithm + */ + interface StdMeshers_Import_1D2D : SMESH::SMESH_2D_Algo + { + }; + /*! + * StdMeshers_Import_1D: interface of "Use existing 1D elements" algorithm + */ + interface StdMeshers_Import_1D : SMESH::SMESH_1D_Algo + { + }; + }; #endif diff --git a/idl/SMESH_Filter.idl b/idl/SMESH_Filter.idl index 56f2cdce2..e12607bcd 100644 --- a/idl/SMESH_Filter.idl +++ b/idl/SMESH_Filter.idl @@ -47,6 +47,8 @@ module SMESH FT_Skew, FT_Area, FT_Volume3D, + FT_MaxElementLength2D, + FT_MaxElementLength3D, FT_FreeBorders, FT_FreeEdges, FT_FreeNodes, @@ -65,6 +67,7 @@ module SMESH FT_LinearOrQuadratic, FT_GroupColor, FT_ElemGeomType, + FT_CoplanarFaces, FT_LessThan, FT_MoreThan, FT_EqualTo, @@ -74,6 +77,17 @@ module SMESH FT_Undefined }; + /*! + * Parameters of a reclangle of histogram + */ + struct HistogramRectangle + { + long nbEvents; + double min; + double max; + }; + typedef sequence Histogram; + /*! * Base interface for all functors ( i.e. numerical functors and predicates ) */ @@ -93,6 +107,8 @@ module SMESH { double GetValue( in long theElementId ); + Histogram GetHistogram( in short nbIntervals ); + /*! * Set precision for calculation. It is a position after point which is * used to functor value after calculation. @@ -108,6 +124,8 @@ module SMESH interface Skew : NumericalFunctor{}; interface Area : NumericalFunctor{}; interface Volume3D : NumericalFunctor{}; + interface MaxElementLength2D : NumericalFunctor{}; + interface MaxElementLength3D : NumericalFunctor{}; interface Length : NumericalFunctor{}; interface Length2D : NumericalFunctor { @@ -346,6 +364,16 @@ module SMESH void SetGeometryType( in GeometryType theType ); }; + /*! + * Functor "Coplanar faces" + * Returns true if a mesh face is a coplanar neighbour to a given one. It checks + * if normal of a face has angle with the threshold face less than a tolerance. + */ + interface CoplanarFaces : Predicate{ + void SetFace ( in long theFaceID ); + void SetTolerance( in double theToler ); + }; + /*! * Filter */ @@ -360,13 +388,13 @@ module SMESH * BinaryOp - binary logical operation FT_LogicalAND, FT_LogicalOR or * (FT_Undefined must be for the last criterion) * ThresholdStr - Threshold value defined as string. Used for: - * 1. Diaposon of identifiers. Example: "1,2,3,5-10,12,27-29" + * 1. Diapason of identifiers. Example: "1,2,3,5-10,12,27-29" * 2. BelongToGeom predicate for storing name of shape * 3. GroupColor predicate for storing group color "0.2;0;0.5" * ThresholdID - One more threshold value defined as string. Used for: * 1. BelongToGeom predicate for storing id of shape * Tolerance - Tolerance is used for comparators (EqualTo comparision) and for - * "Belong to plane" and "Belong to cylinder" predicates + * "Belong to plane", "Belong to cylinder" etc predicates * TypeOfElement - type of element SMESH::NODE, SMESH::FACE (used by BelongToGeom predicate only) * Precision - Precision of numerical functors */ @@ -450,6 +478,8 @@ module SMESH Skew CreateSkew(); Area CreateArea(); Volume3D CreateVolume3D(); + MaxElementLength2D CreateMaxElementLength2D(); + MaxElementLength3D CreateMaxElementLength3D(); Length CreateLength(); Length2D CreateLength2D(); MultiConnection CreateMultiConnection(); @@ -477,6 +507,7 @@ module SMESH GroupColor CreateGroupColor(); ElemGeomType CreateElemGeomType(); + CoplanarFaces CreateCoplanarFaces(); /*! * Create comparators ( predicates ) diff --git a/idl/SMESH_Gen.idl b/idl/SMESH_Gen.idl index 14527a9b3..3c375e625 100644 --- a/idl/SMESH_Gen.idl +++ b/idl/SMESH_Gen.idl @@ -42,6 +42,7 @@ module SMESH interface FilterManager; interface SMESH_Pattern; + interface Measurements; /*! * Tags definition @@ -119,6 +120,8 @@ module SMESH SMESH_Pattern GetPattern(); + Measurements CreateMeasurements(); + /*! Set the current mode */ @@ -244,7 +247,6 @@ module SMESH */ long_array Evaluate(in SMESH_Mesh theMesh, in GEOM::GEOM_Object theSubObject) - //inout long_array theNbElems) raises ( SALOME::SALOME_Exception ); /*! diff --git a/idl/SMESH_Group.idl b/idl/SMESH_Group.idl index c0bb54bc9..adf63dd83 100644 --- a/idl/SMESH_Group.idl +++ b/idl/SMESH_Group.idl @@ -82,11 +82,6 @@ module SMESH */ long_array GetListOfID(); - /*! - * Returns the mesh object this group belongs to - */ - SMESH_Mesh GetMesh(); - /*! * Sets group color */ @@ -121,15 +116,25 @@ module SMESH void Clear(); /*! - * Adds elements to the group + * Adds elements or nodes with specified identifiers to the group */ long Add( in long_array elem_ids ); + /*! + * Adds elements or nodes that match specified predicate to the group + */ long AddByPredicate( in Predicate thePredicate ); + /*! + * Add all elements or nodes from the specified source to the group + */ + long AddFrom( in SMESH_IDSource theSource ); /*! - * Removes elements from the group + * Removes elements or nodes with specified identifiers from the group */ long Remove( in long_array elem_ids ); + /*! + * Removes elements or nodes that match specified predicate from the group + */ long RemoveByPredicate( in Predicate thePredicate ); }; diff --git a/idl/SMESH_Measurements.idl b/idl/SMESH_Measurements.idl new file mode 100644 index 000000000..6a177f51a --- /dev/null +++ b/idl/SMESH_Measurements.idl @@ -0,0 +1,61 @@ +// 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 +// + +// File : SMESH_Measurements.idl +// Author : Pavel Telkov, OCC +// +#ifndef _SMESH_MEASUREMENTS_IDL_ +#define _SMESH_MEASUREMENTS_IDL_ + +#include "SALOME_GenericObj.idl" +#include "SMESH_Mesh.idl" + +module SMESH +{ + + /* + * Measure component + */ + struct Measure { + double minX, minY, minZ; + double maxX, maxY, maxZ; + long node1, node2; + long elem1, elem2; + double value; + }; + + interface Measurements: SALOME::GenericObj + { + /*! + * minimal distance between two entities + */ + Measure MinDistance(in SMESH_IDSource source1, + in SMESH_IDSource source2); + + /*! + * common bounding box of entities + */ + Measure BoundingBox(in ListOfIDSources sources); + }; +}; + +#endif diff --git a/idl/SMESH_Mesh.idl b/idl/SMESH_Mesh.idl index a06e663d5..8165d5c00 100644 --- a/idl/SMESH_Mesh.idl +++ b/idl/SMESH_Mesh.idl @@ -37,6 +37,8 @@ module SMESH typedef sequence ListOfHypothesis; interface SMESH_GroupBase; typedef sequence ListOfGroups; + interface SMESH_IDSource; + typedef sequence ListOfIDSources; typedef sequence double_array ; typedef sequence long_array ; @@ -116,6 +118,7 @@ module SMESH VOLUME, ELEM0D }; + typedef sequence array_of_ElementType ; /*! * Enumeration for element geometry type, like in SMDS @@ -245,6 +248,8 @@ module SMESH long_array elementConnectivities; types_array elementTypes; }; + interface SMESH_Mesh; + interface SMESH_IDSource { /*! @@ -257,6 +262,16 @@ module SMESH * Result array of number enityties */ long_array GetMeshInfo(); + + /*! + * Returns types of elements it contains + */ + array_of_ElementType GetTypes(); + + /*! + * Returns the mesh + */ + SMESH_Mesh GetMesh(); }; interface SMESH_Group; diff --git a/idl/SMESH_MeshEditor.idl b/idl/SMESH_MeshEditor.idl index 983b2f486..c010980be 100644 --- a/idl/SMESH_MeshEditor.idl +++ b/idl/SMESH_MeshEditor.idl @@ -29,6 +29,8 @@ module SMESH { + enum Bnd_Dimension { BND_2DFROM3D, BND_1DFROM3D, BND_1DFROM2D }; + /*! * This interface makes modifications on the Mesh - removing elements and nodes etc. */ @@ -37,13 +39,38 @@ module SMESH { /*! * \brief Wrap a sequence of ids in a SMESH_IDSource + * \param IDsOfElements list of mesh elements identifiers + * \return new ID source object */ - SMESH_IDSource MakeIDSource(in long_array IDsOfElements); + SMESH_IDSource MakeIDSource(in long_array IDsOfElements, in ElementType type); + /*! + * \brief Remove mesh elements specified by their identifiers. + * \param IDsOfElements list of mesh elements identifiers + * \return \c true if elements are correctly removed or \c false otherwise + */ boolean RemoveElements(in long_array IDsOfElements); + /*! + * \brief Remove mesh nodes specified by their identifiers. + * \param IDsOfNodes list of mesh nodes identifiers + * \return \c true if nodes are correctly removed or \c false otherwise + */ boolean RemoveNodes(in long_array IDsOfNodes); + + /*! + * \brief Remove all orphan nodes. + * \return number of removed nodes + */ + long RemoveOrphanNodes(); + /*! + * \brief Add new node. + * \param x X coordinate of new node + * \param y Y coordinate of new node + * \param z Z coordinate of new node + * \return integer identifier of new node + */ long AddNode(in double x, in double y, in double z); /*! @@ -222,6 +249,7 @@ module SMESH * \param methodFlags - flags passing splitting method: * 1 - split the hexahedron into 5 tetrahedrons * 2 - split the hexahedron into 6 tetrahedrons + * 3 - split the hexahedron into 24 tetrahedrons */ void SplitVolumesIntoTetra(in SMESH_IDSource elems, in short methodFlags) raises (SALOME::SALOME_Exception); @@ -616,6 +644,11 @@ module SMESH in double Tolerance, out array_of_long_array GroupsOfNodes); + void FindCoincidentNodesOnPartBut (in SMESH_IDSource SubMeshOrGroup, + in double Tolerance, + out array_of_long_array GroupsOfNodes, + in ListOfIDSources ExceptSubMeshOrGroups); + void MergeNodes (in array_of_long_array GroupsOfNodes); /*! @@ -759,11 +792,23 @@ module SMESH * \param theNodes - group of nodes to be doubled. * \param theModifiedElems - group of elements to be updated. * \return TRUE if operation has been completed successfully, FALSE otherwise - * \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups() + * \sa DoubleNode(), DoubleNodes(), DoubleNodeGroups(), DoubleNodeGroupNew() */ boolean DoubleNodeGroup( in SMESH_GroupBase theNodes, in SMESH_GroupBase theModifiedElems ); + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements. + * Works as DoubleNodeGroup() described above, but returns a new group with + * newly created nodes. + * \param theNodes - group of nodes to be doubled. + * \param theModifiedElems - group of elements to be updated. + * \return a new group with newly created nodes + * \sa DoubleNodeGroup() + */ + SMESH_Group DoubleNodeGroupNew( in SMESH_GroupBase theNodes, + in SMESH_GroupBase theModifiedElems ); + /*! \brief Creates a hole in a mesh by doubling the nodes of some particular elements This method provided for convenience works as DoubleNodes() described above. @@ -812,12 +857,27 @@ module SMESH * \param theAffectedElems - group of elements to which the replicated nodes * should be associated to. * \return TRUE if operation has been completed successfully, FALSE otherwise - * \sa DoubleNodes(), DoubleNodeGroups() + * \sa DoubleNodes(), DoubleNodeGroups(), DoubleNodeElemGroupNew() */ boolean DoubleNodeElemGroup( in SMESH_GroupBase theElems, in SMESH_GroupBase theNodesNot, in SMESH_GroupBase theAffectedElems ); + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements. + * Works as DoubleNodeElemGroup() described above, but returns a new group with + * newly created elements. + * \param theElems - group of of elements (edges or faces) to be replicated + * \param theNodesNot - group of nodes not to replicated + * \param theAffectedElems - group of elements to which the replicated nodes + * should be associated to. + * \return a new group with newly created elements + * \sa DoubleNodeElemGroup() + */ + SMESH_Group DoubleNodeElemGroupNew( in SMESH_GroupBase theElems, + in SMESH_GroupBase theNodesNot, + in SMESH_GroupBase theAffectedElems ); + /*! * \brief Creates a hole in a mesh by doubling the nodes of some particular elements * This method provided for convenience works as DoubleNodes() described above. @@ -863,12 +923,34 @@ module SMESH in GEOM::GEOM_Object theShape ); /*! - * \brief Generated skin mesh (containing 2D cells) from 3D mesh + * \brief Generates skin mesh (containing 2D cells) from 3D mesh * The created 2D mesh elements based on nodes of free faces of boundary volumes * \return TRUE if operation has been completed successfully, FALSE otherwise */ boolean Make2DMeshFrom3D(); + /*! + * \brief Creates missing boundary elements + * \param elements - elements whose boundary is to be checked + * \param dimension - defines type of boundary elements to create + * \param groupName - a name of group to store created boundary elements in, + * "" means not to create the group + * \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 + * boundary elements will be copied into the new mesh + * \param group - returns the create group, if any + * \retval SMESH::SMESH_Mesh - the mesh where elements were added to + */ + SMESH::SMESH_Mesh MakeBoundaryMesh(in SMESH_IDSource elements, + in Bnd_Dimension dimension, + in string groupName, + in string meshName, + in boolean toCopyElements, + in boolean toCopyExistingBondary, + out SMESH_Group group); + }; }; diff --git a/resources/Makefile.am b/resources/Makefile.am index 97f2c3b6f..cc7d5a885 100644 --- a/resources/Makefile.am +++ b/resources/Makefile.am @@ -49,6 +49,7 @@ dist_salomeres_DATA = \ mesh_info.png \ advanced_mesh_info.png \ standard_mesh_info.png \ + mesh_elem_info.png \ mesh_whatis.png \ mesh_init.png \ mesh_length.png \ @@ -57,6 +58,8 @@ dist_salomeres_DATA = \ mesh_free_edges.png \ mesh_free_edges_2d.png \ mesh_free_nodes.png \ + mesh_max_element_length_2d.png \ + mesh_max_element_length_3d.png \ mesh_multi_edges.png \ mesh_multi_edges_2d.png \ mesh_line_n.png \ @@ -70,8 +73,14 @@ dist_salomeres_DATA = \ mesh_pyramid.png \ mesh_quad_n.png \ mesh_quad.png \ + mesh_quadrangle_quadpref.png \ + mesh_quadrangle_quadpref_reversed.png \ + mesh_quadrangle_reduced.png \ + mesh_quadrangle_standard.png \ + mesh_quadrangle_triapref.png \ mesh_rem_element.png \ mesh_rem_node.png \ + mesh_rem_orphan_nodes.png \ mesh_shading.png \ mesh_shrink.png \ mesh_skew.png \ @@ -172,7 +181,11 @@ dist_salomeres_DATA = \ mesh_free_faces.png \ scale.png \ scale_along_axes.png \ - split_into_tetra.png + split_into_tetra.png \ + mesh_duplicate_nodes.png \ + mesh_duplicate_nodes_with_elem.png \ + mesh_bounding_box.png \ + mesh_min_dist.png # VSR: little trick to avoid putting if SMESHCatalog.xml to the distribution archive nodist_salomeres_SCRIPTS = SMESHCatalog.xml diff --git a/resources/SalomeApp.xml b/resources/SalomeApp.xml index e4ddfa738..ea6daa0bf 100644 --- a/resources/SalomeApp.xml +++ b/resources/SalomeApp.xml @@ -33,6 +33,7 @@ + @@ -64,11 +65,16 @@ + + + + + diff --git a/resources/StdMeshers.xml b/resources/StdMeshers.xml index d267ef1f6..41c83c997 100644 --- a/resources/StdMeshers.xml +++ b/resources/StdMeshers.xml @@ -40,7 +40,7 @@ dim="0"/> @@ -122,7 +122,6 @@ + + + + + + + + +#include #include #include @@ -70,6 +71,12 @@ */ namespace{ + + inline gp_XYZ gpXYZ(const SMDS_MeshNode* aNode ) + { + return gp_XYZ(aNode->X(), aNode->Y(), aNode->Z() ); + } + inline double getAngle( const gp_XYZ& P1, const gp_XYZ& P2, const gp_XYZ& P3 ) { gp_Vec v1( P1 - P2 ), v2( P3 - P2 ); @@ -171,6 +178,26 @@ namespace{ return aResult; } + gp_XYZ getNormale( const SMDS_MeshFace* theFace, bool* ok=0 ) + { + int aNbNode = theFace->NbNodes(); + + gp_XYZ q1 = gpXYZ( theFace->GetNode(1)) - gpXYZ( theFace->GetNode(0)); + gp_XYZ q2 = gpXYZ( theFace->GetNode(2)) - gpXYZ( theFace->GetNode(0)); + gp_XYZ n = q1 ^ q2; + if ( aNbNode > 3 ) { + gp_XYZ q3 = gpXYZ( theFace->GetNode(3)) - gpXYZ( theFace->GetNode(0)); + n += q2 ^ q3; + } + double len = n.Modulus(); + bool zeroLen = ( len <= numeric_limits::min()); + if ( !zeroLen ) + n /= len; + + if (ok) *ok = !zeroLen; + + return n; + } } @@ -178,8 +205,8 @@ namespace{ using namespace SMESH::Controls; /* - FUNCTORS -*/ + * FUNCTORS + */ /* Class : NumericalFunctor @@ -277,6 +304,63 @@ double NumericalFunctor::GetValue( long theId ) return 0.; } +//================================================================================ +/*! + * \brief Return histogram of functor values + * \param nbIntervals - number of intervals + * \param nbEvents - number of mesh elements having values within i-th interval + * \param funValues - boundaries of intervals + */ +//================================================================================ + +void NumericalFunctor::GetHistogram(int nbIntervals, + std::vector& nbEvents, + std::vector& funValues) +{ + if ( nbIntervals < 1 || + !myMesh || + !myMesh->GetMeshInfo().NbElements( GetType() )) + return; + nbEvents.resize( nbIntervals, 0 ); + funValues.resize( nbIntervals+1 ); + + // get all values sorted + std::multiset< double > values; + SMDS_ElemIteratorPtr elemIt = myMesh->elementsIterator(GetType()); + while ( elemIt->more() ) + values.insert( GetValue( elemIt->next()->GetID() )); + + // case nbIntervals == 1 + funValues[0] = *values.begin(); + funValues[nbIntervals] = *values.rbegin(); + if ( nbIntervals == 1 ) + { + nbEvents[0] = values.size(); + return; + } + // case of 1 value + if (funValues.front() == funValues.back()) + { + nbEvents.resize( 1 ); + nbEvents[0] = values.size(); + funValues[1] = funValues.back(); + funValues.resize( 2 ); + } + // generic case + std::multiset< double >::iterator min = values.begin(), max; + for ( int i = 0; i < nbIntervals; ++i ) + { + double r = (i+1) / double( nbIntervals ); + funValues[i+1] = funValues.front() * (1-r) + funValues.back() * r; + if ( min != values.end() && *min <= funValues[i+1] ) + { + max = values.upper_bound( funValues[i+1] ); // greater than funValues[i+1], or end() + nbEvents[i] = std::distance( min, max ); + min = max; + } + } +} + //======================================================================= //function : GetValue //purpose : @@ -313,6 +397,246 @@ SMDSAbs_ElementType Volume::GetType() const } +/* + Class : MaxElementLength2D + Description : Functor calculating maximum length of 2D element +*/ + +double MaxElementLength2D::GetValue( long theElementId ) +{ + TSequenceOfXYZ P; + if( GetPoints( theElementId, P ) ) { + double aVal = 0; + const SMDS_MeshElement* aElem = myMesh->FindElement( theElementId ); + SMDSAbs_ElementType aType = aElem->GetType(); + int len = P.size(); + switch( aType ) { + case SMDSAbs_Face: + if( len == 3 ) { // triangles + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 1 )); + aVal = Max(L1,Max(L2,L3)); + break; + } + else if( len == 4 ) { // quadrangles + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 4 )); + double L4 = getDistance(P( 4 ),P( 1 )); + double D1 = getDistance(P( 1 ),P( 3 )); + double D2 = getDistance(P( 2 ),P( 4 )); + aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(D1,D2)); + break; + } + else if( len == 6 ) { // quadratic triangles + double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 )); + double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 )); + double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 1 )); + aVal = Max(L1,Max(L2,L3)); + break; + } + else if( len == 8 ) { // quadratic quadrangles + double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 )); + double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 )); + double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 7 )); + double L4 = getDistance(P( 7 ),P( 8 )) + getDistance(P( 8 ),P( 1 )); + double D1 = getDistance(P( 1 ),P( 5 )); + double D2 = getDistance(P( 3 ),P( 7 )); + aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(D1,D2)); + break; + } + } + + if( myPrecision >= 0 ) + { + double prec = pow( 10., (double)myPrecision ); + aVal = floor( aVal * prec + 0.5 ) / prec; + } + return aVal; + } + return 0.; +} + +double MaxElementLength2D::GetBadRate( double Value, int /*nbNodes*/ ) const +{ + return Value; +} + +SMDSAbs_ElementType MaxElementLength2D::GetType() const +{ + return SMDSAbs_Face; +} + +/* + Class : MaxElementLength3D + Description : Functor calculating maximum length of 3D element +*/ + +double MaxElementLength3D::GetValue( long theElementId ) +{ + TSequenceOfXYZ P; + if( GetPoints( theElementId, P ) ) { + double aVal = 0; + const SMDS_MeshElement* aElem = myMesh->FindElement( theElementId ); + SMDSAbs_ElementType aType = aElem->GetType(); + int len = P.size(); + switch( aType ) { + case SMDSAbs_Volume: + if( len == 4 ) { // tetras + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 1 )); + double L4 = getDistance(P( 1 ),P( 4 )); + double L5 = getDistance(P( 2 ),P( 4 )); + double L6 = getDistance(P( 3 ),P( 4 )); + aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6)); + break; + } + else if( len == 5 ) { // pyramids + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 4 )); + double L4 = getDistance(P( 4 ),P( 1 )); + double L5 = getDistance(P( 1 ),P( 5 )); + double L6 = getDistance(P( 2 ),P( 5 )); + double L7 = getDistance(P( 3 ),P( 5 )); + double L8 = getDistance(P( 4 ),P( 5 )); + aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6)); + aVal = Max(aVal,Max(L7,L8)); + break; + } + else if( len == 6 ) { // pentas + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 1 )); + double L4 = getDistance(P( 4 ),P( 5 )); + double L5 = getDistance(P( 5 ),P( 6 )); + double L6 = getDistance(P( 6 ),P( 4 )); + double L7 = getDistance(P( 1 ),P( 4 )); + double L8 = getDistance(P( 2 ),P( 5 )); + double L9 = getDistance(P( 3 ),P( 6 )); + aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6)); + aVal = Max(aVal,Max(Max(L7,L8),L9)); + break; + } + else if( len == 8 ) { // hexas + double L1 = getDistance(P( 1 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 4 )); + double L4 = getDistance(P( 4 ),P( 1 )); + double L5 = getDistance(P( 5 ),P( 6 )); + double L6 = getDistance(P( 6 ),P( 7 )); + double L7 = getDistance(P( 7 ),P( 8 )); + double L8 = getDistance(P( 8 ),P( 5 )); + double L9 = getDistance(P( 1 ),P( 5 )); + double L10= getDistance(P( 2 ),P( 6 )); + double L11= getDistance(P( 3 ),P( 7 )); + double L12= getDistance(P( 4 ),P( 8 )); + double D1 = getDistance(P( 1 ),P( 7 )); + double D2 = getDistance(P( 2 ),P( 8 )); + double D3 = getDistance(P( 3 ),P( 5 )); + double D4 = getDistance(P( 4 ),P( 6 )); + aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6)); + aVal = Max(aVal,Max(Max(L7,L8),Max(L9,L10))); + aVal = Max(aVal,Max(L11,L12)); + aVal = Max(aVal,Max(Max(D1,D2),Max(D3,D4))); + break; + } + else if( len == 10 ) { // quadratic tetras + double L1 = getDistance(P( 1 ),P( 5 )) + getDistance(P( 5 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 6 )) + getDistance(P( 6 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 7 )) + getDistance(P( 7 ),P( 1 )); + double L4 = getDistance(P( 1 ),P( 8 )) + getDistance(P( 8 ),P( 4 )); + double L5 = getDistance(P( 2 ),P( 9 )) + getDistance(P( 9 ),P( 4 )); + double L6 = getDistance(P( 3 ),P( 10 )) + getDistance(P( 10 ),P( 4 )); + aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6)); + break; + } + else if( len == 13 ) { // quadratic pyramids + double L1 = getDistance(P( 1 ),P( 6 )) + getDistance(P( 6 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 7 )) + getDistance(P( 7 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 8 )) + getDistance(P( 8 ),P( 4 )); + double L4 = getDistance(P( 4 ),P( 9 )) + getDistance(P( 9 ),P( 1 )); + double L5 = getDistance(P( 1 ),P( 10 )) + getDistance(P( 10 ),P( 5 )); + double L6 = getDistance(P( 2 ),P( 11 )) + getDistance(P( 11 ),P( 5 )); + double L7 = getDistance(P( 3 ),P( 12 )) + getDistance(P( 12 ),P( 5 )); + double L8 = getDistance(P( 4 ),P( 13 )) + getDistance(P( 13 ),P( 5 )); + aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6)); + aVal = Max(aVal,Max(L7,L8)); + break; + } + else if( len == 15 ) { // quadratic pentas + double L1 = getDistance(P( 1 ),P( 7 )) + getDistance(P( 7 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 8 )) + getDistance(P( 8 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 9 )) + getDistance(P( 9 ),P( 1 )); + double L4 = getDistance(P( 4 ),P( 10 )) + getDistance(P( 10 ),P( 5 )); + double L5 = getDistance(P( 5 ),P( 11 )) + getDistance(P( 11 ),P( 6 )); + double L6 = getDistance(P( 6 ),P( 12 )) + getDistance(P( 12 ),P( 4 )); + double L7 = getDistance(P( 1 ),P( 13 )) + getDistance(P( 13 ),P( 4 )); + double L8 = getDistance(P( 2 ),P( 14 )) + getDistance(P( 14 ),P( 5 )); + double L9 = getDistance(P( 3 ),P( 15 )) + getDistance(P( 15 ),P( 6 )); + aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6)); + aVal = Max(aVal,Max(Max(L7,L8),L9)); + break; + } + else if( len == 20 ) { // quadratic hexas + double L1 = getDistance(P( 1 ),P( 9 )) + getDistance(P( 9 ),P( 2 )); + double L2 = getDistance(P( 2 ),P( 10 )) + getDistance(P( 10 ),P( 3 )); + double L3 = getDistance(P( 3 ),P( 11 )) + getDistance(P( 11 ),P( 4 )); + double L4 = getDistance(P( 4 ),P( 12 )) + getDistance(P( 12 ),P( 1 )); + double L5 = getDistance(P( 5 ),P( 13 )) + getDistance(P( 13 ),P( 6 )); + double L6 = getDistance(P( 6 ),P( 14 )) + getDistance(P( 14 ),P( 7 )); + double L7 = getDistance(P( 7 ),P( 15 )) + getDistance(P( 15 ),P( 8 )); + double L8 = getDistance(P( 8 ),P( 16 )) + getDistance(P( 16 ),P( 5 )); + double L9 = getDistance(P( 1 ),P( 17 )) + getDistance(P( 17 ),P( 5 )); + double L10= getDistance(P( 2 ),P( 18 )) + getDistance(P( 18 ),P( 6 )); + double L11= getDistance(P( 3 ),P( 19 )) + getDistance(P( 19 ),P( 7 )); + double L12= getDistance(P( 4 ),P( 20 )) + getDistance(P( 20 ),P( 8 )); + double D1 = getDistance(P( 1 ),P( 7 )); + double D2 = getDistance(P( 2 ),P( 8 )); + double D3 = getDistance(P( 3 ),P( 5 )); + double D4 = getDistance(P( 4 ),P( 6 )); + aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6)); + aVal = Max(aVal,Max(Max(L7,L8),Max(L9,L10))); + aVal = Max(aVal,Max(L11,L12)); + aVal = Max(aVal,Max(Max(D1,D2),Max(D3,D4))); + break; + } + else if( len > 1 && aElem->IsPoly() ) { // polys + // get the maximum distance between all pairs of nodes + for( int i = 1; i <= len; i++ ) { + for( int j = 1; j <= len; j++ ) { + if( j > i ) { // optimization of the loop + double D = getDistance( P(i), P(j) ); + aVal = Max( aVal, D ); + } + } + } + } + } + + if( myPrecision >= 0 ) + { + double prec = pow( 10., (double)myPrecision ); + aVal = floor( aVal * prec + 0.5 ) / prec; + } + return aVal; + } + return 0.; +} + +double MaxElementLength3D::GetBadRate( double Value, int /*nbNodes*/ ) const +{ + return Value; +} + +SMDSAbs_ElementType MaxElementLength3D::GetType() const +{ + return SMDSAbs_Volume; +} + + /* Class : MinimumAngle Description : Functor for calculation of minimum angle @@ -408,47 +732,94 @@ double AspectRatio::GetValue( const TSequenceOfXYZ& P ) return alfa * maxLen * half_perimeter / anArea; } else if( nbNodes == 4 ) { // quadrangle - // return aspect ratio of the worst triange which can be built + // Compute lengths of the sides + std::vector< double > aLen (4); + aLen[0] = getDistance( P(1), P(2) ); + aLen[1] = getDistance( P(2), P(3) ); + aLen[2] = getDistance( P(3), P(4) ); + aLen[3] = getDistance( P(4), P(1) ); + // Compute lengths of the diagonals + std::vector< double > aDia (2); + aDia[0] = getDistance( P(1), P(3) ); + aDia[1] = getDistance( P(2), P(4) ); + // Compute areas of all triangles which can be built // taking three nodes of the quadrangle - TSequenceOfXYZ triaPnts(3); - // triangle on nodes 1 3 2 - triaPnts(1) = P(1); - triaPnts(2) = P(3); - triaPnts(3) = P(2); - double ar = GetValue( triaPnts ); - // triangle on nodes 1 3 4 - triaPnts(3) = P(4); - ar = Max ( ar, GetValue( triaPnts )); - // triangle on nodes 1 2 4 - triaPnts(2) = P(2); - ar = Max ( ar, GetValue( triaPnts )); - // triangle on nodes 3 2 4 - triaPnts(1) = P(3); - ar = Max ( ar, GetValue( triaPnts )); - - return ar; - } - else { // nbNodes==8 - quadratic quadrangle - // return aspect ratio of the worst triange which can be built + std::vector< double > anArea (4); + anArea[0] = getArea( P(1), P(2), P(3) ); + anArea[1] = getArea( P(1), P(2), P(4) ); + anArea[2] = getArea( P(1), P(3), P(4) ); + anArea[3] = getArea( P(2), P(3), P(4) ); + // Q = alpha * L * C1 / C2, where + // + // alpha = sqrt( 1/32 ) + // L = max( L1, L2, L3, L4, D1, D2 ) + // C1 = sqrt( ( L1^2 + L1^2 + L1^2 + L1^2 ) / 4 ) + // C2 = min( S1, S2, S3, S4 ) + // Li - lengths of the edges + // Di - lengths of the diagonals + // Si - areas of the triangles + const double alpha = sqrt( 1 / 32. ); + double L = Max( aLen[ 0 ], + Max( aLen[ 1 ], + Max( aLen[ 2 ], + Max( aLen[ 3 ], + Max( aDia[ 0 ], aDia[ 1 ] ) ) ) ) ); + double C1 = sqrt( ( aLen[0] * aLen[0] + + aLen[1] * aLen[1] + + aLen[2] * aLen[2] + + aLen[3] * aLen[3] ) / 4. ); + double C2 = Min( anArea[ 0 ], + Min( anArea[ 1 ], + Min( anArea[ 2 ], anArea[ 3 ] ) ) ); + if ( C2 <= Precision::Confusion() ) + return 0.; + return alpha * L * C1 / C2; + } + else if( nbNodes == 8 ){ // nbNodes==8 - quadratic quadrangle + // Compute lengths of the sides + std::vector< double > aLen (4); + aLen[0] = getDistance( P(1), P(3) ); + aLen[1] = getDistance( P(3), P(5) ); + aLen[2] = getDistance( P(5), P(7) ); + aLen[3] = getDistance( P(7), P(1) ); + // Compute lengths of the diagonals + std::vector< double > aDia (2); + aDia[0] = getDistance( P(1), P(5) ); + aDia[1] = getDistance( P(3), P(7) ); + // Compute areas of all triangles which can be built // taking three nodes of the quadrangle - TSequenceOfXYZ triaPnts(3); - // triangle on nodes 1 3 2 - triaPnts(1) = P(1); - triaPnts(2) = P(5); - triaPnts(3) = P(3); - double ar = GetValue( triaPnts ); - // triangle on nodes 1 3 4 - triaPnts(3) = P(7); - ar = Max ( ar, GetValue( triaPnts )); - // triangle on nodes 1 2 4 - triaPnts(2) = P(3); - ar = Max ( ar, GetValue( triaPnts )); - // triangle on nodes 3 2 4 - triaPnts(1) = P(5); - ar = Max ( ar, GetValue( triaPnts )); - - return ar; + std::vector< double > anArea (4); + anArea[0] = getArea( P(1), P(3), P(5) ); + anArea[1] = getArea( P(1), P(3), P(7) ); + anArea[2] = getArea( P(1), P(5), P(7) ); + anArea[3] = getArea( P(3), P(5), P(7) ); + // Q = alpha * L * C1 / C2, where + // + // alpha = sqrt( 1/32 ) + // L = max( L1, L2, L3, L4, D1, D2 ) + // C1 = sqrt( ( L1^2 + L1^2 + L1^2 + L1^2 ) / 4 ) + // C2 = min( S1, S2, S3, S4 ) + // Li - lengths of the edges + // Di - lengths of the diagonals + // Si - areas of the triangles + const double alpha = sqrt( 1 / 32. ); + double L = Max( aLen[ 0 ], + Max( aLen[ 1 ], + Max( aLen[ 2 ], + Max( aLen[ 3 ], + Max( aDia[ 0 ], aDia[ 1 ] ) ) ) ) ); + double C1 = sqrt( ( aLen[0] * aLen[0] + + aLen[1] * aLen[1] + + aLen[2] * aLen[2] + + aLen[3] * aLen[3] ) / 4. ); + double C2 = Min( anArea[ 0 ], + Min( anArea[ 1 ], + Min( anArea[ 2 ], anArea[ 3 ] ) ) ); + if ( C2 <= Precision::Confusion() ) + return 0.; + return alpha * L * C1 / C2; } + return 0; } double AspectRatio::GetBadRate( double Value, int /*nbNodes*/ ) const @@ -964,16 +1335,20 @@ SMDSAbs_ElementType Skew::GetType() const */ double Area::GetValue( const TSequenceOfXYZ& P ) { - gp_Vec aVec1( P(2) - P(1) ); - gp_Vec aVec2( P(3) - P(1) ); - gp_Vec SumVec = aVec1 ^ aVec2; - for (int i=4; i<=P.size(); i++) { - gp_Vec aVec1( P(i-1) - P(1) ); - gp_Vec aVec2( P(i) - P(1) ); - gp_Vec tmp = aVec1 ^ aVec2; - SumVec.Add(tmp); + double val = 0.0; + if ( P.size() > 2 ) { + gp_Vec aVec1( P(2) - P(1) ); + gp_Vec aVec2( P(3) - P(1) ); + gp_Vec SumVec = aVec1 ^ aVec2; + for (int i=4; i<=P.size(); i++) { + gp_Vec aVec1( P(i-1) - P(1) ); + gp_Vec aVec2( P(i) - P(1) ); + gp_Vec tmp = aVec1 ^ aVec2; + SumVec.Add(tmp); + } + val = SumVec.Magnitude() * 0.5; } - return SumVec.Magnitude() * 0.5; + return val; } double Area::GetBadRate( double Value, int /*nbNodes*/ ) const @@ -1090,7 +1465,7 @@ double Length2D::GetValue( long theElementId) else if (len == 5){ // piramids double L1 = getDistance(P( 1 ),P( 2 )); double L2 = getDistance(P( 2 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 1 )); + double L3 = getDistance(P( 3 ),P( 4 )); double L4 = getDistance(P( 4 ),P( 1 )); double L5 = getDistance(P( 1 ),P( 5 )); double L6 = getDistance(P( 2 ),P( 5 )); @@ -1150,7 +1525,7 @@ double Length2D::GetValue( long theElementId) else if (len == 13){ // quadratic piramids double L1 = getDistance(P( 1 ),P( 6 )) + getDistance(P( 6 ),P( 2 )); double L2 = getDistance(P( 2 ),P( 7 )) + getDistance(P( 7 ),P( 3 )); - double L3 = getDistance(P( 3 ),P( 8 )) + getDistance(P( 8 ),P( 1 )); + double L3 = getDistance(P( 3 ),P( 8 )) + getDistance(P( 8 ),P( 4 )); double L4 = getDistance(P( 4 ),P( 9 )) + getDistance(P( 9 ),P( 1 )); double L5 = getDistance(P( 1 ),P( 10 )) + getDistance(P( 10 ),P( 5 )); double L6 = getDistance(P( 2 ),P( 11 )) + getDistance(P( 11 ),P( 5 )); @@ -2002,13 +2377,71 @@ SMDSAbs_GeometryType ElemGeomType::GetGeomType() const return myGeomType; } +//================================================================================ +/*! + * \brief Class CoplanarFaces + */ +//================================================================================ + +CoplanarFaces::CoplanarFaces() + : myMesh(0), myFaceID(0), myToler(0) +{ +} +bool CoplanarFaces::IsSatisfy( long theElementId ) +{ + if ( myCoplanarIDs.empty() ) + { + // Build a set of coplanar face ids + + if ( !myMesh || !myFaceID || !myToler ) + return false; + + const SMDS_MeshElement* face = myMesh->FindElement( myFaceID ); + if ( !face || face->GetType() != SMDSAbs_Face ) + return false; + + bool normOK; + gp_Vec myNorm = getNormale( static_cast(face), &normOK ); + if (!normOK) + return false; + + const double radianTol = myToler * PI180; + typedef SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > TFaceIt; + std::set checkedFaces, checkedNodes; + std::list faceQueue( 1, face ); + while ( !faceQueue.empty() ) + { + face = faceQueue.front(); + if ( checkedFaces.insert( face ).second ) + { + gp_Vec norm = getNormale( static_cast(face), &normOK ); + if (!normOK || myNorm.Angle( norm ) <= radianTol) + { + myCoplanarIDs.insert( face->GetID() ); + std::set neighborFaces; + for ( int i = 0; i < face->NbCornerNodes(); ++i ) + { + const SMDS_MeshNode* n = face->GetNode( i ); + if ( checkedNodes.insert( n ).second ) + neighborFaces.insert( TFaceIt( n->GetInverseElementIterator(SMDSAbs_Face)), + TFaceIt()); + } + faceQueue.insert( faceQueue.end(), neighborFaces.begin(), neighborFaces.end() ); + } + } + faceQueue.pop_front(); + } + } + return myCoplanarIDs.count( theElementId ); +} + /* - Class : RangeOfIds - Description : Predicate for Range of Ids. - Range may be specified with two ways. - 1. Using AddToRange method - 2. With SetRangeStr method. Parameter of this method is a string - like as "1,2,3,50-60,63,67,70-" + *Class : RangeOfIds + *Description : Predicate for Range of Ids. + * Range may be specified with two ways. + * 1. Using AddToRange method + * 2. With SetRangeStr method. Parameter of this method is a string + * like as "1,2,3,50-60,63,67,70-" */ //======================================================================= @@ -2638,32 +3071,6 @@ static void getLinks( const SMDS_MeshFace* theFace, } } -static gp_XYZ getNormale( const SMDS_MeshFace* theFace ) -{ - gp_XYZ n; - int aNbNode = theFace->NbNodes(); - TColgp_Array1OfXYZ anArrOfXYZ(1,4); - SMDS_ElemIteratorPtr aNodeItr = theFace->nodesIterator(); - int i = 1; - for ( ; aNodeItr->more() && i <= 4; i++ ) { - SMDS_MeshNode* aNode = (SMDS_MeshNode*)aNodeItr->next(); - anArrOfXYZ.SetValue(i, gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) ); - } - - gp_XYZ q1 = anArrOfXYZ.Value(2) - anArrOfXYZ.Value(1); - gp_XYZ q2 = anArrOfXYZ.Value(3) - anArrOfXYZ.Value(1); - n = q1 ^ q2; - if ( aNbNode > 3 ) { - gp_XYZ q3 = anArrOfXYZ.Value(4) - anArrOfXYZ.Value(1); - n += q2 ^ q3; - } - double len = n.Modulus(); - if ( len > 0 ) - n /= len; - - return n; -} - bool ManifoldPart::findConnected ( const ManifoldPart::TDataMapFacePtrInt& theAllFacePtrInt, SMDS_MeshFace* theStartFace, diff --git a/src/Controls/SMESH_ControlsDef.hxx b/src/Controls/SMESH_ControlsDef.hxx index 5849c1f83..915bd9f4b 100644 --- a/src/Controls/SMESH_ControlsDef.hxx +++ b/src/Controls/SMESH_ControlsDef.hxx @@ -127,6 +127,9 @@ 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& nbEvents, + std::vector& funValues); virtual SMDSAbs_ElementType GetType() const = 0; virtual double GetBadRate( double Value, int nbNodes ) const = 0; long GetPrecision() const; @@ -156,6 +159,30 @@ namespace SMESH{ }; + /* + Class : MaxElementLength2D + Description : Functor calculating maximum length of 2D element + */ + class SMESHCONTROLS_EXPORT MaxElementLength2D: public virtual NumericalFunctor{ + public: + virtual double GetValue( long theElementId ); + virtual double GetBadRate( double Value, int nbNodes ) const; + virtual SMDSAbs_ElementType GetType() const; + }; + + + /* + Class : MaxElementLength3D + Description : Functor calculating maximum length of 3D element + */ + class SMESHCONTROLS_EXPORT MaxElementLength3D: public virtual NumericalFunctor{ + public: + virtual double GetValue( long theElementId ); + virtual double GetBadRate( double Value, int nbNodes ) const; + virtual SMDSAbs_ElementType GetType() const; + }; + + /* Class : SMESH_MinimumAngle Description : Functor for calculation of minimum angle @@ -770,11 +797,11 @@ namespace SMESH{ class SMESHCONTROLS_EXPORT ElemGeomType: public virtual Predicate{ public: ElemGeomType(); - virtual void SetMesh( const SMDS_Mesh* theMesh ); - virtual bool IsSatisfy( long theElementId ); - void SetType( SMDSAbs_ElementType theType ); - virtual SMDSAbs_ElementType GetType() const; - void SetGeomType( SMDSAbs_GeometryType theType ); + virtual void SetMesh( const SMDS_Mesh* theMesh ); + virtual bool IsSatisfy( long theElementId ); + void SetType( SMDSAbs_ElementType theType ); + virtual SMDSAbs_ElementType GetType() const; + void SetGeomType( SMDSAbs_GeometryType theType ); virtual SMDSAbs_GeometryType GetGeomType() const; private: @@ -784,6 +811,31 @@ namespace SMESH{ }; typedef boost::shared_ptr ElemGeomTypePtr; + /* + Class : CoplanarFaces + Description : Predicate to check angle between faces + */ + class SMESHCONTROLS_EXPORT CoplanarFaces: public virtual Predicate + { + public: + CoplanarFaces(); + void SetFace( long theID ) { myFaceID = theID; } + long GetFace() const { return myFaceID; } + void SetTolerance (const double theToler) { myToler = theToler; } + double GetTolerance () const { return myToler; } + virtual void SetMesh( const SMDS_Mesh* theMesh ) { myMesh = theMesh; } + virtual SMDSAbs_ElementType GetType() const { return SMDSAbs_Face; } + + virtual bool IsSatisfy( long theElementId ); + + private: + const SMDS_Mesh* myMesh; + long myFaceID; + double myToler; + std::set< long > myCoplanarIDs; + }; + typedef boost::shared_ptr CoplanarFacesPtr; + /* FILTER */ diff --git a/src/DriverUNV/DriverUNV_R_SMDS_Mesh.cxx b/src/DriverUNV/DriverUNV_R_SMDS_Mesh.cxx index bfb1d6394..24150eeda 100644 --- a/src/DriverUNV/DriverUNV_R_SMDS_Mesh.cxx +++ b/src/DriverUNV/DriverUNV_R_SMDS_Mesh.cxx @@ -95,20 +95,24 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() } else if(IsFace(aRec.fe_descriptor_id)) { switch(aRec.fe_descriptor_id){ - case 71: // TRI3 - case 72: - case 74: - - case 41: // Plane Stress Linear Triangle - TRI3 - case 91: // Thin Shell Linear Triangle - TRI3 + case 41: // Plane Stress Linear Triangle + case 51: // Plane Strain Linear Triangle + case 61: // Plate Linear Triangle + case 74: // Membrane Linear Triangle + case 81: // Axisymetric Solid Linear Triangle + case 91: // Thin Shell Linear Triangle anElement = myMesh->AddFaceWithID(aRec.node_labels[0], aRec.node_labels[1], aRec.node_labels[2], aLabel); break; - case 42: // Plane Stress Quadratic Triangle - TRI6 - case 92: // Thin Shell Quadratic Triangle - TRI6 + case 42: // Plane Stress Parabolic Triangle + case 52: // Plane Strain Parabolic Triangle + case 62: // Plate Parabolic Triangle + case 72: // Membrane Parabolic Triangle + case 82: // Axisymetric Solid Parabolic Triangle + case 92: // Thin Shell Parabolic Triangle anElement = myMesh->AddFaceWithID(aRec.node_labels[0], aRec.node_labels[2], aRec.node_labels[4], @@ -118,8 +122,12 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() aLabel); break; - case 44: // Plane Stress Linear Quadrilateral - QUAD4 - case 94: // Thin Shell Linear Quadrilateral - QUAD4 + case 44: // Plane Stress Linear Quadrilateral + case 54: // Plane Strain Linear Quadrilateral + case 64: // Plate Linear Quadrilateral + case 71: // Membrane Linear Quadrilateral + case 84: // Axisymetric Solid Linear Quadrilateral + case 94: // Thin Shell Linear Quadrilateral anElement = myMesh->AddFaceWithID(aRec.node_labels[0], aRec.node_labels[1], aRec.node_labels[2], @@ -127,8 +135,12 @@ Driver_Mesh::Status DriverUNV_R_SMDS_Mesh::Perform() aLabel); break; - case 45: // Plane Stress Quadratic Quadrilateral - QUAD8 - case 95: // Thin Shell Quadratic Quadrilateral - QUAD8 + case 45: // Plane Stress Parabolic Quadrilateral + case 55: // Plane Strain Parabolic Quadrilateral + case 65: // Plate Parabolic Quadrilateral + case 75: // Membrane Parabolic Quadrilateral + case 85: // Axisymetric Solid Parabolic Quadrilateral + case 95: // Thin Shell Parabolic Quadrilateral anElement = myMesh->AddFaceWithID(aRec.node_labels[0], aRec.node_labels[2], aRec.node_labels[4], diff --git a/src/DriverUNV/UNV2412_Structure.cxx b/src/DriverUNV/UNV2412_Structure.cxx index 893fa2391..35cb62afe 100644 --- a/src/DriverUNV/UNV2412_Structure.cxx +++ b/src/DriverUNV/UNV2412_Structure.cxx @@ -30,11 +30,155 @@ using namespace std; using namespace UNV; using namespace UNV2412; -#ifdef _DEBUG_ -static int MYDEBUG = 1; -#else -static int MYDEBUG = 0; -#endif +// Universal Dataset Number 2412 + +// Name: Elements +// Status: Current +// Owner: Simulation +// Revision Date: 14-AUG-1992 +// ----------------------------------------------------------------------- + +// Record 1: FORMAT(6I10) +// Field 1 -- element label +// Field 2 -- fe descriptor id +// Field 3 -- physical property table number +// Field 4 -- material property table number +// Field 5 -- color +// Field 6 -- number of nodes on element + +// Record 2: *** FOR NON-BEAM ELEMENTS *** +// FORMAT(8I10) +// Fields 1-n -- node labels defining element + +// Record 2: *** FOR BEAM ELEMENTS ONLY *** +// FORMAT(3I10) +// Field 1 -- beam orientation node number +// Field 2 -- beam fore-end cross section number +// Field 3 -- beam aft-end cross section number + +// Record 3: *** FOR BEAM ELEMENTS ONLY *** +// FORMAT(8I10) +// Fields 1-n -- node labels defining element + +// Records 1 and 2 are repeated for each non-beam element in the model. +// Records 1 - 3 are repeated for each beam element in the model. + +// Example: + +// -1 +// 2412 +// 1 11 1 5380 7 2 +// 0 1 1 +// 1 2 +// 2 21 2 5380 7 2 +// 0 1 1 +// 3 4 +// 3 22 3 5380 7 2 +// 0 1 2 +// 5 6 +// 6 91 6 5380 7 3 +// 11 18 12 +// 9 95 6 5380 7 8 +// 22 25 29 30 31 26 24 23 +// 14 136 8 0 7 2 +// 53 54 +// 36 116 16 5380 7 20 +// 152 159 168 167 166 158 150 151 +// 154 170 169 153 157 161 173 172 +// 171 160 155 156 +// -1 + +// FE Descriptor Id definitions +// ____________________________ + +// 11 Rod +// 21 Linear beam +// 22 Tapered beam +// 23 Curved beam +// 24 Parabolic beam +// 31 Straight pipe +// 32 Curved pipe +// 41 Plane Stress Linear Triangle +// 42 Plane Stress Parabolic Triangle +// 43 Plane Stress Cubic Triangle +// 44 Plane Stress Linear Quadrilateral +// 45 Plane Stress Parabolic Quadrilateral +// 46 Plane Strain Cubic Quadrilateral +// 51 Plane Strain Linear Triangle +// 52 Plane Strain Parabolic Triangle +// 53 Plane Strain Cubic Triangle +// 54 Plane Strain Linear Quadrilateral +// 55 Plane Strain Parabolic Quadrilateral +// 56 Plane Strain Cubic Quadrilateral +// 61 Plate Linear Triangle +// 62 Plate Parabolic Triangle +// 63 Plate Cubic Triangle +// 64 Plate Linear Quadrilateral +// 65 Plate Parabolic Quadrilateral +// 66 Plate Cubic Quadrilateral +// 71 Membrane Linear Quadrilateral +// 72 Membrane Parabolic Triangle +// 73 Membrane Cubic Triangle +// 74 Membrane Linear Triangle +// 75 Membrane Parabolic Quadrilateral +// 76 Membrane Cubic Quadrilateral +// 81 Axisymetric Solid Linear Triangle +// 82 Axisymetric Solid Parabolic Triangle +// 84 Axisymetric Solid Linear Quadrilateral +// 85 Axisymetric Solid Parabolic Quadrilateral +// 91 Thin Shell Linear Triangle +// 92 Thin Shell Parabolic Triangle +// 93 Thin Shell Cubic Triangle +// 94 Thin Shell Linear Quadrilateral +// 95 Thin Shell Parabolic Quadrilateral +// 96 Thin Shell Cubic Quadrilateral +// 101 Thick Shell Linear Wedge +// 102 Thick Shell Parabolic Wedge +// 103 Thick Shell Cubic Wedge +// 104 Thick Shell Linear Brick +// 105 Thick Shell Parabolic Brick +// 106 Thick Shell Cubic Brick +// 111 Solid Linear Tetrahedron +// 112 Solid Linear Wedge +// 113 Solid Parabolic Wedge +// 114 Solid Cubic Wedge +// 115 Solid Linear Brick +// 116 Solid Parabolic Brick +// 117 Solid Cubic Brick +// 118 Solid Parabolic Tetrahedron +// 121 Rigid Bar +// 122 Rigid Element +// 136 Node To Node Translational Spring +// 137 Node To Node Rotational Spring +// 138 Node To Ground Translational Spring +// 139 Node To Ground Rotational Spring +// 141 Node To Node Damper +// 142 Node To Gound Damper +// 151 Node To Node Gap +// 152 Node To Ground Gap +// 161 Lumped Mass +// 171 Axisymetric Linear Shell +// 172 Axisymetric Parabolic Shell +// 181 Constraint +// 191 Plastic Cold Runner +// 192 Plastic Hot Runner +// 193 Plastic Water Line +// 194 Plastic Fountain +// 195 Plastic Baffle +// 196 Plastic Rod Heater +// 201 Linear node-to-node interface +// 202 Linear edge-to-edge interface +// 203 Parabolic edge-to-edge interface +// 204 Linear face-to-face interface +// 208 Parabolic face-to-face interface +// 212 Linear axisymmetric interface +// 213 Parabolic axisymmetric interface +// 221 Linear rigid surface +// 222 Parabolic rigin surface +// 231 Axisymetric linear rigid surface +// 232 Axisymentric parabolic rigid surface + + static string _label_dataset = "2412"; @@ -158,31 +302,34 @@ bool UNV2412::IsBeam(int theFeDescriptorId){ bool UNV2412::IsFace(int theFeDescriptorId){ - switch (theFeDescriptorId){ + return ( 41 <= theFeDescriptorId && theFeDescriptorId <= 96 ); +// switch (theFeDescriptorId){ - case 71: // TRI3 - case 72: - case 74: +// case 71: // TRI3 +// case 72: +// case 74: - case 41: // Plane Stress Linear Triangle - TRI3 - case 91: // Thin Shell Linear Triangle - TRI3 +// case 41: // Plane Stress Linear Triangle - TRI3 +// case 51: // Plane Strain Linear Triangle +// case 91: // Thin Shell Linear Triangle - TRI3 - case 42: // Plane Stress Quadratic Triangle - TRI6 - case 92: // Thin Shell Quadratic Triangle - TRI6 +// case 42: // Plane Stress Quadratic Triangle - TRI6 +// case 52: // Plane Strain Parabolic Triangle +// case 92: // Thin Shell Quadratic Triangle - TRI6 - case 43: // Plane Stress Cubic Triangle +// case 43: // Plane Stress Cubic Triangle - case 44: // Plane Stress Linear Quadrilateral - QUAD4 - case 94: // Thin Shell Linear Quadrilateral - QUAD4 +// case 44: // Plane Stress Linear Quadrilateral - QUAD4 +// case 94: // Thin Shell Linear Quadrilateral - QUAD4 - case 45: // Plane Stress Quadratic Quadrilateral - QUAD8 - case 95: // Thin Shell Quadratic Quadrilateral - QUAD8 +// case 45: // Plane Stress Quadratic Quadrilateral - QUAD8 +// case 95: // Thin Shell Quadratic Quadrilateral - QUAD8 - case 46: // Plane Stress Cubic Quadrilateral +// case 46: // Plane Stress Cubic Quadrilateral - return true; - } - return false; +// return true; +// } +// return false; } diff --git a/src/DriverUNV/UNV2417_Structure.cxx b/src/DriverUNV/UNV2417_Structure.cxx index 0f7313b76..822e22470 100644 --- a/src/DriverUNV/UNV2417_Structure.cxx +++ b/src/DriverUNV/UNV2417_Structure.cxx @@ -30,13 +30,6 @@ using namespace std; using namespace UNV; using namespace UNV2417; -#ifdef _DEBUG_ -static int MYDEBUG = 0; -#else -static int MYDEBUG = 0; -#endif - - static string _group_labels[] = {"2417", "2429", "2430", "2432", "2435", "2452", "2467", "2477"}; #define NBGROUP 8 diff --git a/src/DriverUNV/UNV_Test.cxx b/src/DriverUNV/UNV_Test.cxx index 55964109a..295363380 100644 --- a/src/DriverUNV/UNV_Test.cxx +++ b/src/DriverUNV/UNV_Test.cxx @@ -29,13 +29,6 @@ using namespace std; -#ifdef DEBUG -static int MYDEBUG = 1; -#else -static int MYDEBUG = 0; -#endif - - void ReadMed(const char* theFileName){ std::ifstream in_stream(theFileName); diff --git a/src/DriverUNV/UNV_Utilities.cxx b/src/DriverUNV/UNV_Utilities.cxx index 7a23dfd76..4cd3a4167 100644 --- a/src/DriverUNV/UNV_Utilities.cxx +++ b/src/DriverUNV/UNV_Utilities.cxx @@ -24,12 +24,6 @@ using namespace std; -#ifdef _DEBUG_ -static int MYDEBUG = 1; -#else -static int MYDEBUG = 0; -#endif - int UNV::PrefixPrinter::myCounter = 0; diff --git a/src/Makefile.am b/src/Makefile.am index c77ff62a0..e244fbde6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -40,7 +40,8 @@ SUBDIRS = \ SMESH_SWIG \ MEFISTO2 \ StdMeshers \ - StdMeshers_I + StdMeshers_I \ + SMESH_PY if SMESH_ENABLE_GUI SUBDIRS += \ @@ -54,4 +55,4 @@ endif DIST_SUBDIRS = SMDS SMESHDS Controls Driver DriverMED DriverDAT DriverUNV DriverSTL SMESH \ SMESH_I SMESHClient SMESH_SWIG MEFISTO2 StdMeshers StdMeshers_I OBJECT \ - SMESHFiltersSelection SMESHGUI PluginUtils SMESH_SWIG_WITHIHM StdMeshersGUI + SMESHFiltersSelection SMESHGUI PluginUtils SMESH_SWIG_WITHIHM StdMeshersGUI SMESH_PY diff --git a/src/OBJECT/Makefile.am b/src/OBJECT/Makefile.am index 0e8cdabd9..219350562 100644 --- a/src/OBJECT/Makefile.am +++ b/src/OBJECT/Makefile.am @@ -34,7 +34,9 @@ salomeinclude_HEADERS = \ SMESH_DeviceActor.h \ SMESH_PreviewActorsCollection.h \ SMESH_ExtractGeometry.h \ - SMESH_FaceOrientationFilter.h + SMESH_FaceOrientationFilter.h \ + SMESH_ScalarBarActor.h + # Libraries targets @@ -46,7 +48,8 @@ dist_libSMESHObject_la_SOURCES = \ SMESH_PreviewActorsCollection.cxx \ SMESH_ExtractGeometry.cxx \ SMESH_ActorUtils.cxx \ - SMESH_FaceOrientationFilter.cxx + SMESH_FaceOrientationFilter.cxx \ + SMESH_ScalarBarActor.cxx libSMESHObject_la_CPPFLAGS = \ $(QT_INCLUDES) \ diff --git a/src/OBJECT/SMESH_Actor.cxx b/src/OBJECT/SMESH_Actor.cxx index cd9e06919..4afc7f4ca 100644 --- a/src/OBJECT/SMESH_Actor.cxx +++ b/src/OBJECT/SMESH_Actor.cxx @@ -30,6 +30,8 @@ #include "SMESH_DeviceActor.h" #include "SMESH_ObjectDef.h" #include "SMESH_ControlsDef.hxx" +#include "SMESH_ScalarBarActor.h" +#include "VTKViewer_CellCenters.h" #include "VTKViewer_ExtractUnstructuredGrid.h" #include "VTKViewer_FramedTextActor.h" #include "SALOME_InteractiveObject.hxx" @@ -59,12 +61,10 @@ #include #include #include -#include #include #include #include -#include #include #include @@ -196,6 +196,7 @@ SMESH_ActorDef::SMESH_ActorDef() 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 @@ -370,7 +371,7 @@ SMESH_ActorDef::SMESH_ActorDef() //Controls - Aspect Ratio: incorrect colors of the best and worst values myLookupTable->SetHueRange(0.667,0.0); - myScalarBarActor = vtkScalarBarActor::New(); + myScalarBarActor = SMESH_ScalarBarActor::New(); myScalarBarActor->SetVisibility(false); myScalarBarActor->SetLookupTable(myLookupTable); @@ -427,7 +428,7 @@ SMESH_ActorDef::SMESH_ActorDef() //--------------------------------------- myCellsNumDataSet = vtkUnstructuredGrid::New(); - myCellCenters = vtkCellCenters::New(); + myCellCenters = VTKViewer_CellCenters::New(); myCellCenters->SetInput(myCellsNumDataSet); myClsMaskPoints = vtkMaskPoints::New(); @@ -487,9 +488,11 @@ SMESH_ActorDef::SMESH_ActorDef() myHighlitableActor->SetQuadraticArcAngle(aQuadraticAngle); my2DActor->SetQuadraticArcAngle(aQuadraticAngle); - // Set color of the name actor + // Set colors of the name actor SMESH::GetColor( "SMESH", "fill_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) ); myNameActor->SetBackgroundColor(anRGB[0], anRGB[1], anRGB[2]); + SMESH::GetColor( "SMESH", "group_name_color", anRGB[0], anRGB[1], anRGB[2], QColor( 255, 255, 255 ) ); + myNameActor->SetForegroundColor(anRGB[0], anRGB[1], anRGB[2]); } @@ -497,6 +500,9 @@ SMESH_ActorDef::~SMESH_ActorDef() { if(MYDEBUG) MESSAGE("~SMESH_ActorDef - "<InvokeEvent( SMESH::DeleteActorEvent, NULL ); + myScalarBarActor->Delete(); myLookupTable->Delete(); @@ -718,51 +724,50 @@ SetControlMode(eControl theMode, bool anIsScalarVisible = theMode > eNone; if(anIsScalarVisible){ - SMESH::Controls::FunctorPtr aFunctor; switch(theMode){ case eLength: { SMESH::Controls::Length* aControl = new SMESH::Controls::Length(); aControl->SetPrecision( myControlsPrecision ); - aFunctor.reset( aControl ); + myFunctor.reset( aControl ); myControlActor = my1DActor; break; } case eLength2D: { - aFunctor.reset(new SMESH::Controls::Length2D()); + myFunctor.reset(new SMESH::Controls::Length2D()); myControlActor = my2DActor; break; } case eFreeBorders: - aFunctor.reset(new SMESH::Controls::FreeBorders()); + myFunctor.reset(new SMESH::Controls::FreeBorders()); myControlActor = my1DActor; break; case eFreeEdges: - aFunctor.reset(new SMESH::Controls::FreeEdges()); + myFunctor.reset(new SMESH::Controls::FreeEdges()); myControlActor = my2DActor; break; case eFreeNodes: - aFunctor.reset(new SMESH::Controls::FreeNodes()); + myFunctor.reset(new SMESH::Controls::FreeNodes()); myControlActor = myNodeActor; break; case eFreeFaces: - aFunctor.reset(new SMESH::Controls::FreeFaces()); + myFunctor.reset(new SMESH::Controls::FreeFaces()); myControlActor = my2DActor; break; case eMultiConnection: - aFunctor.reset(new SMESH::Controls::MultiConnection()); + myFunctor.reset(new SMESH::Controls::MultiConnection()); myControlActor = my1DActor; break; case eMultiConnection2D: - aFunctor.reset(new SMESH::Controls::MultiConnection2D()); + myFunctor.reset(new SMESH::Controls::MultiConnection2D()); myControlActor = my2DActor; break; case eArea: { SMESH::Controls::Area* aControl = new SMESH::Controls::Area(); aControl->SetPrecision( myControlsPrecision ); - aFunctor.reset( aControl ); + myFunctor.reset( aControl ); myControlActor = my2DActor; break; } @@ -770,7 +775,7 @@ SetControlMode(eControl theMode, { SMESH::Controls::Taper* aControl = new SMESH::Controls::Taper(); aControl->SetPrecision( myControlsPrecision ); - aFunctor.reset( aControl ); + myFunctor.reset( aControl ); myControlActor = my2DActor; break; } @@ -778,7 +783,7 @@ SetControlMode(eControl theMode, { SMESH::Controls::AspectRatio* aControl = new SMESH::Controls::AspectRatio(); aControl->SetPrecision( myControlsPrecision ); - aFunctor.reset( aControl ); + myFunctor.reset( aControl ); myControlActor = my2DActor; break; } @@ -786,7 +791,7 @@ SetControlMode(eControl theMode, { SMESH::Controls::AspectRatio3D* aControl = new SMESH::Controls::AspectRatio3D(); aControl->SetPrecision( myControlsPrecision ); - aFunctor.reset( aControl ); + myFunctor.reset( aControl ); myControlActor = my3DActor; break; } @@ -794,7 +799,23 @@ SetControlMode(eControl theMode, { SMESH::Controls::Volume* aControl = new SMESH::Controls::Volume(); aControl->SetPrecision( myControlsPrecision ); - aFunctor.reset( aControl ); + myFunctor.reset( aControl ); + myControlActor = my3DActor; + break; + } + case eMaxElementLength2D: + { + SMESH::Controls::MaxElementLength2D* aControl = new SMESH::Controls::MaxElementLength2D(); + aControl->SetPrecision( myControlsPrecision ); + myFunctor.reset( aControl ); + myControlActor = my2DActor; + break; + } + case eMaxElementLength3D: + { + SMESH::Controls::MaxElementLength3D* aControl = new SMESH::Controls::MaxElementLength3D(); + aControl->SetPrecision( myControlsPrecision ); + myFunctor.reset( aControl ); myControlActor = my3DActor; break; } @@ -802,7 +823,7 @@ SetControlMode(eControl theMode, { SMESH::Controls::MinimumAngle* aControl = new SMESH::Controls::MinimumAngle(); aControl->SetPrecision( myControlsPrecision ); - aFunctor.reset( aControl ); + myFunctor.reset( aControl ); myControlActor = my2DActor; break; } @@ -810,7 +831,7 @@ SetControlMode(eControl theMode, { SMESH::Controls::Warping* aControl = new SMESH::Controls::Warping(); aControl->SetPrecision( myControlsPrecision ); - aFunctor.reset( aControl ); + myFunctor.reset( aControl ); myControlActor = my2DActor; break; } @@ -818,7 +839,7 @@ SetControlMode(eControl theMode, { SMESH::Controls::Skew* aControl = new SMESH::Controls::Skew(); aControl->SetPrecision( myControlsPrecision ); - aFunctor.reset( aControl ); + myFunctor.reset( aControl ); myControlActor = my2DActor; break; } @@ -832,21 +853,21 @@ SetControlMode(eControl theMode, myControlMode = theMode; switch(myControlMode){ case eFreeNodes: - myNodeExtActor->SetExtControlMode(aFunctor); + myNodeExtActor->SetExtControlMode(myFunctor); break; case eFreeEdges: case eFreeBorders: - my1DExtActor->SetExtControlMode(aFunctor); + my1DExtActor->SetExtControlMode(myFunctor); break; case eFreeFaces: - my2DExtActor->SetExtControlMode(aFunctor); + my2DExtActor->SetExtControlMode(myFunctor); break; case eLength2D: case eMultiConnection2D: - my1DExtActor->SetExtControlMode(aFunctor,myScalarBarActor,myLookupTable); + my1DExtActor->SetExtControlMode(myFunctor,myScalarBarActor,myLookupTable); break; default: - myControlActor->SetControlMode(aFunctor,myScalarBarActor,myLookupTable); + myControlActor->SetControlMode(myFunctor,myScalarBarActor,myLookupTable); } } @@ -869,8 +890,11 @@ SetControlMode(eControl theMode, SetEntityMode(eVolumes); } - }else if(theCheckEntityMode){ - myEntityMode = eAllEntity; + } + else { + if(theCheckEntityMode) + myEntityMode = eAllEntity; + myFunctor.reset(); } SetRepresentation(GetRepresentation()); @@ -1344,6 +1368,7 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode) aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_TETRA); aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON); aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE); + aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID); aHightFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET); } aFilter->Update(); @@ -1801,92 +1826,6 @@ GetClippingPlane(vtkIdType theID) return myCippingPlaneCont[theID].Get(); } - -static void ComputeBoundsParam(vtkDataSet* theDataSet, - vtkFloatingPointType theDirection[3], vtkFloatingPointType theMinPnt[3], - vtkFloatingPointType& theMaxBoundPrj, vtkFloatingPointType& theMinBoundPrj) -{ - vtkFloatingPointType aBounds[6]; - theDataSet->GetBounds(aBounds); - - //Enlarge bounds in order to avoid conflicts of precision - for(int i = 0; i < 6; i += 2){ - static double EPS = 1.0E-3; - vtkFloatingPointType aDelta = (aBounds[i+1] - aBounds[i])*EPS; - aBounds[i] -= aDelta; - aBounds[i+1] += aDelta; - } - - vtkFloatingPointType aBoundPoints[8][3] = { {aBounds[0],aBounds[2],aBounds[4]}, - {aBounds[1],aBounds[2],aBounds[4]}, - {aBounds[0],aBounds[3],aBounds[4]}, - {aBounds[1],aBounds[3],aBounds[4]}, - {aBounds[0],aBounds[2],aBounds[5]}, - {aBounds[1],aBounds[2],aBounds[5]}, - {aBounds[0],aBounds[3],aBounds[5]}, - {aBounds[1],aBounds[3],aBounds[5]}}; - - int aMaxId = 0, aMinId = aMaxId; - theMaxBoundPrj = vtkMath::Dot(theDirection,aBoundPoints[aMaxId]); - theMinBoundPrj = theMaxBoundPrj; - for(int i = 1; i < 8; i++){ - vtkFloatingPointType aTmp = vtkMath::Dot(theDirection,aBoundPoints[i]); - if(theMaxBoundPrj < aTmp){ - theMaxBoundPrj = aTmp; - aMaxId = i; - } - if(theMinBoundPrj > aTmp){ - theMinBoundPrj = aTmp; - aMinId = i; - } - } - vtkFloatingPointType *aMinPnt = aBoundPoints[aMaxId]; - theMinPnt[0] = aMinPnt[0]; - theMinPnt[1] = aMinPnt[1]; - theMinPnt[2] = aMinPnt[2]; -} - - -static void DistanceToPosition(vtkDataSet* theDataSet, - vtkFloatingPointType theDirection[3], vtkFloatingPointType theDist, vtkFloatingPointType thePos[3]) -{ - vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3]; - ComputeBoundsParam(theDataSet,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj); - vtkFloatingPointType aLength = (aMaxBoundPrj-aMinBoundPrj)*theDist; - thePos[0] = aMinPnt[0]-theDirection[0]*aLength; - thePos[1] = aMinPnt[1]-theDirection[1]*aLength; - thePos[2] = aMinPnt[2]-theDirection[2]*aLength; -} - - -static void PositionToDistance(vtkDataSet* theDataSet, - vtkFloatingPointType theDirection[3], vtkFloatingPointType thePos[3], vtkFloatingPointType& theDist) -{ - vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3]; - ComputeBoundsParam(theDataSet,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj); - vtkFloatingPointType aPrj = vtkMath::Dot(theDirection,thePos); - theDist = (aPrj-aMinBoundPrj)/(aMaxBoundPrj-aMinBoundPrj); -} - - -void SMESH_ActorDef::SetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType theDist, vtkPlane* thePlane) -{ - thePlane->SetNormal(theDir); - vtkFloatingPointType anOrigin[3]; - ::DistanceToPosition(GetUnstructuredGrid(),theDir,theDist,anOrigin); - thePlane->SetOrigin(anOrigin); -} - - -void SMESH_ActorDef::GetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType& theDist, vtkPlane* thePlane) -{ - thePlane->GetNormal(theDir); - - vtkFloatingPointType anOrigin[3]; - thePlane->GetOrigin(anOrigin); - ::PositionToDistance(GetUnstructuredGrid(),theDir,anOrigin,theDist); -} - void SMESH_ActorDef::UpdateScalarBar() { SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr(); @@ -2000,6 +1939,21 @@ void SMESH_ActorDef::UpdateScalarBar() if( mgr->hasValue( "SMESH", "scalar_bar_num_colors" ) ) anIntVal = mgr->integerValue( "SMESH", "scalar_bar_num_colors", anIntVal ); myScalarBarActor->SetMaximumNumberOfColors( anIntVal == 0 ? 64 : anIntVal ); + + bool distributionVisibility = mgr->booleanValue("SMESH","distribution_visibility"); + myScalarBarActor->SetDistributionVisibility(distributionVisibility); + + int coloringType = mgr->integerValue("SMESH", "distribution_coloring_type", 0); + myScalarBarActor->SetDistributionColoringType(coloringType); + + QColor distributionColor = mgr->colorValue("SMESH", "distribution_color", + QColor(255, 255, 255)); + double rgb[3]; + rgb[0]= distributionColor.red()/255.; + rgb[1]= distributionColor.green()/255.; + rgb[2]= distributionColor.blue()/255.; + myScalarBarActor->SetDistributionColor(rgb); + } diff --git a/src/OBJECT/SMESH_Actor.h b/src/OBJECT/SMESH_Actor.h index bb4e2fb68..24a57a00a 100644 --- a/src/OBJECT/SMESH_Actor.h +++ b/src/OBJECT/SMESH_Actor.h @@ -31,13 +31,20 @@ #include #include "SMESH_Object.h" +#include + class vtkUnstructuredGrid; -class vtkScalarBarActor; +class SMESH_ScalarBarActor; class vtkPlane; class vtkImplicitBoolean; +namespace SMESH +{ + const vtkIdType DeleteActorEvent = vtkCommand::UserEvent + 100; +} + class SMESHOBJECT_EXPORT SMESH_Actor: public SALOME_Actor { static SMESH_Actor* New() { return NULL;} @@ -115,14 +122,13 @@ 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}; + eMinimumAngle, eWarping, eSkew, eAspectRatio3D, eMultiConnection2D, eVolume3D, + eMaxElementLength2D, eMaxElementLength3D}; virtual void SetControlMode(eControl theMode) = 0; virtual eControl GetControlMode() = 0; + virtual SMESH::Controls::FunctorPtr GetFunctor() = 0; - virtual vtkScalarBarActor* GetScalarBarActor() = 0; - - virtual void SetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType theDist, vtkPlane* thePlane) = 0; - virtual void GetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType& theDist, vtkPlane* thePlane) = 0; + virtual SMESH_ScalarBarActor* GetScalarBarActor() = 0; virtual void RemoveAllClippingPlanes() = 0; virtual vtkIdType GetNumberOfClippingPlanes() = 0; diff --git a/src/OBJECT/SMESH_ActorDef.h b/src/OBJECT/SMESH_ActorDef.h index e3d65ff7a..09b2232f0 100644 --- a/src/OBJECT/SMESH_ActorDef.h +++ b/src/OBJECT/SMESH_ActorDef.h @@ -59,23 +59,20 @@ class vtkPolyDataMapper; class vtkUnstructuredGrid; class vtkMergeFilter; class vtkPolyData; - class vtkMapper; class vtkActor2D; class vtkMaskPoints; -class vtkCellCenters; class vtkLabeledDataMapper; class vtkSelectVisiblePoints; - -class vtkScalarBarActor; class vtkLookupTable; - class vtkPlane; class vtkImplicitBoolean; - class vtkTimeStamp; +class VTKViewer_CellCenters; + class SMESH_DeviceActor; +class SMESH_ScalarBarActor; class SMESH_ActorDef : public SMESH_Actor @@ -184,11 +181,9 @@ class SMESH_ActorDef : public SMESH_Actor virtual void SetControlMode(eControl theMode); virtual eControl GetControlMode(){ return myControlMode;} + virtual SMESH::Controls::FunctorPtr GetFunctor() { return myFunctor; } - virtual vtkScalarBarActor* GetScalarBarActor(){ return myScalarBarActor;} - - virtual void SetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType theDist, vtkPlane* thePlane); - virtual void GetPlaneParam(vtkFloatingPointType theDir[3], vtkFloatingPointType& theDist, vtkPlane* thePlane); + virtual SMESH_ScalarBarActor* GetScalarBarActor(){ return myScalarBarActor;} virtual void RemoveAllClippingPlanes(); virtual vtkIdType GetNumberOfClippingPlanes(); @@ -217,7 +212,7 @@ class SMESH_ActorDef : public SMESH_Actor TVisualObjPtr myVisualObj; vtkTimeStamp* myTimeStamp; - vtkScalarBarActor* myScalarBarActor; + SMESH_ScalarBarActor* myScalarBarActor; vtkLookupTable* myLookupTable; vtkProperty* mySurfaceProp; @@ -234,6 +229,7 @@ class SMESH_ActorDef : public SMESH_Actor SMESH_DeviceActor* myHighlitableActor; eControl myControlMode; + SMESH::Controls::FunctorPtr myFunctor; vtkProperty* my2DExtProp; SMESH_DeviceActor* my2DActor; SMESH_DeviceActor* my2DExtActor; @@ -271,7 +267,7 @@ class SMESH_ActorDef : public SMESH_Actor vtkUnstructuredGrid* myCellsNumDataSet; vtkActor2D *myCellsLabels; vtkMaskPoints* myClsMaskPoints; - vtkCellCenters* myCellCenters; + VTKViewer_CellCenters* myCellCenters; vtkLabeledDataMapper* myClsLabeledDataMapper; vtkSelectVisiblePoints* myClsSelectVisiblePoints; diff --git a/src/OBJECT/SMESH_DeviceActor.cxx b/src/OBJECT/SMESH_DeviceActor.cxx index 4be8cadec..600a4987c 100644 --- a/src/OBJECT/SMESH_DeviceActor.cxx +++ b/src/OBJECT/SMESH_DeviceActor.cxx @@ -26,6 +26,7 @@ // Module : SMESH // #include "SMESH_DeviceActor.h" +#include "SMESH_ScalarBarActor.h" #include "SMESH_ExtractGeometry.h" #include "SMESH_ControlsDef.hxx" #include "SMESH_ActorUtils.h" @@ -48,7 +49,6 @@ #include #include -#include #include #include #include @@ -282,7 +282,7 @@ SMESH_DeviceActor void SMESH_DeviceActor ::SetControlMode(SMESH::Controls::FunctorPtr theFunctor, - vtkScalarBarActor* theScalarBarActor, + SMESH_ScalarBarActor* theScalarBarActor, vtkLookupTable* theLookupTable) { bool anIsInitialized = theFunctor; @@ -310,6 +310,12 @@ SMESH_DeviceActor double aValue = aNumericalFunctor->GetValue(anObjId); aScalars->SetValue(i,aValue); } + int nbIntervals = theScalarBarActor->GetMaximumNumberOfColors(); + std::vector nbEvents; + std::vector funValues; + aNumericalFunctor->GetHistogram(nbIntervals, nbEvents, funValues); + theScalarBarActor->SetDistribution(nbEvents); + }else if(Predicate* aPredicate = dynamic_cast(theFunctor.get())){ for(vtkIdType i = 0; i < aNbCells; i++){ vtkIdType anId = myExtractUnstructuredGrid->GetInputId(i); @@ -336,7 +342,7 @@ SMESH_DeviceActor void SMESH_DeviceActor ::SetExtControlMode(SMESH::Controls::FunctorPtr theFunctor, - vtkScalarBarActor* theScalarBarActor, + SMESH_ScalarBarActor* theScalarBarActor, vtkLookupTable* theLookupTable) { bool anIsInitialized = theFunctor; @@ -469,6 +475,16 @@ SMESH_DeviceActor myMergeFilter->SetScalars(aDataSet); aDataSet->Delete(); } + + //Set Distribution + if(NumericalFunctor* aNumericalFunctor = dynamic_cast(theFunctor.get())){ + int nbIntervals = theScalarBarActor->GetMaximumNumberOfColors(); + std::vector nbEvents; + std::vector funValues; + aNumericalFunctor->GetHistogram(nbIntervals, nbEvents, funValues); + theScalarBarActor->SetDistribution(nbEvents); + } + } GetMapper()->SetScalarVisibility(anIsInitialized); theScalarBarActor->SetVisibility(anIsInitialized); diff --git a/src/OBJECT/SMESH_DeviceActor.h b/src/OBJECT/SMESH_DeviceActor.h index 7c506bd38..1e598fa84 100644 --- a/src/OBJECT/SMESH_DeviceActor.h +++ b/src/OBJECT/SMESH_DeviceActor.h @@ -42,7 +42,6 @@ class vtkProperty; class vtkMergeFilter; class vtkShrinkFilter; class vtkUnstructuredGrid; -class vtkScalarBarActor; class vtkLookupTable; class vtkImplicitBoolean; class vtkPassThroughFilter; @@ -54,6 +53,7 @@ class VTKViewer_PolyDataMapper; class SMESH_ExtractGeometry; class SMESH_FaceOrientationFilter; +class SMESH_ScalarBarActor; class SMESHOBJECT_EXPORT SMESH_DeviceActor: public vtkLODActor{ @@ -120,10 +120,10 @@ class SMESHOBJECT_EXPORT SMESH_DeviceActor: public vtkLODActor{ vtkUnstructuredGrid* GetUnstructuredGrid(); void SetControlMode(SMESH::Controls::FunctorPtr theFunctor, - vtkScalarBarActor* theScalarBarActor, + SMESH_ScalarBarActor* theScalarBarActor, vtkLookupTable* theLookupTable); void SetExtControlMode(SMESH::Controls::FunctorPtr theFunctor, - vtkScalarBarActor* theScalarBarActor, + SMESH_ScalarBarActor* theScalarBarActor, vtkLookupTable* theLookupTable); void SetExtControlMode(SMESH::Controls::FunctorPtr theFunctor); diff --git a/src/OBJECT/SMESH_FaceOrientationFilter.cxx b/src/OBJECT/SMESH_FaceOrientationFilter.cxx index 9f01d0bdc..d2407af6b 100644 --- a/src/OBJECT/SMESH_FaceOrientationFilter.cxx +++ b/src/OBJECT/SMESH_FaceOrientationFilter.cxx @@ -23,6 +23,8 @@ #include "SUIT_Session.h" #include "SUIT_ResourceMgr.h" +#include + #include #include #include @@ -33,7 +35,6 @@ #include #include #include -#include #include #include @@ -59,7 +60,7 @@ SMESH_FaceOrientationFilter::SMESH_FaceOrientationFilter() myFacePolyData = vtkPolyData::New(); - myFaceCenters = vtkCellCenters::New(); + myFaceCenters = VTKViewer_CellCenters::New(); myFaceCenters->SetInput(myFacePolyData); myFaceMaskPoints = vtkMaskPoints::New(); diff --git a/src/OBJECT/SMESH_FaceOrientationFilter.h b/src/OBJECT/SMESH_FaceOrientationFilter.h index 7a1721cb6..813468047 100644 --- a/src/OBJECT/SMESH_FaceOrientationFilter.h +++ b/src/OBJECT/SMESH_FaceOrientationFilter.h @@ -24,11 +24,12 @@ #include -class vtkCellCenters; class vtkGlyph3D; class vtkGlyphSource2D; class vtkMaskPoints; +class VTKViewer_CellCenters; + class SMESHOBJECT_EXPORT SMESH_FaceOrientationFilter : public vtkPolyDataAlgorithm { public: @@ -63,7 +64,7 @@ private: vtkFloatingPointType myOrientationScale; vtkPolyData* myArrowPolyData; vtkPolyData* myFacePolyData; - vtkCellCenters* myFaceCenters; + VTKViewer_CellCenters* myFaceCenters; vtkMaskPoints* myFaceMaskPoints; vtkGlyphSource2D* myGlyphSource; vtkGlyph3D* myBaseGlyph; diff --git a/src/OBJECT/SMESH_Object.cxx b/src/OBJECT/SMESH_Object.cxx index eb43a6b5f..480a0fe3f 100644 --- a/src/OBJECT/SMESH_Object.cxx +++ b/src/OBJECT/SMESH_Object.cxx @@ -119,7 +119,7 @@ static inline vtkIdType getCellType( const SMDSAbs_ElementType theType, return VTK_QUADRATIC_WEDGE; } else if ( theNbNodes==13 ) { - return VTK_CONVEX_POINT_SET; + return VTK_QUADRATIC_PYRAMID; //VTK_CONVEX_POINT_SET; } else return VTK_EMPTY_CELL; diff --git a/src/OBJECT/SMESH_PreviewActorsCollection.cxx b/src/OBJECT/SMESH_PreviewActorsCollection.cxx index d014af78c..059edd927 100644 --- a/src/OBJECT/SMESH_PreviewActorsCollection.cxx +++ b/src/OBJECT/SMESH_PreviewActorsCollection.cxx @@ -35,7 +35,6 @@ // VTK includes #include -#include #include #include #include diff --git a/src/OBJECT/SMESH_ScalarBarActor.cxx b/src/OBJECT/SMESH_ScalarBarActor.cxx new file mode 100644 index 000000000..3f7622672 --- /dev/null +++ b/src/OBJECT/SMESH_ScalarBarActor.cxx @@ -0,0 +1,923 @@ +// 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 +// +// File : SMESH_ScalarBarActor.cxx +// Author : Roman NIKOLAEV +// Module : SMESH +// + +#include "SMESH_ScalarBarActor.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SHRINK_COEF 0.08; + +vtkStandardNewMacro(SMESH_ScalarBarActor); + +vtkCxxSetObjectMacro(SMESH_ScalarBarActor,LookupTable,vtkScalarsToColors); +vtkCxxSetObjectMacro(SMESH_ScalarBarActor,LabelTextProperty,vtkTextProperty); +vtkCxxSetObjectMacro(SMESH_ScalarBarActor,TitleTextProperty,vtkTextProperty); + +//---------------------------------------------------------------------------- +// Instantiate object with 64 maximum colors; 5 labels; %%-#6.3g label +// format, no title, and vertical orientation. The initial scalar bar +// size is (0.05 x 0.8) of the viewport size. +SMESH_ScalarBarActor::SMESH_ScalarBarActor() { + this->LookupTable = NULL; + this->Position2Coordinate->SetValue(0.17, 0.8); + + this->PositionCoordinate->SetCoordinateSystemToNormalizedViewport(); + this->PositionCoordinate->SetValue(0.82,0.1); + + this->MaximumNumberOfColors = 64; + this->NumberOfLabels = 5; + this->NumberOfLabelsBuilt = 0; + this->Orientation = VTK_ORIENT_VERTICAL; + this->Title = NULL; + + this->LabelTextProperty = vtkTextProperty::New(); + this->LabelTextProperty->SetFontSize(12); + this->LabelTextProperty->SetBold(1); + this->LabelTextProperty->SetItalic(1); + this->LabelTextProperty->SetShadow(1); + this->LabelTextProperty->SetFontFamilyToArial(); + + this->TitleTextProperty = vtkTextProperty::New(); + this->TitleTextProperty->ShallowCopy(this->LabelTextProperty); + + this->LabelFormat = new char[8]; + sprintf(this->LabelFormat,"%s","%-#6.3g"); + + this->TitleMapper = vtkTextMapper::New(); + this->TitleActor = vtkActor2D::New(); + this->TitleActor->SetMapper(this->TitleMapper); + this->TitleActor->GetPositionCoordinate()-> + SetReferenceCoordinate(this->PositionCoordinate); + + this->TextMappers = NULL; + this->TextActors = NULL; + + this->ScalarBar = vtkPolyData::New(); + this->ScalarBarMapper = vtkPolyDataMapper2D::New(); + this->ScalarBarMapper->SetInput(this->ScalarBar); + this->ScalarBarActor = vtkActor2D::New(); + this->ScalarBarActor->SetMapper(this->ScalarBarMapper); + this->ScalarBarActor->GetPositionCoordinate()-> + SetReferenceCoordinate(this->PositionCoordinate); + this->LastOrigin[0] = 0; + this->LastOrigin[1] = 0; + this->LastSize[0] = 0; + this->LastSize[1] = 0; + + + // rnv begin + // Customization of the vtkScalarBarActor to show distribution histogram. + myDistribution = vtkPolyData::New(); + myDistributionMapper = vtkPolyDataMapper2D::New(); + myDistributionMapper->SetInput(this->myDistribution); + + myDistributionActor = vtkActor2D::New(); + myDistributionActor->SetMapper(this->myDistributionMapper); + myDistributionActor->GetPositionCoordinate()-> + SetReferenceCoordinate(this->PositionCoordinate); + + // By default distribution histogram is invisible + myDistributionActor->SetVisibility(0); + + // By default monocolor + myDistributionColoringType = SMESH_MONOCOLOR_TYPE; + // rnv end +} + +//---------------------------------------------------------------------------- +// Release any graphics resources that are being consumed by this actor. +// The parameter window could be used to determine which graphic +// resources to release. +void SMESH_ScalarBarActor::ReleaseGraphicsResources(vtkWindow *win) +{ + this->TitleActor->ReleaseGraphicsResources(win); + if (this->TextMappers != NULL ) + { + for (int i=0; i < this->NumberOfLabelsBuilt; i++) + { + this->TextActors[i]->ReleaseGraphicsResources(win); + } + } + this->ScalarBarActor->ReleaseGraphicsResources(win); + // rnv begin + // Customization of the vtkScalarBarActor to show distribution histogram. + myDistributionActor->ReleaseGraphicsResources(win); +} + + +/*--------------------------------------------------------------------------*/ +SMESH_ScalarBarActor::~SMESH_ScalarBarActor() { + if (this->LabelFormat) + { + delete [] this->LabelFormat; + this->LabelFormat = NULL; + } + + this->TitleMapper->Delete(); + this->TitleActor->Delete(); + + if (this->TextMappers != NULL ) + { + for (int i=0; i < this->NumberOfLabelsBuilt; i++) + { + this->TextMappers[i]->Delete(); + this->TextActors[i]->Delete(); + } + delete [] this->TextMappers; + delete [] this->TextActors; + } + + this->ScalarBar->Delete(); + this->ScalarBarMapper->Delete(); + this->ScalarBarActor->Delete(); + + if (this->Title) + { + delete [] this->Title; + this->Title = NULL; + } + + this->SetLookupTable(NULL); + this->SetLabelTextProperty(NULL); + this->SetTitleTextProperty(NULL); + + // rnv begin + // Customization of the vtkScalarBarActor to show distribution histogram: + myDistribution->Delete(); + myDistributionMapper->Delete(); + myDistributionActor->Delete(); + // rnv end +} + +//---------------------------------------------------------------------------- +int SMESH_ScalarBarActor::RenderOverlay(vtkViewport *viewport) +{ + int renderedSomething = 0; + int i; + + // Everything is built, just have to render + if (this->Title != NULL) + { + renderedSomething += this->TitleActor->RenderOverlay(viewport); + } + this->ScalarBarActor->RenderOverlay(viewport); + this->myDistributionActor->RenderOverlay(viewport); + if( this->TextActors == NULL) + { + vtkWarningMacro(<<"Need a mapper to render a scalar bar"); + return renderedSomething; + } + + for (i=0; iNumberOfLabels; i++) + { + renderedSomething += this->TextActors[i]->RenderOverlay(viewport); + } + + renderedSomething = (renderedSomething > 0)?(1):(0); + + return renderedSomething; +} + + +//---------------------------------------------------------------------------- +int SMESH_ScalarBarActor::RenderOpaqueGeometry(vtkViewport *viewport) +{ + int renderedSomething = 0; + int i; + int size[2]; + + if (!this->LookupTable) + { + vtkWarningMacro(<<"Need a mapper to render a scalar bar"); + return 0; + } + + if (!this->TitleTextProperty) + { + vtkErrorMacro(<<"Need title text property to render a scalar bar"); + return 0; + } + + if (!this->LabelTextProperty) + { + vtkErrorMacro(<<"Need label text property to render a scalar bar"); + return 0; + } + + // Check to see whether we have to rebuild everything + int positionsHaveChanged = 0; + if (viewport->GetMTime() > this->BuildTime || + (viewport->GetVTKWindow() && + viewport->GetVTKWindow()->GetMTime() > this->BuildTime)) + { + // if the viewport has changed we may - or may not need + // to rebuild, it depends on if the projected coords chage + int *barOrigin; + barOrigin = this->PositionCoordinate->GetComputedViewportValue(viewport); + size[0] = + this->Position2Coordinate->GetComputedViewportValue(viewport)[0] - + barOrigin[0]; + size[1] = + this->Position2Coordinate->GetComputedViewportValue(viewport)[1] - + barOrigin[1]; + if (this->LastSize[0] != size[0] || + this->LastSize[1] != size[1] || + this->LastOrigin[0] != barOrigin[0] || + this->LastOrigin[1] != barOrigin[1]) + { + positionsHaveChanged = 1; + } + } + + // Check to see whether we have to rebuild everything + if (positionsHaveChanged || + this->GetMTime() > this->BuildTime || + this->LookupTable->GetMTime() > this->BuildTime || + this->LabelTextProperty->GetMTime() > this->BuildTime || + this->TitleTextProperty->GetMTime() > this->BuildTime) + { + vtkDebugMacro(<<"Rebuilding subobjects"); + + // Delete previously constructed objects + // + if (this->TextMappers != NULL ) + { + for (i=0; i < this->NumberOfLabelsBuilt; i++) + { + this->TextMappers[i]->Delete(); + this->TextActors[i]->Delete(); + } + delete [] this->TextMappers; + delete [] this->TextActors; + } + + // Build scalar bar object; determine its type + // + // is this a vtkLookupTable or a subclass of vtkLookupTable + // with its scale set to log + // NOTE: it's possible we could to without the 'lut' variable + // later in the code, but if the vtkLookupTableSafeDownCast operation + // fails for some reason, this code will break in new ways. So, the 'LUT' + // variable is used for this operation only + vtkLookupTable *LUT = vtkLookupTable::SafeDownCast( this->LookupTable ); + int isLogTable = 0; + if ( LUT ) + { + if ( LUT->GetScale() == VTK_SCALE_LOG10 ) + { + isLogTable = 1; + } + } + + // we hard code how many steps to display + vtkScalarsToColors *lut = this->LookupTable; + int numColors = this->MaximumNumberOfColors; + double *range = lut->GetRange(); + + int numPts = 2*(numColors + 1); + vtkPoints *pts = vtkPoints::New(); + pts->SetNumberOfPoints(numPts); + vtkCellArray *polys = vtkCellArray::New(); + polys->Allocate(polys->EstimateSize(numColors,4)); + vtkUnsignedCharArray *colors = vtkUnsignedCharArray::New(); + colors->SetNumberOfComponents(3); + colors->SetNumberOfTuples(numColors); + + + // rnv begin + // Customization of the vtkScalarBarActor to show distribution histogram. + bool distrVisibility = (numColors == this->myNbValues.size()); + vtkPoints *distrPts; + vtkCellArray *distrPolys; + vtkUnsignedCharArray *distColors = 0; + int numDistrPts = 0, numPositiveVal=0, maxValue=0; + if(!distrVisibility) + vtkDebugMacro(<<" Distribution invisible, because numColors == this->myNbValues.size()"); + + if (distrVisibility && GetDistributionVisibility()) { + for( i=0 ;iSetNumberOfPoints(numDistrPts); + distrPolys->Allocate(distrPolys->EstimateSize(numPositiveVal,4)); + this->myDistribution->Initialize(); + this->myDistribution->SetPoints(distrPts); + this->myDistribution->SetPolys(distrPolys); + distrPts->Delete(); + distrPolys->Delete(); + if ( myDistributionColoringType == SMESH_MULTICOLOR_TYPE ) { + distColors = vtkUnsignedCharArray::New(); + distColors->SetNumberOfComponents(3); + distColors->SetNumberOfTuples(numPositiveVal); + this->myDistribution->GetCellData()->SetScalars(distColors); + distColors->Delete(); + } else if( myDistributionColoringType == SMESH_MONOCOLOR_TYPE ){ + this->myDistribution->GetCellData()->SetScalars(NULL); + } + } else { + myDistribution->Reset(); + } + // rnv end + + this->ScalarBarActor->SetProperty(this->GetProperty()); + this->ScalarBar->Initialize(); + this->ScalarBar->SetPoints(pts); + this->ScalarBar->SetPolys(polys); + this->ScalarBar->GetCellData()->SetScalars(colors); + pts->Delete(); polys->Delete(); colors->Delete(); + + // get the viewport size in display coordinates + int *barOrigin, barWidth, barHeight, distrHeight; + barOrigin = this->PositionCoordinate->GetComputedViewportValue(viewport); + size[0] = + this->Position2Coordinate->GetComputedViewportValue(viewport)[0] - + barOrigin[0]; + size[1] = + this->Position2Coordinate->GetComputedViewportValue(viewport)[1] - + barOrigin[1]; + this->LastOrigin[0] = barOrigin[0]; + this->LastOrigin[1] = barOrigin[1]; + this->LastSize[0] = size[0]; + this->LastSize[1] = size[1]; + + // Update all the composing objects + this->TitleActor->SetProperty(this->GetProperty()); + this->TitleMapper->SetInput(this->Title); + if (this->TitleTextProperty->GetMTime() > this->BuildTime) + { + // Shallow copy here so that the size of the title prop is not affected + // by the automatic adjustment of its text mapper's size (i.e. its + // mapper's text property is identical except for the font size + // which will be modified later). This allows text actors to + // share the same text property, and in that case specifically allows + // the title and label text prop to be the same. + this->TitleMapper->GetTextProperty()->ShallowCopy(this->TitleTextProperty); + this->TitleMapper->GetTextProperty()->SetJustificationToCentered(); + } + + // find the best size for the title font + int titleSize[2]; + this->SizeTitle(titleSize, size, viewport); + + // find the best size for the ticks + int labelSize[2]; + this->AllocateAndSizeLabels(labelSize, size, viewport,range); + this->NumberOfLabelsBuilt = this->NumberOfLabels; + + // generate points + double x[3]; x[2] = 0.0; + double delta, itemH, shrink; + if ( this->Orientation == VTK_ORIENT_VERTICAL ) { + // rnv begin + // Customization of the vtkScalarBarActor to show distribution histogram. + double delimeter=0.0; + if(GetDistributionVisibility() && distrVisibility) { + delimeter=0.01*size[0]; //1 % from horizontal size of the full presentation size. + barWidth = size[0] - 4 - labelSize[0]; + distrHeight = barWidth/2; + } else { + barWidth = size[0] - 4 - labelSize[0]; + distrHeight = 0; + } + + barHeight = (int)(0.86*size[1]); + delta=(double)barHeight/numColors; + + for ( i=0; iSetPoint(2*i,x); + x[0] = barWidth; + pts->SetPoint(2*i+1,x); + } + + if(GetDistributionVisibility() && distrVisibility) { + // Distribution points + shrink = delta*SHRINK_COEF; + vtkIdType distPtsId=0; + vtkIdType distPtsIds[4]; + for(i=0; iSetPoint(distPtsId++,x); + + // second point of polygon (quadrangle) + x[0] = itemH; + distPtsIds[1] = distPtsId; + distrPts->SetPoint(distPtsId++,x); + + x[1] = i*delta+delta-shrink; + + // third point of polygon (quadrangle) + x[0] = 0; + distPtsIds[3] = distPtsId; + distrPts->SetPoint(distPtsId++,x); + + // fourth point of polygon (quadrangle) + x[0] = itemH; + distPtsIds[2] = distPtsId; + distrPts->SetPoint(distPtsId++,x); + + //Inser Quadrangle + distrPolys->InsertNextCell(4,distPtsIds); + } + } + } + } + // rnv end + else { + barWidth = size[0]; + + // rnv begin + // Customization of the vtkScalarBarActor to show distribution histogram. + double coef1, delimeter=0.0; + if(GetDistributionVisibility() && distrVisibility) { + coef1=0.62; + distrHeight = (int)((coef1/2)*size[1]); + //delimeter between distribution diagram and scalar bar + delimeter=0.02*size[1]; + } + else { + coef1=0.4; + barHeight = (int)(coef1*size[1]); + distrHeight = 0; + } + + barHeight = (int)(coef1*size[1]); + + delta=(double)barWidth/numColors; + for (i=0; iSetPoint(2*i,x); + x[1] = distrHeight + delimeter; + pts->SetPoint(2*i+1,x); + } + + if(GetDistributionVisibility() && distrVisibility) { + // Distribution points + shrink = delta*SHRINK_COEF; + vtkIdType distPtsId=0; + vtkIdType distPtsIds[4]; + for(i=0; iSetPoint(distPtsId++,x); + + // second point of polygon (quadrangle) + x[0] = i*delta+shrink; + x[1] = itemH; + distPtsIds[3] = distPtsId; + distrPts->SetPoint(distPtsId++,x); + + // third point of polygon (quadrangle) + x[0] = i*delta+delta-shrink; + x[1] = 0; + distPtsIds[1] = distPtsId; + distrPts->SetPoint(distPtsId++,x); + + // fourth point of polygon (quadrangle) + x[0] = i*delta+delta-shrink; + x[1] = itemH; + distPtsIds[2] = distPtsId; + distrPts->SetPoint(distPtsId++,x); + + // Add polygon into poly data + distrPolys->InsertNextCell(4,distPtsIds); + } + } + } + // rnv end + } + + //polygons & cell colors + unsigned char *rgba, *rgb; + vtkIdType ptIds[4], dcCount=0; + for (i=0; iInsertNextCell(4,ptIds); + + if ( isLogTable ) + { + double rgbval = log10(range[0]) + + i*(log10(range[1])-log10(range[0]))/(numColors -1); + rgba = lut->MapValue(pow(10.0,rgbval)); + } + else + { + rgba = lut->MapValue(range[0] + (range[1] - range[0])* + ((double)i /(numColors-1.0))); + } + + rgb = colors->GetPointer(3*i); //write into array directly + rgb[0] = rgba[0]; + rgb[1] = rgba[1]; + rgb[2] = rgba[2]; + + // rnv begin + // Customization of the vtkScalarBarActor to show distribution histogram. + if(myNbValues[i] && myDistributionColoringType == SMESH_MULTICOLOR_TYPE && GetDistributionVisibility() && distrVisibility) + { + rgb = distColors->GetPointer(3*dcCount); //write into array directly + rgb[0] = rgba[0]; + rgb[1] = rgba[1]; + rgb[2] = rgba[2]; + dcCount++; + } + } + + // Now position everything properly + // + double val; + if (this->Orientation == VTK_ORIENT_VERTICAL) + { + int sizeTextData[2]; + + // center the title + this->TitleActor->SetPosition(size[0]/2, 0.9*size[1]); + + for (i=0; i < this->NumberOfLabels; i++) + { + if (this->NumberOfLabels > 1) + { + val = (double)i/(this->NumberOfLabels-1) *barHeight; + } + else + { + val = 0.5*barHeight; + } + this->TextMappers[i]->GetSize(viewport,sizeTextData); + this->TextMappers[i]->GetTextProperty()->SetJustificationToLeft(); + this->TextActors[i]->SetPosition(barWidth+3, + val - sizeTextData[1]/2); + } + } + else + { + this->TitleActor->SetPosition(size[0]/2, + barHeight + labelSize[1] + 0.1*size[1]); + for (i=0; i < this->NumberOfLabels; i++) + { + this->TextMappers[i]->GetTextProperty()->SetJustificationToCentered(); + if (this->NumberOfLabels > 1) + { + val = (double)i/(this->NumberOfLabels-1) * barWidth; + } + else + { + val = 0.5*barWidth; + } + this->TextActors[i]->SetPosition(val, barHeight + 0.05*size[1]); + } + } + + this->BuildTime.Modified(); + } + + // Everything is built, just have to render + if (this->Title != NULL) + { + renderedSomething += this->TitleActor->RenderOpaqueGeometry(viewport); + } + this->ScalarBarActor->RenderOpaqueGeometry(viewport); + this->myDistributionActor->RenderOpaqueGeometry(viewport); + for (i=0; iNumberOfLabels; i++) + { + renderedSomething += this->TextActors[i]->RenderOpaqueGeometry(viewport); + } + + renderedSomething = (renderedSomething > 0)?(1):(0); + + return renderedSomething; +} + +//---------------------------------------------------------------------------- +void SMESH_ScalarBarActor::PrintSelf(ostream& os, vtkIndent indent) +{ + this->Superclass::PrintSelf(os,indent); + + if ( this->LookupTable ) + { + os << indent << "Lookup Table:\n"; + this->LookupTable->PrintSelf(os,indent.GetNextIndent()); + } + else + { + os << indent << "Lookup Table: (none)\n"; + } + + if (this->TitleTextProperty) + { + os << indent << "Title Text Property:\n"; + this->TitleTextProperty->PrintSelf(os,indent.GetNextIndent()); + } + else + { + os << indent << "Title Text Property: (none)\n"; + } + + if (this->LabelTextProperty) + { + os << indent << "Label Text Property:\n"; + this->LabelTextProperty->PrintSelf(os,indent.GetNextIndent()); + } + else + { + os << indent << "Label Text Property: (none)\n"; + } + + os << indent << "Title: " << (this->Title ? this->Title : "(none)") << "\n"; + os << indent << "Maximum Number Of Colors: " + << this->MaximumNumberOfColors << "\n"; + os << indent << "Number Of Labels: " << this->NumberOfLabels << "\n"; + os << indent << "Number Of Labels Built: " << this->NumberOfLabelsBuilt << "\n"; + + os << indent << "Orientation: "; + if ( this->Orientation == VTK_ORIENT_HORIZONTAL ) + { + os << "Horizontal\n"; + } + else + { + os << "Vertical\n"; + } + + os << indent << "Label Format: " << this->LabelFormat << "\n"; +} + +//---------------------------------------------------------------------------- +void SMESH_ScalarBarActor::ShallowCopy(vtkProp *prop) +{ + SMESH_ScalarBarActor *a = SMESH_ScalarBarActor::SafeDownCast(prop); + if ( a != NULL ) + { + this->SetPosition2(a->GetPosition2()); + this->SetLookupTable(a->GetLookupTable()); + this->SetMaximumNumberOfColors(a->GetMaximumNumberOfColors()); + this->SetOrientation(a->GetOrientation()); + this->SetLabelTextProperty(a->GetLabelTextProperty()); + this->SetTitleTextProperty(a->GetTitleTextProperty()); + this->SetLabelFormat(a->GetLabelFormat()); + this->SetTitle(a->GetTitle()); + this->GetPositionCoordinate()->SetCoordinateSystem( + a->GetPositionCoordinate()->GetCoordinateSystem()); + this->GetPositionCoordinate()->SetValue( + a->GetPositionCoordinate()->GetValue()); + this->GetPosition2Coordinate()->SetCoordinateSystem( + a->GetPosition2Coordinate()->GetCoordinateSystem()); + this->GetPosition2Coordinate()->SetValue( + a->GetPosition2Coordinate()->GetValue()); + } + + // Now do superclass + this->vtkActor2D::ShallowCopy(prop); +} + +//---------------------------------------------------------------------------- +void SMESH_ScalarBarActor::AllocateAndSizeLabels(int *labelSize, + int *size, + vtkViewport *viewport, + double *range) +{ + labelSize[0] = labelSize[1] = 0; + + this->TextMappers = new vtkTextMapper * [this->NumberOfLabels]; + this->TextActors = new vtkActor2D * [this->NumberOfLabels]; + + char string[512]; + + double val; + int i; + + // TODO: this should be optimized, maybe by keeping a list of + // allocated mappers, in order to avoid creation/destruction of + // their underlying text properties (i.e. each time a mapper is + // created, text properties are created and shallow-assigned a font size + // which value might be "far" from the target font size). + + // is this a vtkLookupTable or a subclass of vtkLookupTable + // with its scale set to log + vtkLookupTable *LUT = vtkLookupTable::SafeDownCast( this->LookupTable ); + int isLogTable = 0; + if ( LUT ) + { + if ( LUT->GetScale() == VTK_SCALE_LOG10 ) + { + isLogTable = 1; + } + } + + for (i=0; i < this->NumberOfLabels; i++) + { + this->TextMappers[i] = vtkTextMapper::New(); + + if ( isLogTable ) + { + double lval; + if (this->NumberOfLabels > 1) + { + lval = log10(range[0]) + (double)i/(this->NumberOfLabels-1) * + (log10(range[1])-log10(range[0])); + } + else + { + lval = log10(range[0]) + 0.5*(log10(range[1])-log10(range[0])); + } + val = pow(10.0,lval); + } + else + { + if (this->NumberOfLabels > 1) + { + val = range[0] + + (double)i/(this->NumberOfLabels-1) * (range[1]-range[0]); + } + else + { + val = range[0] + 0.5*(range[1]-range[0]); + } + } + + sprintf(string, this->LabelFormat, val); + this->TextMappers[i]->SetInput(string); + + // Shallow copy here so that the size of the label prop is not affected + // by the automatic adjustment of its text mapper's size (i.e. its + // mapper's text property is identical except for the font size + // which will be modified later). This allows text actors to + // share the same text property, and in that case specifically allows + // the title and label text prop to be the same. + this->TextMappers[i]->GetTextProperty()->ShallowCopy( + this->LabelTextProperty); + + this->TextActors[i] = vtkActor2D::New(); + this->TextActors[i]->SetMapper(this->TextMappers[i]); + this->TextActors[i]->SetProperty(this->GetProperty()); + this->TextActors[i]->GetPositionCoordinate()-> + SetReferenceCoordinate(this->PositionCoordinate); + } + + if (this->NumberOfLabels) + { + int targetWidth, targetHeight; + // rnv begin + // Customization of the vtkScalarBarActor to show distribution histogram. + bool distrVisibility = this->MaximumNumberOfColors == this->myNbValues.size(); + double coef; + if( GetDistributionVisibility() && distrVisibility ) + if(this->Orientation == VTK_ORIENT_VERTICAL) + coef = 0.4; + else + coef = 0.18; + else + if(this->Orientation == VTK_ORIENT_VERTICAL) + coef = 0.6; + else + coef=0.25; + + + if ( this->Orientation == VTK_ORIENT_VERTICAL ) + { + targetWidth = (int)(coef*size[0]); + targetHeight = (int)(0.86*size[1]/this->NumberOfLabels); + } + else + { + targetWidth = (int)(size[0]*0.8/this->NumberOfLabels); + targetHeight = (int)(coef*size[1]); + } + // rnv end + + vtkTextMapper::SetMultipleConstrainedFontSize(viewport, + targetWidth, + targetHeight, + this->TextMappers, + this->NumberOfLabels, + labelSize); + } +} + +//---------------------------------------------------------------------------- +void SMESH_ScalarBarActor::SizeTitle(int *titleSize, + int *size, + vtkViewport *viewport) +{ + titleSize[0] = titleSize[1] = 0; + + if (this->Title == NULL || !strlen(this->Title)) + { + return; + } + + int targetWidth, targetHeight; + + targetWidth = size[0]; + // rnv begin + // Customization of the vtkScalarBarActor to show distribution histogram. + bool distrVisibility = this->MaximumNumberOfColors == this->myNbValues.size(); + double coef; + if( GetDistributionVisibility() && distrVisibility ) + coef=0.18; + else + coef=0.25; + + if ( this->Orientation == VTK_ORIENT_VERTICAL ) + { + targetHeight = (int)(0.1*size[1]); + } + else + { + targetHeight = (int)(coef*size[1]); + } + + this->TitleMapper->SetConstrainedFontSize( + viewport, targetWidth, targetHeight); + + this->TitleMapper->GetSize(viewport, titleSize); +} + + +/*--------------------------------------------------------------------------*/ +void SMESH_ScalarBarActor::SetDistributionVisibility(int flag) { + myDistributionActor->SetVisibility(flag); + Modified(); +} + + +/*--------------------------------------------------------------------------*/ +int SMESH_ScalarBarActor::GetDistributionVisibility() { + return myDistributionActor->GetVisibility(); +} + + +void SMESH_ScalarBarActor::SetDistribution(std::vector theNbValues) { + myNbValues = theNbValues; +} + + +void SMESH_ScalarBarActor::SetDistributionColor (double rgb[3]) { + myDistributionActor->GetProperty()->SetColor(rgb); + Modified(); +} + +void SMESH_ScalarBarActor::GetDistributionColor (double rgb[3]) { + myDistributionActor->GetProperty()->GetColor(rgb); +} diff --git a/src/OBJECT/SMESH_ScalarBarActor.h b/src/OBJECT/SMESH_ScalarBarActor.h new file mode 100644 index 000000000..0f895cd57 --- /dev/null +++ b/src/OBJECT/SMESH_ScalarBarActor.h @@ -0,0 +1,246 @@ +// 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 SCALAR BAR : 2D Actor for the visualization scalar bar with the distribution diagram +// it is customized vtkScalarBarActor. +// File : SMESH_ScalarBarActor.h +// Author : Roman NIKOLAEV +// Module : SMESH + + +// .NAME vtkScalarBarActor - Create a scalar bar with labels +// .SECTION Description +// vtkScalarBarActor creates a scalar bar with annotation text. A scalar +// bar is a legend that indicates to the viewer the correspondence between +// color value and data value. The legend consists of a rectangular bar +// made of rectangular pieces each colored a constant value. Since +// vtkScalarBarActor is a subclass of vtkActor2D, it is drawn in the image +// plane (i.e., in the renderer's viewport) on top of the 3D graphics window. +// +// To use vtkScalarBarActor you must associate a vtkScalarsToColors (or +// subclass) with it. The lookup table defines the colors and the +// range of scalar values used to map scalar data. Typically, the +// number of colors shown in the scalar bar is not equal to the number +// of colors in the lookup table, in which case sampling of +// the lookup table is performed. +// +// Other optional capabilities include specifying the fraction of the +// viewport size (both x and y directions) which will control the size +// of the scalar bar and the number of annotation labels. The actual position +// of the scalar bar on the screen is controlled by using the +// vtkActor2D::SetPosition() method (by default the scalar bar is +// centered in the viewport). Other features include the ability to +// orient the scalar bar horizontally of vertically and controlling +// the format (printf style) with which to print the labels on the +// scalar bar. Also, the vtkScalarBarActor's property is applied to +// the scalar bar and annotation (including layer, and +// compositing operator). +// +// Set the text property/attributes of the title and the labels through the +// vtkTextProperty objects associated to this actor. +// +// .SECTION Caveats +// If a vtkLogLookupTable is specified as the lookup table to use, then the +// labels are created using a logarithmic scale. +// +// .SECTION See Also +// vtkActor2D vtkTextProperty vtkTextMapper vtkPolyDataMapper2D + +#ifndef SMESH_SCALAR_BAR_ACTOR_H +#define SMESH_SCALAR_BAR_ACTOR_H + +#include + +#include + +#include + +class vtkPolyData; +class vtkPolyDataMapper2D; +class vtkScalarsToColors; +class vtkTextMapper; +class vtkTextProperty; + +#define VTK_ORIENT_HORIZONTAL 0 +#define VTK_ORIENT_VERTICAL 1 + +#define SMESH_MONOCOLOR_TYPE 0 +#define SMESH_MULTICOLOR_TYPE 1 + + +class SMESHOBJECT_EXPORT SMESH_ScalarBarActor: public vtkActor2D { + public: + void PrintSelf(ostream& os, vtkIndent indent); + + vtkTypeMacro(SMESH_ScalarBarActor,vtkActor2D); + + // Description: + // Instantiate object with 64 maximum colors; 5 labels; %%-#6.3g label + // format, no title, and vertical orientation. The initial scalar bar + // size is (0.05 x 0.8) of the viewport size. + static SMESH_ScalarBarActor *New(); + + // Description: + // Draw the scalar bar and annotation text to the screen. + int RenderOpaqueGeometry(vtkViewport* viewport); + int RenderTranslucentGeometry(vtkViewport*) { return 0; }; + int RenderOverlay(vtkViewport* viewport); + + // Description: + // Release any graphics resources that are being consumed by this actor. + // The parameter window could be used to determine which graphic + // resources to release. + virtual void ReleaseGraphicsResources(vtkWindow *); + + // Description: + // Set/Get the vtkLookupTable to use. The lookup table specifies the number + // of colors to use in the table (if not overridden), as well as the scalar + // range. + virtual void SetLookupTable(vtkScalarsToColors*); + vtkGetObjectMacro(LookupTable,vtkScalarsToColors); + + // Description: + // Set/Get the maximum number of scalar bar segments to show. This may + // differ from the number of colors in the lookup table, in which case + // the colors are samples from the lookup table. + vtkSetClampMacro(MaximumNumberOfColors, int, 2, VTK_LARGE_INTEGER); + vtkGetMacro(MaximumNumberOfColors, int); + + // Description: + // Set/Get the number of annotation labels to show. + vtkSetClampMacro(NumberOfLabels, int, 0, 64); + vtkGetMacro(NumberOfLabels, int); + + // Description: + // Control the orientation of the scalar bar. + vtkSetClampMacro(Orientation,int,VTK_ORIENT_HORIZONTAL, VTK_ORIENT_VERTICAL); + vtkGetMacro(Orientation, int); + void SetOrientationToHorizontal() + {this->SetOrientation(VTK_ORIENT_HORIZONTAL);}; + void SetOrientationToVertical() {this->SetOrientation(VTK_ORIENT_VERTICAL);}; + + // Description: + // Set/Get the title text property. + virtual void SetTitleTextProperty(vtkTextProperty *p); + vtkGetObjectMacro(TitleTextProperty,vtkTextProperty); + + // Description: + // Set/Get the labels text property. + virtual void SetLabelTextProperty(vtkTextProperty *p); + vtkGetObjectMacro(LabelTextProperty,vtkTextProperty); + + // Description: + // Set/Get the format with which to print the labels on the scalar + // bar. + vtkSetStringMacro(LabelFormat); + vtkGetStringMacro(LabelFormat); + + // Description: + // Set/Get the title of the scalar bar actor, + vtkSetStringMacro(Title); + vtkGetStringMacro(Title); + + // Description: + // Shallow copy of a scalar bar actor. Overloads the virtual vtkProp method. + void ShallowCopy(vtkProp *prop); + + // Description: + // Set visibility of the distribution histogram + // rnv: Customization of the vtkScalarBarActor to show distribution histogram: + virtual void SetDistributionVisibility(int flag); + + // Description: + // Set visibility of the distribution histogram + // rnv: Customization of the vtkScalarBarActor to show distribution histogram: + virtual int GetDistributionVisibility(); + // Description: + // Set distribution + virtual void SetDistribution(std::vector theNbValues); + + // Description: + // Set distribution coloring type (SMESH_MONOCOLOR_TYPE or SMESH_MULTICOLOR_TYPE) + void SetDistributionColoringType(int theDistributionColoringType) {myDistributionColoringType = theDistributionColoringType;Modified();} + + // Description: + // Get distribution coloring type ((SMESH_MONOCOLOR_TYPE or SMESH_MULTICOLOR_TYPE)) + int GetDistributionColoringType() {return myDistributionColoringType;} + + // Description: + // Set Distribution Color + void SetDistributionColor (double rgb[3]); + + // Description: + // Get Distribution Color + void GetDistributionColor (double rgb[3]); + + + + protected: + SMESH_ScalarBarActor(); + ~SMESH_ScalarBarActor(); + + vtkScalarsToColors *LookupTable; + vtkTextProperty *TitleTextProperty; + vtkTextProperty *LabelTextProperty; + + int MaximumNumberOfColors; + int NumberOfLabels; + int NumberOfLabelsBuilt; + int Orientation; + char *Title; + char *LabelFormat; + + vtkTextMapper **TextMappers; + virtual void AllocateAndSizeLabels(int *labelSize, int *size, + vtkViewport *viewport, double *range); + + + + private: + vtkTextMapper *TitleMapper; + vtkActor2D *TitleActor; + + vtkActor2D **TextActors; + + vtkPolyData *ScalarBar; + vtkPolyDataMapper2D *ScalarBarMapper; + vtkActor2D *ScalarBarActor; + + vtkTimeStamp BuildTime; + int LastSize[2]; + int LastOrigin[2]; + + void SizeTitle(int *titleSize, int *size, vtkViewport *viewport); + + // rnv: Customization of the vtkScalarBarActor to show distribution histogram: + vtkPolyData* myDistribution; //Distribution polygonal data + vtkActor2D* myDistributionActor; //Distribution actor + vtkPolyDataMapper2D* myDistributionMapper; //Distribution mapper + std::vector myNbValues; //Nb values for the range + int myDistributionColoringType; //Distribution color type (monocolor or multicolor) + + private: + SMESH_ScalarBarActor(const SMESH_ScalarBarActor&); // Not implemented. + void operator=(const SMESH_ScalarBarActor&); // Not implemented. +}; + +#endif //SMESH_SCALAR_BAR_ACTOR_H diff --git a/src/PluginUtils/GeomSelectionTools.cxx b/src/PluginUtils/GeomSelectionTools.cxx index ceafd175d..45d5c42a3 100644 --- a/src/PluginUtils/GeomSelectionTools.cxx +++ b/src/PluginUtils/GeomSelectionTools.cxx @@ -297,5 +297,47 @@ GeomAbs_SurfaceType GeomSelectionTools::getFaceInformation(TopoDS_Shape S) } +////////////////////////////////////////// +// Utility functions +////////////////////////////////////////// +#include +#include +QString PluginUtils::PrintDoubleValue( double theValue, int thePrecision ) +{ + const double prec = 1e-12; + + if ( qAbs(theValue) < prec ) + return "0"; + + QString aRes = QLocale().toString( theValue, thePrecision >= 0 ? 'f' : 'g', qAbs( thePrecision ) ); + + if ( prec > 0 ) { + int p = 0; + while ( p < thePrecision ) { + QString aRes = QLocale().toString( theValue, thePrecision >= 0 ? 'f' : 'g', qAbs( p++ ) ); + double v = aRes.toDouble(); + double err = qAbs( theValue - v ); + if ( err > 0 && err <= prec ) + break; + } + } + + // remove trailing zeroes + + QRegExp expre( QString( "(%1|%2)[+-]?[0-9]+$" ).arg( QLocale().exponential().toLower(), + QLocale().exponential().toUpper() ) ); + + int idx = aRes.indexOf( expre ); + QString aResExp = ""; + if ( idx >= 0 ) { + aResExp = aRes.mid( idx ); + aRes = aRes.left( idx ); + } + + if ( aRes.contains( QLocale().decimalPoint() ) ) + aRes.remove( QRegExp( QString( "(\\%1|0)0*$" ).arg( QLocale().decimalPoint() ) ) ); + + return aRes == "-0" ? QString( "0" ) : aRes + aResExp; +} diff --git a/src/PluginUtils/GeomSelectionTools.h b/src/PluginUtils/GeomSelectionTools.h index 0995556f1..d00a2ba22 100644 --- a/src/PluginUtils/GeomSelectionTools.h +++ b/src/PluginUtils/GeomSelectionTools.h @@ -78,6 +78,14 @@ public: _PTR(Study) getMyStudy(); }; +////////////////////////////////////////// +// Utility functions +////////////////////////////////////////// + +namespace PluginUtils +{ + GEOMSELECTIONTOOLS_EXPORT QString PrintDoubleValue( double, int = 16 ); +}; #endif // _GEOMSELECTIONTOOLS_H_ diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index 408ad1f0e..d3d41b135 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -2191,12 +2191,18 @@ namespace { class IdSortedIterator : public SMDS_Iterator { const SMDS_MeshElementIDFactory& myIDFact; - int myID, myMaxID; + int myID, myMaxID, myNbFound, myTotalNb; + SMDSAbs_ElementType myType; ELEM myElem; public: - IdSortedIterator(const SMDS_MeshElementIDFactory& fact) - :myIDFact( fact ), myID(1), myMaxID( myIDFact.GetMaxID() ), myElem(0) + IdSortedIterator(const SMDS_MeshElementIDFactory& fact, + const SMDSAbs_ElementType type, // SMDSAbs_All NOT allowed!!! + const int totalNb) + :myIDFact( fact ), + myID(1), myMaxID( myIDFact.GetMaxID() ),myNbFound(0), myTotalNb( totalNb ), + myType( type ), + myElem(0) { next(); } @@ -2207,8 +2213,14 @@ namespace { ELEM next() { ELEM current = myElem; - for ( myElem = 0; myID <= myMaxID && !myElem; ++myID ) - myElem = (ELEM) myIDFact.MeshElement( myID ); + + for ( myElem = 0; !myElem && myNbFound < myTotalNb && myID <= myMaxID; ++myID ) + if ((myElem = (ELEM) myIDFact.MeshElement( myID )) + && myElem->GetType() != myType ) + myElem = 0; + + myNbFound += bool(myElem); + return current; } }; @@ -2224,7 +2236,7 @@ SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const < SetOfNodes, const SMDS_MeshNode*, SMDS_NodeIterator > TIterator; typedef IdSortedIterator< const SMDS_MeshNode* > TSortedIterator; return ( idInceasingOrder ? - SMDS_NodeIteratorPtr( new TSortedIterator( *myNodeIDFactory )) : + SMDS_NodeIteratorPtr( new TSortedIterator( *myNodeIDFactory, SMDSAbs_Node, NbNodes())) : SMDS_NodeIteratorPtr( new TIterator(myNodes))); } @@ -2232,44 +2244,64 @@ SMDS_NodeIteratorPtr SMDS_Mesh::nodesIterator(bool idInceasingOrder) const ///Return an iterator on 0D elements of the current mesh. /////////////////////////////////////////////////////////////////////////////// -SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator() const +SMDS_0DElementIteratorPtr SMDS_Mesh::elements0dIterator(bool idInceasingOrder) const { typedef MYNCollection_Map_Iterator < SetOf0DElements, const SMDS_Mesh0DElement*, SMDS_0DElementIterator > TIterator; - return SMDS_0DElementIteratorPtr(new TIterator(my0DElements)); + typedef IdSortedIterator< const SMDS_Mesh0DElement* > TSortedIterator; + return ( idInceasingOrder ? + SMDS_0DElementIteratorPtr( new TSortedIterator( *myElementIDFactory, + SMDSAbs_0DElement, + Nb0DElements() )) : + SMDS_0DElementIteratorPtr( new TIterator(my0DElements))); } /////////////////////////////////////////////////////////////////////////////// ///Return an iterator on edges of the current mesh. /////////////////////////////////////////////////////////////////////////////// -SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator() const +SMDS_EdgeIteratorPtr SMDS_Mesh::edgesIterator(bool idInceasingOrder) const { typedef MYNCollection_Map_Iterator < SetOfEdges, const SMDS_MeshEdge*, SMDS_EdgeIterator > TIterator; - return SMDS_EdgeIteratorPtr(new TIterator(myEdges)); + typedef IdSortedIterator< const SMDS_MeshEdge* > TSortedIterator; + return ( idInceasingOrder ? + SMDS_EdgeIteratorPtr( new TSortedIterator( *myElementIDFactory, + SMDSAbs_Edge, + NbEdges() )) : + SMDS_EdgeIteratorPtr(new TIterator(myEdges))); } /////////////////////////////////////////////////////////////////////////////// ///Return an iterator on faces of the current mesh. /////////////////////////////////////////////////////////////////////////////// -SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator() const +SMDS_FaceIteratorPtr SMDS_Mesh::facesIterator(bool idInceasingOrder) const { typedef MYNCollection_Map_Iterator < SetOfFaces, const SMDS_MeshFace*, SMDS_FaceIterator > TIterator; - return SMDS_FaceIteratorPtr(new TIterator(myFaces)); + typedef IdSortedIterator< const SMDS_MeshFace* > TSortedIterator; + return ( idInceasingOrder ? + SMDS_FaceIteratorPtr( new TSortedIterator( *myElementIDFactory, + SMDSAbs_Face, + NbFaces() )) : + SMDS_FaceIteratorPtr(new TIterator(myFaces))); } /////////////////////////////////////////////////////////////////////////////// ///Return an iterator on volumes of the current mesh. /////////////////////////////////////////////////////////////////////////////// -SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator() const +SMDS_VolumeIteratorPtr SMDS_Mesh::volumesIterator(bool idInceasingOrder) const { typedef MYNCollection_Map_Iterator < SetOfVolumes, const SMDS_MeshVolume*, SMDS_VolumeIterator > TIterator; - return SMDS_VolumeIteratorPtr(new TIterator(myVolumes)); + typedef IdSortedIterator< const SMDS_MeshVolume* > TSortedIterator; + return ( idInceasingOrder ? + SMDS_VolumeIteratorPtr( new TSortedIterator( *myElementIDFactory, + SMDSAbs_Volume, + NbVolumes() )) : + SMDS_VolumeIteratorPtr(new TIterator(myVolumes))); } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/SMDS/SMDS_Mesh.hxx b/src/SMDS/SMDS_Mesh.hxx index 36f7e37c1..e9397b6a2 100644 --- a/src/SMDS/SMDS_Mesh.hxx +++ b/src/SMDS/SMDS_Mesh.hxx @@ -48,11 +48,11 @@ public: SMDS_Mesh(); - SMDS_NodeIteratorPtr nodesIterator(bool idInceasingOrder=false) const; - SMDS_0DElementIteratorPtr elements0dIterator() const; - SMDS_EdgeIteratorPtr edgesIterator() const; - SMDS_FaceIteratorPtr facesIterator() const; - SMDS_VolumeIteratorPtr volumesIterator() const; + SMDS_NodeIteratorPtr nodesIterator (bool idInceasingOrder=false) const; + SMDS_0DElementIteratorPtr elements0dIterator(bool idInceasingOrder=false) const; + SMDS_EdgeIteratorPtr edgesIterator (bool idInceasingOrder=false) const; + SMDS_FaceIteratorPtr facesIterator (bool idInceasingOrder=false) const; + SMDS_VolumeIteratorPtr volumesIterator (bool idInceasingOrder=false) const; SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type=SMDSAbs_All) const; SMDSAbs_ElementType GetElementType( const int id, const bool iselem ) const; diff --git a/src/SMDS/SMDS_MeshElement.hxx b/src/SMDS/SMDS_MeshElement.hxx index 938abf0b2..593b7fe00 100644 --- a/src/SMDS/SMDS_MeshElement.hxx +++ b/src/SMDS/SMDS_MeshElement.hxx @@ -69,7 +69,7 @@ public: ///Return the type of the current element virtual SMDSAbs_ElementType GetType() const = 0; - virtual bool IsPoly() const { return false; }; + virtual bool IsPoly() const { return false; } virtual bool IsQuadratic() const; //! Return type of entity virtual SMDSAbs_EntityType GetEntityType() const = 0; diff --git a/src/SMDS/SMDS_MeshNode.cxx b/src/SMDS/SMDS_MeshNode.cxx index 73610b661..9df6348a5 100644 --- a/src/SMDS/SMDS_MeshNode.cxx +++ b/src/SMDS/SMDS_MeshNode.cxx @@ -239,11 +239,6 @@ void SMDS_MeshNode::ClearInverseElements() myInverseElements.Clear(); } -bool SMDS_MeshNode::emptyInverseElements() -{ - return myInverseElements.IsEmpty() != Standard_False; -} - //================================================================================ /*! * \brief Count inverse elements of given type diff --git a/src/SMDS/SMDS_MeshNode.hxx b/src/SMDS/SMDS_MeshNode.hxx index 2d932f355..9ab02f20f 100644 --- a/src/SMDS/SMDS_MeshNode.hxx +++ b/src/SMDS/SMDS_MeshNode.hxx @@ -38,23 +38,26 @@ class SMDS_EXPORT SMDS_MeshNode:public SMDS_MeshElement public: SMDS_MeshNode(double x, double y, double z); - void Print(std::ostream & OS) const; + double X() const; double Y() const; double Z() const; + void setXYZ(double x, double y, double z); + void AddInverseElement(const SMDS_MeshElement * ME); void RemoveInverseElement(const SMDS_MeshElement * parent); void ClearInverseElements(); - bool emptyInverseElements(); SMDS_ElemIteratorPtr GetInverseElementIterator(SMDSAbs_ElementType type=SMDSAbs_All) const; int NbInverseElements(SMDSAbs_ElementType type=SMDSAbs_All) const; + void SetPosition(const SMDS_PositionPtr& aPos); const SMDS_PositionPtr& GetPosition() const; + SMDSAbs_ElementType GetType() const; SMDSAbs_EntityType GetEntityType() const {return SMDSEntity_Node;} - int NbNodes() const; - void setXYZ(double x, double y, double z); + friend bool operator<(const SMDS_MeshNode& e1, const SMDS_MeshNode& e2); + void Print(std::ostream & OS) const; /*! * \brief Return node by its index @@ -62,6 +65,7 @@ public: * \retval const SMDS_MeshNode* - the node */ virtual const SMDS_MeshNode* GetNode(const int) const { return this; } + virtual int NbNodes() const; protected: SMDS_ElemIteratorPtr diff --git a/src/SMDS/SMDS_VolumeTool.cxx b/src/SMDS/SMDS_VolumeTool.cxx index 52633d610..42640287c 100644 --- a/src/SMDS/SMDS_VolumeTool.cxx +++ b/src/SMDS/SMDS_VolumeTool.cxx @@ -518,8 +518,10 @@ bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume) // define volume orientation XYZ botNormal; GetFaceNormal( 0, botNormal.x, botNormal.y, botNormal.z ); - const SMDS_MeshNode* topNode = myVolumeNodes[ myVolumeNbNodes - 1 ]; const SMDS_MeshNode* botNode = myVolumeNodes[ 0 ]; + int topNodeIndex = myVolume->NbCornerNodes() - 1; + while ( !IsLinked( 0, topNodeIndex, /*ignoreMediumNodes=*/true )) --topNodeIndex; + const SMDS_MeshNode* topNode = myVolumeNodes[ topNodeIndex ]; XYZ upDir (topNode->X() - botNode->X(), topNode->Y() - botNode->Y(), topNode->Z() - botNode->Z() ); @@ -1024,6 +1026,27 @@ bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, doub return true; } +//================================================================================ +/*! + * \brief Return barycenter of a face + */ +//================================================================================ + +bool SMDS_VolumeTool::GetFaceBaryCenter (int faceIndex, double & X, double & Y, double & Z) +{ + if ( !setFace( faceIndex )) + return false; + + X = Y = Z = 0.0; + for ( int i = 0; i < myFaceNbNodes; ++i ) + { + X += myFaceNodes[i]->X() / myFaceNbNodes; + Y += myFaceNodes[i]->Y() / myFaceNbNodes; + Z += myFaceNodes[i]->Z() / myFaceNbNodes; + } + return true; +} + //======================================================================= //function : GetFaceArea //purpose : Return face area @@ -1085,10 +1108,12 @@ int SMDS_VolumeTool::GetOppFaceIndex( int faceIndex ) const //======================================================================= //function : IsLinked //purpose : return true if theNode1 is linked with theNode2 +// If theIgnoreMediumNodes then corner nodes of quadratic cell are considered linked as well //======================================================================= bool SMDS_VolumeTool::IsLinked (const SMDS_MeshNode* theNode1, - const SMDS_MeshNode* theNode2) const + const SMDS_MeshNode* theNode2, + const bool theIgnoreMediumNodes) const { if ( !myVolume ) return false; @@ -1135,10 +1160,12 @@ bool SMDS_VolumeTool::IsLinked (const SMDS_MeshNode* theNode1, //function : IsLinked //purpose : return true if the node with theNode1Index is linked // with the node with theNode2Index +// If theIgnoreMediumNodes then corner nodes of quadratic cell are considered linked as well //======================================================================= bool SMDS_VolumeTool::IsLinked (const int theNode1Index, - const int theNode2Index) const + const int theNode2Index, + bool theIgnoreMediumNodes) const { if ( myVolume->IsPoly() ) { return IsLinked(myVolumeNodes[theNode1Index], myVolumeNodes[theNode2Index]); @@ -1150,10 +1177,31 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index, if ( minInd < 0 || maxInd > myVolumeNbNodes - 1 || maxInd == minInd ) return false; - switch ( myVolumeNbNodes ) { - case 4: + SMDSAbs_EntityType type = myVolume->GetEntityType(); + if ( myVolume->IsQuadratic() ) + { + int firstMediumInd = myVolume->NbCornerNodes(); + if ( minInd >= firstMediumInd ) + return false; // medium nodes are not linked + if ( maxInd < firstMediumInd ) // both nodes are corners + if ( theIgnoreMediumNodes ) + type = SMDSAbs_EntityType( int(type)-1 ); // check linkage of corner nodes + else + return false; // corner nodes are not linked directly in a quadratic cell + } + + switch ( type ) { + case SMDSEntity_Tetra: return true; - case 5: + case SMDSEntity_Hexa: + switch ( maxInd - minInd ) { + case 1: return minInd != 3; + case 3: return minInd == 0 || minInd == 4; + case 4: return true; + default:; + } + break; + case SMDSEntity_Pyramid: if ( maxInd == 4 ) return true; switch ( maxInd - minInd ) { @@ -1162,7 +1210,7 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index, default:; } break; - case 6: + case SMDSEntity_Penta: switch ( maxInd - minInd ) { case 1: return minInd != 2; case 2: return minInd == 0 || minInd == 3; @@ -1170,15 +1218,7 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index, default:; } break; - case 8: - switch ( maxInd - minInd ) { - case 1: return minInd != 3; - case 3: return minInd == 0 || minInd == 4; - case 4: return true; - default:; - } - break; - case 10: + case SMDSEntity_Quad_Tetra: { switch ( minInd ) { case 0: if( maxInd==4 || maxInd==6 || maxInd==7 ) return true; @@ -1189,7 +1229,22 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index, } break; } - case 13: + case SMDSEntity_Quad_Hexa: + { + switch ( minInd ) { + case 0: if( maxInd==8 || maxInd==11 || maxInd==16 ) return true; + case 1: if( maxInd==8 || maxInd==9 || maxInd==17 ) return true; + case 2: if( maxInd==9 || maxInd==10 || maxInd==18 ) return true; + case 3: if( maxInd==10 || maxInd==11 || maxInd==19 ) return true; + case 4: if( maxInd==12 || maxInd==15 || maxInd==16 ) return true; + case 5: if( maxInd==12 || maxInd==13 || maxInd==17 ) return true; + case 6: if( maxInd==13 || maxInd==14 || maxInd==18 ) return true; + case 7: if( maxInd==14 || maxInd==15 || maxInd==19 ) return true; + default:; + } + break; + } + case SMDSEntity_Quad_Pyramid: { switch ( minInd ) { case 0: if( maxInd==5 || maxInd==8 || maxInd==9 ) return true; @@ -1201,7 +1256,7 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index, } break; } - case 15: + case SMDSEntity_Quad_Penta: { switch ( minInd ) { case 0: if( maxInd==6 || maxInd==8 || maxInd==12 ) return true; @@ -1214,21 +1269,6 @@ bool SMDS_VolumeTool::IsLinked (const int theNode1Index, } break; } - case 20: - { - switch ( minInd ) { - case 0: if( maxInd==8 || maxInd==11 || maxInd==16 ) return true; - case 1: if( maxInd==8 || maxInd==9 || maxInd==17 ) return true; - case 2: if( maxInd==9 || maxInd==10 || maxInd==18 ) return true; - case 3: if( maxInd==10 || maxInd==11 || maxInd==19 ) return true; - case 4: if( maxInd==12 || maxInd==15 || maxInd==16 ) return true; - case 5: if( maxInd==12 || maxInd==13 || maxInd==17 ) return true; - case 6: if( maxInd==13 || maxInd==14 || maxInd==18 ) return true; - case 7: if( maxInd==14 || maxInd==15 || maxInd==19 ) return true; - default:; - } - break; - } default:; } return false; diff --git a/src/SMDS/SMDS_VolumeTool.hxx b/src/SMDS/SMDS_VolumeTool.hxx index 6791fb9c7..8d82a6091 100644 --- a/src/SMDS/SMDS_VolumeTool.hxx +++ b/src/SMDS/SMDS_VolumeTool.hxx @@ -102,13 +102,17 @@ class SMDS_EXPORT SMDS_VolumeTool // ----------------------- bool IsLinked (const SMDS_MeshNode* theNode1, - const SMDS_MeshNode* theNode2) const; + const SMDS_MeshNode* theNode2, + const bool theIgnoreMediumNodes=false) const; // Return true if theNode1 is linked with theNode2. + // If theIgnoreMediumNodes then corner nodes of quadratic cell are considered linked as well bool IsLinked (const int theNode1Index, - const int theNode2Index) const; + const int theNode2Index, + bool theIgnoreMediumNodes=false) const; // Return true if the node with theNode1Index is linked // with the node with theNode2Index + // If theIgnoreMediumNodes then corner nodes of quadratic cell are considered linked as well int GetNodeIndex(const SMDS_MeshNode* theNode) const; // Return an index of theNode @@ -158,6 +162,9 @@ class SMDS_EXPORT SMDS_VolumeTool bool GetFaceNormal (int faceIndex, double & X, double & Y, double & Z); // Return a normal to a face + bool GetFaceBaryCenter (int faceIndex, double & X, double & Y, double & Z); + // Return barycenter of a face + double GetFaceArea( int faceIndex ); // Return face area diff --git a/src/SMESH/SMESH_Algo.cxx b/src/SMESH/SMESH_Algo.cxx index 671e2660f..3a6a4efd9 100644 --- a/src/SMESH/SMESH_Algo.cxx +++ b/src/SMESH/SMESH_Algo.cxx @@ -492,7 +492,11 @@ bool SMESH_Algo::InitCompatibleHypoFilter( SMESH_HypoFilter & theFilter, GeomAbs_Shape SMESH_Algo::Continuity(TopoDS_Edge E1, TopoDS_Edge E2) { - E1.Orientation(TopAbs_FORWARD), E2.Orientation(TopAbs_FORWARD); // avoid pb with internal edges + //E1.Orientation(TopAbs_FORWARD), E2.Orientation(TopAbs_FORWARD); // avoid pb with internal edges + if (E1.Orientation() > TopAbs_REVERSED) // INTERNAL + E1.Orientation( TopAbs_FORWARD ); + if (E2.Orientation() > TopAbs_REVERSED) // INTERNAL + E2.Orientation( TopAbs_FORWARD ); TopoDS_Vertex V = TopExp::LastVertex (E1, true); if ( !V.IsSame( TopExp::FirstVertex(E2, true ))) if ( !TopExp::CommonVertex( E1, E2, V )) diff --git a/src/SMESH/SMESH_Algo.hxx b/src/SMESH/SMESH_Algo.hxx index 03c0b7bdb..83b34c3a9 100644 --- a/src/SMESH/SMESH_Algo.hxx +++ b/src/SMESH/SMESH_Algo.hxx @@ -86,14 +86,14 @@ public: /*! * \brief Saves nothing in a stream * \param save - the stream - * \retval virtual std::ostream & - the stream + * \retval std::ostream & - the stream */ virtual std::ostream & SaveTo(std::ostream & save); /*! * \brief Loads nothing from a stream * \param load - the stream - * \retval virtual std::ostream & - the stream + * \retval std::ostream & - the stream */ virtual std::istream & LoadFrom(std::istream & load); @@ -236,7 +236,7 @@ public: * * This method is called when a submesh gets HYP_OK algo_state. * After being set, event listener is notified on each event of a submesh. - * By default non listener is set + * By default none listener is set */ virtual void SetEventListener(SMESH_subMesh* subMesh); @@ -323,7 +323,8 @@ public: */ static std::vector< const SMDS_MeshNode*> GetCommonNodes(const SMDS_MeshElement* e1, const SMDS_MeshElement* e2); -protected: + + protected: /*! * \brief store error and comment and then return ( error == COMPERR_OK ) diff --git a/src/SMESH/SMESH_Block.cxx b/src/SMESH/SMESH_Block.cxx index b26cfbd9a..6d20d6be8 100644 --- a/src/SMESH/SMESH_Block.cxx +++ b/src/SMESH/SMESH_Block.cxx @@ -960,7 +960,7 @@ int SMESH_Block::GetShapeIDByParams ( const gp_XYZ& theCoord ) * \param theFirstVertex - the vertex of the outer wire to set first in the returned * list ( theFirstVertex may be NULL ) * \param theEdges - all ordered edges of theFace (outer edges goes first). - * \param theNbVertexInWires - nb of vertices (== nb of edges) in each wire + * \param theNbEdgesInWires - nb of edges (== nb of vertices in closed wire) in each wire * \param theShapeAnalysisAlgo - if true, ShapeAnalysis::OuterWire() is used to find * the outer wire else BRepTools::OuterWire() is used. * \retval int - nb of wires @@ -974,7 +974,7 @@ int SMESH_Block::GetShapeIDByParams ( const gp_XYZ& theCoord ) int SMESH_Block::GetOrderedEdges (const TopoDS_Face& theFace, TopoDS_Vertex theFirstVertex, list< TopoDS_Edge >& theEdges, - list< int > & theNbVertexInWires, + list< int > & theNbEdgesInWires, const bool theShapeAnalysisAlgo) { // put wires in a list, so that an outer wire comes first @@ -991,7 +991,7 @@ int SMESH_Block::GetOrderedEdges (const TopoDS_Face& theFace, } // loop on edges of wires - theNbVertexInWires.clear(); + theNbEdgesInWires.clear(); list::iterator wlIt = aWireList.begin(); for ( ; wlIt != aWireList.end(); wlIt++ ) { @@ -1009,7 +1009,7 @@ int SMESH_Block::GetOrderedEdges (const TopoDS_Face& theFace, for ( TopoDS_Iterator e( *wlIt ); e.More(); e.Next(), ++iE ) theEdges.push_back( TopoDS::Edge( e.Value() )); } - theNbVertexInWires.push_back( iE ); + theNbEdgesInWires.push_back( iE ); iE = 0; if ( wlIt == aWireList.begin() && theEdges.size() > 1 ) { // the outer wire // orient closed edges @@ -1047,7 +1047,7 @@ int SMESH_Block::GetOrderedEdges (const TopoDS_Face& theFace, theEdges.splice(theEdges.end(), theEdges, theEdges.begin(), ++theEdges.begin()); TopExp::Vertices( theEdges.front(), vv[0], vv[1], true ); - if ( iE++ > theNbVertexInWires.back() ) { + if ( iE++ > theNbEdgesInWires.back() ) { #ifdef _DEBUG_ gp_Pnt p = BRep_Tool::Pnt( theFirstVertex ); MESSAGE ( " : Warning : vertex "<< theFirstVertex.TShape().operator->() diff --git a/src/SMESH/SMESH_Block.hxx b/src/SMESH/SMESH_Block.hxx index f3d951069..4851c0eaf 100644 --- a/src/SMESH/SMESH_Block.hxx +++ b/src/SMESH/SMESH_Block.hxx @@ -277,7 +277,7 @@ public: static int GetOrderedEdges (const TopoDS_Face& theFace, TopoDS_Vertex theFirstVertex, std::list< TopoDS_Edge >& theEdges, - std::list< int > & theNbVertexInWires, + std::list< int > & theNbEdgesInWires, const bool theShapeAnalysisAlgo=false); // Return nb wires and a list of oredered edges. // It is used to assign indices to subshapes. diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index f2c7f2eef..47947add9 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -191,7 +191,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, } // ------------------------------------------------------------ - // sort list of meshes according to mesh order + // sort list of submeshes according to mesh order // ------------------------------------------------------------ aMesh.SortByMeshOrder( smWithAlgoSupportingSubmeshes ); diff --git a/src/SMESH/SMESH_Group.cxx b/src/SMESH/SMESH_Group.cxx index 4d88aed63..b2f5a125d 100644 --- a/src/SMESH/SMESH_Group.cxx +++ b/src/SMESH/SMESH_Group.cxx @@ -63,5 +63,5 @@ SMESH_Group::SMESH_Group (int theID, SMESH_Group::~SMESH_Group () { - delete myGroupDS; + delete myGroupDS; myGroupDS=0; } diff --git a/src/SMESH/SMESH_Group.hxx b/src/SMESH/SMESH_Group.hxx index 8d942bce4..c3e62ad2a 100644 --- a/src/SMESH/SMESH_Group.hxx +++ b/src/SMESH/SMESH_Group.hxx @@ -24,7 +24,6 @@ // File : SMESH_Group.hxx // Author : Michael Sazonov (OCC) // Module : SMESH -// $Header$ // #ifndef _SMESH_Group_HeaderFile #define _SMESH_Group_HeaderFile diff --git a/src/SMESH/SMESH_HypoFilter.cxx b/src/SMESH/SMESH_HypoFilter.cxx index 1f6685d15..397d8a753 100644 --- a/src/SMESH/SMESH_HypoFilter.cxx +++ b/src/SMESH/SMESH_HypoFilter.cxx @@ -23,13 +23,16 @@ // SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_HypoFilter.cxx // Module : SMESH -// $Header$ // #include "SMESH_HypoFilter.hxx" +#include "SMESH_Gen.hxx" #include "SMESH_Hypothesis.hxx" +#include "SMESH_MesherHelper.hxx" #include "SMESH_subMesh.hxx" +#include + using namespace std; @@ -113,7 +116,7 @@ bool SMESH_HypoFilter::InstancePredicate::IsOk(const SMESH_Hypothesis* aHyp, //======================================================================= bool SMESH_HypoFilter::IsAssignedToPredicate::IsOk(const SMESH_Hypothesis* aHyp, - const TopoDS_Shape& aShape) const + const TopoDS_Shape& aShape) const { return ( !_mainShape.IsNull() && !aShape.IsNull() && _mainShape.IsSame( aShape )); } @@ -126,7 +129,19 @@ bool SMESH_HypoFilter::IsAssignedToPredicate::IsOk(const SMESH_Hypothesis* aHyp, bool SMESH_HypoFilter::IsMoreLocalThanPredicate::IsOk(const SMESH_Hypothesis* aHyp, const TopoDS_Shape& aShape) const { - return ( aShape.ShapeType() > _shapeType ); + if ( SMESH_MesherHelper::IsSubShape( aShape, /*mainShape=*/_shape )) + return true; + + if ( aShape.ShapeType() == TopAbs_COMPOUND && + !SMESH_MesherHelper::IsSubShape( _shape, /*mainShape=*/aShape)) // issue 0020963 + { + for ( int type = TopAbs_SOLID; type < TopAbs_SHAPE; ++type ) + if ( aHyp->GetDim() == SMESH_Gen::GetShapeDim( TopAbs_ShapeEnum( type ))) + for ( TopExp_Explorer exp( aShape, TopAbs_ShapeEnum( type )); exp.More(); exp.Next()) + if ( SMESH_MesherHelper::IsSubShape( exp.Current(), /*mainShape=*/_shape )) + return true; + } + return false; } //======================================================================= @@ -347,3 +362,5 @@ SMESH_HypoFilter::~SMESH_HypoFilter() Init(0); } + + diff --git a/src/SMESH/SMESH_HypoFilter.hxx b/src/SMESH/SMESH_HypoFilter.hxx index 0fb043e57..e7c7c274b 100644 --- a/src/SMESH/SMESH_HypoFilter.hxx +++ b/src/SMESH/SMESH_HypoFilter.hxx @@ -23,7 +23,6 @@ // SMESH SMESH : implementaion of SMESH idl descriptions // File : SMESH_HypoFilter.hxx // Module : SMESH -// $Header$ // #ifndef SMESH_HypoFilter_HeaderFile #define SMESH_HypoFilter_HeaderFile @@ -78,6 +77,8 @@ class SMESH_EXPORT SMESH_HypoFilter: public SMESH_HypoPredicate static SMESH_HypoPredicate* HasDim(const int theDim); static SMESH_HypoPredicate* HasType(const int theHypType); + bool IsEmpty() const { return myPredicates.empty(); } + /*! * \brief check aHyp or/and aShape it is assigned to */ @@ -168,8 +169,8 @@ class SMESH_EXPORT SMESH_HypoFilter: public SMESH_HypoPredicate }; struct IsMoreLocalThanPredicate : public SMESH_HypoPredicate { - TopAbs_ShapeEnum _shapeType; - IsMoreLocalThanPredicate( const TopoDS_Shape& shape ):_shapeType(shape.ShapeType()){} + TopoDS_Shape _shape; + IsMoreLocalThanPredicate( const TopoDS_Shape& shape ):_shape(shape){} bool IsOk(const SMESH_Hypothesis* aHyp, const TopoDS_Shape& aShape) const; }; diff --git a/src/SMESH/SMESH_Hypothesis.cxx b/src/SMESH/SMESH_Hypothesis.cxx index 8210f156d..9ababf9e4 100644 --- a/src/SMESH/SMESH_Hypothesis.cxx +++ b/src/SMESH/SMESH_Hypothesis.cxx @@ -151,6 +151,24 @@ void SMESH_Hypothesis::SetLibName(const char* theLibName) _libName = string(theLibName); } +//======================================================================= +//function : GetMeshByPersistentID +//purpose : Find a mesh with given persistent ID +//======================================================================= + +SMESH_Mesh* SMESH_Hypothesis::GetMeshByPersistentID(int id) +{ + StudyContextStruct* myStudyContext = _gen->GetStudyContext(_studyId); + map::iterator itm = itm = myStudyContext->mapMesh.begin(); + for ( ; itm != myStudyContext->mapMesh.end(); itm++) + { + SMESH_Mesh* mesh = (*itm).second; + if ( mesh->GetMeshDS()->GetPersistentId() == id ) + return mesh; + } + return 0; +} + //============================================================================= /*! * diff --git a/src/SMESH/SMESH_Hypothesis.hxx b/src/SMESH/SMESH_Hypothesis.hxx index 1eb5ae8c8..82afd4bbc 100644 --- a/src/SMESH/SMESH_Hypothesis.hxx +++ b/src/SMESH/SMESH_Hypothesis.hxx @@ -114,6 +114,11 @@ public: virtual bool IsAuxiliary() const { return GetType() == PARAM_ALGO && _param_algo_dim < 0; } + /*! + * \brief Find a mesh with given persistent ID + */ + SMESH_Mesh* GetMeshByPersistentID(int id); + protected: SMESH_Gen* _gen; int _studyId; diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index 5cf9ba6c5..39c2ca976 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -101,6 +101,7 @@ SMESH_Mesh::SMESH_Mesh(int theLocalId, _isAutoColor = false; _isModified = false; _shapeDiagonal = 0.0; + _rmGroupCallUp = 0; _myMeshDS->ShapeToMesh( PseudoShape() ); } @@ -126,6 +127,9 @@ SMESH_Mesh::~SMESH_Mesh() delete aGroup; } _mapGroup.clear(); + + if ( _rmGroupCallUp) delete _rmGroupCallUp; + _rmGroupCallUp = 0; } //============================================================================= @@ -267,6 +271,7 @@ void SMESH_Mesh::Clear() while ( smIt->more() ) { sm = smIt->next(); sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); + sm->ComputeStateEngine( SMESH_subMesh::CLEAN ); // for event listeners (issue 0020918) } } _isModified = false; @@ -457,6 +462,9 @@ SMESH_Hypothesis::Hypothesis_Status // NotConformAllowed can be only global if ( !isGlobalHyp ) { + // NOTE: this is not a correct way to check a name of hypothesis, + // there should be an attribute of hypothesis saying that it can/can't + // be global/local string hypName = anHyp->GetName(); if ( hypName == "NotConformAllowed" ) { @@ -499,7 +507,7 @@ SMESH_Hypothesis::Hypothesis_Status } } } - HasModificationsToDiscard(); // to reset _isModified flag if mesh become empty + HasModificationsToDiscard(); // to reset _isModified flag if a mesh becomes empty if(MYDEBUG) subMesh->DumpAlgoState(true); if(MYDEBUG) SCRUTE(ret); @@ -970,7 +978,7 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h } } } - HasModificationsToDiscard(); // to reset _isModified flag if mesh become empty + HasModificationsToDiscard(); // to reset _isModified flag if mesh becomes empty } //============================================================================= @@ -1410,6 +1418,18 @@ list SMESH_Mesh::GetGroupIds() const return anIds; } +//================================================================================ +/*! + * \brief Set a caller of RemoveGroup() at level of CORBA API implementation. + * The set upCaller will be deleted by SMESH_Mesh + */ +//================================================================================ + +void SMESH_Mesh::SetRemoveGroupCallUp( TRmGroupCallUp* upCaller ) +{ + if ( _rmGroupCallUp ) delete _rmGroupCallUp; + _rmGroupCallUp = upCaller; +} //============================================================================= /*! @@ -1417,13 +1437,16 @@ list SMESH_Mesh::GetGroupIds() const */ //============================================================================= -void SMESH_Mesh::RemoveGroup (const int theGroupID) +bool SMESH_Mesh::RemoveGroup (const int theGroupID) { if (_mapGroup.find(theGroupID) == _mapGroup.end()) - return; + return false; GetMeshDS()->RemoveGroup( _mapGroup[theGroupID]->GetGroupDS() ); delete _mapGroup[theGroupID]; _mapGroup.erase (theGroupID); + if (_rmGroupCallUp) + _rmGroupCallUp->RemoveGroup( theGroupID ); + return true; } //======================================================================= @@ -1612,6 +1635,7 @@ void SMESH_Mesh::fillAncestorsMap(const TopoDS_Shape& theShape) for ( desType = TopAbs_VERTEX; desType >= memberType; desType-- ) for (TopExp_Explorer des( theShape, TopAbs_ShapeEnum( desType )); des.More(); des.Next()) { + if ( !_mapAncestors.Contains( des.Current() )) continue;// issue 0020982 TopTools_ListOfShape& ancList = _mapAncestors.ChangeFromKey( des.Current() ); TopTools_ListIteratorOfListOfShape ancIt (ancList); while ( ancIt.More() && ancIt.Value().ShapeType() >= memberType ) diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index ac504ced6..c88bbd02d 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -141,12 +141,14 @@ public: void ClearLog() throw(SALOME_Exception); - int GetId() { return _id; } + int GetId() const { return _id; } SMESHDS_Mesh * GetMeshDS() { return _myMeshDS; } - SMESH_Gen *GetGen() { return _gen; } + const SMESHDS_Mesh * GetMeshDS() const { return _myMeshDS; } + SMESH_Gen *GetGen() { return _gen; } + SMESH_subMesh *GetSubMesh(const TopoDS_Shape & aSubShape) throw(SALOME_Exception); @@ -266,10 +268,18 @@ public: SMESH_Group* GetGroup (const int theGroupID); - void RemoveGroup (const int theGroupID); + bool RemoveGroup (const int theGroupID); SMESH_Group* ConvertToStandalone ( int theGroupID ); + struct TRmGroupCallUp + { + virtual void RemoveGroup (const int theGroupID)=0; + virtual ~TRmGroupCallUp() {} + }; + void SetRemoveGroupCallUp( TRmGroupCallUp * upCaller ); + + SMDSAbs_ElementType GetElementType( const int id, const bool iselem ); void ClearMeshOrder(); @@ -303,9 +313,9 @@ protected: std::list _subMeshesUsingHypothesisList; SMESHDS_Document * _myDocument; SMESHDS_Mesh * _myMeshDS; + SMESH_Gen * _gen; std::map _mapSubMesh; std::map _mapGroup; - SMESH_Gen * _gen; bool _isAutoColor; bool _isModified; //!< modified since last total re-compute, issue 0020693 @@ -316,6 +326,11 @@ protected: TListOfListOfInt _mySubMeshOrder; + // Struct calling RemoveGroup at CORBA API implementation level, used + // to make an upper level be consistent with a lower one when group removal + // is invoked by hyp modification + TRmGroupCallUp* _rmGroupCallUp; + protected: SMESH_Mesh() {}; SMESH_Mesh(const SMESH_Mesh&) {}; diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index 6801d7d0d..f26db9a0c 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -35,6 +35,7 @@ #include "SMDS_SpacePosition.hxx" #include "SMDS_QuadraticFaceOfNodes.hxx" #include "SMDS_MeshGroup.hxx" +#include "SMDS_SetIterator.hxx" #include "SMESHDS_Group.hxx" #include "SMESHDS_Mesh.hxx" @@ -99,6 +100,8 @@ using namespace SMESH::Controls; typedef map > TElemOfNodeListMap; typedef map > TElemOfElemListMap; +typedef SMDS_SetIterator< SMDS_pElement, TIDSortedElemSet::const_iterator> TSetIterator; + //======================================================================= //function : SMESH_MeshEditor //purpose : @@ -219,6 +222,7 @@ SMESH_MeshEditor::AddElement(const vector & node, node[16],node[17],node[18],node[19] ); } } + if ( e ) myLastCreatedElems.Append( e ); return e; } @@ -251,8 +255,8 @@ SMDS_MeshElement* SMESH_MeshEditor::AddElement(const vector & nodeIDs // Modify a compute state of sub-meshes which become empty //======================================================================= -bool SMESH_MeshEditor::Remove (const list< int >& theIDs, - const bool isNodes ) +int SMESH_MeshEditor::Remove (const list< int >& theIDs, + const bool isNodes ) { myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); @@ -260,6 +264,7 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs, SMESHDS_Mesh* aMesh = GetMeshDS(); set< SMESH_subMesh *> smmap; + int removed = 0; list::const_iterator it = theIDs.begin(); for ( ; it != theIDs.end(); it++ ) { const SMDS_MeshElement * elem; @@ -296,6 +301,7 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs, aMesh->RemoveNode( static_cast< const SMDS_MeshNode* >( elem )); else aMesh->RemoveElement( elem ); + removed++; } // Notify sub-meshes about modification @@ -309,7 +315,7 @@ bool SMESH_MeshEditor::Remove (const list< int >& theIDs, // if ( SMESH_subMesh * sm = GetMesh()->GetSubMeshContaining( 1 ) ) // sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); - return true; + return removed; } //======================================================================= @@ -1240,6 +1246,7 @@ namespace const int* _connectivity; //!< foursomes of tetra connectivy finished by -1 bool _baryNode; //!< additional node is to be created at cell barycenter bool _ownConn; //!< to delete _connectivity in destructor + map _faceBaryNode; //!< map face index to node at BC of face TSplitMethod( int nbTet=0, const int* conn=0, bool addNode=false) : _nbTetra(nbTet), _connectivity(conn), _baryNode(addNode), _ownConn(false) {} @@ -1265,7 +1272,12 @@ namespace TSplitMethod getSplitMethod( SMDS_VolumeTool& vol, const int theMethodFlags) { - int iQ = vol.Element()->IsQuadratic() ? 2 : 1; + const int iQ = vol.Element()->IsQuadratic() ? 2 : 1; + + // at HEXA_TO_24 method, each face of volume is split into triangles each based on + // an edge and a face barycenter; tertaherdons are based on triangles and + // a volume barycenter + const bool is24TetMode = ( theMethodFlags == SMESH_MeshEditor::HEXA_TO_24 ); // Find out how adjacent volumes are split @@ -1274,7 +1286,7 @@ namespace for ( int iF = 0; iF < vol.NbFaces(); ++iF ) { int nbNodes = vol.NbFaceNodes( iF ) / iQ; - maxTetConnSize += 4 * ( nbNodes - 2 ); + maxTetConnSize += 4 * ( nbNodes - (is24TetMode ? 0 : 2)); if ( nbNodes < 4 ) continue; list< TTriangleFacet >& triaSplits = triaSplitsByFace[ iF ]; @@ -1312,7 +1324,7 @@ namespace // Among variants of split method select one compliant with adjacent volumes TSplitMethod method; - if ( !vol.Element()->IsPoly() ) + if ( !vol.Element()->IsPoly() && !is24TetMode ) { int nbVariants = 2, nbTet = 0; const int** connVariants = 0; @@ -1320,7 +1332,7 @@ namespace { case SMDSEntity_Hexa: case SMDSEntity_Quad_Hexa: - if ( theMethodFlags & SMESH_MeshEditor::HEXA_TO_5 ) + if ( theMethodFlags == SMESH_MeshEditor::HEXA_TO_5 ) connVariants = theHexTo5, nbTet = 5; else connVariants = theHexTo6, nbTet = 6, nbVariants = 4; @@ -1384,7 +1396,7 @@ namespace facet->contains( nInd[ iQ * ((iCommon+2)%nbNodes) ])) break; } - else if ( nbNodes > 3 ) + else if ( nbNodes > 3 && !is24TetMode ) { // find the best method of splitting into triangles by aspect ratio SMESH::Controls::NumericalFunctorPtr aspectRatio( new SMESH::Controls::AspectRatio); @@ -1405,18 +1417,37 @@ namespace } if ( iCommon >= nbNodes ) iCommon = 0; // something wrong - // fill connectivity of tetra + + // fill connectivity of tetrahedra based on a current face int nbTet = nbNodes - 2; - for ( int i = 0; i < nbTet; ++i ) + if ( is24TetMode && nbNodes > 3 && triaSplits.empty()) { - int i1 = (iCommon+1+i) % nbNodes, i2 = (iCommon+2+i) % nbNodes; - if ( !vol.IsFaceExternal( iF )) swap( i1, i2 ); - connectivity[ connSize++ ] = nInd[ iQ * iCommon ]; - connectivity[ connSize++ ] = nInd[ iQ * i1 ]; - connectivity[ connSize++ ] = nInd[ iQ * i2 ]; - connectivity[ connSize++ ] = baryCenInd; - ++method._nbTetra; + method._faceBaryNode.insert( make_pair( iF, (const SMDS_MeshNode*)0 )); + int faceBaryCenInd = baryCenInd + method._faceBaryNode.size(); + nbTet = nbNodes; + for ( int i = 0; i < nbTet; ++i ) + { + int i1 = i, i2 = (i+1) % nbNodes; + if ( !vol.IsFaceExternal( iF )) swap( i1, i2 ); + connectivity[ connSize++ ] = nInd[ iQ * i1 ]; + connectivity[ connSize++ ] = nInd[ iQ * i2 ]; + connectivity[ connSize++ ] = faceBaryCenInd; + connectivity[ connSize++ ] = baryCenInd; + } } + else + { + for ( int i = 0; i < nbTet; ++i ) + { + int i1 = (iCommon+1+i) % nbNodes, i2 = (iCommon+2+i) % nbNodes; + if ( !vol.IsFaceExternal( iF )) swap( i1, i2 ); + connectivity[ connSize++ ] = nInd[ iQ * iCommon ]; + connectivity[ connSize++ ] = nInd[ iQ * i1 ]; + connectivity[ connSize++ ] = nInd[ iQ * i2 ]; + connectivity[ connSize++ ] = baryCenInd; + } + } + method._nbTetra += nbTet; } connectivity[ connSize++ ] = -1; } @@ -1451,6 +1482,29 @@ namespace } return false; } + + //======================================================================= + /*! + * \brief A key of a face of volume + */ + //======================================================================= + + struct TVolumeFaceKey: pair< int, pair< int, int> > + { + TVolumeFaceKey( SMDS_VolumeTool& vol, int iF ) + { + TIDSortedNodeSet sortedNodes; + const int iQ = vol.Element()->IsQuadratic() ? 2 : 1; + int nbNodes = vol.NbFaceNodes( iF ); + const SMDS_MeshNode** fNodes = vol.GetFaceNodes( iF ); + for ( int i = 0; i < nbNodes; i += iQ ) + sortedNodes.insert( fNodes[i] ); + TIDSortedNodeSet::iterator n = sortedNodes.begin(); + first = (*(n++))->GetID(); + second.first = (*(n++))->GetID(); + second.second = (*(n++))->GetID(); + } + }; } // namespace //======================================================================= @@ -1473,6 +1527,10 @@ void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems, SMESH_SequenceOfElemPtr newNodes, newElems; + // map face of volume to it's baricenrtic node + map< TVolumeFaceKey, const SMDS_MeshNode* > volFace2BaryNode; + double bc[3]; + TIDSortedElemSet::const_iterator elem = theElems.begin(); for ( ; elem != theElems.end(); ++elem ) { @@ -1485,7 +1543,7 @@ void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems, TSplitMethod splitMethod = getSplitMethod( volTool, theMethodFlags ); if ( splitMethod._nbTetra < 1 ) continue; - // find submesh to add new tetras in + // find submesh to add new tetras to if ( !subMesh || !subMesh->Contains( *elem )) { int shapeID = FindShape( *elem ); @@ -1514,12 +1572,28 @@ void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems, if ( splitMethod._baryNode ) { // make a node at barycenter - gp_XYZ gc( 0,0,0 ); - gc = accumulate( NXyzIterator((*elem)->nodesIterator()), xyzEnd, gc ) / nodes.size(); - SMDS_MeshNode* gcNode = helper.AddNode( gc.X(), gc.Y(), gc.Z() ); + volTool.GetBaryCenter( bc[0], bc[1], bc[2] ); + SMDS_MeshNode* gcNode = helper.AddNode( bc[0], bc[1], bc[2] ); nodes.push_back( gcNode ); newNodes.Append( gcNode ); } + if ( !splitMethod._faceBaryNode.empty() ) + { + // make or find baricentric nodes of faces + map::iterator iF_n = splitMethod._faceBaryNode.begin(); + for ( ; iF_n != splitMethod._faceBaryNode.end(); ++iF_n ) + { + map< TVolumeFaceKey, const SMDS_MeshNode* >::iterator f_n = + volFace2BaryNode.insert + ( make_pair( TVolumeFaceKey( volTool,iF_n->first ), (const SMDS_MeshNode*)0) ).first; + if ( !f_n->second ) + { + volTool.GetFaceBaryCenter( iF_n->first, bc[0], bc[1], bc[2] ); + newNodes.Append( f_n->second = helper.AddNode( bc[0], bc[1], bc[2] )); + } + nodes.push_back( iF_n->second = f_n->second ); + } + } // make tetras helper.SetElementsOnShape( true ); @@ -1546,48 +1620,69 @@ void SMESH_MeshEditor::SplitVolumesIntoTetra (const TIDSortedElemSet & theElems, volTool.GetFaceNodes( iF ) + nbNodes*iQ ); while ( const SMDS_MeshElement* face = GetMeshDS()->FindFace( fNodes )) { - // among possible triangles create ones discribed by split method - const int* nInd = volTool.GetFaceNodesIndices( iF ); - int nbVariants = ( nbNodes == 4 ? 2 : nbNodes ); - int iCom = 0; // common node of triangle faces to split into - list< TTriangleFacet > facets; - for ( int iVar = 0; iVar < nbVariants; ++iVar, ++iCom ) + // make triangles + helper.SetElementsOnShape( false ); + vector< const SMDS_MeshElement* > triangles; + + map::iterator iF_n = splitMethod._faceBaryNode.find(iF); + if ( iF_n != splitMethod._faceBaryNode.end() ) { - TTriangleFacet t012( nInd[ iQ * ( iCom )], - nInd[ iQ * ( (iCom+1)%nbNodes )], - nInd[ iQ * ( (iCom+2)%nbNodes )]); - TTriangleFacet t023( nInd[ iQ * ( iCom )], - nInd[ iQ * ( (iCom+2)%nbNodes )], - nInd[ iQ * ( (iCom+3)%nbNodes )]); - if ( splitMethod.hasFacet( t012 ) && splitMethod.hasFacet( t023 )) + for ( int iN = 0; iN < nbNodes*iQ; iN += iQ ) { - facets.push_back( t012 ); - facets.push_back( t023 ); - for ( int iLast = iCom+4; iLast < iCom+nbNodes; ++iLast ) - facets.push_back( TTriangleFacet( nInd[ iQ * ( iCom )], - nInd[ iQ * ((iLast-1)%nbNodes )], - nInd[ iQ * ((iLast )%nbNodes )])); - break; + const SMDS_MeshNode* n1 = fNodes[iN]; + const SMDS_MeshNode *n2 = fNodes[(iN+iQ)%nbNodes*iQ]; + const SMDS_MeshNode *n3 = iF_n->second; + if ( !volTool.IsFaceExternal( iF )) + swap( n2, n3 ); + triangles.push_back( helper.AddFace( n1,n2,n3 )); + } + } + else + { + // among possible triangles create ones discribed by split method + const int* nInd = volTool.GetFaceNodesIndices( iF ); + int nbVariants = ( nbNodes == 4 ? 2 : nbNodes ); + int iCom = 0; // common node of triangle faces to split into + list< TTriangleFacet > facets; + for ( int iVar = 0; iVar < nbVariants; ++iVar, ++iCom ) + { + TTriangleFacet t012( nInd[ iQ * ( iCom )], + nInd[ iQ * ( (iCom+1)%nbNodes )], + nInd[ iQ * ( (iCom+2)%nbNodes )]); + TTriangleFacet t023( nInd[ iQ * ( iCom )], + nInd[ iQ * ( (iCom+2)%nbNodes )], + nInd[ iQ * ( (iCom+3)%nbNodes )]); + if ( splitMethod.hasFacet( t012 ) && splitMethod.hasFacet( t023 )) + { + facets.push_back( t012 ); + facets.push_back( t023 ); + for ( int iLast = iCom+4; iLast < iCom+nbNodes; ++iLast ) + facets.push_back( TTriangleFacet( nInd[ iQ * ( iCom )], + nInd[ iQ * ((iLast-1)%nbNodes )], + nInd[ iQ * ((iLast )%nbNodes )])); + break; + } + } + list< TTriangleFacet >::iterator facet = facets.begin(); + for ( ; facet != facets.end(); ++facet ) + { + if ( !volTool.IsFaceExternal( iF )) + swap( facet->_n2, facet->_n3 ); + triangles.push_back( helper.AddFace( volNodes[ facet->_n1 ], + volNodes[ facet->_n2 ], + volNodes[ facet->_n3 ])); } } - // find submesh to add new faces in + // find submesh to add new triangles in if ( !fSubMesh || !fSubMesh->Contains( face )) { int shapeID = FindShape( face ); fSubMesh = GetMeshDS()->MeshElements( shapeID ); } - // make triangles - helper.SetElementsOnShape( false ); - vector< const SMDS_MeshElement* > triangles; - list< TTriangleFacet >::iterator facet = facets.begin(); - for ( ; facet != facets.end(); ++facet ) + for ( int i = 0; i < triangles.size(); ++i ) { - if ( !volTool.IsFaceExternal( iF )) - swap( facet->_n2, facet->_n3 ); - triangles.push_back( helper.AddFace( volNodes[ facet->_n1 ], - volNodes[ facet->_n2 ], - volNodes[ facet->_n3 ])); - if ( triangles.back() && fSubMesh ) + if ( !triangles.back() ) continue; + if ( fSubMesh ) fSubMesh->AddElement( triangles.back()); newElems.Append( triangles.back() ); } @@ -5106,10 +5201,17 @@ void SMESH_MeshEditor::LinearAngleVariation(const int nbSteps, } -//======================================================================= -//function : Transform -//purpose : -//======================================================================= +//================================================================================ +/*! + * \brief Move or copy theElements applying theTrsf to their nodes + * \param theElems - elements to transform, if theElems is empty then apply to all mesh nodes + * \param theTrsf - transformation to apply + * \param theCopy - if true, create translated copies of theElems + * \param theMakeGroups - if true and theCopy, create translated groups + * \param theTargetMesh - mesh to copy translated elements into + * \retval SMESH_MeshEditor::PGroupIDs - list of ids of created groups + */ +//================================================================================ SMESH_MeshEditor::PGroupIDs SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, @@ -5137,6 +5239,7 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, groupPostfix = "translated"; break; case gp_Scale: + case gp_CompoundTrsf: // different scale by axis groupPostfix = "scaled"; break; default: @@ -5159,7 +5262,36 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, // source elements for each generated one SMESH_SequenceOfElemPtr srcElems, srcNodes; - // loop on theElems + // issue 021015: EDF 1578 SMESH: Free nodes are removed when translating a mesh + list orphanCopy; // copies of orphan nodes + vector orphanNode; // original orphan nodes + + if ( theElems.empty() ) // transform the whole mesh + { + // add all elements + SMDS_ElemIteratorPtr eIt = aMesh->elementsIterator(); + while ( eIt->more() ) theElems.insert( eIt->next() ); + // add orphan nodes + SMDS_MeshElementIDFactory idFactory; + SMDS_NodeIteratorPtr nIt = aMesh->nodesIterator(); + while ( nIt->more() ) + { + const SMDS_MeshNode* node = nIt->next(); + if ( node->NbInverseElements() == 0 && !theElems.insert( node ).second ) + { + // node was not inserted into theElems because an element with the same ID + // is already there. As a work around we insert a copy of node with + // an ID = - + orphanCopy.push_back( *node ); // copy node + SMDS_MeshNode* nodeCopy = &orphanCopy.back(); + int uniqueID = -orphanNode.size(); + orphanNode.push_back( node ); + idFactory.BindID( uniqueID, nodeCopy ); + theElems.insert( nodeCopy ); + } + } + } + // loop on theElems to transorm nodes TIDSortedElemSet::iterator itElem; for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { const SMDS_MeshElement* elem = *itElem; @@ -5170,8 +5302,10 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, SMDS_ElemIteratorPtr itN = elem->nodesIterator(); while ( itN->more() ) { - // check if a node has been already transformed const SMDS_MeshNode* node = cast2Node( itN->next() ); + if ( node->GetID() < 0 ) + node = orphanNode[ -node->GetID() ]; + // check if a node has been already transformed pair n2n_isnew = nodeMap.insert( make_pair ( node, node )); if ( !n2n_isnew.second ) @@ -5401,10 +5535,8 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, } } else if ( theCopy ) { - if ( SMDS_MeshElement* copy = AddElement( nodes, elem->GetType(), elem->IsPoly() )) { - myLastCreatedElems.Append( copy ); + if ( AddElement( nodes, elem->GetType(), elem->IsPoly() )) srcElems.Append( elem ); - } } else { // reverse element as it was reversed by transformation @@ -5422,331 +5554,6 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, return newGroupIDs; } - -//======================================================================= -//function : Scale -//purpose : -//======================================================================= - -SMESH_MeshEditor::PGroupIDs -SMESH_MeshEditor::Scale (TIDSortedElemSet & theElems, - const gp_Pnt& thePoint, - const std::list& theScaleFact, - const bool theCopy, - const bool theMakeGroups, - SMESH_Mesh* theTargetMesh) -{ - myLastCreatedElems.Clear(); - myLastCreatedNodes.Clear(); - - SMESH_MeshEditor targetMeshEditor( theTargetMesh ); - SMESHDS_Mesh* aTgtMesh = theTargetMesh ? theTargetMesh->GetMeshDS() : 0; - SMESHDS_Mesh* aMesh = GetMeshDS(); - - double scaleX=1.0, scaleY=1.0, scaleZ=1.0; - std::list::const_iterator itS = theScaleFact.begin(); - scaleX = (*itS); - if(theScaleFact.size()==1) { - scaleY = (*itS); - scaleZ= (*itS); - } - if(theScaleFact.size()==2) { - itS++; - scaleY = (*itS); - scaleZ= (*itS); - } - if(theScaleFact.size()>2) { - itS++; - scaleY = (*itS); - itS++; - scaleZ= (*itS); - } - - // map old node to new one - TNodeNodeMap nodeMap; - - // elements sharing moved nodes; those of them which have all - // nodes mirrored but are not in theElems are to be reversed - TIDSortedElemSet inverseElemSet; - - // source elements for each generated one - SMESH_SequenceOfElemPtr srcElems, srcNodes; - - // loop on theElems - TIDSortedElemSet::iterator itElem; - for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { - const SMDS_MeshElement* elem = *itElem; - if ( !elem ) - continue; - - // loop on elem nodes - SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - while ( itN->more() ) { - - // check if a node has been already transformed - const SMDS_MeshNode* node = cast2Node( itN->next() ); - pair n2n_isnew = - nodeMap.insert( make_pair ( node, node )); - if ( !n2n_isnew.second ) - continue; - - //double coord[3]; - //coord[0] = node->X(); - //coord[1] = node->Y(); - //coord[2] = node->Z(); - //theTrsf.Transforms( coord[0], coord[1], coord[2] ); - double dx = (node->X() - thePoint.X()) * scaleX; - double dy = (node->Y() - thePoint.Y()) * scaleY; - double dz = (node->Z() - thePoint.Z()) * scaleZ; - if ( theTargetMesh ) { - //const SMDS_MeshNode * newNode = aTgtMesh->AddNode( coord[0], coord[1], coord[2] ); - const SMDS_MeshNode * newNode = - aTgtMesh->AddNode( thePoint.X()+dx, thePoint.Y()+dy, thePoint.Z()+dz ); - n2n_isnew.first->second = newNode; - myLastCreatedNodes.Append(newNode); - srcNodes.Append( node ); - } - else if ( theCopy ) { - //const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] ); - const SMDS_MeshNode * newNode = - aMesh->AddNode( thePoint.X()+dx, thePoint.Y()+dy, thePoint.Z()+dz ); - n2n_isnew.first->second = newNode; - myLastCreatedNodes.Append(newNode); - srcNodes.Append( node ); - } - else { - //aMesh->MoveNode( node, coord[0], coord[1], coord[2] ); - aMesh->MoveNode( node, thePoint.X()+dx, thePoint.Y()+dy, thePoint.Z()+dz ); - // node position on shape becomes invalid - const_cast< SMDS_MeshNode* > ( node )->SetPosition - ( SMDS_SpacePosition::originSpacePosition() ); - } - - // keep inverse elements - //if ( !theCopy && !theTargetMesh && needReverse ) { - // SMDS_ElemIteratorPtr invElemIt = node->GetInverseElementIterator(); - // while ( invElemIt->more() ) { - // const SMDS_MeshElement* iel = invElemIt->next(); - // inverseElemSet.insert( iel ); - // } - //} - } - } - - // either create new elements or reverse mirrored ones - //if ( !theCopy && !needReverse && !theTargetMesh ) - if ( !theCopy && !theTargetMesh ) - return PGroupIDs(); - - TIDSortedElemSet::iterator invElemIt = inverseElemSet.begin(); - for ( ; invElemIt != inverseElemSet.end(); invElemIt++ ) - theElems.insert( *invElemIt ); - - // replicate or reverse elements - - enum { - REV_TETRA = 0, // = nbNodes - 4 - REV_PYRAMID = 1, // = nbNodes - 4 - REV_PENTA = 2, // = nbNodes - 4 - REV_FACE = 3, - REV_HEXA = 4, // = nbNodes - 4 - FORWARD = 5 - }; - int index[][8] = { - { 2, 1, 0, 3, 4, 0, 0, 0 }, // REV_TETRA - { 2, 1, 0, 3, 4, 0, 0, 0 }, // REV_PYRAMID - { 2, 1, 0, 5, 4, 3, 0, 0 }, // REV_PENTA - { 2, 1, 0, 3, 0, 0, 0, 0 }, // REV_FACE - { 2, 1, 0, 3, 6, 5, 4, 7 }, // REV_HEXA - { 0, 1, 2, 3, 4, 5, 6, 7 } // FORWARD - }; - - for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) - { - const SMDS_MeshElement* elem = *itElem; - if ( !elem || elem->GetType() == SMDSAbs_Node ) - continue; - - int nbNodes = elem->NbNodes(); - int elemType = elem->GetType(); - - if (elem->IsPoly()) { - // Polygon or Polyhedral Volume - switch ( elemType ) { - case SMDSAbs_Face: - { - vector poly_nodes (nbNodes); - int iNode = 0; - SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - while (itN->more()) { - const SMDS_MeshNode* node = - static_cast(itN->next()); - TNodeNodeMap::iterator nodeMapIt = nodeMap.find(node); - if (nodeMapIt == nodeMap.end()) - break; // not all nodes transformed - //if (needReverse) { - // // reverse mirrored faces and volumes - // poly_nodes[nbNodes - iNode - 1] = (*nodeMapIt).second; - //} else { - poly_nodes[iNode] = (*nodeMapIt).second; - //} - iNode++; - } - if ( iNode != nbNodes ) - continue; // not all nodes transformed - - if ( theTargetMesh ) { - myLastCreatedElems.Append(aTgtMesh->AddPolygonalFace(poly_nodes)); - srcElems.Append( elem ); - } - else if ( theCopy ) { - myLastCreatedElems.Append(aMesh->AddPolygonalFace(poly_nodes)); - srcElems.Append( elem ); - } - else { - aMesh->ChangePolygonNodes(elem, poly_nodes); - } - } - break; - case SMDSAbs_Volume: - { - // ATTENTION: Reversing is not yet done!!! - const SMDS_PolyhedralVolumeOfNodes* aPolyedre = - dynamic_cast( elem ); - if (!aPolyedre) { - MESSAGE("Warning: bad volumic element"); - continue; - } - - vector poly_nodes; - vector quantities; - - bool allTransformed = true; - int nbFaces = aPolyedre->NbFaces(); - for (int iface = 1; iface <= nbFaces && allTransformed; iface++) { - int nbFaceNodes = aPolyedre->NbFaceNodes(iface); - for (int inode = 1; inode <= nbFaceNodes && allTransformed; inode++) { - const SMDS_MeshNode* node = aPolyedre->GetFaceNode(iface, inode); - TNodeNodeMap::iterator nodeMapIt = nodeMap.find(node); - if (nodeMapIt == nodeMap.end()) { - allTransformed = false; // not all nodes transformed - } else { - poly_nodes.push_back((*nodeMapIt).second); - } - } - quantities.push_back(nbFaceNodes); - } - if ( !allTransformed ) - continue; // not all nodes transformed - - if ( theTargetMesh ) { - myLastCreatedElems.Append(aTgtMesh->AddPolyhedralVolume(poly_nodes, quantities)); - srcElems.Append( elem ); - } - else if ( theCopy ) { - myLastCreatedElems.Append(aMesh->AddPolyhedralVolume(poly_nodes, quantities)); - srcElems.Append( elem ); - } - else { - aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities); - } - } - break; - default:; - } - continue; - } - - // Regular elements - int* i = index[ FORWARD ]; - //if ( needReverse && nbNodes > 2) // reverse mirrored faces and volumes - // if ( elemType == SMDSAbs_Face ) - // i = index[ REV_FACE ]; - // else - // i = index[ nbNodes - 4 ]; - - if(elem->IsQuadratic()) { - static int anIds[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}; - i = anIds; - //if(needReverse) { - // if(nbNodes==3) { // quadratic edge - // static int anIds[] = {1,0,2}; - // i = anIds; - // } - // else if(nbNodes==6) { // quadratic triangle - // static int anIds[] = {0,2,1,5,4,3}; - // i = anIds; - // } - // else if(nbNodes==8) { // quadratic quadrangle - // static int anIds[] = {0,3,2,1,7,6,5,4}; - // i = anIds; - // } - // else if(nbNodes==10) { // quadratic tetrahedron of 10 nodes - // static int anIds[] = {0,2,1,3,6,5,4,7,9,8}; - // i = anIds; - // } - // else if(nbNodes==13) { // quadratic pyramid of 13 nodes - // static int anIds[] = {0,3,2,1,4,8,7,6,5,9,12,11,10}; - // i = anIds; - // } - // else if(nbNodes==15) { // quadratic pentahedron with 15 nodes - // static int anIds[] = {0,2,1,3,5,4,8,7,6,11,10,9,12,14,13}; - // i = anIds; - // } - // else { // nbNodes==20 - quadratic hexahedron with 20 nodes - // static int anIds[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17}; - // i = anIds; - // } - //} - } - - // find transformed nodes - vector nodes(nbNodes); - int iNode = 0; - SMDS_ElemIteratorPtr itN = elem->nodesIterator(); - while ( itN->more() ) { - const SMDS_MeshNode* node = - static_cast( itN->next() ); - TNodeNodeMap::iterator nodeMapIt = nodeMap.find( node ); - if ( nodeMapIt == nodeMap.end() ) - break; // not all nodes transformed - nodes[ i [ iNode++ ]] = (*nodeMapIt).second; - } - if ( iNode != nbNodes ) - continue; // not all nodes transformed - - if ( theTargetMesh ) { - if ( SMDS_MeshElement* copy = - targetMeshEditor.AddElement( nodes, elem->GetType(), elem->IsPoly() )) { - myLastCreatedElems.Append( copy ); - srcElems.Append( elem ); - } - } - else if ( theCopy ) { - if ( SMDS_MeshElement* copy = AddElement( nodes, elem->GetType(), elem->IsPoly() )) { - myLastCreatedElems.Append( copy ); - srcElems.Append( elem ); - } - } - else { - // reverse element as it was reversed by transformation - if ( nbNodes > 2 ) - aMesh->ChangeElementNodes( elem, &nodes[0], nbNodes ); - } - } - - PGroupIDs newGroupIDs; - - if ( theMakeGroups && theCopy || - theMakeGroups && theTargetMesh ) { - string groupPostfix = "scaled"; - newGroupIDs = generateGroups( srcNodes, srcElems, groupPostfix, theTargetMesh ); - } - - return newGroupIDs; -} - - //======================================================================= /*! * \brief Create groups of elements made during transformation @@ -5881,24 +5688,21 @@ SMESH_MeshEditor::generateGroups(const SMESH_SequenceOfElemPtr& nodeGens, */ //================================================================================ -void SMESH_MeshEditor::FindCoincidentNodes (set & theNodes, - const double theTolerance, - TListOfListOfNodes & theGroupsOfNodes) +void SMESH_MeshEditor::FindCoincidentNodes (TIDSortedNodeSet & theNodes, + const double theTolerance, + TListOfListOfNodes & theGroupsOfNodes) { myLastCreatedElems.Clear(); myLastCreatedNodes.Clear(); - set nodes; if ( theNodes.empty() ) { // get all nodes in the mesh - SMDS_NodeIteratorPtr nIt = GetMeshDS()->nodesIterator(); + SMDS_NodeIteratorPtr nIt = GetMeshDS()->nodesIterator(/*idInceasingOrder=*/true); while ( nIt->more() ) - nodes.insert( nodes.end(),nIt->next()); + theNodes.insert( theNodes.end(),nIt->next()); } - else - nodes=theNodes; - SMESH_OctreeNode::FindCoincidentNodes ( nodes, &theGroupsOfNodes, theTolerance); + SMESH_OctreeNode::FindCoincidentNodes ( theNodes, &theGroupsOfNodes, theTolerance); } @@ -5918,9 +5722,9 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher { myMesh = ( SMESHDS_Mesh* ) theMesh; - set nodes; + TIDSortedNodeSet nodes; if ( theMesh ) { - SMDS_NodeIteratorPtr nIt = theMesh->nodesIterator(); + SMDS_NodeIteratorPtr nIt = theMesh->nodesIterator(/*idInceasingOrder=*/true); while ( nIt->more() ) nodes.insert( nodes.end(), nIt->next() ); } @@ -5972,12 +5776,13 @@ struct SMESH_NodeSearcherImpl: public SMESH_NodeSearcher treeList.push_back( myOctreeNode ); SMDS_MeshNode pointNode( thePnt.X(), thePnt.Y(), thePnt.Z() ); + bool pointInside = myOctreeNode->isInside( &pointNode, myHalfLeafSize ); for ( trIt = treeList.begin(); trIt != treeList.end(); ++trIt) { SMESH_OctreeNode* tree = *trIt; if ( !tree->isLeaf() ) // put children to the queue { - if ( !tree->isInside( &pointNode, myHalfLeafSize )) continue; + if ( pointInside && !tree->isInside( &pointNode, myHalfLeafSize )) continue; SMESH_OctreeNodeIteratorPtr cIt = tree->GetChildrenIterator(); while ( cIt->more() ) treeList.push_back( cIt->next() ); @@ -6068,7 +5873,7 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint() { public: - ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType); + ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType, double tolerance = NodeRadius ); void getElementsNearPoint( const gp_Pnt& point, TIDSortedElemSet& foundElems); void getElementsNearLine ( const gp_Ax1& line, TIDSortedElemSet& foundElems); ~ElementBndBoxTree(); @@ -6084,7 +5889,7 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint() { const SMDS_MeshElement* _element; int _refCount; // an ElementBox can be included in several tree branches - ElementBox(const SMDS_MeshElement* elem); + ElementBox(const SMDS_MeshElement* elem, double tolerance); }; vector< ElementBox* > _elements; }; @@ -6095,7 +5900,7 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint() */ //================================================================================ - ElementBndBoxTree::ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType) + ElementBndBoxTree::ElementBndBoxTree(const SMDS_Mesh& mesh, SMDSAbs_ElementType elemType, double tolerance) :SMESH_Octree( new SMESH_Octree::Limit( MaxLevel, /*minSize=*/0. )) { int nbElems = mesh.GetMeshInfo().NbElements( elemType ); @@ -6103,7 +5908,7 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint() SMDS_ElemIteratorPtr elemIt = mesh.elementsIterator( elemType ); while ( elemIt->more() ) - _elements.push_back( new ElementBox( elemIt->next() )); + _elements.push_back( new ElementBox( elemIt->next(),tolerance )); if ( _elements.size() > MaxNbElemsInLeaf ) compute(); @@ -6227,14 +6032,14 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint() */ //================================================================================ - ElementBndBoxTree::ElementBox::ElementBox(const SMDS_MeshElement* elem) + ElementBndBoxTree::ElementBox::ElementBox(const SMDS_MeshElement* elem, double tolerance) { _element = elem; _refCount = 1; SMDS_ElemIteratorPtr nIt = elem->nodesIterator(); while ( nIt->more() ) Add( SMESH_MeshEditor::TNodeXYZ( cast2Node( nIt->next() ))); - Enlarge( NodeRadius ); + Enlarge( tolerance ); } } // namespace @@ -6268,6 +6073,9 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher vector< const SMDS_MeshElement* >& foundElements); virtual TopAbs_State GetPointState(const gp_Pnt& point); + void GetElementsNearLine( const gp_Ax1& line, + SMDSAbs_ElementType type, + vector< const SMDS_MeshElement* >& foundElems); double getTolerance(); bool getIntersParamOnLine(const gp_Lin& line, const SMDS_MeshElement* face, const double tolerance, double & param); @@ -6276,7 +6084,7 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher { return _outerFaces.empty() || _outerFaces.count(face); } - struct TInters //!< data of intersection of the line and the mesh face used in GetPointState() + struct TInters //!< data of intersection of the line and the mesh face (used in GetPointState()) { const SMDS_MeshElement* _face; gp_Vec _faceNorm; @@ -6351,7 +6159,7 @@ double SMESH_ElementSearcherImpl::getTolerance() elemSize = max( dist, elemSize ); } } - _tolerance = 1e-6 * elemSize; + _tolerance = 1e-4 * elemSize; } } return _tolerance; @@ -6542,7 +6350,7 @@ FindElementsByPoint(const gp_Pnt& point, if ( !_ebbTree || _elementType != type ) { if ( _ebbTree ) delete _ebbTree; - _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type ); + _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type, tolerance ); } TIDSortedElemSet suspectElems; _ebbTree->getElementsNearPoint( point, suspectElems ); @@ -6777,6 +6585,26 @@ TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point) return TopAbs_UNKNOWN; } +//======================================================================= +/*! + * \brief Return elements possibly intersecting the line + */ +//======================================================================= + +void SMESH_ElementSearcherImpl::GetElementsNearLine( const gp_Ax1& line, + SMDSAbs_ElementType type, + vector< const SMDS_MeshElement* >& foundElems) +{ + if ( !_ebbTree || _elementType != type ) + { + if ( _ebbTree ) delete _ebbTree; + _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type ); + } + TIDSortedElemSet suspectFaces; // elements possibly intersecting the line + _ebbTree->getElementsNearLine( line, suspectFaces ); + foundElems.assign( suspectFaces.begin(), suspectFaces.end()); +} + //======================================================================= /*! * \brief Return SMESH_ElementSearcher @@ -8860,7 +8688,7 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, int nbElem = 0; if( !theSm ) return nbElem; - const bool notFromGroups = false; + vector nbNodeInFaces; SMDS_ElemIteratorPtr ElemItr = theSm->GetElements(); while(ElemItr->more()) { @@ -8870,15 +8698,13 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, int id = elem->GetID(); int nbNodes = elem->NbNodes(); - vector aNds (nbNodes); - - for(int i = 0; i < nbNodes; i++) - { - aNds[i] = elem->GetNode(i); - } SMDSAbs_ElementType aType = elem->GetType(); - GetMeshDS()->RemoveFreeElement(elem, theSm, notFromGroups); + vector nodes (elem->begin_nodes(), elem->end_nodes()); + if ( elem->GetEntityType() == SMDSEntity_Polyhedra ) + nbNodeInFaces = static_cast( elem )->GetQuanities(); + + GetMeshDS()->RemoveFreeElement(elem, theSm, /*fromGroups=*/false); const SMDS_MeshElement* NewElem = 0; @@ -8886,7 +8712,7 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, { case SMDSAbs_Edge : { - NewElem = theHelper.AddEdge(aNds[0], aNds[1], id, theForce3d); + NewElem = theHelper.AddEdge(nodes[0], nodes[1], id, theForce3d); break; } case SMDSAbs_Face : @@ -8894,12 +8720,13 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, switch(nbNodes) { case 3: - NewElem = theHelper.AddFace(aNds[0], aNds[1], aNds[2], id, theForce3d); + NewElem = theHelper.AddFace(nodes[0], nodes[1], nodes[2], id, theForce3d); break; case 4: - NewElem = theHelper.AddFace(aNds[0], aNds[1], aNds[2], aNds[3], id, theForce3d); + NewElem = theHelper.AddFace(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d); break; default: + NewElem = theHelper.AddPolygonalFace(nodes, id, theForce3d); continue; } break; @@ -8909,20 +8736,20 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, switch(nbNodes) { case 4: - NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], id, theForce3d); + NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d); break; case 5: - NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], aNds[4], id, theForce3d); + NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], id, theForce3d); break; case 6: - NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], aNds[4], aNds[5], id, theForce3d); + NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], nodes[5], id, theForce3d); break; case 8: - NewElem = theHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], - aNds[4], aNds[5], aNds[6], aNds[7], id, theForce3d); + NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5], nodes[6], nodes[7], id, theForce3d); break; default: - continue; + NewElem = theHelper.AddPolyhedralVolume(nodes, nbNodeInFaces, id, theForce3d); } break; } @@ -8946,7 +8773,6 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) SMESH_MesherHelper aHelper(*myMesh); aHelper.SetIsQuadratic( true ); - const bool notFromGroups = false; int nbCheckedElems = 0; if ( myMesh->HasShapeToMesh() ) @@ -8977,7 +8803,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) const SMDS_MeshNode* n1 = edge->GetNode(0); const SMDS_MeshNode* n2 = edge->GetNode(1); - meshDS->RemoveFreeElement(edge, smDS, notFromGroups); + meshDS->RemoveFreeElement(edge, smDS, /*fromGroups=*/false); const SMDS_MeshEdge* NewEdge = aHelper.AddEdge(n1, n2, id, theForce3d); ReplaceElemInGroups( edge, NewEdge, GetMeshDS()); @@ -8991,29 +8817,25 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) int id = face->GetID(); int nbNodes = face->NbNodes(); - vector aNds (nbNodes); + vector nodes ( face->begin_nodes(), face->end_nodes()); - for(int i = 0; i < nbNodes; i++) - { - aNds[i] = face->GetNode(i); - } - - meshDS->RemoveFreeElement(face, smDS, notFromGroups); + meshDS->RemoveFreeElement(face, smDS, /*fromGroups=*/false); SMDS_MeshFace * NewFace = 0; switch(nbNodes) { case 3: - NewFace = aHelper.AddFace(aNds[0], aNds[1], aNds[2], id, theForce3d); + NewFace = aHelper.AddFace(nodes[0], nodes[1], nodes[2], id, theForce3d); break; case 4: - NewFace = aHelper.AddFace(aNds[0], aNds[1], aNds[2], aNds[3], id, theForce3d); + NewFace = aHelper.AddFace(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d); break; default: - continue; + NewFace = aHelper.AddPolygonalFace(nodes, id, theForce3d); } ReplaceElemInGroups( face, NewFace, GetMeshDS()); } + vector nbNodeInFaces; SMDS_VolumeIteratorPtr aVolumeItr = meshDS->volumesIterator(); while(aVolumeItr->more()) { @@ -9022,42 +8844,41 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) int id = volume->GetID(); int nbNodes = volume->NbNodes(); - vector aNds (nbNodes); - - for(int i = 0; i < nbNodes; i++) - { - aNds[i] = volume->GetNode(i); - } + vector nodes (volume->begin_nodes(), volume->end_nodes()); + if ( volume->GetEntityType() == SMDSEntity_Polyhedra ) + nbNodeInFaces = static_cast(volume)->GetQuanities(); - meshDS->RemoveFreeElement(volume, smDS, notFromGroups); + meshDS->RemoveFreeElement(volume, smDS, /*fromGroups=*/false); SMDS_MeshVolume * NewVolume = 0; switch(nbNodes) { case 4: - NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2], - aNds[3], id, theForce3d ); + NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], + nodes[3], id, theForce3d ); break; case 5: - NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2], - aNds[3], aNds[4], id, theForce3d); + NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], + nodes[3], nodes[4], id, theForce3d); break; case 6: - NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2], - aNds[3], aNds[4], aNds[5], id, theForce3d); + NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], + nodes[3], nodes[4], nodes[5], id, theForce3d); break; case 8: - NewVolume = aHelper.AddVolume(aNds[0], aNds[1], aNds[2], aNds[3], - aNds[4], aNds[5], aNds[6], aNds[7], id, theForce3d); + NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], + nodes[4], nodes[5], nodes[6], nodes[7], id, theForce3d); break; default: - continue; + NewVolume = aHelper.AddPolyhedralVolume(nodes, nbNodeInFaces, id, theForce3d); } ReplaceElemInGroups(volume, NewVolume, meshDS); } } - if ( !theForce3d && !getenv("NO_FixQuadraticElements")) { - aHelper.SetSubShape(0); // apply to the whole mesh + + if ( !theForce3d && !getenv("NO_FixQuadraticElements")) + { // setenv NO_FixQuadraticElements to know if FixQuadraticElements() is guilty of bad conversion + aHelper.SetSubShape(0); // apply FixQuadraticElements() to the whole mesh aHelper.FixQuadraticElements(); } } @@ -9085,8 +8906,8 @@ int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh * theSm, { int id = elem->GetID(); int nbNodes = elem->NbNodes(); - vector aNds, mediumNodes; - aNds.reserve( nbNodes ); + vector nodes, mediumNodes; + nodes.reserve( nbNodes ); mediumNodes.reserve( nbNodes ); for(int i = 0; i < nbNodes; i++) @@ -9096,15 +8917,15 @@ int SMESH_MeshEditor::removeQuadElem(SMESHDS_SubMesh * theSm, if( elem->IsMediumNode( n ) ) mediumNodes.push_back( n ); else - aNds.push_back( n ); + nodes.push_back( n ); } - if( aNds.empty() ) continue; + if( nodes.empty() ) continue; SMDSAbs_ElementType aType = elem->GetType(); //remove old quadratic element meshDS->RemoveFreeElement( elem, theSm, notFromGroups ); - SMDS_MeshElement * NewElem = AddElement( aNds, aType, false, id ); + SMDS_MeshElement * NewElem = AddElement( nodes, aType, false, id ); ReplaceElemInGroups(elem, NewElem, meshDS); if( theSm && NewElem ) theSm->AddElement( NewElem ); @@ -10010,7 +9831,7 @@ bool SMESH_MeshEditor::doubleNodes( SMESHDS_Mesh* theMeshDS, continue; if ( theIsDoubleElem ) - myLastCreatedElems.Append( AddElement(newNodes, anElem->GetType(), anElem->IsPoly()) ); + AddElement(newNodes, anElem->GetType(), anElem->IsPoly()); else theMeshDS->ChangeElementNodes( anElem, &newNodes[ 0 ], anElem->NbNodes() ); @@ -10235,7 +10056,7 @@ bool SMESH_MeshEditor::DoubleNodesInRegion( const TIDSortedElemSet& theElems, //================================================================================ /*! - * \brief Generated skin mesh (containing 2D cells) from 3D mesh + * \brief Generates skin mesh (containing 2D cells) from 3D mesh * The created 2D mesh elements based on nodes of free faces of boundary volumes * \return TRUE if operation has been completed successfully, FALSE otherwise */ @@ -10277,9 +10098,195 @@ bool SMESH_MeshEditor::Make2DMeshFrom3D() nbExisted++; continue; // face already exsist } - myLastCreatedElems.Append( AddElement(nodes, SMDSAbs_Face, isPoly && iface == 1) ); + AddElement(nodes, SMDSAbs_Face, isPoly && iface == 1); nbCreated++; } } return ( nbFree==(nbExisted+nbCreated) ); } + +namespace +{ + inline const SMDS_MeshNode* getNodeWithSameID(SMESHDS_Mesh* mesh, const SMDS_MeshNode* node) + { + if ( const SMDS_MeshNode* n = mesh->FindNode( node->GetID() )) + return n; + return mesh->AddNodeWithID( node->X(),node->Y(),node->Z(), node->GetID() ); + } +} +//================================================================================ +/*! + * \brief Creates missing boundary elements + * \param elements - elements whose boundary is to be checked + * \param dimension - defines type of boundary elements to create + * \param group - a group to store created boundary elements in + * \param targetMesh - a mesh to store created boundary elements in + * \param toCopyElements - if true, the checked elements will be copied into the targetMesh + * \param toCopyExistingBondary - if true, not only new but also pre-existing + * boundary elements will be copied into the targetMesh + */ +//================================================================================ + +void SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements, + Bnd_Dimension dimension, + SMESH_Group* group/*=0*/, + SMESH_Mesh* targetMesh/*=0*/, + bool toCopyElements/*=false*/, + bool toCopyExistingBondary/*=false*/) +{ + SMDSAbs_ElementType missType = (dimension == BND_2DFROM3D) ? SMDSAbs_Face : SMDSAbs_Edge; + SMDSAbs_ElementType elemType = (dimension == BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume; + // hope that all elements are of the same type, do not check them all + if ( !elements.empty() && (*elements.begin())->GetType() != elemType ) + throw SALOME_Exception(LOCALIZED("wrong element type")); + + if ( !targetMesh ) + toCopyElements = toCopyExistingBondary = false; + + SMESH_MeshEditor tgtEditor( targetMesh ? targetMesh : myMesh ); + SMESHDS_Mesh* aMesh = GetMeshDS(), *tgtMeshDS = tgtEditor.GetMeshDS(); + + SMDS_VolumeTool vTool; + TIDSortedElemSet emptySet, avoidSet; + int inode; + + typedef vector TConnectivity; + + SMDS_ElemIteratorPtr eIt; + if (elements.empty()) + eIt = aMesh->elementsIterator(elemType); + else + eIt = SMDS_ElemIteratorPtr( new TSetIterator( elements.begin(), elements.end() )); + + while (eIt->more()) + { + const SMDS_MeshElement* elem = eIt->next(); + const int iQuad = elem->IsQuadratic(); + + // 1. For an elem, get present bnd elements and connectivities of missing bnd elements + vector presentBndElems; + vector missingBndElems; + TConnectivity nodes; + if ( vTool.Set(elem) ) // elem is a volume ------------------------------------------ + { + vTool.SetExternalNormal(); + for ( int iface = 0, n = vTool.NbFaces(); iface < n; iface++ ) + { + if (!vTool.IsFreeFace(iface)) + continue; + int nbFaceNodes = vTool.NbFaceNodes(iface); + const SMDS_MeshNode** nn = vTool.GetFaceNodes(iface); + if ( missType == SMDSAbs_Edge ) // boundary edges + { + nodes.resize( 2+iQuad ); + for ( int i = 0; i < nbFaceNodes; i += 1+iQuad) + { + for ( int j = 0; j < nodes.size(); ++j ) + nodes[j] =nn[i+j]; + if ( const SMDS_MeshElement* edge = + aMesh->FindElement(nodes,SMDSAbs_Edge,/*noMedium=*/0)) + presentBndElems.push_back( edge ); + else + missingBndElems.push_back( nodes ); + } + } + else // boundary face + { + nodes.clear(); + for ( inode = 0; inode < nbFaceNodes; inode += 1+iQuad) + nodes.push_back( nn[inode] ); + if (iQuad) + for ( inode = 1; inode < nbFaceNodes; inode += 2) + nodes.push_back( nn[inode] ); + + if (const SMDS_MeshFace * f = aMesh->FindFace( nodes ) ) + presentBndElems.push_back( f ); + else + missingBndElems.push_back( nodes ); + } + } + } + else // elem is a face ------------------------------------------ + { + avoidSet.clear(), avoidSet.insert( elem ); + int nbNodes = elem->NbCornerNodes(); + nodes.resize( 2 /*+ iQuad*/); + for ( int i = 0; i < nbNodes; i++ ) + { + nodes[0] = elem->GetNode(i); + nodes[1] = elem->GetNode((i+1)%nbNodes); + if ( FindFaceInSet( nodes[0], nodes[1], emptySet, avoidSet)) + continue; // not free link + + //if ( iQuad ) + //nodes[2] = elem->GetNode( i + nbNodes ); + if ( const SMDS_MeshElement* edge = + aMesh->FindElement(nodes,SMDSAbs_Edge,/*noMedium=*/true)) + presentBndElems.push_back( edge ); + else + missingBndElems.push_back( nodes ); + } + } + + // 2. Add missing boundary elements + if ( targetMesh != myMesh ) + // instead of making a map of nodes in this mesh and targetMesh, + // we create nodes with same IDs. We can renumber them later, if needed + for ( int i = 0; i < missingBndElems.size(); ++i ) + { + TConnectivity& srcNodes = missingBndElems[i]; + TConnectivity nodes( srcNodes.size() ); + for ( inode = 0; inode < nodes.size(); ++inode ) + nodes[inode] = getNodeWithSameID( tgtMeshDS, srcNodes[inode] ); + tgtEditor.AddElement(nodes, missType, elem->IsPoly() && nodes.size()/(iQuad+1)>4); + } + else + for ( int i = 0; i < missingBndElems.size(); ++i ) + { + TConnectivity& nodes = missingBndElems[i]; + tgtEditor.AddElement(nodes, missType, elem->IsPoly() && nodes.size()/(iQuad+1)>4); + } + + // 3. Copy present boundary elements + if ( toCopyExistingBondary ) + for ( int i = 0 ; i < presentBndElems.size(); ++i ) + { + const SMDS_MeshElement* e = presentBndElems[i]; + TConnectivity nodes( e->NbNodes() ); + for ( inode = 0; inode < nodes.size(); ++inode ) + nodes[inode] = getNodeWithSameID( tgtMeshDS, e->GetNode(inode) ); + tgtEditor.AddElement(nodes, missType, e->IsPoly()); + // leave only missing elements in tgtEditor.myLastCreatedElems + tgtEditor.myLastCreatedElems.Remove( tgtEditor.myLastCreatedElems.Size() ); + } + } // loop on given elements + + // 4. Fill group with missing boundary elements + if ( group ) + { + if ( SMESHDS_Group* g = dynamic_cast( group->GetGroupDS() )) + for ( int i = 0; i < tgtEditor.myLastCreatedElems.Size(); ++i ) + g->SMDSGroup().Add( tgtEditor.myLastCreatedElems( i+1 )); + } + tgtEditor.myLastCreatedElems.Clear(); + + // 5. Copy given elements + if ( toCopyElements ) + { + if (elements.empty()) + eIt = aMesh->elementsIterator(elemType); + else + eIt = SMDS_ElemIteratorPtr( new TSetIterator( elements.begin(), elements.end() )); + while (eIt->more()) + { + const SMDS_MeshElement* elem = eIt->next(); + TConnectivity nodes( elem->NbNodes() ); + for ( inode = 0; inode < nodes.size(); ++inode ) + nodes[inode] = getNodeWithSameID( tgtMeshDS, elem->GetNode(inode) ); + tgtEditor.AddElement(nodes, elemType, elem->IsPoly()); + + tgtEditor.myLastCreatedElems.Clear(); + } + } + return; +} diff --git a/src/SMESH/SMESH_MeshEditor.hxx b/src/SMESH/SMESH_MeshEditor.hxx index d9f4b5d28..dabe3f8db 100644 --- a/src/SMESH/SMESH_MeshEditor.hxx +++ b/src/SMESH/SMESH_MeshEditor.hxx @@ -60,6 +60,7 @@ typedef std::map TNodeNodeMap; //!< Set of elements sorted by ID, to be used to assure predictability of edition typedef std::set< const SMDS_MeshElement*, TIDCompare > TIDSortedElemSet; +typedef std::set< const SMDS_MeshNode*, TIDCompare > TIDSortedNodeSet; typedef pair< const SMDS_MeshNode*, const SMDS_MeshNode* > NLink; @@ -92,6 +93,13 @@ struct SMESH_ElementSearcher std::vector< const SMDS_MeshElement* >& foundElems)=0; virtual TopAbs_State GetPointState(const gp_Pnt& point) = 0; + + /*! + * \brief Return elements possibly intersecting the line + */ + virtual void GetElementsNearLine( const gp_Ax1& line, + SMDSAbs_ElementType type, + std::vector< const SMDS_MeshElement* >& foundElems)=0; }; //======================================================================= @@ -171,7 +179,7 @@ public: const bool isPoly, const int ID = 0); - bool Remove (const std::list< int >& theElemIDs, const bool isNodes); + int Remove (const std::list< int >& theElemIDs, const bool isNodes); // Remove a node or an element. // Modify a compute state of sub-meshes which become empty @@ -237,7 +245,7 @@ public: SMESH::Controls::NumericalFunctorPtr theCriterion); - enum SplitVolumToTetraFlags { HEXA_TO_5 = 1, HEXA_TO_6 = 2 };//!& theScaleFact, - const bool theCopy, - const bool theMakeGroups, - SMESH_Mesh* theTargetMesh=0); - typedef std::list< std::list< const SMDS_MeshNode* > > TListOfListOfNodes; - void FindCoincidentNodes (std::set & theNodes, - const double theTolerance, - TListOfListOfNodes & theGroupsOfNodes); + void FindCoincidentNodes (TIDSortedNodeSet & theNodes, + const double theTolerance, + TListOfListOfNodes & theGroupsOfNodes); // Return list of group of nodes close to each other within theTolerance. // Search among theNodes or in the whole mesh if theNodes is empty. /*! - * \brief Return SMESH_NodeSearcher + * \brief Return SMESH_NodeSearcher. The caller is responsible for deleteing it */ SMESH_NodeSearcher* GetNodeSearcher(); /*! - * \brief Return SMESH_ElementSearcher + * \brief Return SMESH_ElementSearcher. The caller is responsible for deleteing it */ SMESH_ElementSearcher* GetElementSearcher(); /*! @@ -532,12 +523,18 @@ public: // theBetweenNode1 - theBetweenNode2, between theBetweenNode1 and theBetweenNode2. void ConvertToQuadratic(const bool theForce3d); - //converts all mesh to quadratic one, deletes old elements, replacing - //them with quadratic ones with the same id. + // Converts all mesh to quadratic one, deletes old elements, replacing + // them with quadratic ones with the same id. + // If theForce3d = 1; this results in the medium node lying at the + // middle of the line segments connecting start and end node of a mesh + // element + // If theForce3d = 0; this results in the medium node lying at the + // geometrical edge from which the mesh element is built bool ConvertFromQuadratic(); - //converts all mesh from quadratic to ordinary ones, deletes old quadratic elements, replacing - //them with ordinary mesh elements with the same id. + // Converts all mesh from quadratic to ordinary ones, deletes old quadratic elements, replacing + // them with ordinary mesh elements with the same id. + // Returns true in case of success, false otherwise. static void AddToSameGroups (const SMDS_MeshElement* elemToAdd, const SMDS_MeshElement* elemInGroups, @@ -627,13 +624,17 @@ public: const TIDSortedElemSet& theNodesNot, const TopoDS_Shape& theShape ); - /*! - * \brief Generated skin mesh (containing 2D cells) from 3D mesh - * The created 2D mesh elements based on nodes of free faces of boundary volumes - * \return TRUE if operation has been completed successfully, FALSE otherwise - */ bool Make2DMeshFrom3D(); - + + enum Bnd_Dimension { BND_2DFROM3D, BND_1DFROM3D, BND_1DFROM2D }; + + void MakeBoundaryMesh(const TIDSortedElemSet& elements, + Bnd_Dimension dimension, + SMESH_Group* group = 0, + SMESH_Mesh* targetMesh = 0, + bool toCopyElements = false, + bool toCopyExistingBondary = false); + private: /*! diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index 8cdacf7ed..bb96f0352 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -89,9 +89,16 @@ SMESH_MesherHelper::SMESH_MesherHelper(SMESH_Mesh& theMesh) SMESH_MesherHelper::~SMESH_MesherHelper() { - TID2Projector::iterator i_proj = myFace2Projector.begin(); - for ( ; i_proj != myFace2Projector.end(); ++i_proj ) - delete i_proj->second; + { + TID2ProjectorOnSurf::iterator i_proj = myFace2Projector.begin(); + for ( ; i_proj != myFace2Projector.end(); ++i_proj ) + delete i_proj->second; + } + { + TID2ProjectorOnCurve::iterator i_proj = myEdge2Projector.begin(); + for ( ; i_proj != myEdge2Projector.end(); ++i_proj ) + delete i_proj->second; + } } //======================================================================= @@ -356,7 +363,7 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F, static_cast(n->GetPosition().get()); uv.SetCoord(fpos->GetUParameter(),fpos->GetVParameter()); if ( check ) - uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), BRep_Tool::Tolerance( F )); + uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*MaxTolerance( F )); } else if(Pos->GetTypeOfPosition()==SMDS_TOP_EDGE) { @@ -375,12 +382,12 @@ gp_XY SMESH_MesherHelper::GetNodeUV(const TopoDS_Face& F, else uv.SetCoord(0.,0.); if ( check || !validU ) - uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), BRep_Tool::Tolerance( E ),/*force=*/ !validU ); + uvOK = CheckNodeUV( F, n, uv.ChangeCoord(), 10*MaxTolerance( F ),/*force=*/ !validU ); // for a node on a seam edge select one of UVs on 2 pcurves if ( n2 && IsSeamShape( edgeID ) ) { - uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0 )); + uv = GetUVOnSeam( uv, GetNodeUV( F, n2, 0, check )); } else { // adjust uv to period @@ -491,12 +498,12 @@ bool SMESH_MesherHelper::CheckNodeUV(const TopoDS_Face& F, } Quantity_Parameter U,V; projector.LowerDistanceParameters(U,V); + uv.SetCoord( U,V ); if ( nodePnt.Distance( surface->Value( U, V )) > tol ) { MESSAGE( "SMESH_MesherHelper::CheckNodeUV(), invalid projection" ); return false; } - uv.SetCoord( U,V ); } else if ( uv.Modulus() > numeric_limits::min() ) { @@ -517,8 +524,8 @@ GeomAPI_ProjectPointOnSurf& SMESH_MesherHelper::GetProjector(const TopoDS_Face& { Handle(Geom_Surface) surface = BRep_Tool::Surface( F,loc ); int faceID = GetMeshDS()->ShapeToIndex( F ); - TID2Projector& i2proj = const_cast< TID2Projector&>( myFace2Projector ); - TID2Projector::iterator i_proj = i2proj.find( faceID ); + TID2ProjectorOnSurf& i2proj = const_cast< TID2ProjectorOnSurf&>( myFace2Projector ); + TID2ProjectorOnSurf::iterator i_proj = i2proj.find( faceID ); if ( i_proj == i2proj.end() ) { if ( tol == 0 ) tol = BRep_Tool::Tolerance( F ); @@ -632,7 +639,7 @@ double SMESH_MesherHelper::GetNodeU(const TopoDS_Edge& E, if ( !force && pos->GetTypeOfPosition()==SMDS_TOP_EDGE ) force = ( GetMeshDS()->ShapeToIndex( E ) != pos->GetShapeId() ); - *check = CheckNodeU( E, n, param, tol, force ); + *check = CheckNodeU( E, n, param, 2*tol, force ); } return param; } @@ -647,7 +654,8 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge& E, const SMDS_MeshNode* n, double& u, const double tol, - const bool force) const + const bool force, + double* distance) const { if ( force || !myOkNodePosShapes.count( n->GetPosition()->GetShapeId() )) { @@ -666,22 +674,37 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge& E, { gp_Pnt nodePnt = SMESH_MeshEditor::TNodeXYZ( n ); if ( !loc.IsIdentity() ) nodePnt.Transform( loc.Transformation().Inverted() ); - if ( nodePnt.Distance( curve->Value( u )) > tol ) + double dist = nodePnt.Distance( curve->Value( u )); + if ( distance ) *distance = dist; + if ( dist > tol ) { // u incorrect, project the node to the curve - GeomAPI_ProjectPointOnCurve projector( nodePnt, curve, f, l ); - if ( projector.NbPoints() < 1 ) + int edgeID = GetMeshDS()->ShapeToIndex( E ); + TID2ProjectorOnCurve& i2proj = const_cast< TID2ProjectorOnCurve&>( myEdge2Projector ); + TID2ProjectorOnCurve::iterator i_proj = + i2proj.insert( make_pair( edgeID, (GeomAPI_ProjectPointOnCurve*) 0 )).first; + if ( !i_proj->second ) + { + i_proj->second = new GeomAPI_ProjectPointOnCurve(); + i_proj->second->Init( curve, f, l ); + } + GeomAPI_ProjectPointOnCurve* projector = i_proj->second; + projector->Perform( nodePnt ); + if ( projector->NbPoints() < 1 ) { MESSAGE( "SMESH_MesherHelper::CheckNodeU() failed to project" ); return false; } - Quantity_Parameter U = projector.LowerDistanceParameter(); - if ( nodePnt.Distance( curve->Value( U )) > tol ) + Quantity_Parameter U = projector->LowerDistanceParameter(); + u = double( U ); + dist = nodePnt.Distance( curve->Value( U )); + if ( distance ) *distance = dist; + if ( dist > tol ) { MESSAGE( "SMESH_MesherHelper::CheckNodeU(), invalid projection" ); return false; } - u = double( U ); + //u = double( U ); } else if ( fabs( u ) > numeric_limits::min() ) { @@ -767,6 +790,11 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1, } else if (edgeID>0 || shapeType == TopAbs_EDGE) { + if ( Pos1->GetTypeOfPosition()==SMDS_TOP_EDGE && + Pos2->GetTypeOfPosition()==SMDS_TOP_EDGE && + Pos1->GetShapeId() != Pos2->GetShapeId() ) // issue 0021006 + return getMediumNodeOnComposedWire(n1,n2,force3d); + if( myShape.IsNull() ) E = TopoDS::Edge(meshDS->IndexToShape(edgeID)); else { @@ -834,16 +862,16 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1, if ( !F.IsNull() ) { gp_XY UV = ( uv[0] + uv[1] ) / 2.; - CheckNodeUV( F, n12, UV, BRep_Tool::Tolerance( F ), /*force=*/true); + CheckNodeUV( F, n12, UV, 2*BRep_Tool::Tolerance( F ), /*force=*/true); meshDS->SetNodeOnFace(n12, faceID, UV.X(), UV.Y() ); } else if ( !E.IsNull() ) { double U = ( u[0] + u[1] ) / 2.; - CheckNodeU( E, n12, U, BRep_Tool::Tolerance( E ), /*force=*/true); + CheckNodeU( E, n12, U, 2*BRep_Tool::Tolerance( E ), /*force=*/true); meshDS->SetNodeOnEdge(n12, edgeID, U); } - else if ( myShapeID > 1 ) + else if ( myShapeID > 0 ) { meshDS->SetNodeInVolume(n12, myShapeID); } @@ -851,6 +879,78 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1, return n12; } +//================================================================================ +/*! + * \brief Makes a medium node if nodes reside different edges + */ +//================================================================================ + +const SMDS_MeshNode* SMESH_MesherHelper::getMediumNodeOnComposedWire(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + bool force3d) +{ + gp_Pnt middle = 0.5 * XYZ(n1) + 0.5 * XYZ(n2); + SMDS_MeshNode* n12 = AddNode( middle.X(), middle.Y(), middle.Z() ); + + // To find position on edge and 3D position for n12, + // project to 2 edges and select projection most close to + + double u = 0, distMiddleProj = Precision::Infinite(); + int iOkEdge = 0; + TopoDS_Edge edges[2]; + for ( int is2nd = 0; is2nd < 2; ++is2nd ) + { + // get an edge + const SMDS_MeshNode* n = is2nd ? n2 : n1; + TopoDS_Shape shape = GetSubShapeByNode( n, GetMeshDS() ); + if ( shape.IsNull() || shape.ShapeType() != TopAbs_EDGE ) + continue; + + // project to get U of projection and distance from middle to projection + TopoDS_Edge edge = edges[ is2nd ] = TopoDS::Edge( shape ); + double node2MiddleDist = middle.Distance( XYZ(n) ); + double foundU = GetNodeU( edge, n ), foundDist = node2MiddleDist; + CheckNodeU( edge, n12, foundU, 2*BRep_Tool::Tolerance(edge), /*force=*/true, &foundDist ); + if ( foundDist < node2MiddleDist ) + { + distMiddleProj = foundDist; + u = foundU; + iOkEdge = is2nd; + } + } + if ( Precision::IsInfinite( distMiddleProj )) + { + // both projections failed; set n12 on the edge of n1 with U of a common vertex + TopoDS_Vertex vCommon; + if ( TopExp::CommonVertex( edges[0], edges[1], vCommon )) + u = BRep_Tool::Parameter( vCommon, edges[0] ); + else + { + double f,l, u0 = GetNodeU( edges[0], n1 ); + BRep_Tool::Range( edges[0],f,l ); + u = ( fabs(u0-f) < fabs(u0-l) ) ? f : l; + } + iOkEdge = 0; + distMiddleProj = 0; + } + + // move n12 to position of a successfull projection + double tol = BRep_Tool::Tolerance(edges[ iOkEdge ]); + if ( !force3d && distMiddleProj > 2*tol ) + { + TopLoc_Location loc; double f,l; + Handle(Geom_Curve) curve = BRep_Tool::Curve( edges[iOkEdge],loc,f,l ); + gp_Pnt p = curve->Value( u ); + GetMeshDS()->MoveNode( n12, p.X(), p.Y(), p.Z() ); + } + + GetMeshDS()->SetNodeOnEdge(n12, edges[iOkEdge], u); + + myTLinkNodeMap.insert( make_pair( SMESH_TLink(n1,n2), n12 )); + + return n12; +} + //======================================================================= //function : AddNode //purpose : Creates a node @@ -1006,6 +1106,45 @@ SMDS_MeshFace* SMESH_MesherHelper::AddFace(const SMDS_MeshNode* n1, return elem; } +//======================================================================= +//function : AddPolygonalFace +//purpose : Creates polygon, with additional nodes in quadratic mesh +//======================================================================= + +SMDS_MeshFace* SMESH_MesherHelper::AddPolygonalFace (const vector& nodes, + const int id, + const bool force3d) +{ + SMESHDS_Mesh * meshDS = GetMeshDS(); + SMDS_MeshFace* elem = 0; + + if(!myCreateQuadratic) { + if(id) + elem = meshDS->AddPolygonalFaceWithID(nodes, id); + else + elem = meshDS->AddPolygonalFace(nodes); + } + else { + vector newNodes; + for ( int i = 0; i < nodes.size(); ++i ) + { + const SMDS_MeshNode* n1 = nodes[i]; + const SMDS_MeshNode* n2 = nodes[(i+1)/nodes.size()]; + const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d); + newNodes.push_back( n1 ); + newNodes.push_back( n12 ); + } + if(id) + elem = meshDS->AddPolygonalFaceWithID(newNodes, id); + else + elem = meshDS->AddPolygonalFace(newNodes); + } + if ( mySetElemOnShape && myShapeID > 0 ) + meshDS->SetMeshElementOnShape( elem, myShapeID ); + + return elem; +} + //======================================================================= //function : AddVolume //purpose : Creates quadratic or linear prism @@ -1196,6 +1335,62 @@ SMDS_MeshVolume* SMESH_MesherHelper::AddVolume(const SMDS_MeshNode* n1, return elem; } +//======================================================================= +//function : AddPolyhedralVolume +//purpose : Creates polyhedron. In quadratic mesh, adds medium nodes +//======================================================================= + +SMDS_MeshVolume* +SMESH_MesherHelper::AddPolyhedralVolume (const std::vector& nodes, + const std::vector& quantities, + const int id, + const bool force3d) +{ + SMESHDS_Mesh * meshDS = GetMeshDS(); + SMDS_MeshVolume* elem = 0; + if(!myCreateQuadratic) + { + if(id) + elem = meshDS->AddPolyhedralVolumeWithID(nodes, quantities, id); + else + elem = meshDS->AddPolyhedralVolume(nodes, quantities); + } + else + { + vector newNodes; + vector newQuantities; + for ( int iFace=0, iN=0; iFace < quantities.size(); ++iFace) + { + int nbNodesInFace = quantities[iFace]; + newQuantities.push_back(0); + for ( int i = 0; i < nbNodesInFace; ++i ) + { + const SMDS_MeshNode* n1 = nodes[ iN + i ]; + newNodes.push_back( n1 ); + newQuantities.back()++; + + const SMDS_MeshNode* n2 = nodes[ iN + ( i+1==nbNodesInFace ? 0 : i+1 )]; +// if ( n1->GetPosition()->GetTypeOfPosition() != SMDS_TOP_3DSPACE && +// n2->GetPosition()->GetTypeOfPosition() != SMDS_TOP_3DSPACE ) + { + const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,force3d); + newNodes.push_back( n12 ); + newQuantities.back()++; + } + } + iN += nbNodesInFace; + } + if(id) + elem = meshDS->AddPolyhedralVolumeWithID( newNodes, newQuantities, id ); + else + elem = meshDS->AddPolyhedralVolume( newNodes, newQuantities ); + } + if ( mySetElemOnShape && myShapeID > 0 ) + meshDS->SetMeshElementOnShape( elem, myShapeID ); + + return elem; +} + //======================================================================= //function : LoadNodeColumns //purpose : Load nodes bound to face into a map of node columns @@ -1343,6 +1538,26 @@ bool SMESH_MesherHelper::IsSubShape( const TopoDS_Shape& shape, SMESH_Mesh* aMes shape.ShapeType() == TopAbs_COMPOUND && aMesh->GetMeshDS()->IsGroupOfSubShapes( shape ); } +//================================================================================ +/*! + * \brief Return maximal tolerance of shape + */ +//================================================================================ + +double SMESH_MesherHelper::MaxTolerance( const TopoDS_Shape& shape ) +{ + double tol = Precision::Confusion(); + TopExp_Explorer exp; + for ( exp.Init( shape, TopAbs_FACE ); exp.More(); exp.Next() ) + tol = Max( tol, BRep_Tool::Tolerance( TopoDS::Face( exp.Current()))); + for ( exp.Init( shape, TopAbs_EDGE ); exp.More(); exp.Next() ) + tol = Max( tol, BRep_Tool::Tolerance( TopoDS::Edge( exp.Current()))); + for ( exp.Init( shape, TopAbs_VERTEX ); exp.More(); exp.Next() ) + tol = Max( tol, BRep_Tool::Tolerance( TopoDS::Vertex( exp.Current()))); + + return tol; +} + //======================================================================= //function : IsQuadraticMesh //purpose : Check mesh without geometry for: if all elements on this shape are quadratic, @@ -1388,16 +1603,23 @@ double SMESH_MesherHelper::GetOtherParam(const double param) const return fabs(param-myPar1[i]) < fabs(param-myPar2[i]) ? myPar2[i] : myPar1[i]; } +//#include + //======================================================================= namespace { // Structures used by FixQuadraticElements() //======================================================================= #define __DMP__(txt) \ -//cout << txt + //cout << txt #define MSG(txt) __DMP__(txt< < 1/15 * + return middleNodeMove2 < 1/15./15. * linkLen2; + } struct QFace; // --------------------------------------- @@ -1434,8 +1656,10 @@ namespace { // Structures used by FixQuadraticElements() { _nodeMove += move; _nbMoves += sum ? (_nbMoves==0) : 1; } gp_XYZ Move() const { return _nodeMove.XYZ() / _nbMoves; } bool IsMoved() const { return (_nbMoves > 0 && !IsStraight()); } - bool IsStraight() const { return _nodeMove.SquareMagnitude() <= straightTol2; } - + bool IsStraight() const + { return isStraightLink( (XYZ(node1())-XYZ(node2())).SquareModulus(), + _nodeMove.SquareMagnitude()); + } bool operator<(const QLink& other) const { return (node1()->GetID() == other.node1()->GetID() ? node2()->GetID() < other.node2()->GetID() : @@ -1457,7 +1681,7 @@ namespace { // Structures used by FixQuadraticElements() TChainLink(const QLink* qlink=0):_qlink(qlink) { _qfaces[0] = _qfaces[1] = 0; } - void SetFace(const QFace* face) { int iF = _qfaces[0] ? 1 : 0; _qfaces[iF]=face; } + void SetFace(const QFace* face) const { int iF = _qfaces[0] ? 1 : 0; _qfaces[iF]=face; } bool IsBoundary() const { return !_qfaces[1]; } @@ -1616,7 +1840,7 @@ namespace { // Structures used by FixQuadraticElements() } //================================================================================ /*! - * \brief Make up chain of links + * \brief Make up a chain of links * \param iSide - link to add first * \param chain - chain to fill in * \param pos - postion of medium nodes the links should have @@ -1635,22 +1859,33 @@ namespace { // Structures used by FixQuadraticElements() if ( _sides.size() != 4 ) { // triangle - visit all my continous faces MSGBEG( *this ); + TLinkSet links; list< const QFace* > faces( 1, this ); - for (list< const QFace* >::iterator fIt = faces.begin(); fIt != faces.end(); ++fIt ) { - const QFace* face = *fIt; + while ( !faces.empty() ) { + const QFace* face = faces.front(); for ( int i = 0; i < face->_sides.size(); ++i ) { if ( !face->_sideIsAdded[i] && face->_sides[i] ) { face->_sideIsAdded[i] = true; - TChain::iterator chLink = chain.insert( chain.begin(), TChainLink(face->_sides[i])); + // find a face side in the chain + TLinkInSet chLink = links.insert( TChainLink(face->_sides[i])).first; +// TChain::iterator chLink = chain.begin(); +// for ( ; chLink != chain.end(); ++chLink ) +// if ( chLink->_qlink == face->_sides[i] ) +// break; +// if ( chLink == chain.end() ) +// chLink = chain.insert( chain.begin(), TChainLink(face->_sides[i])); + // add a face to a chained link and put a continues face in the queue chLink->SetFace( face ); if ( face->_sides[i]->MediumPos() >= pos ) if ( const QFace* contFace = face->_sides[i]->GetContinuesFace( face )) faces.push_back( contFace ); } } + faces.pop_front(); } if ( error < ERR_TRI ) error = ERR_TRI; + chain.insert( chain.end(), links.begin(),links.end() ); return false; } _sideIsAdded[iSide] = true; // not to add this link to chain again @@ -1716,7 +1951,7 @@ namespace { // Structures used by FixQuadraticElements() TLinkInSet link = links.find( _sides[iL] ); if ( link == linksEnd ) continue; if ( (*link)->MediumPos() > SMDS_TOP_FACE ) - continue; // We work on faces here, don't go into a volume + continue; // We work on faces here, don't go inside a solid // check link if ( link->IsBoundary() ) { @@ -1859,7 +2094,8 @@ namespace { // Structures used by FixQuadraticElements() // propagate to adjacent faces till limit step or boundary double len1 = thePrevLen + (theLink->MiddlePnt() - _sides[iL1]->MiddlePnt()).Modulus(); double len2 = thePrevLen + (theLink->MiddlePnt() - _sides[iL2]->MiddlePnt()).Modulus(); - gp_Vec linkDir1, linkDir2; + gp_Vec linkDir1(0,0,0); // initialize to avoid valgrind error ("Conditional jump...") + gp_Vec linkDir2(0,0,0); try { OCC_CATCH_SIGNALS; if ( f1 ) @@ -2095,7 +2331,7 @@ namespace { // Structures used by FixQuadraticElements() enum TSplitTriaResult { _OK, _NO_CORNERS, _FEW_ROWS, _MANY_ROWS, _NO_SIDELINK, _BAD_MIDQUAD, _NOT_RECT, - _NO_MIDQUAD, _NO_UPTRIA, _BAD_SET_SIZE, _BAD_CORNER, _BAD_START, _NO_BOTLINK }; + _NO_MIDQUAD, _NO_UPTRIA, _BAD_SET_SIZE, _BAD_CORNER, _BAD_START, _NO_BOTLINK, _TWISTED_CHAIN }; TSplitTriaResult splitTrianglesIntoChains( TChain & allLinks, vector< TChain> & resultChains, @@ -2161,6 +2397,8 @@ namespace { // Structures used by FixQuadraticElements() const QFace* botTria = botLink->_qfaces[0]; // bottom triangle bound by botLink if ( !botTria ) { // the column ends + if ( botLink == startLink ) + return _TWISTED_CHAIN; // issue 0020951 linkSet.erase( botLink ); if ( iRow != rowChains.size() ) return _FEW_ROWS; // different nb of rows in columns @@ -2220,8 +2458,10 @@ namespace { // Structures used by FixQuadraticElements() // next bottom link ends at the new corner linkSet.erase( botLink ); botLink = upTria->GetLinkByNode( linkSet, (isCase2 ? *sideLink : *midQuadLink), corner ); - if ( botLink == linksEnd || botLink == (isCase2 ? midQuadLink : sideLink)) + if ( botLink == linksEnd || botLink == midQuadLink || botLink == sideLink) return _NO_BOTLINK; + if ( midQuadLink == startLink || sideLink == startLink ) + return _TWISTED_CHAIN; // issue 0020951 linkSet.erase( midQuadLink ); linkSet.erase( sideLink ); @@ -2265,7 +2505,7 @@ namespace { // Structures used by FixQuadraticElements() return _OK; } -} +} //namespace //======================================================================= /*! @@ -2278,37 +2518,49 @@ namespace { // Structures used by FixQuadraticElements() void SMESH_MesherHelper::FixQuadraticElements(bool volumeOnly) { - // apply algorithm to solids or geom faces + // 0. Apply algorithm to solids or geom faces // ---------------------------------------------- if ( myShape.IsNull() ) { if ( !myMesh->HasShapeToMesh() ) return; SetSubShape( myMesh->GetShapeToMesh() ); +#ifdef _DEBUG_ + int nbSolids = 0; + TopTools_IndexedMapOfShape solids; + TopExp::MapShapes(myShape,TopAbs_SOLID,solids); + nbSolids = solids.Extent(); +#endif TopTools_MapOfShape faces; // faces not in solid or in not meshed solid for ( TopExp_Explorer f(myShape,TopAbs_FACE,TopAbs_SOLID); f.More(); f.Next() ) { - faces.Add( f.Current() ); + faces.Add( f.Current() ); // not in solid } for ( TopExp_Explorer s(myShape,TopAbs_SOLID); s.More(); s.Next() ) { if ( myMesh->GetSubMesh( s.Current() )->IsEmpty() ) { // get faces of solid for ( TopExp_Explorer f( s.Current(), TopAbs_FACE); f.More(); f.Next() ) - faces.Add( f.Current() ); + faces.Add( f.Current() ); // in not meshed solid } else { // fix nodes in the solid and its faces + MSG("FIX SOLID " << nbSolids-- << " #" << GetMeshDS()->ShapeToIndex(s.Current())); SMESH_MesherHelper h(*myMesh); h.SetSubShape( s.Current() ); h.FixQuadraticElements(false); } } // fix nodes on geom faces +#ifdef _DEBUG_ + int nbfaces = faces.Extent(); +#endif for ( TopTools_MapIteratorOfMapOfShape fIt( faces ); fIt.More(); fIt.Next() ) { + MSG("FIX FACE " << nbfaces-- << " #" << GetMeshDS()->ShapeToIndex(fIt.Key())); SMESH_MesherHelper h(*myMesh); h.SetSubShape( fIt.Key() ); h.FixQuadraticElements(true); } + //perf_print_all_meters(1); return; } - // Find out type of elements and get iterator on them + // 1. Find out type of elements and get iterator on them // --------------------------------------------------- SMDS_ElemIteratorPtr elemIt; @@ -2327,7 +2579,7 @@ void SMESH_MesherHelper::FixQuadraticElements(bool volumeOnly) if ( !elemIt || !elemIt->more() || elemType < SMDSAbs_Face ) return; - // Fill in auxiliary data structures + // 2. Fill in auxiliary data structures // ---------------------------------- set< QLink > links; @@ -2336,7 +2588,7 @@ void SMESH_MesherHelper::FixQuadraticElements(bool volumeOnly) set< QFace >::iterator pFace; bool isCurved = false; - bool hasRectFaces = false; + //bool hasRectFaces = false; set nbElemNodeSet; if ( elemType == SMDSAbs_Volume ) @@ -2369,9 +2621,9 @@ void SMESH_MesherHelper::FixQuadraticElements(bool volumeOnly) if ( pFace->NbVolumes() == 0 ) pFace->AddSelfToLinks(); pFace->SetVolume( vol ); - hasRectFaces = hasRectFaces || - ( volTool.GetVolumeType() == SMDS_VolumeTool::QUAD_HEXA || - volTool.GetVolumeType() == SMDS_VolumeTool::QUAD_PENTA ); +// hasRectFaces = hasRectFaces || +// ( volTool.GetVolumeType() == SMDS_VolumeTool::QUAD_HEXA || +// volTool.GetVolumeType() == SMDS_VolumeTool::QUAD_PENTA ); #ifdef _DEBUG_ if ( nbN == 6 ) pFace->_face = GetMeshDS()->FindFace(faceNodes[0],faceNodes[2],faceNodes[4]); @@ -2407,13 +2659,13 @@ void SMESH_MesherHelper::FixQuadraticElements(bool volumeOnly) // store QFace pFace = faces.insert( QFace( faceLinks )).first; pFace->AddSelfToLinks(); - hasRectFaces = ( hasRectFaces || nbN == 4 ); + //hasRectFaces = ( hasRectFaces || nbN == 4 ); } } if ( !isCurved ) return; // no curved edges of faces - // Compute displacement of medium nodes + // 3. Compute displacement of medium nodes // ------------------------------------- // two loops on faces: the first is to treat boundary links, the second is for internal ones @@ -2423,6 +2675,7 @@ void SMESH_MesherHelper::FixQuadraticElements(bool volumeOnly) for ( ; isInside < 2; ++isInside ) { MSG( "--------------- LOOP (inside=" << isInside << ") ------------------"); SMDS_TypeOfPosition pos = isInside ? SMDS_TOP_3DSPACE : SMDS_TOP_FACE; + SMDS_TypeOfPosition bndPos = isInside ? SMDS_TOP_FACE : SMDS_TOP_EDGE; for ( pFace = faces.begin(); pFace != faces.end(); ++pFace ) { if ( bool(isInside) == pFace->IsBoundary() ) @@ -2461,7 +2714,12 @@ void SMESH_MesherHelper::FixQuadraticElements(bool volumeOnly) TChain& chain = chains[iC]; if ( chain.empty() ) continue; if ( chain.front()->IsStraight() && chain.back()->IsStraight() ) { - MSG("3D straight"); + MSG("3D straight - ignore"); + continue; + } + if ( chain.front()->MediumPos() > bndPos || + chain.back()->MediumPos() > bndPos ) { + MSG("Internal chain - ignore"); continue; } // mesure chain length and compute link position along the chain @@ -2498,6 +2756,7 @@ void SMESH_MesherHelper::FixQuadraticElements(bool volumeOnly) { face = TopoDS::Face( f ); Handle(Geom_Surface) surf = BRep_Tool::Surface(face,loc); + bool isStraight[2]; for ( int is1 = 0; is1 < 2; ++is1 ) // move0 or move1 { TChainLink& link = is1 ? chain.back() : chain.front(); @@ -2508,10 +2767,14 @@ void SMESH_MesherHelper::FixQuadraticElements(bool volumeOnly) // uvMove = uvm - uv12 gp_XY uvMove = applyIn2D(surf, uvm, uv12, gp_XY_Subtracted, /*inPeriod=*/false); ( is1 ? move1 : move0 ).SetCoord( uvMove.X(), uvMove.Y(), 0 ); + if ( !is1 ) // correct nodeOnFace for move1 (issue 0020919) + nodeOnFace = (*(++chain.rbegin()))->_mediumNode; + isStraight[is1] = isStraightLink( (uv2-uv1).SquareModulus(),uvMove.SquareModulus()); } - if ( move0.SquareMagnitude() < straightTol2 && - move1.SquareMagnitude() < straightTol2 ) { - MSG("2D straight"); +// if ( move0.SquareMagnitude() < straightTol2 && +// move1.SquareMagnitude() < straightTol2 ) { + if ( isStraight[0] && isStraight[1] ) { + MSG("2D straight - ignore"); continue; // straight - no need to move nodes of internal links } } @@ -2563,7 +2826,8 @@ void SMESH_MesherHelper::FixQuadraticElements(bool volumeOnly) { gp_XY uv0 = GetNodeUV( face, (*link0)->_mediumNode, 0, &checkUV); gp_XY uv2 = GetNodeUV( face, (*link2)->_mediumNode, 0, &checkUV); - MSG( "uv0: "< #include +#include class GeomAPI_ProjectPointOnSurf; +class GeomAPI_ProjectPointOnCurve; typedef std::map TLinkNodeMap; typedef std::map::iterator ItTLinkNode; @@ -139,6 +141,8 @@ public: static bool IsSubShape( const TopoDS_Shape& shape, SMESH_Mesh* aMesh ); + static double MaxTolerance( const TopoDS_Shape& shape ); + public: // ---------- PUBLIC INSTANCE METHODS ---------- @@ -221,8 +225,15 @@ public: const SMDS_MeshNode* n4, const int id = 0, const bool force3d = false); + + /*! + * Creates polygon, with additional nodes in quadratic mesh + */ + SMDS_MeshFace* AddPolygonalFace (const std::vector& nodes, + const int id = 0, + const bool force3d = false); /*! - * Creates quadratic or linear tetraahedron + * Creates quadratic or linear tetrahedron */ SMDS_MeshVolume* AddVolume(const SMDS_MeshNode* n1, const SMDS_MeshNode* n2, @@ -264,6 +275,14 @@ public: const SMDS_MeshNode* n8, const int id = 0, bool force3d = true); + + /*! + * Creates polyhedron. In quadratic mesh, adds medium nodes + */ + SMDS_MeshVolume* AddPolyhedralVolume (const std::vector& nodes, + const std::vector& quantities, + const int ID=0, + const bool force3d = true); /*! * \brief Return U of the given node on the edge */ @@ -298,7 +317,8 @@ public: const SMDS_MeshNode* n, double& u, const double tol, - const bool force=false) const; + const bool force=false, + double* distance=0) const; /*! * \brief Return middle UV taking in account surface period */ @@ -453,6 +473,9 @@ protected: */ gp_Pnt2d GetUVOnSeam( const gp_Pnt2d& uv1, const gp_Pnt2d& uv2 ) const; + const SMDS_MeshNode* getMediumNodeOnComposedWire(const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + bool force3d); private: // Forbiden copy constructor @@ -466,8 +489,10 @@ protected: double myPar1[2], myPar2[2]; // U and V bounds of a closed periodic surface int myParIndex; // bounds' index (1-U, 2-V, 3-both) - typedef std::map< int, GeomAPI_ProjectPointOnSurf* > TID2Projector; - TID2Projector myFace2Projector; + typedef std::map< int, GeomAPI_ProjectPointOnSurf* > TID2ProjectorOnSurf; + TID2ProjectorOnSurf myFace2Projector; + typedef std::map< int, GeomAPI_ProjectPointOnCurve* > TID2ProjectorOnCurve; + TID2ProjectorOnCurve myEdge2Projector; TopoDS_Shape myShape; SMESH_Mesh* myMesh; diff --git a/src/SMESH/SMESH_OctreeNode.cxx b/src/SMESH/SMESH_OctreeNode.cxx index 37a7d4f1b..7cfe10d11 100644 --- a/src/SMESH/SMESH_OctreeNode.cxx +++ b/src/SMESH/SMESH_OctreeNode.cxx @@ -29,7 +29,6 @@ // #include "SMESH_OctreeNode.hxx" -#include "SMDS_MeshNode.hxx" #include "SMDS_SetIterator.hxx" #include @@ -44,7 +43,7 @@ using namespace std; * \param minBoxSize - Minimal size of the Octree Box */ //================================================================ -SMESH_OctreeNode::SMESH_OctreeNode (const set & theNodes, const int maxLevel, +SMESH_OctreeNode::SMESH_OctreeNode (const TIDSortedNodeSet & theNodes, const int maxLevel, const int maxNbNodes , const double minBoxSize ) :SMESH_Octree( new SMESH_Octree::Limit( maxLevel,minBoxSize)), myMaxNbNodes(maxNbNodes), @@ -86,7 +85,7 @@ SMESH_Octree* SMESH_OctreeNode::allocateOctreeChild() const Bnd_B3d* SMESH_OctreeNode::buildRootBox() { Bnd_B3d* box = new Bnd_B3d; - set::iterator it = myNodes.begin(); + TIDSortedNodeSet::iterator it = myNodes.begin(); for (; it != myNodes.end(); it++) { const SMDS_MeshNode* n1 = *it; gp_XYZ p1( n1->X(), n1->Y(), n1->Z() ); @@ -129,7 +128,7 @@ void SMESH_OctreeNode::buildChildrenData() gp_XYZ max = getBox().CornerMax(); gp_XYZ mid = (min + max)/2.; - set::iterator it = myNodes.begin(); + TIDSortedNodeSet::iterator it = myNodes.begin(); while (it != myNodes.end()) { const SMDS_MeshNode* n1 = *it; @@ -214,7 +213,7 @@ bool SMESH_OctreeNode::NodesAround(const SMDS_MeshNode * node, { double minDist = precision * precision; gp_Pnt p1 ( node->X(), node->Y(), node->Z() ); - set::iterator nIt = myNodes.begin(); + TIDSortedNodeSet::iterator nIt = myNodes.begin(); for ( ; nIt != myNodes.end(); ++nIt ) { gp_Pnt p2 ( (*nIt)->X(), (*nIt)->Y(), (*nIt)->Z() ); @@ -243,7 +242,7 @@ bool SMESH_OctreeNode::NodesAround(const SMDS_MeshNode * node, * \param maxNbNodes - maximum Nodes in a Leaf of the SMESH_OctreeNode constructed, default value is 5 */ //============================= -void SMESH_OctreeNode::FindCoincidentNodes (set& theSetOfNodes, +void SMESH_OctreeNode::FindCoincidentNodes (TIDSortedNodeSet& theSetOfNodes, list< list< const SMDS_MeshNode*> >* theGroupsOfNodes, const double theTolerance, const int maxLevel, @@ -263,11 +262,11 @@ void SMESH_OctreeNode::FindCoincidentNodes (set& theSetOfN * \param theGroupsOfNodes - list of nodes closed to each other returned */ //============================= -void SMESH_OctreeNode::FindCoincidentNodes ( set* theSetOfNodes, +void SMESH_OctreeNode::FindCoincidentNodes ( TIDSortedNodeSet* theSetOfNodes, const double theTolerance, list< list< const SMDS_MeshNode*> >* theGroupsOfNodes) { - set::iterator it1 = theSetOfNodes->begin(); + TIDSortedNodeSet::iterator it1 = theSetOfNodes->begin(); list::iterator it2; while (it1 != theSetOfNodes->end()) @@ -316,7 +315,7 @@ void SMESH_OctreeNode::FindCoincidentNodes ( set* theSetOf */ //====================================================================================== void SMESH_OctreeNode::FindCoincidentNodes (const SMDS_MeshNode * Node, - set* SetOfNodes, + TIDSortedNodeSet* SetOfNodes, list* Result, const double precision) { @@ -329,8 +328,8 @@ void SMESH_OctreeNode::FindCoincidentNodes (const SMDS_MeshNode * Node, { gp_Pnt p1 (Node->X(), Node->Y(), Node->Z()); - set myNodesCopy = myNodes; - set::iterator it = myNodesCopy.begin(); + TIDSortedNodeSet myNodesCopy = myNodes; + TIDSortedNodeSet::iterator it = myNodesCopy.begin(); double tol2 = precision * precision; bool squareBool; @@ -383,7 +382,7 @@ void SMESH_OctreeNode::UpdateByMoveNode( const SMDS_MeshNode* node, const gp_Pnt { if ( isLeaf() ) { - set::iterator pNode = myNodes.find( node ); + TIDSortedNodeSet::iterator pNode = myNodes.find( node ); bool nodeInMe = ( pNode != myNodes.end() ); SMDS_MeshNode pointNode( toPnt.X(), toPnt.Y(), toPnt.Z() ); @@ -430,6 +429,6 @@ SMESH_OctreeNodeIteratorPtr SMESH_OctreeNode::GetChildrenIterator() SMDS_NodeIteratorPtr SMESH_OctreeNode::GetNodeIterator() { return SMDS_NodeIteratorPtr - ( new SMDS_SetIterator< SMDS_pNode, set< SMDS_pNode >::const_iterator > + ( new SMDS_SetIterator< SMDS_pNode, TIDSortedNodeSet::const_iterator > ( myNodes.begin(), myNodes.size() ? myNodes.end() : myNodes.begin())); } diff --git a/src/SMESH/SMESH_OctreeNode.hxx b/src/SMESH/SMESH_OctreeNode.hxx index f5e3fbf52..951d2bc14 100644 --- a/src/SMESH/SMESH_OctreeNode.hxx +++ b/src/SMESH/SMESH_OctreeNode.hxx @@ -31,6 +31,7 @@ #define _SMESH_OCTREENODE_HXX_ #include "SMESH_Octree.hxx" +#include "SMDS_MeshNode.hxx" #include #include @@ -42,15 +43,16 @@ class SMDS_MeshNode; class SMESH_OctreeNode; -typedef SMDS_Iterator SMESH_OctreeNodeIterator; -typedef boost::shared_ptr SMESH_OctreeNodeIteratorPtr; +typedef SMDS_Iterator SMESH_OctreeNodeIterator; +typedef boost::shared_ptr SMESH_OctreeNodeIteratorPtr; +typedef std::set< const SMDS_MeshNode*, TIDCompare > TIDSortedNodeSet; class SMESH_OctreeNode : public SMESH_Octree { public: // Constructor - SMESH_OctreeNode (const std::set& theNodes, const int maxLevel = 8, + SMESH_OctreeNode (const TIDSortedNodeSet& theNodes, const int maxLevel = 8, const int maxNbNodes = 5, const double minBoxSize = 0.); //============================= @@ -64,9 +66,9 @@ public: virtual const bool isInside(const SMDS_MeshNode * Node, const double precision = 0.); // Return in Result a list of Nodes potentials to be near Node - void NodesAround(const SMDS_MeshNode * Node, + void NodesAround(const SMDS_MeshNode * Node, std::list* Result, - const double precision = 0.); + const double precision = 0.); // Return in dist2Nodes nodes mapped to their square distance from Node bool NodesAround(const SMDS_MeshNode * Node, @@ -75,13 +77,13 @@ public: // Return in theGroupsOfNodes a list of group of nodes close to each other within theTolerance // Search for all the nodes in nodes - void FindCoincidentNodes ( std::set* nodes, + void FindCoincidentNodes ( TIDSortedNodeSet* nodes, const double theTolerance, std::list< std::list< const SMDS_MeshNode*> >* theGroupsOfNodes); // Static method that return in theGroupsOfNodes a list of group of nodes close to each other within // theTolerance search for all the nodes in nodes - static void FindCoincidentNodes ( std::set& nodes, + static void FindCoincidentNodes ( TIDSortedNodeSet& nodes, std::list< std::list< const SMDS_MeshNode*> >* theGroupsOfNodes, const double theTolerance = 0.00001, const int maxLevel = -1, @@ -117,16 +119,16 @@ protected: virtual SMESH_Octree* allocateOctreeChild() const; // Return in result a list of nodes closed to Node and remove it from SetOfNodes - void FindCoincidentNodes( const SMDS_MeshNode * Node, - std::set* SetOfNodes, + void FindCoincidentNodes( const SMDS_MeshNode * Node, + TIDSortedNodeSet* SetOfNodes, std::list* Result, - const double precision); + const double precision); // The max number of nodes a leaf box can contain - int myMaxNbNodes; + int myMaxNbNodes; // The set of nodes inside the box of the Octree (Empty if Octree is not a leaf) - std::set myNodes; + TIDSortedNodeSet myNodes; }; diff --git a/src/SMESH/SMESH_Pattern.cxx b/src/SMESH/SMESH_Pattern.cxx index 43ee8669d..0857f545d 100644 --- a/src/SMESH/SMESH_Pattern.cxx +++ b/src/SMESH/SMESH_Pattern.cxx @@ -766,7 +766,12 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, } paramNodeMap.insert( make_pair( u, node )); } - } + + //rnv : To fix the bug IPAL21999 Pattern Mapping - New - collapse of pattern mesh + if ( paramNodeMap.size() != eSubMesh->NbNodes() ) + return setErrorCode(ERR_UNEXPECTED); + } + // put U in [0,1] so that the first key-point has U==0 bool isSeam = helper.IsRealSeam( edge ); double du = l - f; diff --git a/src/SMESH/SMESH_Pattern.hxx b/src/SMESH/SMESH_Pattern.hxx index 4bac41585..e809ca195 100644 --- a/src/SMESH/SMESH_Pattern.hxx +++ b/src/SMESH/SMESH_Pattern.hxx @@ -191,7 +191,9 @@ class SMESH_EXPORT SMESH_Pattern { // Apply(mesh_face) ERR_APPLF_BAD_FACE_GEOM, // bad face geometry // MakeMesh - ERR_MAKEM_NOT_COMPUTED // mapping failed + ERR_MAKEM_NOT_COMPUTED, // mapping failed + //Unexpected error + ERR_UNEXPECTED // Unexpected of the pattern mapping alorithm }; ErrorCode GetErrorCode() const { return myErrorCode; } diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 4d92816fc..69b33a94c 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -265,7 +265,7 @@ bool SMESH_subMesh::SubMeshesComputed() break; // the rest subMeshes are all of less dimension SMESHDS_SubMesh * ds = sm->GetSubMeshDS(); bool computeOk = (sm->GetComputeState() == COMPUTE_OK || - (ds && ( ds->NbNodes() || ds->NbElements() ))); + (ds && ( dimToCheck ? ds->NbElements() : ds->NbNodes() ))); if (!computeOk) { int type = ss.ShapeType(); @@ -372,23 +372,24 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn() case TopAbs_COMPOUND: { //MESSAGE("compound"); - for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More(); - exp.Next()) + for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More();exp.Next()) { InsertDependence(exp.Current()); } - for (TopExp_Explorer exp(_subShape, TopAbs_SHELL, TopAbs_SOLID); exp.More(); - exp.Next()) + for (TopExp_Explorer exp(_subShape, TopAbs_SHELL, TopAbs_SOLID); exp.More(); exp.Next()) { + if ( BRep_Tool::IsClosed(exp.Current() )) InsertDependence(exp.Current()); //only shell not in solid + else + for (TopExp_Explorer expF(exp.Current(), TopAbs_FACE); expF.More();expF.Next()) + InsertDependence(expF.Current()); // issue 0020959: HEXA_3D fails on shell + } - for (TopExp_Explorer exp(_subShape, TopAbs_FACE, TopAbs_SHELL); exp.More(); - exp.Next()) + for (TopExp_Explorer exp(_subShape, TopAbs_FACE, TopAbs_SHELL); exp.More();exp.Next()) { InsertDependence(exp.Current()); } - for (TopExp_Explorer exp(_subShape, TopAbs_EDGE, TopAbs_FACE); exp.More(); - exp.Next()) + for (TopExp_Explorer exp(_subShape, TopAbs_EDGE, TopAbs_FACE); exp.More();exp.Next()) { InsertDependence(exp.Current()); } @@ -396,9 +397,8 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn() } case TopAbs_COMPSOLID: { - //MESSAGE("compsolid"); - for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More(); - exp.Next()) + //MESSAGE("compsolid"); + for (TopExp_Explorer exp(_subShape, TopAbs_SOLID); exp.More(); exp.Next()) { InsertDependence(exp.Current()); } @@ -407,8 +407,7 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn() case TopAbs_SHELL: { //MESSAGE("shell"); - for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More(); - exp.Next()) + for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More(); exp.Next()) { InsertDependence(exp.Current()); } @@ -417,8 +416,7 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn() case TopAbs_WIRE: { //MESSAGE("wire"); - for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More(); - exp.Next()) + for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More(); exp.Next()) { InsertDependence(exp.Current()); } @@ -428,8 +426,7 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn() { //MESSAGE("solid"); if(_father->HasShapeToMesh()) { - for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More(); - exp.Next()) + for (TopExp_Explorer exp(_subShape, TopAbs_FACE); exp.More();exp.Next()) { InsertDependence(exp.Current()); } @@ -439,8 +436,7 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn() case TopAbs_FACE: { //MESSAGE("face"); - for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More(); - exp.Next()) + for (TopExp_Explorer exp(_subShape, TopAbs_EDGE); exp.More();exp.Next()) { InsertDependence(exp.Current()); } @@ -449,11 +445,10 @@ const map < int, SMESH_subMesh * >& SMESH_subMesh::DependsOn() case TopAbs_EDGE: { //MESSAGE("edge"); - for (TopExp_Explorer exp(_subShape, TopAbs_VERTEX); exp.More(); - exp.Next()) + for (TopExp_Explorer exp(_subShape, TopAbs_VERTEX); exp.More(); exp.Next()) { - InsertDependence(exp.Current()); - } + InsertDependence(exp.Current()); + } break; } case TopAbs_VERTEX: @@ -1005,9 +1000,12 @@ SMESH_Hypothesis::Hypothesis_Status if ( ret == SMESH_Hypothesis::HYP_OK && !algo->NeedDescretBoundary() && !algo->SupportSubmeshes()) { + TopoDS_Shape algoAssignedTo, otherAssignedTo; + gen->GetAlgo( *_father, _subShape, &algoAssignedTo ); map::reverse_iterator i_sm = _mapDepend.rbegin(); for ( ; ( ret == SMESH_Hypothesis::HYP_OK && i_sm != _mapDepend.rend()) ; ++i_sm ) - if ( gen->GetAlgo( *_father, i_sm->second->_subShape )) + if ( gen->GetAlgo( *_father, i_sm->second->_subShape, &otherAssignedTo ) && + SMESH_MesherHelper::IsSubShape( /*sub=*/otherAssignedTo, /*main=*/algoAssignedTo )) ret = SMESH_Hypothesis::HYP_HIDING_ALGO; } } @@ -1430,18 +1428,29 @@ bool SMESH_subMesh::ComputeStateEngine(int event) else ret = false; } - if (ret && !_alwaysComputed && shape == _subShape) { // check if anything was built - ret = ( GetSubMeshDS() && ( GetSubMeshDS()->NbElements() || GetSubMeshDS()->NbNodes() )); + TopExp_Explorer subS(shape, _subShape.ShapeType()); + if (ret) // check if anything was built + { + for (; ret && subS.More(); subS.Next()) + ret = _father->GetSubMesh( subS.Current() )->IsMeshComputed(); } bool isComputeErrorSet = !CheckComputeError( algo, shape ); if (!ret && !isComputeErrorSet) { // Set _computeError - if ( !_computeError ) - _computeError = SMESH_ComputeError::New(); - if ( _computeError->IsOK() ) - _computeError->myName = COMPERR_ALGO_FAILED; - _computeState = FAILED_TO_COMPUTE; + for (subS.ReInit(); subS.More(); subS.Next()) + { + SMESH_subMesh* sm = _father->GetSubMesh( subS.Current() ); + if ( !sm->IsMeshComputed() ) + { + if ( !sm->_computeError ) + sm->_computeError = SMESH_ComputeError::New(); + if ( sm->_computeError->IsOK() ) + sm->_computeError->myName = COMPERR_ALGO_FAILED; + sm->_computeState = FAILED_TO_COMPUTE; + sm->_computeError->myAlgo = algo; + } + } } if (ret) { @@ -1538,6 +1547,8 @@ bool SMESH_subMesh::ComputeStateEngine(int event) switch (event) { case MODIF_ALGO_STATE: + if ( !IsEmpty() ) + ComputeStateEngine( CLEAN ); algo = gen->GetAlgo((*_father), _subShape); if (algo && !algo->NeedDescretBoundary()) CleanDependsOn(); // clean sub-meshes with event CLEAN diff --git a/src/SMESHDS/SMESHDS_Group.cxx b/src/SMESHDS/SMESHDS_Group.cxx index 46fc68259..e86089c8f 100644 --- a/src/SMESHDS/SMESHDS_Group.cxx +++ b/src/SMESHDS/SMESHDS_Group.cxx @@ -156,7 +156,7 @@ class MyGroupIterator: public SMDS_ElemIterator //purpose : //======================================================================= -SMDS_ElemIteratorPtr SMESHDS_Group::GetElements() +SMDS_ElemIteratorPtr SMESHDS_Group::GetElements() const { return SMDS_ElemIteratorPtr( new MyGroupIterator ( myGroup )); } diff --git a/src/SMESHDS/SMESHDS_Group.hxx b/src/SMESHDS/SMESHDS_Group.hxx index fc4bbc503..5538e1635 100644 --- a/src/SMESHDS/SMESHDS_Group.hxx +++ b/src/SMESHDS/SMESHDS_Group.hxx @@ -54,7 +54,7 @@ class SMESHDS_EXPORT SMESHDS_Group : public SMESHDS_GroupBase virtual bool Contains (const SMDS_MeshElement* elem); - virtual SMDS_ElemIteratorPtr GetElements(); + virtual SMDS_ElemIteratorPtr GetElements() const; bool Add (const int theID); diff --git a/src/SMESHDS/SMESHDS_GroupBase.hxx b/src/SMESHDS/SMESHDS_GroupBase.hxx index 9fefca27d..2782e8951 100644 --- a/src/SMESHDS/SMESHDS_GroupBase.hxx +++ b/src/SMESHDS/SMESHDS_GroupBase.hxx @@ -66,7 +66,7 @@ class SMESHDS_EXPORT SMESHDS_GroupBase virtual bool Contains (const SMDS_MeshElement* elem); - virtual SMDS_ElemIteratorPtr GetElements() = 0; + virtual SMDS_ElemIteratorPtr GetElements() const = 0; int GetID (const int theIndex); // use it for iterations 1..Extent() diff --git a/src/SMESHDS/SMESHDS_GroupOnGeom.cxx b/src/SMESHDS/SMESHDS_GroupOnGeom.cxx index abd5d552b..aad0ee4f2 100644 --- a/src/SMESHDS/SMESHDS_GroupOnGeom.cxx +++ b/src/SMESHDS/SMESHDS_GroupOnGeom.cxx @@ -102,7 +102,7 @@ class MyIterator: public SMDS_ElemIterator //purpose : //======================================================================= -SMDS_ElemIteratorPtr SMESHDS_GroupOnGeom::GetElements() +SMDS_ElemIteratorPtr SMESHDS_GroupOnGeom::GetElements() const { return SMDS_ElemIteratorPtr( new MyIterator ( GetType(), mySubMesh )); } diff --git a/src/SMESHDS/SMESHDS_GroupOnGeom.hxx b/src/SMESHDS/SMESHDS_GroupOnGeom.hxx index bb6f0900d..1b4b5a924 100644 --- a/src/SMESHDS/SMESHDS_GroupOnGeom.hxx +++ b/src/SMESHDS/SMESHDS_GroupOnGeom.hxx @@ -51,7 +51,7 @@ class SMESHDS_EXPORT SMESHDS_GroupOnGeom: public SMESHDS_GroupBase virtual bool Contains (const SMDS_MeshElement* elem); - virtual SMDS_ElemIteratorPtr GetElements(); + virtual SMDS_ElemIteratorPtr GetElements() const; private: diff --git a/src/SMESHDS/SMESHDS_Mesh.cxx b/src/SMESHDS/SMESHDS_Mesh.cxx index 091e4f70c..0ae03d0c5 100644 --- a/src/SMESHDS/SMESHDS_Mesh.cxx +++ b/src/SMESHDS/SMESHDS_Mesh.cxx @@ -61,6 +61,7 @@ SMESHDS_Mesh::SMESHDS_Mesh(int theMeshID, bool theIsEmbeddedMode): { myScript = new SMESHDS_Script(theIsEmbeddedMode); myCurSubMesh = 0; + SetPersistentId(theMeshID); } //======================================================================= @@ -69,6 +70,28 @@ bool SMESHDS_Mesh::IsEmbeddedMode() return myIsEmbeddedMode; } +//================================================================================ +/*! + * \brief Store ID persistent during lifecycle + */ +//================================================================================ + +void SMESHDS_Mesh::SetPersistentId(int id) +{ + if (NbNodes() == 0) + myPersistentID = id; +} +//================================================================================ +/*! + * \brief Return ID persistent during lifecycle + */ +//================================================================================ + +int SMESHDS_Mesh::GetPersistentId() const +{ + return myPersistentID; +} + //======================================================================= //function : ShapeToMesh //purpose : @@ -561,8 +584,8 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolume(const SMDS_MeshNode * n1, //function : AddPolygonalFace //purpose : //======================================================================= -SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (std::vector nodes_ids, - const int ID) +SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (const std::vector& nodes_ids, + const int ID) { SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes_ids, ID); if (anElem) { @@ -572,8 +595,8 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID (std::vector nodes_ids, } SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID - (std::vector nodes, - const int ID) + (const std::vector& nodes, + const int ID) { SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID); if (anElem) { @@ -588,7 +611,7 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFaceWithID } SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace - (std::vector nodes) + (const std::vector& nodes) { SMDS_MeshFace *anElem = SMDS_Mesh::AddPolygonalFace(nodes); if (anElem) { @@ -606,9 +629,9 @@ SMDS_MeshFace* SMESHDS_Mesh::AddPolygonalFace //function : AddPolyhedralVolume //purpose : //======================================================================= -SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (std::vector nodes_ids, - std::vector quantities, - const int ID) +SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (const std::vector& nodes_ids, + const std::vector& quantities, + const int ID) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes_ids, quantities, ID); if (anElem) { @@ -618,9 +641,9 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID (std::vector nodes } SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID - (std::vector nodes, - std::vector quantities, - const int ID) + (const std::vector& nodes, + const std::vector& quantities, + const int ID) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID); if (anElem) { @@ -635,8 +658,8 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolumeWithID } SMDS_MeshVolume* SMESHDS_Mesh::AddPolyhedralVolume - (std::vector nodes, - std::vector quantities) + (const std::vector& nodes, + const std::vector& quantities) { SMDS_MeshVolume *anElem = SMDS_Mesh::AddPolyhedralVolume(nodes, quantities); if (anElem) { @@ -1073,15 +1096,13 @@ TopoDS_Shape SMESHDS_Mesh::ShapeToMesh() const bool SMESHDS_Mesh::IsGroupOfSubShapes (const TopoDS_Shape& theShape) const { - if ( myShape.IsSame( theShape )) + if ( myIndexToShape.Contains(theShape) ) return true; - for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() ) { - if (myIndexToShape.Contains( it.Value() ) || - IsGroupOfSubShapes( it.Value() )) + for ( TopoDS_Iterator it( theShape ); it.More(); it.Next() ) + if (IsGroupOfSubShapes( it.Value() )) return true; - } - + return false; } @@ -1205,7 +1226,7 @@ int SMESHDS_Mesh::AddCompoundSubmesh(const TopoDS_Shape& S, TopAbs_ShapeEnum type) { int aMainIndex = 0; - if ( IsGroupOfSubShapes( S ) || (S.ShapeType() == TopAbs_VERTEX && myIndexToShape.Contains(S)) ) + if ( IsGroupOfSubShapes( S )) { aMainIndex = myIndexToShape.Add( S ); bool all = ( type == TopAbs_SHAPE ); @@ -1249,6 +1270,17 @@ const TopoDS_Shape& SMESHDS_Mesh::IndexToShape(int ShapeIndex) const return nullShape; } +//================================================================================ +/*! + * \brief Return max index of sub-mesh + */ +//================================================================================ + +int SMESHDS_Mesh::MaxSubMeshIndex() const +{ + return myShapeIndexToSubMesh.empty() ? 0 : myShapeIndexToSubMesh.rbegin()->first; +} + //======================================================================= //function : ShapeToIndex //purpose : diff --git a/src/SMESHDS/SMESHDS_Mesh.hxx b/src/SMESHDS/SMESHDS_Mesh.hxx index 386abc3d3..7e852c774 100644 --- a/src/SMESHDS/SMESHDS_Mesh.hxx +++ b/src/SMESHDS/SMESHDS_Mesh.hxx @@ -50,7 +50,7 @@ #include #include /* - * Using of native haah_map isn't portable and don't work on WIN32 platform. + * Using of native hash_map isn't portable and don't work on WIN32 platform. * So this functionality implement on new NCollection_DataMap technology */ #include "SMESHDS_DataMapOfShape.hxx" @@ -61,6 +61,8 @@ class SMESHDS_EXPORT SMESHDS_Mesh:public SMDS_Mesh{ public: SMESHDS_Mesh(int theMeshID, bool theIsEmbeddedMode); bool IsEmbeddedMode(); + void SetPersistentId(int id); + int GetPersistentId() const; void ShapeToMesh(const TopoDS_Shape & S); TopoDS_Shape ShapeToMesh() const; @@ -354,27 +356,27 @@ public: const SMDS_MeshNode * n37, const SMDS_MeshNode * n48); - virtual SMDS_MeshFace* AddPolygonalFaceWithID (std::vector nodes_ids, - const int ID); + virtual SMDS_MeshFace* AddPolygonalFaceWithID (const std::vector& nodes_ids, + const int ID); - virtual SMDS_MeshFace* AddPolygonalFaceWithID (std::vector nodes, - const int ID); + virtual SMDS_MeshFace* AddPolygonalFaceWithID (const std::vector& nodes, + const int ID); - virtual SMDS_MeshFace* AddPolygonalFace (std::vector nodes); + virtual SMDS_MeshFace* AddPolygonalFace (const std::vector& nodes); virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID - (std::vector nodes_ids, - std::vector quantities, - const int ID); + (const std::vector& nodes_ids, + const std::vector& quantities, + const int ID); virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID - (std::vector nodes, - std::vector quantities, - const int ID); + (const std::vector& nodes, + const std::vector& quantities, + const int ID); virtual SMDS_MeshVolume* AddPolyhedralVolume - (std::vector nodes, - std::vector quantities); + (const std::vector& nodes, + const std::vector& quantities); void MoveNode(const SMDS_MeshNode *, double x, double y, double z); virtual void RemoveNode(const SMDS_MeshNode *); @@ -423,6 +425,7 @@ public: int ShapeToIndex(const TopoDS_Shape & aShape) const; const TopoDS_Shape& IndexToShape(int ShapeIndex) const; int MaxShapeIndex() const { return myIndexToShape.Extent(); } + int MaxSubMeshIndex() const; SMESHDS_SubMesh * NewSubMesh(int Index); int AddCompoundSubmesh(const TopoDS_Shape& S, TopAbs_ShapeEnum type = TopAbs_SHAPE); @@ -449,7 +452,7 @@ private: if ( it == myShapeIndexToSubMesh.end() ) it = myShapeIndexToSubMesh.insert( std::make_pair(Index, new SMESHDS_SubMesh() )).first; it->second->AddNode( aNode ); // add aNode to submesh - } + } /*int HashCode( const TopoDS_Shape& S, const Standard_Integer theUpper ) const { @@ -462,7 +465,7 @@ private: ShapeToHypothesis myShapeToHypothesis; - int myMeshID; + int myMeshID, myPersistentID; TopoDS_Shape myShape; typedef std::map TShapeIndexToSubMesh; diff --git a/src/SMESHFiltersSelection/SMESH_Type.h b/src/SMESHFiltersSelection/SMESH_Type.h index 4531a8760..89857d89c 100644 --- a/src/SMESHFiltersSelection/SMESH_Type.h +++ b/src/SMESHFiltersSelection/SMESH_Type.h @@ -52,6 +52,11 @@ enum MeshObjectType { SUBMESH_SOLID, SUBMESH_COMPOUND, GROUP, + GROUP_NODE, + GROUP_EDGE, + GROUP_FACE, + GROUP_VOLUME, + GROUP_0D, COMPONENT }; diff --git a/src/SMESHFiltersSelection/SMESH_TypeFilter.cxx b/src/SMESHFiltersSelection/SMESH_TypeFilter.cxx index bfede0418..1fbb37516 100644 --- a/src/SMESHFiltersSelection/SMESH_TypeFilter.cxx +++ b/src/SMESHFiltersSelection/SMESH_TypeFilter.cxx @@ -81,6 +81,7 @@ bool SMESH_TypeFilter::isOk (const SUIT_DataOwner* theDataOwner) const // 4 | |- Applied algorithms ( selectable in Use Case Browser ) // 5 | |- Regular 1D // |- Group Of Nodes + // |- Group 1 if (aLevel <= 0) return false; @@ -172,6 +173,36 @@ bool SMESH_TypeFilter::isOk (const SUIT_DataOwner* theDataOwner) const Ok = true; break; } + case GROUP_NODE: + { + if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_NodeGroups)) + Ok = true; + break; + } + case GROUP_EDGE: + { + if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_EdgeGroups)) + Ok = true; + break; + } + case GROUP_FACE: + { + if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_FaceGroups)) + Ok = true; + break; + } + case GROUP_VOLUME: + { + if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_VolumeGroups)) + Ok = true; + break; + } + case GROUP_0D: + { + if (aLevel == 3 && (objFather->Tag() == SMESH::Tag_VolumeGroups+1)) + Ok = true; + break; + } } } return Ok; diff --git a/src/SMESHGUI/Makefile.am b/src/SMESHGUI/Makefile.am index 1030ffd65..7e7448f59 100644 --- a/src/SMESHGUI/Makefile.am +++ b/src/SMESHGUI/Makefile.am @@ -47,12 +47,10 @@ salomeinclude_HEADERS = \ SMESHGUI_GroupDlg.h \ SMESHGUI_RemoveNodesDlg.h \ SMESHGUI_RemoveElementsDlg.h \ - SMESHGUI_MeshInfosDlg.h \ - SMESHGUI_StandardMeshInfosDlg.h \ - SMESHGUI_WhatIsDlg.h \ + SMESHGUI_MeshInfo.h \ + SMESHGUI_Measurements.h \ SMESHGUI_Preferences_ColorDlg.h \ SMESHGUI_Preferences_ScalarBarDlg.h \ - SMESHGUI_MoveNodesDlg.h \ SMESHGUI_AddMeshElementDlg.h \ SMESHGUI_XmlHandler.h \ SMESHGUI_Filter.h \ @@ -72,7 +70,8 @@ salomeinclude_HEADERS = \ SMESHGUI_ScaleDlg.h \ SMESHGUI_SymmetryDlg.h \ SMESHGUI_SewingDlg.h \ - SMESHGUI_EditMeshDlg.h \ + SMESHGUI_DuplicateNodesDlg.h \ + SMESHGUI_MergeDlg.h \ SMESHGUI_MeshUtils.h \ SMESHGUI_CreatePolyhedralVolumeDlg.h \ SMESHGUI_Operation.h \ @@ -111,12 +110,10 @@ dist_libSMESH_la_SOURCES = \ SMESHGUI_GroupDlg.cxx \ SMESHGUI_RemoveNodesDlg.cxx \ SMESHGUI_RemoveElementsDlg.cxx \ - SMESHGUI_MeshInfosDlg.cxx \ - SMESHGUI_StandardMeshInfosDlg.cxx \ - SMESHGUI_WhatIsDlg.cxx \ + SMESHGUI_MeshInfo.cxx \ + SMESHGUI_Measurements.cxx \ SMESHGUI_Preferences_ColorDlg.cxx \ SMESHGUI_Preferences_ScalarBarDlg.cxx \ - SMESHGUI_MoveNodesDlg.cxx \ SMESHGUI_AddMeshElementDlg.cxx \ SMESHGUI_XmlHandler.cxx \ SMESHGUI_Filter.cxx \ @@ -136,7 +133,8 @@ dist_libSMESH_la_SOURCES = \ SMESHGUI_ScaleDlg.cxx \ SMESHGUI_SymmetryDlg.cxx \ SMESHGUI_SewingDlg.cxx \ - SMESHGUI_EditMeshDlg.cxx \ + SMESHGUI_DuplicateNodesDlg.cxx \ + SMESHGUI_MergeDlg.cxx \ SMESHGUI_Utils.cxx \ SMESHGUI_GEOMGenUtils.cxx \ SMESHGUI_MeshUtils.cxx \ @@ -183,12 +181,10 @@ MOC_FILES = \ SMESHGUI_GroupDlg_moc.cxx \ SMESHGUI_RemoveNodesDlg_moc.cxx \ SMESHGUI_RemoveElementsDlg_moc.cxx \ - SMESHGUI_MeshInfosDlg_moc.cxx \ - SMESHGUI_StandardMeshInfosDlg_moc.cxx \ - SMESHGUI_WhatIsDlg_moc.cxx \ + SMESHGUI_MeshInfo_moc.cxx \ + SMESHGUI_Measurements_moc.cxx \ SMESHGUI_Preferences_ColorDlg_moc.cxx \ SMESHGUI_Preferences_ScalarBarDlg_moc.cxx \ - SMESHGUI_MoveNodesDlg_moc.cxx \ SMESHGUI_AddMeshElementDlg_moc.cxx \ SMESHGUI_FilterDlg_moc.cxx \ SMESHGUI_FilterLibraryDlg_moc.cxx \ @@ -206,7 +202,8 @@ MOC_FILES = \ SMESHGUI_ScaleDlg_moc.cxx \ SMESHGUI_SymmetryDlg_moc.cxx \ SMESHGUI_SewingDlg_moc.cxx \ - SMESHGUI_EditMeshDlg_moc.cxx \ + SMESHGUI_DuplicateNodesDlg_moc.cxx \ + SMESHGUI_MergeDlg_moc.cxx \ SMESHGUI_CreatePolyhedralVolumeDlg_moc.cxx \ SMESHGUI_Operation_moc.cxx \ SMESHGUI_SelectionOp_moc.cxx \ @@ -269,4 +266,5 @@ libSMESH_la_LDFLAGS = \ # resources files nodist_salomeres_DATA= \ SMESH_images.qm \ - SMESH_msg_en.qm + SMESH_msg_en.qm \ + SMESH_msg_fr.qm diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index f777acbc4..6ea18bbf0 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -19,12 +19,13 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI.cxx +// Author : Nicolas REJNERI, Open CASCADE S.A.S. -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI.cxx -// Author : Nicolas REJNERI, Open CASCADE S.A.S. -// SMESH includes -// +#include // E.A. must be included before Python.h to fix compilation on windows +#include "Python.h" +// SMESH includes #include "SMESHGUI.h" #include "SMESHGUI_AddMeshElementDlg.h" #include "SMESHGUI_AddQuadraticElementDlg.h" @@ -35,7 +36,7 @@ #include "SMESHGUI_CreatePolyhedralVolumeDlg.h" #include "SMESHGUI_DeleteGroupDlg.h" #include "SMESHGUI_Displayer.h" -#include "SMESHGUI_EditMeshDlg.h" +#include "SMESHGUI_MergeDlg.h" #include "SMESHGUI_ExtrusionAlongPathDlg.h" #include "SMESHGUI_ExtrusionDlg.h" #include "SMESHGUI_FileInfoDlg.h" @@ -49,11 +50,12 @@ #include "SMESHGUI_Hypotheses.h" #include "SMESHGUI_Make2DFrom3DOp.h" #include "SMESHGUI_MakeNodeAtPointDlg.h" -#include "SMESHGUI_MeshInfosDlg.h" +//#include "SMESHGUI_MeshInfosDlg.h" +#include "SMESHGUI_Measurements.h" +#include "SMESHGUI_MeshInfo.h" #include "SMESHGUI_MeshOp.h" #include "SMESHGUI_MeshOrderOp.h" #include "SMESHGUI_MeshPatternDlg.h" -#include "SMESHGUI_MoveNodesDlg.h" #include "SMESHGUI_MultiEditDlg.h" #include "SMESHGUI_NodesDlg.h" #include "SMESHGUI_Preferences_ColorDlg.h" @@ -67,12 +69,13 @@ #include "SMESHGUI_SewingDlg.h" #include "SMESHGUI_SingleEditDlg.h" #include "SMESHGUI_SmoothingDlg.h" -#include "SMESHGUI_StandardMeshInfosDlg.h" +//#include "SMESHGUI_StandardMeshInfosDlg.h" #include "SMESHGUI_SymmetryDlg.h" #include "SMESHGUI_TranslationDlg.h" #include "SMESHGUI_ScaleDlg.h" #include "SMESHGUI_TransparencyDlg.h" -#include "SMESHGUI_WhatIsDlg.h" +//#include "SMESHGUI_WhatIsDlg.h" +#include "SMESHGUI_DuplicateNodesDlg.h" #include "SMESHGUI_Utils.h" #include "SMESHGUI_MeshUtils.h" @@ -84,7 +87,9 @@ #include #include +#include #include +#include "SMESH_ControlsDef.hxx" // SALOME GUI includes #include @@ -121,19 +126,21 @@ #include #include CORBA_CLIENT_HEADER(SALOMEDS_Attributes) #include CORBA_CLIENT_HEADER(SMESH_MeshEditor) +#include CORBA_CLIENT_HEADER(SMESH_Measurements) // Qt includes // #define INCLUDE_MENUITEM_DEF // VSR commented ???????? #include +#include // BOOST includes #include // VTK includes -#include #include #include #include +#include // SALOME KERNEL includes #include @@ -146,6 +153,10 @@ #include #include +//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 + //namespace{ // Declarations //============================================================= @@ -170,14 +181,14 @@ std::string myExtension; if ( theCommandID == 113 ) { - filter.append( QObject::tr( "MED files (*.med)" ) ); - filter.append( QObject::tr( "All files (*)" ) ); + filter.append( QObject::tr( "MED_FILES_FILTER" ) + " (*.med)" ); + filter.append( QObject::tr( "ALL_FILES_FILTER" ) + " (*)" ); } else if ( theCommandID == 112 ) { - filter.append( QObject::tr( "IDEAS files (*.unv)" ) ); + filter.append( QObject::tr( "IDEAS_FILES_FILTER" ) + " (*.unv)" ); } else if ( theCommandID == 111 ) { - filter.append( QObject::tr( "DAT files (*.dat)" ) ); + filter.append( QObject::tr( "DAT_FILES_FILTER" ) + " (*.dat)" ); } QString anInitialPath = ""; @@ -242,6 +253,13 @@ aPixmap->SetPixMap( "ICON_SMESH_TREE_MESH_IMPORTED" ); if ( theCommandID == 112 ) // mesh names aren't taken from the file for UNV import SMESH::SetName( aMeshSO, QFileInfo(filename).fileName() ); + +#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 + aMeshes[i]->Destroy(); +#endif } else { isEmpty = true; @@ -277,7 +295,7 @@ // actually, the following condition can't be met (added for insurance) if( selected.Extent() == 0 || - selected.Extent() > 1 && theCommandID != 122 && theCommandID != 125 ) + ( selected.Extent() > 1 && theCommandID != 122 && theCommandID != 125 ) ) return; bool hasDuplicatedMeshNames = false; @@ -323,7 +341,7 @@ QList aReservedColors; - QString aFilter, aTitle = QObject::tr("Export mesh"); + QString aFilter, aTitle = QObject::tr("SMESH_EXPORT_MESH"); QMap aFilterMap; QMap aFilterMapSTL; switch ( theCommandID ) { @@ -346,13 +364,13 @@ // PAL18696 QString v21 (aMesh->GetVersionString(SMESH::MED_V2_1, 2)); QString v22 (aMesh->GetVersionString(SMESH::MED_V2_2, 2)); - aFilterMap.insert( QString("MED ") + v21 + " (*.med)", SMESH::MED_V2_1 ); - aFilterMap.insert( QString("MED ") + v22 + " (*.med)", SMESH::MED_V2_2 ); + aFilterMap.insert( QObject::tr( "MED_VX_FILES_FILTER" ).arg( v21 ) + " (*.med)", SMESH::MED_V2_1 ); + aFilterMap.insert( QObject::tr( "MED_VX_FILES_FILTER" ).arg( v22 ) + " (*.med)", SMESH::MED_V2_2 ); } break; case 124: case 121: - aFilter = QObject::tr("DAT files (*.dat)"); + aFilter = QObject::tr( "DAT_FILES_FILTER" ) + " (*.dat)"; break; case 126: case 123: @@ -367,7 +385,7 @@ if (aRet != 0) return; } - aFilter = QObject::tr("IDEAS files (*.unv)"); + aFilter = QObject::tr( "IDEAS_FILES_FILTER" ) + " (*.unv)"; } break; case 140: @@ -395,8 +413,8 @@ return; } - aFilterMapSTL.insert( QObject::tr("STL ASCII (*.stl)"), 1 ); // 1 - ASCII mode - aFilterMapSTL.insert( QObject::tr("STL Binary (*.stl)"), 0 ); // 0 - Binary mode + aFilterMapSTL.insert( QObject::tr( "STL_ASCII_FILES_FILTER" ) + " (*.stl)", 1 ); // 1 - ASCII mode + aFilterMapSTL.insert( QObject::tr( "STL_BIN_FILES_FILTER" ) + " (*.stl)", 0 ); // 0 - Binary mode } break; default: @@ -431,7 +449,7 @@ SUIT_FileDlg* fd = new SUIT_FileDlg( SMESHGUI::desktop(), false, true, true ); fd->setWindowTitle( aTitle ); fd->setNameFilters( filters ); - fd->selectNameFilter( QObject::tr("STL ASCII (*.stl)") ); + fd->selectNameFilter( QObject::tr( "STL_ASCII_FILES_FILTER" ) + " (*.stl)" ); if ( !anInitialPath.isEmpty() ) fd->setDirectory( anInitialPath ); fd->selectFile(aMeshName); @@ -702,6 +720,121 @@ SMESH::RepaintCurrentView(); } + QString functorToString( SMESH::Controls::FunctorPtr f ) + { + QString type = QObject::tr( "UNKNOWN_CONTROL" ); + if ( dynamic_cast< SMESH::Controls::Volume* >( f.get() ) ) + type = QObject::tr( "VOLUME_3D_ELEMENTS" ); + else if ( dynamic_cast< SMESH::Controls::MaxElementLength2D* >( f.get() ) ) + type = QObject::tr( "MAX_ELEMENT_LENGTH_2D" ); + else if ( dynamic_cast< SMESH::Controls::MaxElementLength3D* >( f.get() ) ) + type = QObject::tr( "MAX_ELEMENT_LENGTH_3D" ); + else if ( dynamic_cast< SMESH::Controls::MinimumAngle* >( f.get() ) ) + type = QObject::tr( "MINIMUMANGLE_ELEMENTS" ); + else if ( dynamic_cast< SMESH::Controls::AspectRatio* >( f.get() ) ) + type = QObject::tr( "ASPECTRATIO_ELEMENTS" ); + else if ( dynamic_cast< SMESH::Controls::AspectRatio3D* >( f.get() ) ) + type = QObject::tr( "ASPECTRATIO_3D_ELEMENTS" ); + else if ( dynamic_cast< SMESH::Controls::Warping* >( f.get() ) ) + type = QObject::tr( "WARP_ELEMENTS" ); + else if ( dynamic_cast< SMESH::Controls::Taper* >( f.get() ) ) + type = QObject::tr( "TAPER_ELEMENTS" ); + else if ( dynamic_cast< SMESH::Controls::Skew* >( f.get() ) ) + type = QObject::tr( "SKEW_ELEMENTS" ); + else if ( dynamic_cast< SMESH::Controls::Area* >( f.get() ) ) + type = QObject::tr( "AREA_ELEMENTS" ); + else if ( dynamic_cast< SMESH::Controls::Length* >( f.get() ) ) + type = QObject::tr( "LENGTH_EDGES" ); + else if ( dynamic_cast< SMESH::Controls::Length2D* >( f.get() ) ) + type = QObject::tr( "LENGTH2D_EDGES" ); + else if ( dynamic_cast< SMESH::Controls::MultiConnection* >( f.get() ) ) + type = QObject::tr( "MULTI_BORDERS" ); + else if ( dynamic_cast< SMESH::Controls::MultiConnection2D* >( f.get() ) ) + type = QObject::tr( "MULTI2D_BORDERS" ); + else if ( dynamic_cast< SMESH::Controls::FreeNodes* >( f.get() ) ) + type = QObject::tr( "FREE_NODES" ); + else if ( dynamic_cast< SMESH::Controls::FreeEdges* >( f.get() ) ) + type = QObject::tr( "FREE_EDGES" ); + else if ( dynamic_cast< SMESH::Controls::FreeBorders* >( f.get() ) ) + type = QObject::tr( "FREE_BORDERS" ); + else if ( dynamic_cast< SMESH::Controls::FreeFaces* >( f.get() ) ) + type = QObject::tr( "FREE_FACES" ); + return type; + } + + void SaveDistribution() + { + LightApp_SelectionMgr* aSel = SMESHGUI::selectionMgr(); + SALOME_ListIO selected; + if ( aSel ) + aSel->selectedObjects( selected ); + + 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(); + SMESH::Controls::FunctorPtr aFunctor = anActor->GetFunctor(); + if ( aScalarBarActor && aFunctor ) { + SMESH::Controls::NumericalFunctor* aNumFun = dynamic_cast( aFunctor.get() ); + if ( aNumFun ) { + int nbRanges = aScalarBarActor->GetMaximumNumberOfColors(); + std::vector nbEvents; + std::vector funValues; + aNumFun->GetHistogram( nbRanges, nbEvents, funValues ); + QString anInitialPath = ""; + if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() ) + anInitialPath = QDir::currentPath(); + QString aMeshName = anIO->getName(); + QStringList filter; + filter.append( QObject::tr( "TEXT_FILES_FILTER" ) + " (*.txt)" ); + filter.append( QObject::tr( "ALL_FILES_FILTER" ) + " (*)" ); + QString aFilename = anInitialPath + "/" + aMeshName + "_" + + functorToString( aFunctor ).toLower().simplified().replace( QRegExp( " |-" ), "_" ) + ".txt"; + aFilename = SUIT_FileDlg::getFileName( SMESHGUI::desktop(), + aFilename, + filter, + QObject::tr( "SMESH_SAVE_DISTRIBUTION" ), + false ); + if ( !aFilename.isEmpty() ) { + QFile f( aFilename ); + if ( f.open( QFile::WriteOnly | QFile::Truncate ) ) { + QTextStream out( &f ); + out << "# Mesh: " << aMeshName << endl; + out << "# Control: " << functorToString( aFunctor ) << endl; + out << "#" << endl; + out.setFieldWidth( 10 ); + for ( int i = 0; i < qMin( nbEvents.size(), funValues.size()-1 ); i++ ) + out << funValues[i] << "\t" << funValues[i+1] << "\t" << nbEvents[i] << endl; + f.close(); + } + } + } + } + } + } + } + } + + void ShowDistribution() { + LightApp_SelectionMgr* aSel = SMESHGUI::selectionMgr(); + SALOME_ListIO selected; + if ( aSel ) + aSel->selectedObjects( selected ); + + 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()); + } + } + } + } + void DisableAutoColor(){ LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); SALOME_ListIO selected; @@ -728,136 +861,144 @@ if( !aSel || !appStudy ) return; + if( theCommandID == 1134 ) { // Clipping dialog can be activated without selection + if( SMESHGUI* aModule = SMESHGUI::GetSMESHGUI() ) { + aModule->EmitSignalDeactivateDialog(); + if( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( aModule ) ) + (new SMESHGUI_ClippingDlg( aModule, aViewWindow ))->show(); + } + return; + } + _PTR(Study) aStudy = appStudy->studyDS(); aSel->selectedObjects( selected ); if(selected.Extent() >= 1){ switch(theCommandID){ - case 1134:{ - SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog(); - (new SMESHGUI_ClippingDlg( SMESHGUI::GetSMESHGUI() ))->show(); - return; - } case 1133:{ SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog(); (new SMESHGUI_TransparencyDlg( SMESHGUI::GetSMESHGUI() ))->show(); return; - }} - SALOME_ListIteratorOfListIO It( selected ); - for( ; It.More(); It.Next()){ - Handle(SALOME_InteractiveObject) IObject = It.Value(); - if(IObject->hasEntry()){ - if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){ - switch(theCommandID){ - case 211: - anActor->SetRepresentation(SMESH_Actor::eEdge); - break; - case 212: - anActor->SetRepresentation(SMESH_Actor::eSurface); - break; - case 213: - if(anActor->IsShrunk()) - anActor->UnShrink(); - else - anActor->SetShrink(); - break; - case 215: - anActor->SetRepresentation(SMESH_Actor::ePoint); - break; - case 231: - if(anActor->GetQuadratic2DRepresentation() != SMESH_Actor::eLines) - anActor->SetQuadratic2DRepresentation(SMESH_Actor::eLines); - break; - case 232: - if(anActor->GetQuadratic2DRepresentation() != SMESH_Actor::eArcs) - anActor->SetQuadratic2DRepresentation(SMESH_Actor::eArcs); - break; - case 1132:{ + } + case 1132:{ + QColor c, e, b, n, c0D, o; + int size0D = 0; + int Edgewidth = 0; + vtkFloatingPointType Shrink = 0.0; + vtkFloatingPointType faces_orientation_scale = 0.0; + bool faces_orientation_3dvectors = false; + + VTK::MarkerType aMarkerTypeCurrent = VTK::MT_NONE; + VTK::MarkerScale aMarkerScaleCurrent = VTK::MS_NONE; + int aMarkerTextureCurrent = 0; + + SALOME_ListIteratorOfListIO It( selected ); + for( ; It.More(); It.Next()){ + Handle(SALOME_InteractiveObject) IObject = It.Value(); + if(IObject->hasEntry()){ + if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){ vtkFloatingPointType color[3]; anActor->GetSufaceColor(color[0], color[1], color[2]); int c0 = int (color[0] * 255); int c1 = int (color[1] * 255); int c2 = int (color[2] * 255); - QColor c(c0, c1, c2); + c.setRgb(c0, c1, c2); vtkFloatingPointType edgecolor[3]; anActor->GetEdgeColor(edgecolor[0], edgecolor[1], edgecolor[2]); c0 = int (edgecolor[0] * 255); c1 = int (edgecolor[1] * 255); c2 = int (edgecolor[2] * 255); - QColor e(c0, c1, c2); + e.setRgb(c0, c1, c2); vtkFloatingPointType backfacecolor[3]; anActor->GetBackSufaceColor(backfacecolor[0], backfacecolor[1], backfacecolor[2]); c0 = int (backfacecolor[0] * 255); c1 = int (backfacecolor[1] * 255); c2 = int (backfacecolor[2] * 255); - QColor b(c0, c1, c2); + b.setRgb(c0, c1, c2); vtkFloatingPointType nodecolor[3]; anActor->GetNodeColor(nodecolor[0], nodecolor[1], nodecolor[2]); c0 = int (nodecolor[0] * 255); c1 = int (nodecolor[1] * 255); c2 = int (nodecolor[2] * 255); - QColor n(c0, c1, c2); + n.setRgb(c0, c1, c2); vtkFloatingPointType color0D[3]; anActor->Get0DColor(color0D[0], color0D[1], color0D[2]); c0 = int (color0D[0] * 255); c1 = int (color0D[1] * 255); c2 = int (color0D[2] * 255); - QColor c0D(c0, c1, c2); + c0D.setRgb(c0, c1, c2); - int size0D = (int)anActor->Get0DSize(); + size0D = (int)anActor->Get0DSize(); if(size0D == 0) size0D = 1; - int Edgewidth = (int)anActor->GetLineWidth(); + Edgewidth = (int)anActor->GetLineWidth(); if(Edgewidth == 0) Edgewidth = 1; - vtkFloatingPointType Shrink = anActor->GetShrinkFactor(); + Shrink = anActor->GetShrinkFactor(); vtkFloatingPointType faces_orientation_color[3]; anActor->GetFacesOrientationColor(faces_orientation_color); c0 = int (faces_orientation_color[0] * 255); c1 = int (faces_orientation_color[1] * 255); c2 = int (faces_orientation_color[2] * 255); - QColor o(c0, c1, c2); - - vtkFloatingPointType faces_orientation_scale = anActor->GetFacesOrientationScale(); - bool faces_orientation_3dvectors = anActor->GetFacesOrientation3DVectors(); - - SMESHGUI_Preferences_ColorDlg *aDlg = - new SMESHGUI_Preferences_ColorDlg( SMESHGUI::GetSMESHGUI() ); - aDlg->SetColor(1, c); - aDlg->SetColor(2, e); - aDlg->SetColor(3, n); - aDlg->SetColor(4, b); - aDlg->SetColor(5, c0D); - aDlg->SetColor(6, o); - aDlg->SetIntValue(1, Edgewidth); - aDlg->SetIntValue(2, int(Shrink*100.)); - aDlg->SetIntValue(3, size0D); - aDlg->SetDoubleValue(1, faces_orientation_scale); - aDlg->SetBooleanValue(1, faces_orientation_3dvectors); - - aDlg->setCustomMarkerMap( theMarkerMap[ aStudy->StudyId() ] ); - - VTK::MarkerType aMarkerTypeCurrent = anActor->GetMarkerType(); - VTK::MarkerScale aMarkerScaleCurrent = anActor->GetMarkerScale(); - int aMarkerTextureCurrent = anActor->GetMarkerTexture(); - if( aMarkerTypeCurrent != VTK::MT_USER ) - aDlg->setStandardMarker( aMarkerTypeCurrent, aMarkerScaleCurrent ); - else - aDlg->setCustomMarker( aMarkerTextureCurrent ); - - if(aDlg->exec()){ - QColor color = aDlg->GetColor(1); - QColor edgecolor = aDlg->GetColor(2); - QColor nodecolor = aDlg->GetColor(3); - QColor backfacecolor = aDlg->GetColor(4); - QColor color0D = aDlg->GetColor(5); - QColor faces_orientation_color = aDlg->GetColor(6); + o.setRgb(c0, c1, c2); + + faces_orientation_scale = anActor->GetFacesOrientationScale(); + faces_orientation_3dvectors = anActor->GetFacesOrientation3DVectors(); + + aMarkerTypeCurrent = anActor->GetMarkerType(); + aMarkerScaleCurrent = anActor->GetMarkerScale(); + aMarkerTextureCurrent = anActor->GetMarkerTexture(); + + // even if there are multiple objects in the selection, + // we need only the first one to get values for the dialog + break; + } + } + } + + SMESHGUI_Preferences_ColorDlg *aDlg = + new SMESHGUI_Preferences_ColorDlg( SMESHGUI::GetSMESHGUI() ); + aDlg->SetColor(1, c); + aDlg->SetColor(2, e); + aDlg->SetColor(3, n); + aDlg->SetColor(4, b); + aDlg->SetColor(5, c0D); + aDlg->SetColor(6, o); + aDlg->SetIntValue(1, Edgewidth); + aDlg->SetIntValue(2, int(Shrink*100.)); + aDlg->SetIntValue(3, size0D); + aDlg->SetDoubleValue(1, faces_orientation_scale); + aDlg->SetBooleanValue(1, faces_orientation_3dvectors); + + aDlg->setCustomMarkerMap( theMarkerMap[ aStudy->StudyId() ] ); + + if( aMarkerTypeCurrent != VTK::MT_USER ) + aDlg->setStandardMarker( aMarkerTypeCurrent, aMarkerScaleCurrent ); + else + aDlg->setCustomMarker( aMarkerTextureCurrent ); + + if(aDlg->exec()){ + QColor color = aDlg->GetColor(1); + QColor edgecolor = aDlg->GetColor(2); + QColor nodecolor = aDlg->GetColor(3); + QColor backfacecolor = aDlg->GetColor(4); + QColor color0D = aDlg->GetColor(5); + QColor faces_orientation_color = aDlg->GetColor(6); + + /* Point marker */ + theMarkerMap[ aStudy->StudyId() ] = aDlg->getCustomMarkerMap(); + + SALOME_ListIteratorOfListIO It( selected ); + for( ; It.More(); It.Next()){ + Handle(SALOME_InteractiveObject) IObject = It.Value(); + if(IObject->hasEntry()){ + if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){ /* actor color and backface color */ anActor->SetSufaceColor(vtkFloatingPointType (color.red()) / 255., vtkFloatingPointType (color.green()) / 255., @@ -894,9 +1035,6 @@ anActor->SetFacesOrientationScale(aDlg->GetDoubleValue(1)); anActor->SetFacesOrientation3DVectors(aDlg->GetBooleanValue(1)); - /* Point marker */ - theMarkerMap[ aStudy->StudyId() ] = aDlg->getCustomMarkerMap(); - VTK::MarkerType aMarkerTypeNew = aDlg->getMarkerType(); VTK::MarkerScale aMarkerScaleNew = aDlg->getStandardMarkerScale(); int aMarkerTextureNew = aDlg->getCustomMarkerID(); @@ -927,11 +1065,45 @@ aGroupColor.B = (float)aColor.blue() / 255.0; aGroupObject->SetColor( aGroupColor ); } - - delete aDlg; } + } + } + SMESH::RepaintCurrentView(); + } + delete aDlg; + return; + } + } + SALOME_ListIteratorOfListIO It( selected ); + for( ; It.More(); It.Next()){ + Handle(SALOME_InteractiveObject) IObject = It.Value(); + if(IObject->hasEntry()){ + if(SMESH_Actor *anActor = SMESH::FindActorByEntry(IObject->getEntry())){ + switch(theCommandID){ + case 211: + anActor->SetRepresentation(SMESH_Actor::eEdge); + break; + case 212: + anActor->SetRepresentation(SMESH_Actor::eSurface); + break; + case 213: + if(anActor->IsShrunk()) + anActor->UnShrink(); + else + anActor->SetShrink(); + break; + case 215: + anActor->SetRepresentation(SMESH_Actor::ePoint); + break; + case 231: + if(anActor->GetQuadratic2DRepresentation() != SMESH_Actor::eLines) + anActor->SetQuadratic2DRepresentation(SMESH_Actor::eLines); + break; + case 232: + if(anActor->GetQuadratic2DRepresentation() != SMESH_Actor::eArcs) + anActor->SetQuadratic2DRepresentation(SMESH_Actor::eArcs); break; - }} + } } } } @@ -949,77 +1121,66 @@ if( !selected.IsEmpty() ){ Handle(SALOME_InteractiveObject) anIO = selected.First(); if(!anIO.IsNull()){ - QString aTitle; SMESH_Actor::eControl aControl = SMESH_Actor::eNone; if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIO->getEntry())){ switch ( theCommandID ){ case 6001: - aTitle = QObject::tr( "LENGTH_EDGES" ); aControl = SMESH_Actor::eLength; break; case 6018: - aTitle = QObject::tr( "LENGTH2D_EDGES" ); aControl = SMESH_Actor::eLength2D; break; case 6002: - aTitle = QObject::tr( "FREE_EDGES" ); aControl = SMESH_Actor::eFreeEdges; break; case 6003: - aTitle = QObject::tr( "FREE_BORDERS" ); aControl = SMESH_Actor::eFreeBorders; break; case 6004: - aTitle = QObject::tr( "MULTI_BORDERS" ); aControl = SMESH_Actor::eMultiConnection; break; case 6005: - aTitle = QObject::tr( "FREE_NODES" ); aControl = SMESH_Actor::eFreeNodes; break; case 6019: - aTitle = QObject::tr( "MULTI2D_BORDERS" ); aControl = SMESH_Actor::eMultiConnection2D; break; case 6011: - aTitle = QObject::tr( "AREA_ELEMENTS" ); aControl = SMESH_Actor::eArea; break; case 6012: - aTitle = QObject::tr( "TAPER_ELEMENTS" ); aControl = SMESH_Actor::eTaper; break; case 6013: - aTitle = QObject::tr( "ASPECTRATIO_ELEMENTS" ); aControl = SMESH_Actor::eAspectRatio; break; case 6017: - aTitle = QObject::tr( "ASPECTRATIO_3D_ELEMENTS" ); aControl = SMESH_Actor::eAspectRatio3D; break; case 6014: - aTitle = QObject::tr( "MINIMUMANGLE_ELEMENTS" ); aControl = SMESH_Actor::eMinimumAngle; break; case 6015: - aTitle = QObject::tr( "WARP_ELEMENTS" ); aControl = SMESH_Actor::eWarping; break; case 6016: - aTitle = QObject::tr( "SKEW_ELEMENTS" ); aControl = SMESH_Actor::eSkew; break; case 6009: - aTitle = QObject::tr( "SMESH_VOLUME" ); aControl = SMESH_Actor::eVolume3D; break; case 6021: - aTitle = QObject::tr( "FREE_FACES" ); aControl = SMESH_Actor::eFreeFaces; break; + case 6022: + aControl = SMESH_Actor::eMaxElementLength2D; + break; + case 6023: + aControl = SMESH_Actor::eMaxElementLength3D; + break; } anActor->SetControlMode(aControl); - anActor->GetScalarBarActor()->SetTitle(aTitle.toLatin1().data()); + anActor->GetScalarBarActor()->SetTitle( functorToString( anActor->GetFunctor() ).toLatin1().constData() ); SMESH::RepaintCurrentView(); } } @@ -1154,7 +1315,7 @@ SalomeApp_Application* anApp = dynamic_cast( SUIT_Session::session()->activeApplication() ); SUIT_ViewManager* vm = anApp->activeViewManager(); - int nbSf = vm->getViewsCount(); + int nbSf = vm ? vm->getViewsCount() : 0; SALOME_ListIteratorOfListIO It(selected); @@ -1196,7 +1357,7 @@ std::string anEntry = SO->GetID(); /** Erase graphical object **/ - if(SO->FindAttribute(anAttr, "AttributeIOR")){ + if(SO->FindAttribute(anAttr, "AttributeIOR") && vm ){ QVector aViews = vm->getViews(); for(int i = 0; i < nbSf; i++){ SUIT_ViewWindow *sf = aViews[i]; @@ -1286,8 +1447,15 @@ LightApp_Module( "SMESH" ) myState = -1; myDisplayer = 0; + myEventCallbackCommand = vtkCallbackCommand::New(); + myEventCallbackCommand->Delete(); + myEventCallbackCommand->SetClientData( this ); + myEventCallbackCommand->SetCallback( SMESHGUI::ProcessEvents ); + myPriority = 0.0; + SMESH::GetFilterManager(); SMESH::GetPattern(); + SMESH::GetMeasurements(); /* load resources for all available meshers */ SMESH::InitAvailableHypotheses(); @@ -1300,8 +1468,12 @@ LightApp_Module( "SMESH" ) //============================================================================= SMESHGUI::~SMESHGUI() { +#ifdef WITHGENERICOBJ SMESH::GetFilterManager()->Destroy(); + SMESH::GetMeasurements()->Destroy(); +#endif SMESH::GetFilterManager() = SMESH::FilterManager::_nil(); + SMESH::GetMeasurements() = SMESH::Measurements::_nil(); } //============================================================================= @@ -1318,13 +1490,22 @@ LightApp_SelectionMgr* SMESHGUI::selectionMgr() return 0; } -bool SMESHGUI::automaticUpdate() +//============================================================================= +/*! + * + */ +//============================================================================= +bool SMESHGUI::automaticUpdate(unsigned int requestedSize, bool* limitExceeded) { SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); if ( !resMgr ) return false; - return resMgr->booleanValue( "SMESH", "auto_update", false ); + bool autoUpdate = resMgr->booleanValue( "SMESH", "auto_update", false ); + long updateLimit = resMgr->integerValue( "SMESH", "update_limit", 500000 ); + bool exceeded = updateLimit > 0 && requestedSize > updateLimit; + if ( limitExceeded ) *limitExceeded = autoUpdate && exceeded; + return autoUpdate && !exceeded; } //============================================================================= @@ -1639,6 +1820,19 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) SMESHGUI_Preferences_ScalarBarDlg::ScalarBarProperties( this ); break; } + case 202: + { + // dump control distribution data to the text file + ::SaveDistribution(); + break; + } + + case 203: + { + // show/ distribution + ::ShowDistribution(); + break; + } // Auto-color case 1136: @@ -1666,7 +1860,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) case 232: ::SetDisplayMode(theCommandID, myMarkerMap); break; - + // Display Entity case 216: // 0D elements case 217: // Edges @@ -1773,7 +1967,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) } else aSel->setSelectedObjects( to_process ); - + break; } @@ -1804,20 +1998,6 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) break; } - case 406: // MOVE NODE - { - if ( !vtkwnd ) - { - SUIT_MessageBox::warning( desktop(), tr( "SMESH_WRN_WARNING" ), - tr( "NOT_A_VTK_VIEWER" ) ); - break; - } - - if(checkLock(aStudy)) break; - ( new SMESHGUI_MoveNodesDlg( this ) )->show(); - break; - } - case 701: // COMPUTE MESH case 711: // PRECOMPUTE MESH case 712: // EVALUATE MESH @@ -2231,7 +2411,9 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) } case 900: // MESH INFOS + case 903: // WHAT IS { + int page = theCommandID == 900 ? SMESHGUI_MeshInfoDlg::BaseInfo : SMESHGUI_MeshInfoDlg::ElemInfo; EmitSignalDeactivateDialog(); LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr(); SALOME_ListIO selected; @@ -2239,21 +2421,20 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) aSel->selectedObjects( selected ); if ( selected.Extent() > 1 ) { // a dlg for each IO - SALOME_ListIO IOs; - SALOME_ListIteratorOfListIO It (selected); + SALOME_ListIteratorOfListIO It( selected ); for ( ; It.More(); It.Next() ) { - IOs.Clear(); IOs.Append( It.Value() ); - aSel->setSelectedObjects( IOs ); - ( new SMESHGUI_MeshInfosDlg( this ) )->show(); + SMESHGUI_MeshInfoDlg* dlg = new SMESHGUI_MeshInfoDlg( SMESHGUI::desktop(), page ); + dlg->showInfo( It.Value() ); + dlg->show(); } - // restore selection - aSel->setSelectedObjects( selected ); } - else - ( new SMESHGUI_MeshInfosDlg( this ) )->show(); + else { + SMESHGUI_MeshInfoDlg* dlg = new SMESHGUI_MeshInfoDlg( SMESHGUI::desktop(), page ); + dlg->show(); + } break; } - + /* case 902: // STANDARD MESH INFOS { EmitSignalDeactivateDialog(); @@ -2278,13 +2459,13 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) ( new SMESHGUI_StandardMeshInfosDlg( this ) )->show(); break; } - case 903: // WHAT IS { EmitSignalDeactivateDialog(); ( new SMESHGUI_WhatIsDlg( this ) )->show(); break; } + */ case 904: // FIND ELEM { @@ -2569,6 +2750,44 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) updateObjBrowser(); break; } + case 4044: // REMOVE ORPHAN NODES + { + if(checkLock(aStudy)) break; + SALOME_ListIO selected; + if( LightApp_SelectionMgr *aSel = SMESHGUI::selectionMgr() ) + aSel->selectedObjects( selected ); + if ( selected.Extent() == 1 ) { + Handle(SALOME_InteractiveObject) anIO = selected.First(); + SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(anIO); + if ( !aMesh->_is_nil() ) { + bool confirm = SUIT_MessageBox::question( SMESHGUI::desktop(), + tr( "SMESH_WARNING" ), + tr( "REMOVE_ORPHAN_NODES_QUESTION"), + SUIT_MessageBox::Yes | + SUIT_MessageBox::No, + SUIT_MessageBox::No ) == SUIT_MessageBox::Yes; + if( confirm ) { + try { + SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor(); + int removed = aMeshEditor->RemoveOrphanNodes(); + SUIT_MessageBox::information(SMESHGUI::desktop(), + tr("SMESH_INFORMATION"), + tr("NB_NODES_REMOVED").arg(removed)); + if ( removed > 0 ) { + SMESH::UpdateView(); + SMESHGUI::Modified(); + } + } + catch (const SALOME::SALOME_Exception& S_ex) { + SalomeApp_Tools::QtCatchCorbaException(S_ex); + } + catch (...) { + } + } + } + } + break; + } case 4051: // RENUMBERING NODES { if(checkLock(aStudy)) break; @@ -2654,7 +2873,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) if(checkLock(aStudy)) break; if(vtkwnd) { EmitSignalDeactivateDialog(); - ( new SMESHGUI_EditMeshDlg( this, 0 ) )->show(); + ( new SMESHGUI_MergeDlg( this, 0 ) )->show(); } else { SUIT_MessageBox::warning(SMESHGUI::desktop(), @@ -2667,7 +2886,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) if (checkLock(aStudy)) break; if (vtkwnd) { EmitSignalDeactivateDialog(); - ( new SMESHGUI_EditMeshDlg( this, 1 ) )->show(); + ( new SMESHGUI_MergeDlg( this, 1 ) )->show(); } else { SUIT_MessageBox::warning(SMESHGUI::desktop(), tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); @@ -2693,6 +2912,20 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) break; } + case 4069: // DUPLICATE NODES + { + if(checkLock(aStudy)) break; + if ( vtkwnd ) { + EmitSignalDeactivateDialog(); + ( new SMESHGUI_DuplicateNodesDlg( this ) )->show(); + } + else { + SUIT_MessageBox::warning(SMESHGUI::desktop(), + tr("SMESH_WRN_WARNING"), tr("SMESH_WRN_VIEWER_VTK")); + } + break; + } + case 5105: // Library of selection filters { static QList aTypes; @@ -2727,6 +2960,8 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) case 6005: case 6009: case 6021: + case 6022: + case 6023: if ( vtkwnd ) { LightApp_SelectionMgr* mgr = selectionMgr(); @@ -2777,8 +3012,9 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) LightApp_SelectionMgr* mgr = selectionMgr(); SALOME_ListIO selected; mgr->selectedObjects( selected ); - if (selected.Extent() == 1) { - Handle(SALOME_InteractiveObject) anIObject = selected.First(); + SALOME_ListIteratorOfListIO it(selected); + for( ; it.More(); it.Next()) { + Handle(SALOME_InteractiveObject) anIObject = it.Value(); if(anIObject->hasEntry()) if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIObject->getEntry())){ anActor->SetCellsLabeled( !anActor->GetCellsLabeled() ); @@ -2786,6 +3022,15 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) } break; } + case 501: + case 502: + { + int page = theCommandID == 501 ? SMESHGUI_MeasureDlg::MinDistance : SMESHGUI_MeasureDlg::BoundingBox; + EmitSignalDeactivateDialog(); + SMESHGUI_MeasureDlg* dlg = new SMESHGUI_MeasureDlg( SMESHGUI::desktop(), page ); + dlg->show(); + break; + } } anApp->updateActions(); //SRN: To update a Save button in the toolbar @@ -2841,7 +3086,8 @@ void SMESHGUI::BuildPresentation( const Handle(SALOME_InteractiveObject) & theIO // function : createSMESHAction // purpose : //======================================================================= -void SMESHGUI::createSMESHAction( const int id, const QString& po_id, const QString& icon_id, const int key, const bool toggle ) +void SMESHGUI::createSMESHAction( const int id, const QString& po_id, const QString& icon_id, + const int key, const bool toggle, const QString& shortcutAction ) { QIcon icon; QWidget* parent = application()->desktop(); @@ -2858,7 +3104,8 @@ void SMESHGUI::createSMESHAction( const int id, const QString& po_id, const QStr menu = tr( QString( "MEN_%1" ).arg( po_id ).toLatin1().data() ), status_bar = tr( QString( "STB_%1" ).arg( po_id ).toLatin1().data() ); - createAction( id, tooltip, icon, menu, status_bar, key, parent, toggle, this, SLOT( OnGUIEvent() ) ); + createAction( id, tooltip, icon, menu, status_bar, key, parent, + toggle, this, SLOT( OnGUIEvent() ), shortcutAction ); } //======================================================================= @@ -2948,12 +3195,14 @@ void SMESHGUI::initialize( CAM_Application* app ) createSMESHAction( 814, "UNDERLYING_ELEMS","ICON_UNDERLYING_ELEMS" ); createSMESHAction( 813, "DEL_GROUP", "ICON_DEL_GROUP" ); createSMESHAction( 900, "ADV_INFO", "ICON_ADV_INFO" ); - createSMESHAction( 902, "STD_INFO", "ICON_STD_INFO" ); + //createSMESHAction( 902, "STD_INFO", "ICON_STD_INFO" ); createSMESHAction( 903, "WHAT_IS", "ICON_WHAT_IS" ); createSMESHAction( 904, "FIND_ELEM", "ICON_FIND_ELEM" ); createSMESHAction( 6001, "LENGTH", "ICON_LENGTH", 0, true ); createSMESHAction( 6002, "FREE_EDGE", "ICON_FREE_EDGE", 0, true ); 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( 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 ); @@ -2977,6 +3226,7 @@ void SMESHGUI::initialize( CAM_Application* app ) createSMESHAction( 4032, "HEXA", "ICON_DLG_HEXAS" ); createSMESHAction( 4041, "REMOVE_NODES", "ICON_DLG_REM_NODE" ); createSMESHAction( 4042, "REMOVE_ELEMENTS", "ICON_DLG_REM_ELEMENT" ); + createSMESHAction( 4044, "REMOVE_ORPHAN_NODES", "ICON_DLG_REM_ORPHAN_NODES" ); createSMESHAction( 4043, "CLEAR_MESH" , "ICON_CLEAR_MESH" ); createSMESHAction( 4051, "RENUM_NODES", "ICON_DLG_RENUMBERING_NODES" ); createSMESHAction( 4052, "RENUM_ELEMENTS", "ICON_DLG_RENUMBERING_ELEMENTS" ); @@ -2986,9 +3236,9 @@ void SMESHGUI::initialize( CAM_Application* app ) createSMESHAction( 4064, "SEW", "ICON_SMESH_SEWING_FREEBORDERS" ); createSMESHAction( 4065, "MERGE", "ICON_SMESH_MERGE_NODES" ); createSMESHAction( 4066, "MERGE_ELEMENTS", "ICON_DLG_MERGE_ELEMENTS" ); - createSMESHAction( 4067, "MESH_THROU_POINT","ICON_DLG_MESH_THROU_POINT" ); + createSMESHAction( 4067, "MESH_THROU_POINT","ICON_DLG_MOVE_NODE" ); createSMESHAction( 4068, "SCALE", "ICON_DLG_MESH_SCALE" ); - createSMESHAction( 406, "MOVE", "ICON_DLG_MOVE_NODE" ); + createSMESHAction( 4069, "DUPLICATE_NODES", "ICON_SMESH_DUPLICATE_NODES" ); createSMESHAction( 407, "INV", "ICON_DLG_MESH_DIAGONAL" ); createSMESHAction( 408, "UNION2", "ICON_UNION2TRI" ); createSMESHAction( 409, "ORIENT", "ICON_DLG_MESH_ORIENTATION" ); @@ -3004,6 +3254,8 @@ void SMESHGUI::initialize( CAM_Application* app ) createSMESHAction( 419, "SPLIT_TO_TETRA", "ICON_SPLIT_TO_TETRA" ); createSMESHAction( 200, "RESET" ); createSMESHAction( 201, "SCALAR_BAR_PROP" ); + createSMESHAction( 202, "SAVE_DISTRIBUTION" ); + createSMESHAction( 203, "SHOW_DISTRIBUTION","",0, true ); createSMESHAction( 211, "WIRE", "ICON_WIRE", 0, true ); createSMESHAction( 212, "SHADE", "ICON_SHADE", 0, true ); createSMESHAction( 213, "SHRINK", "ICON_SHRINK", 0, true ); @@ -3033,6 +3285,9 @@ void SMESHGUI::initialize( CAM_Application* app ) createSMESHAction( 1137, "DISABLE_AUTO_COLOR" ); createSMESHAction( 2000, "CTRL" ); + createSMESHAction( 501, "MEASURE_MIN_DIST", "ICON_MEASURE_MIN_DIST" ); + createSMESHAction( 502, "MEASURE_BND_BOX", "ICON_MEASURE_BND_BOX" ); + createSMESHAction( 300, "ERASE" ); createSMESHAction( 301, "DISPLAY" ); createSMESHAction( 302, "DISPLAY_ONLY" ); @@ -3046,18 +3301,23 @@ void SMESHGUI::initialize( CAM_Application* app ) createSMESHAction( 4040, "QUADRATIC_HEXAHEDRON", "ICON_DLG_QUADRATIC_HEXAHEDRON" ); // ----- create menu -------------- - int fileId = createMenu( tr( "MEN_FILE" ), -1, 1 ), - editId = createMenu( tr( "MEN_EDIT" ), -1, 3 ), - toolsId = createMenu( tr( "MEN_TOOLS" ), -1, 5, 50 ), - meshId = createMenu( tr( "MEN_MESH" ), -1, 70, 10 ), - ctrlId = createMenu( tr( "MEN_CTRL" ), -1, 60, 10 ), - modifyId = createMenu( tr( "MEN_MODIFY" ), -1, 40, 10 ), - viewId = createMenu( tr( "MEN_VIEW" ), -1, 2 ); + int fileId = createMenu( tr( "MEN_FILE" ), -1, 1 ), + editId = createMenu( tr( "MEN_EDIT" ), -1, 3 ), + toolsId = createMenu( tr( "MEN_TOOLS" ), -1, 5, 50 ), + meshId = createMenu( tr( "MEN_MESH" ), -1, 70, 10 ), + ctrlId = createMenu( tr( "MEN_CTRL" ), -1, 60, 10 ), + modifyId = createMenu( tr( "MEN_MODIFY" ), -1, 40, 10 ), + measureId = createMenu( tr( "MEN_MEASURE" ), -1, 50, 10 ), + viewId = createMenu( tr( "MEN_VIEW" ), -1, 2 ); createMenu( separator(), fileId ); int importId = createMenu( tr( "MEN_IMPORT" ), fileId, -1, 10 ), exportId = createMenu( tr( "MEN_EXPORT" ), fileId, -1, 10 ), + nodeId = createMenu( tr( "MEN_NODE_CTRL" ), ctrlId, -1, 10 ), + edgeId = createMenu( tr( "MEN_EDGE_CTRL" ), ctrlId, -1, 10 ), + faceId = createMenu( tr( "MEN_FACE_CTRL" ), ctrlId, -1, 10 ), + volumeId = createMenu( tr( "MEN_VOLUME_CTRL" ), ctrlId, -1, 10 ), addId = createMenu( tr( "MEN_ADD" ), modifyId, 402 ), removeId = createMenu( tr( "MEN_REMOVE" ), modifyId, 403 ), renumId = createMenu( tr( "MEN_RENUM" ), modifyId, 404 ), @@ -3103,30 +3363,29 @@ void SMESHGUI::initialize( CAM_Application* app ) createMenu( 813, meshId, -1 ); createMenu( separator(), meshId, -1 ); createMenu( 900, meshId, -1 ); - createMenu( 902, meshId, -1 ); + //createMenu( 902, meshId, -1 ); createMenu( 903, meshId, -1 ); createMenu( 904, meshId, -1 ); createMenu( separator(), meshId, -1 ); - createMenu( 6003, ctrlId, -1 ); - createMenu( 6001, ctrlId, -1 ); - createMenu( 6004, ctrlId, -1 ); - createMenu( separator(), ctrlId, -1 ); - createMenu( 6005, ctrlId, -1 ); - createMenu( 6002, ctrlId, -1 ); - createMenu( 6018, ctrlId, -1 ); - createMenu( 6019, ctrlId, -1 ); - createMenu( 6011, ctrlId, -1 ); - createMenu( 6012, ctrlId, -1 ); - createMenu( 6013, ctrlId, -1 ); - createMenu( 6014, ctrlId, -1 ); - createMenu( 6015, ctrlId, -1 ); - createMenu( 6016, ctrlId, -1 ); - createMenu( separator(), ctrlId, -1 ); - createMenu( 6017, ctrlId, -1 ); - createMenu( 6009, ctrlId, -1 ); - createMenu( 6021, ctrlId, -1 ); - createMenu( separator(), ctrlId, -1 ); + createMenu( 6005, nodeId, -1 ); + createMenu( 6002, edgeId, -1 ); + createMenu( 6003, edgeId, -1 ); + createMenu( 6001, edgeId, -1 ); + createMenu( 6004, edgeId, -1 ); + createMenu( 6021, faceId, -1 ); + createMenu( 6018, faceId, -1 ); + createMenu( 6019, faceId, -1 ); + createMenu( 6011, faceId, -1 ); + createMenu( 6012, faceId, -1 ); + createMenu( 6013, faceId, -1 ); + createMenu( 6014, faceId, -1 ); + createMenu( 6015, faceId, -1 ); + createMenu( 6016, faceId, -1 ); + createMenu( 6022, faceId, -1 ); + createMenu( 6017, volumeId, -1 ); + createMenu( 6009, volumeId, -1 ); + createMenu( 6023, volumeId, -1 ); createMenu( 4000, addId, -1 ); createMenu( 4009, addId, -1 ); @@ -3148,6 +3407,8 @@ void SMESHGUI::initialize( CAM_Application* app ) createMenu( 4041, removeId, -1 ); createMenu( 4042, removeId, -1 ); + createMenu( 4044, removeId, -1 ); + createMenu( separator(), removeId, -1 ); createMenu( 4043, removeId, -1 ); createMenu( 4051, renumId, -1 ); @@ -3160,8 +3421,8 @@ void SMESHGUI::initialize( CAM_Application* app ) createMenu( 4065, transfId, -1 ); createMenu( 4066, transfId, -1 ); createMenu( 4068, transfId, -1 ); + createMenu( 4069, transfId, -1 ); - createMenu( 406, modifyId, -1 ); createMenu( 4067,modifyId, -1 ); createMenu( 407, modifyId, -1 ); createMenu( 408, modifyId, -1 ); @@ -3177,6 +3438,8 @@ void SMESHGUI::initialize( CAM_Application* app ) createMenu( 417, modifyId, -1 ); createMenu( 418, modifyId, -1 ); + createMenu( 501, measureId, -1 ); + createMenu( 502, measureId, -1 ); createMenu( 214, viewId, -1 ); // ----- create toolbars -------------- @@ -3203,17 +3466,19 @@ void SMESHGUI::initialize( CAM_Application* app ) //createTool( 815, meshTb ); createTool( separator(), meshTb ); createTool( 900, meshTb ); - createTool( 902, meshTb ); + //createTool( 902, meshTb ); createTool( 903, meshTb ); createTool( 904, meshTb ); createTool( separator(), meshTb ); - createTool( 6001, ctrlTb ); + createTool( 6005, ctrlTb ); + createTool( separator(), ctrlTb ); + createTool( 6002, ctrlTb ); createTool( 6003, ctrlTb ); + createTool( 6001, ctrlTb ); createTool( 6004, ctrlTb ); createTool( separator(), ctrlTb ); - createTool( 6005, ctrlTb ); - createTool( 6002, ctrlTb ); + createTool( 6021, ctrlTb ); createTool( 6018, ctrlTb ); createTool( 6019, ctrlTb ); createTool( 6011, ctrlTb ); @@ -3222,10 +3487,11 @@ void SMESHGUI::initialize( CAM_Application* app ) createTool( 6014, ctrlTb ); createTool( 6015, ctrlTb ); createTool( 6016, ctrlTb ); + createTool( 6022, ctrlTb ); createTool( separator(), ctrlTb ); createTool( 6017, ctrlTb ); createTool( 6009, ctrlTb ); - createTool( 6021, ctrlTb ); + createTool( 6023, ctrlTb ); createTool( separator(), ctrlTb ); createTool( 4000, addRemTb ); @@ -3248,6 +3514,7 @@ void SMESHGUI::initialize( CAM_Application* app ) createTool( separator(), addRemTb ); createTool( 4041, addRemTb ); createTool( 4042, addRemTb ); + createTool( 4044, addRemTb ); createTool( 4043, addRemTb ); createTool( separator(), addRemTb ); createTool( 4051, addRemTb ); @@ -3260,9 +3527,9 @@ void SMESHGUI::initialize( CAM_Application* app ) createTool( 4065, addRemTb ); createTool( 4066, addRemTb ); createTool( 4068, addRemTb ); + createTool( 4069, addRemTb ); createTool( separator(), addRemTb ); - createTool( 406, modifyTb ); createTool( 4067,modifyTb ); createTool( 407, modifyTb ); createTool( 408, modifyTb ); @@ -3332,7 +3599,7 @@ void SMESHGUI::initialize( CAM_Application* app ) createPopupItem( 713, OB, mesh, "&& isComputable" ); // MESH ORDER createPopupItem( 214, OB, mesh_group ); // UPDATE createPopupItem( 900, OB, mesh_group ); // ADV_INFO - createPopupItem( 902, OB, mesh ); // STD_INFO + //createPopupItem( 902, OB, mesh ); // STD_INFO createPopupItem( 903, OB, mesh_group ); // WHAT_IS createPopupItem( 904, OB, mesh_group ); // FIND_ELEM popupMgr()->insert( separator(), -1, 0 ); @@ -3368,7 +3635,7 @@ void SMESHGUI::initialize( CAM_Application* app ) popupMgr()->insert( separator(), -1, 0 ); createPopupItem( 214, View, mesh_group ); // UPDATE createPopupItem( 900, View, mesh_group ); // ADV_INFO - createPopupItem( 902, View, mesh ); // STD_INFO + //createPopupItem( 902, View, mesh ); // STD_INFO createPopupItem( 903, View, mesh_group ); // WHAT_IS createPopupItem( 904, View, mesh_group ); // FIND_ELEM popupMgr()->insert( separator(), -1, 0 ); @@ -3456,12 +3723,12 @@ void SMESHGUI::initialize( CAM_Application* app ) //------------------------------------------------- // Representation of the 2D Quadratic elements - //------------------------------------------------- + //------------------------------------------------- anId = popupMgr()->insert( tr( "MEN_QUADRATIC_REPRESENT" ), -1, -1 ); popupMgr()->insert( action( 231 ), anId, -1 ); // LINE REPRESENTATION popupMgr()->setRule( action( 231 ), aMeshInVTK + "and isVisible",QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( 231 ), "quadratic2DMode = 'eLines'", QtxPopupMgr::ToggleRule ); - + popupMgr()->insert( action( 232 ), anId, -1 ); // ARC REPRESENTATION popupMgr()->setRule( action( 232 ), aMeshInVTK + "and isVisible", QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( 232 ), "quadratic2DMode = 'eArcs'", QtxPopupMgr::ToggleRule ); @@ -3485,14 +3752,6 @@ void SMESHGUI::initialize( CAM_Application* app ) popupMgr()->insert( action( 1133 ), -1, -1 ); popupMgr()->setRule( action( 1133 ), aMeshInVTK + "&& isVisible", QtxPopupMgr::VisibleRule ); - //------------------------------------------------- - // Clipping - //------------------------------------------------- - popupMgr()->insert( action( 1134 ), -1, -1 ); - popupMgr()->setRule( action( 1134 ), aMeshInVTK + "&& selcount=1 && isVisible", QtxPopupMgr::VisibleRule ); - - popupMgr()->insert( separator(), -1, -1 ); - //------------------------------------------------- // Controls //------------------------------------------------- @@ -3503,88 +3762,110 @@ void SMESHGUI::initialize( CAM_Application* app ) aMeshInVtkHasVolumes = aMeshInVTK + "&&" + hasVolumes; anId = popupMgr()->insert( tr( "MEN_CTRL" ), -1, -1 ); - + popupMgr()->insert( action( 200 ), anId, -1 ); // RESET popupMgr()->setRule( action( 200 ), aMeshInVTK + "&& controlMode <> 'eNone'", QtxPopupMgr::VisibleRule ); popupMgr()->insert( separator(), anId, -1 ); - popupMgr()->insert( action( 6003 ), anId, -1 ); // FREE_BORDER + int aSubId = popupMgr()->insert( tr( "MEN_NODE_CTRL" ), anId, -1 ); // NODE CONTROLS + + popupMgr()->insert( action( 6005 ), aSubId, -1 ); // FREE_NODE + popupMgr()->setRule( action( 6005 ), aMeshInVtkHasNodes, QtxPopupMgr::VisibleRule ); + popupMgr()->setRule( action( 6005 ), "controlMode = 'eFreeNodes'", QtxPopupMgr::ToggleRule ); + + aSubId = popupMgr()->insert( tr( "MEN_EDGE_CTRL" ), anId, -1 ); // EDGE CONTROLS + + popupMgr()->insert( action( 6002 ), aSubId, -1 ); // FREE_EDGE + popupMgr()->setRule( action( 6002 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule ); + popupMgr()->setRule( action( 6002 ), "controlMode = 'eFreeEdges'", QtxPopupMgr::ToggleRule ); + + popupMgr()->insert( action( 6003 ), aSubId, -1 ); // FREE_BORDER popupMgr()->setRule( action( 6003 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( 6003 ), "controlMode = 'eFreeBorders'", QtxPopupMgr::ToggleRule ); - popupMgr()->insert( action( 6001 ), anId, -1 ); // LENGTH + popupMgr()->insert( action( 6001 ), aSubId, -1 ); // LENGTH popupMgr()->setRule( action( 6001 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( 6001 ), "controlMode = 'eLength'", QtxPopupMgr::ToggleRule ); - popupMgr()->insert( action( 6004 ), anId, -1 ); // CONNECTION + popupMgr()->insert( action( 6004 ), aSubId, -1 ); // CONNECTION popupMgr()->setRule( action( 6004 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( 6004 ), "controlMode = 'eMultiConnection'", QtxPopupMgr::ToggleRule ); - popupMgr()->insert( separator(), anId, -1 ); + aSubId = popupMgr()->insert( tr( "MEN_FACE_CTRL" ), anId, -1 ); // FACE CONTROLS - popupMgr()->insert( action( 6005 ), anId, -1 ); // FREE_NODE - popupMgr()->setRule( action( 6005 ), aMeshInVtkHasNodes, QtxPopupMgr::VisibleRule ); - popupMgr()->setRule( action( 6005 ), "controlMode = 'eFreeNodes'", QtxPopupMgr::ToggleRule ); - - popupMgr()->insert( action( 6002 ), anId, -1 ); // FREE_EDGE - popupMgr()->setRule( action( 6002 ), aMeshInVtkHasEdges, QtxPopupMgr::VisibleRule ); - popupMgr()->setRule( action( 6002 ), "controlMode = 'eFreeEdges'", QtxPopupMgr::ToggleRule ); + 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 ), anId, -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 ), anId, -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 ), anId, -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 ), anId, -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 ), anId, -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 ), anId, -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 ), anId, -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 ), anId, -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( separator(), anId, -1 ); + 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 ); + + aSubId = popupMgr()->insert( tr( "MEN_VOLUME_CTRL" ), anId, -1 ); // VOLUME CONTROLS - popupMgr()->insert( action( 6017 ), anId, -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 ); - popupMgr()->insert ( action( 6009 ), anId, -1 ); // VOLUME_3D + popupMgr()->insert ( action( 6009 ), aSubId, -1 ); // VOLUME_3D popupMgr()->setRule( action( 6009 ), aMeshInVtkHasVolumes, QtxPopupMgr::VisibleRule ); popupMgr()->setRule( action( 6009 ), "controlMode = 'eVolume3D'", QtxPopupMgr::ToggleRule ); - popupMgr()->insert( action( 6021 ), anId, -1 ); // FREE_FACE - popupMgr()->setRule( action( 6021 ), aMeshInVtkHasFaces /*aMeshInVtkHasVolumes*/, - QtxPopupMgr::VisibleRule ); - popupMgr()->setRule( action( 6021 ), "controlMode = 'eFreeFaces'", QtxPopupMgr::ToggleRule ); + 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( separator(), anId, -1 ); popupMgr()->insert( action( 201 ), anId, -1 ); // SCALAR_BAR_PROP popupMgr()->setRule( action( 201 ), aMeshInVTK + "&& controlMode <> 'eNone'", QtxPopupMgr::VisibleRule ); + popupMgr()->insert( separator(), anId, -1 ); + + popupMgr()->insert( action( 202 ), anId, -1 ); // SAVE_DISTRIBUTION + popupMgr()->setRule( action( 202 ), aMeshInVTK + "&& isNumFunctor", QtxPopupMgr::VisibleRule ); + + popupMgr()->insert( action( 203 ), anId, -1 ); // SHOW_DISTRIBUTION + popupMgr()->setRule( action( 203 ), aMeshInVTK + "&& isNumFunctor", QtxPopupMgr::VisibleRule ); + popupMgr()->setRule( action( 203 ), aMeshInVTK + "&& isNumFunctor && isDistributionVisible", QtxPopupMgr::ToggleRule); + + popupMgr()->insert( separator(), -1, -1 ); - + //------------------------------------------------- // Display / Erase //------------------------------------------------- @@ -3601,8 +3882,19 @@ void SMESHGUI::initialize( CAM_Application* app ) popupMgr()->insert( separator(), -1, -1 ); + //------------------------------------------------- + // Clipping + //------------------------------------------------- + popupMgr()->insert( action( 1134 ), -1, -1 ); + popupMgr()->setRule( action( 1134 ), "client='VTKViewer'", QtxPopupMgr::VisibleRule ); + + popupMgr()->insert( separator(), -1, -1 ); + connect( application(), SIGNAL( viewManagerActivated( SUIT_ViewManager* ) ), this, SLOT( onViewManagerActivated( SUIT_ViewManager* ) ) ); + + connect( application(), SIGNAL( viewManagerRemoved( SUIT_ViewManager* ) ), + this, SLOT( onViewManagerRemoved( SUIT_ViewManager* ) ) ); } //================================================================================ @@ -3634,7 +3926,7 @@ bool SMESHGUI::reusableOperation( const int id ) { // compute, evaluate and precompute are not reusable operations return ( id == 701 || id == 711 || id == 712 ) ? false : SalomeApp_Module::reusableOperation( id ); -} +} bool SMESHGUI::activateModule( SUIT_Study* study ) { @@ -3643,6 +3935,21 @@ bool SMESHGUI::activateModule( SUIT_Study* study ) setMenuShown( true ); setToolShown( true ); + // import Python module that manages SMESH plugins (need to be here because SalomePyQt API uses active module) + PyGILState_STATE gstate = PyGILState_Ensure(); + PyObject* pluginsmanager=PyImport_ImportModule((char*)"salome_pluginsmanager"); + if(pluginsmanager==NULL) + PyErr_Print(); + else + { + PyObject* result=PyObject_CallMethod( pluginsmanager, (char*)"initialize", (char*)"isss",1,"smesh",tr("MEN_MESH").toStdString().c_str(),tr("SMESH_PLUGINS_OTHER").toStdString().c_str()); + if(result==NULL) + PyErr_Print(); + Py_XDECREF(result); + } + PyGILState_Release(gstate); + // end of GEOM plugins loading + // Reset actions accelerator keys action(111)->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B)); // Import DAT action(112)->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_U)); // Import UNV @@ -3759,13 +4066,60 @@ void SMESHGUI::onViewManagerActivated( SUIT_ViewManager* mgr ) SMESH::UpdateSelectionProp( this ); } +void SMESHGUI::onViewManagerRemoved( SUIT_ViewManager* theViewManager ) +{ + if( theViewManager && theViewManager->getType() == SVTK_Viewer::Type() ) + myClippingPlaneInfoMap.erase( theViewManager ); +} + +void SMESHGUI::addActorAsObserver( SMESH_Actor* theActor ) +{ + theActor->AddObserver( SMESH::DeleteActorEvent, + myEventCallbackCommand.GetPointer(), + myPriority ); +} + +void SMESHGUI::ProcessEvents( vtkObject* theObject, + unsigned long theEvent, + void* theClientData, + void* theCallData ) +{ + if( SMESHGUI* aSMESHGUI = reinterpret_cast( theClientData ) ) { + if( theObject && theEvent == SMESH::DeleteActorEvent ) { + if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( theObject ) ) { + SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = aSMESHGUI->getClippingPlaneInfoMap(); + SMESHGUI_ClippingPlaneInfoMap::iterator anIter1 = aClippingPlaneInfoMap.begin(); + for( ; anIter1 != aClippingPlaneInfoMap.end(); anIter1++ ) { + SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = anIter1->second; + SMESHGUI_ClippingPlaneInfoList::iterator anIter2 = aClippingPlaneInfoList.begin(); + for( ; anIter2 != aClippingPlaneInfoList.end(); anIter2++ ) { + SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter2; + std::list& anActorList = aClippingPlaneInfo.ActorList; + SMESH::TActorList::iterator anIter3 = anActorList.begin(); + for ( ; anIter3 != anActorList.end(); anIter3++ ) { + if( anActor == *anIter3 ) { + anActorList.erase( anIter3 ); + break; + } + } + } + } + } + } + } +} + void SMESHGUI::createPreferences() { // General tab ------------------------------------------------------------------------ int genTab = addPreference( tr( "PREF_TAB_GENERAL" ) ); - int updateGroup = addPreference( tr( "PREF_GROUP_UPDATE" ), genTab ); - addPreference( tr( "PREF_AUTO_UPDATE" ), updateGroup, LightApp_Preferences::Bool, "SMESH", "auto_update" ); + int autoUpdate = addPreference( tr( "PREF_AUTO_UPDATE" ), genTab, LightApp_Preferences::Auto, "SMESH", "auto_update" ); + int lim = addPreference( tr( "PREF_UPDATE_LIMIT" ), autoUpdate, LightApp_Preferences::IntSpin, "SMESH", "update_limit" ); + setPreferenceProperty( lim, "min", 0 ); + setPreferenceProperty( lim, "max", 100000000 ); + setPreferenceProperty( lim, "step", 1000 ); + setPreferenceProperty( lim, "special", tr( "PREF_UPDATE_LIMIT_NOLIMIT" ) ); int qaGroup = addPreference( tr( "PREF_GROUP_QUALITY" ), genTab ); setPreferenceProperty( qaGroup, "columns", 2 ); @@ -3807,8 +4161,8 @@ void SMESHGUI::createPreferences() "SMESH", "max_angle" ); setPreferenceProperty( maxAngle, "min", 1 ); setPreferenceProperty( maxAngle, "max", 90 ); - - + + int exportgroup = addPreference( tr( "PREF_GROUP_EXPORT" ), genTab ); setPreferenceProperty( exportgroup, "columns", 2 ); @@ -3819,9 +4173,9 @@ void SMESHGUI::createPreferences() setPreferenceProperty( computeGroup, "columns", 2 ); int notifyMode = addPreference( tr( "PREF_NOTIFY_MODE" ), computeGroup, LightApp_Preferences::Selector, "SMESH", "show_result_notification" ); modes.clear(); - modes.append( "Never" ); - modes.append( "Errors only" ); - modes.append( "Always" ); + modes.append( tr( "PREF_NOTIFY_NEVER" ) ); + modes.append( tr( "PREF_NOTIFY_ERROR" ) ); + modes.append( tr( "PREF_NOTIFY_ALWAYS" ) ); indices.clear(); indices.append( 0 ); indices.append( 1 ); @@ -3829,6 +4183,18 @@ void SMESHGUI::createPreferences() setPreferenceProperty( notifyMode, "strings", modes ); setPreferenceProperty( notifyMode, "indexes", indices ); + int infoGroup = addPreference( tr( "PREF_GROUP_INFO" ), genTab ); + setPreferenceProperty( computeGroup, "columns", 2 ); + int elemInfo = addPreference( tr( "PREF_ELEM_INFO" ), infoGroup, LightApp_Preferences::Selector, "SMESH", "mesh_elem_info" ); + modes.clear(); + modes.append( tr( "PREF_ELEM_INFO_SIMPLE" ) ); + modes.append( tr( "PREF_ELEM_INFO_TREE" ) ); + indices.clear(); + indices.append( 0 ); + indices.append( 1 ); + setPreferenceProperty( elemInfo, "strings", modes ); + setPreferenceProperty( elemInfo, "indexes", indices ); + int segGroup = addPreference( tr( "PREF_GROUP_SEGMENT_LENGTH" ), genTab ); setPreferenceProperty( segGroup, "columns", 2 ); int segLen = addPreference( tr( "PREF_SEGMENT_LENGTH" ), segGroup, LightApp_Preferences::IntSpin, @@ -3839,15 +4205,15 @@ void SMESHGUI::createPreferences() "SMESH", "nb_segments_per_edge" ); setPreferenceProperty( nbSeg, "min", 1 ); setPreferenceProperty( nbSeg, "max", 10000000 ); - + // Quantities with individual precision settings int precGroup = addPreference( tr( "SMESH_PREF_GROUP_PRECISION" ), genTab ); setPreferenceProperty( precGroup, "columns", 2 ); - + const int nbQuantities = 6; int precs[nbQuantities], ii = 0; precs[ii++] = addPreference( tr( "SMESH_PREF_length_precision" ), precGroup, - LightApp_Preferences::IntSpin, "SMESH", "length_precision" ); + LightApp_Preferences::IntSpin, "SMESH", "length_precision" ); precs[ii++] = addPreference( tr( "SMESH_PREF_angle_precision" ), precGroup, LightApp_Preferences::IntSpin, "SMESH", "angle_precision" ); precs[ii++] = addPreference( tr( "SMESH_PREF_len_tol_precision" ), precGroup, @@ -3857,14 +4223,14 @@ void SMESHGUI::createPreferences() precs[ii++] = addPreference( tr( "SMESH_PREF_area_precision" ), precGroup, LightApp_Preferences::IntSpin, "SMESH", "area_precision" ); precs[ii ] = addPreference( tr( "SMESH_PREF_vol_precision" ), precGroup, - LightApp_Preferences::IntSpin, "SMESH", "vol_precision" ); - + LightApp_Preferences::IntSpin, "SMESH", "vol_precision" ); + // Set property for precision value for spinboxes for ( ii = 0; ii < nbQuantities; ii++ ){ setPreferenceProperty( precs[ii], "min", -14 ); setPreferenceProperty( precs[ii], "max", 14 ); setPreferenceProperty( precs[ii], "precision", 2 ); - } + } // Mesh tab ------------------------------------------------------------------------ int meshTab = addPreference( tr( "PREF_TAB_MESH" ) ); @@ -3906,6 +4272,11 @@ void SMESHGUI::createPreferences() addPreference( tr( "PREF_BACKFACE" ), elemGroup, LightApp_Preferences::Color, "SMESH", "backface_color" ); addPreference( tr( "PREF_COLOR_0D" ), elemGroup, LightApp_Preferences::Color, "SMESH", "elem0d_color" ); + int grpGroup = addPreference( tr( "PREF_GROUP_GROUPS" ), meshTab ); + setPreferenceProperty( grpGroup, "columns", 2 ); + + addPreference( tr( "PREF_GRP_NAMES" ), grpGroup, LightApp_Preferences::Color, "SMESH", "group_name_color" ); + //int sp = addPreference( "", elemGroup, LightApp_Preferences::Space ); //setPreferenceProperty( sp, "hstretch", 0 ); //setPreferenceProperty( sp, "vstretch", 0 ); @@ -4043,6 +4414,18 @@ void SMESHGUI::createPreferences() setPreferenceProperty( hh, "min", 0.0 ); setPreferenceProperty( hh, "max", 1.0 ); setPreferenceProperty( hh, "step", 0.1 ); + + int distributionGr = addPreference( tr( "SMESH_DISTRIBUTION_SCALARBAR" ), sbarTab, LightApp_Preferences::Auto, "SMESH", "distribution_visibility" ); + int coloringType = addPreference( tr( "SMESH_DISTRIBUTION_COLORING_TYPE" ), distributionGr, LightApp_Preferences::Selector, "SMESH", "distribution_coloring_type" ); + setPreferenceProperty( distributionGr, "columns", 3 ); + QStringList types; + types.append( tr( "SMESH_MONOCOLOR" ) ); + types.append( tr( "SMESH_MULTICOLOR" ) ); + indices.clear(); indices.append( 0 ); indices.append( 1 ); + setPreferenceProperty( coloringType, "strings", types ); + setPreferenceProperty( coloringType, "indexes", indices ); + addPreference( tr( "SMESH_DISTRIBUTION_COLOR" ), distributionGr, LightApp_Preferences::Color, "SMESH", "distribution_color" ); + } void SMESHGUI::preferencesChanged( const QString& sect, const QString& name ) @@ -4262,12 +4645,9 @@ SALOMEDS::Color SMESHGUI::getUniqueColor( const QList& theReser if( aTolerance < 1 ) break; } - //cout << "Iteration N" << anIterations << " (tolerance=" << aTolerance << ")"<< endl; aHue = (int)( 360.0 * rand() / RAND_MAX ); - //cout << "Hue = " << aHue << endl; - //cout << "Auto colors : "; bool ok = true; QList::const_iterator it = theReservedColors.constBegin(); QList::const_iterator itEnd = theReservedColors.constEnd(); @@ -4278,21 +4658,17 @@ SALOMEDS::Color SMESHGUI::getUniqueColor( const QList& theReser int h, s, v; aQColor.getHsv( &h, &s, &v ); - //cout << h << " "; if( abs( h - aHue ) < aTolerance ) { ok = false; - //cout << "break (diff = " << abs( h - aHue ) << ")"; break; } } - //cout << endl; if( ok ) break; } - //cout << "Hue of the returned color = " << aHue << endl; QColor aColor; aColor.setHsv( aHue, 255, 255 ); @@ -4380,6 +4756,37 @@ void SMESHGUI::storeVisualParameters (int savePoint) // saving VTK actors properties if (vType == SVTK_Viewer::Type()) { + // store the clipping planes attached to the view manager + SMESHGUI_ClippingPlaneInfoList aClippingPlaneInfoList; + SMESHGUI_ClippingPlaneInfoMap::const_iterator anIter = myClippingPlaneInfoMap.find( vman ); + if( anIter != myClippingPlaneInfoMap.end() ) + aClippingPlaneInfoList = anIter->second; + + if( !aClippingPlaneInfoList.empty() ) { + SMESHGUI_ClippingPlaneInfoList::const_iterator anIter = aClippingPlaneInfoList.begin(); + for( int anId = 0; anIter != aClippingPlaneInfoList.end(); anIter++, anId++ ) + { + const SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter; + SMESH::OrientedPlane* aPlane = aClippingPlaneInfo.Plane; + + QString aPropertyName( "ClippingPlane" ); + aPropertyName += gSeparator; + aPropertyName += QString::number( vtkViewers ); + aPropertyName += gSeparator; + aPropertyName += QString::number( anId ); + + QString aPropertyValue = QString::number( (int)aPlane->GetOrientation() ).toLatin1().constData(); + aPropertyValue += gDigitsSep; + aPropertyValue += QString::number( aPlane->GetDistance() ).toLatin1().constData(); + aPropertyValue += gDigitsSep; + aPropertyValue += QString::number( aPlane->myAngle[0] ).toLatin1().constData(); + aPropertyValue += gDigitsSep; + aPropertyValue += QString::number( aPlane->myAngle[1] ).toLatin1().constData(); + + ip->setProperty( aPropertyName.toStdString(), aPropertyValue.toStdString() ); + } + } + QVector views = vman->getViews(); for (int i = 0, iEnd = vman->getViewsCount(); i < iEnd; i++) { @@ -4505,22 +4912,25 @@ void SMESHGUI::storeVisualParameters (int savePoint) // Clipping param = vtkParam + "ClippingPlane"; - int nPlanes = aSmeshActor->GetNumberOfClippingPlanes(); - if (!nPlanes) - ip->setParameter(entry, param, "Off"); - for (int ipl = 0; ipl < nPlanes; ipl++) { - //vtkPlane* plane = aSmeshActor->GetClippingPlane(ipl); - SMESH::Orientation anOrientation; - double aDistance; - vtkFloatingPointType anAngle[2]; - SMESHGUI_ClippingDlg::GetPlaneParam(aSmeshActor, ipl, anOrientation, aDistance, anAngle); - std::string planeValue = QString::number((int)anOrientation).toLatin1().data(); - planeValue += gDigitsSep; planeValue += QString::number(aDistance).toLatin1().data(); - planeValue += gDigitsSep; planeValue += QString::number(anAngle[0]).toLatin1().data(); - planeValue += gDigitsSep; planeValue += QString::number(anAngle[1]).toLatin1().data(); - - ip->setParameter(entry, param + QString::number(ipl+1).toLatin1().data(), planeValue); + int aPlaneId = 0; + if( !aClippingPlaneInfoList.empty() ) { + SMESHGUI_ClippingPlaneInfoList::const_iterator anIter1 = aClippingPlaneInfoList.begin(); + for( int anId = 0; anIter1 != aClippingPlaneInfoList.end(); anIter1++, anId++ ) + { + const SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter1; + std::list anActorList = aClippingPlaneInfo.ActorList; + SMESH::TActorList::iterator anIter2 = anActorList.begin(); + for ( ; anIter2 != anActorList.end(); anIter2++ ) { + if( aSmeshActor == *anIter2 ) { + ip->setParameter( entry, param + QString::number( ++aPlaneId ).toLatin1().constData(), + QString::number( anId ).toLatin1().constData() ); + break; + } + } + } } + if( aPlaneId == 0 ) + ip->setParameter( entry, param, "Off" ); } // if (io->hasEntry()) } // SMESH_Actor && hasIO } // isVisible @@ -4532,6 +4942,25 @@ void SMESHGUI::storeVisualParameters (int savePoint) } // for (viewManagers) } +// data structures for clipping planes processing +typedef struct { + int Id; + vtkIdType Orientation; + vtkFloatingPointType Distance; + vtkFloatingPointType Angle[2]; +} TPlaneData; +typedef std::list TPlaneDataList; +typedef std::map TPlaneDataMap; + +typedef std::list TActorList; +typedef struct { + int PlaneId; + TActorList ActorList; + SUIT_ViewManager* ViewManager; +} TPlaneInfo; +typedef std::list TPlaneInfoList; +typedef std::map TPlaneInfoMap; + /*! * \brief Restore visual parameters * @@ -4556,8 +4985,9 @@ void SMESHGUI::restoreVisualParameters (int savePoint) savePoint); _PTR(IParameters) ip = ClientFactory::getIParameters(ap); - // restore map of custom markers + // restore map of custom markers and map of clipping planes VTK::MarkerMap& aMarkerMap = myMarkerMap[ studyDS->StudyId() ]; + TPlaneDataMap aPlaneDataMap; std::vector properties = ip->getProperties(); for (std::vector::iterator propIt = properties.begin(); propIt != properties.end(); ++propIt) @@ -4567,52 +4997,103 @@ void SMESHGUI::restoreVisualParameters (int savePoint) QString aPropertyValue( ip->getProperty( property ).c_str() ); QStringList aPropertyNameList = aPropertyName.split( gSeparator, QString::SkipEmptyParts ); - if( aPropertyNameList.size() != 2 ) + if( aPropertyNameList.isEmpty() ) continue; - int anId = 0; - bool ok = false; - if( aPropertyNameList[0] == "texture" ) - anId = aPropertyNameList[1].toInt( &ok ); + QString aPropertyType = aPropertyNameList[0]; + if( aPropertyType == "texture" ) + { + if( aPropertyNameList.size() != 2 ) + continue; - if( !ok || anId < 1 ) - continue; + bool ok = false; + int anId = aPropertyNameList[1].toInt( &ok ); + if( !ok || anId < 1 ) + continue; - QStringList aPropertyValueList = aPropertyValue.split( gPathSep, QString::SkipEmptyParts ); - if( aPropertyValueList.size() != 2 ) - continue; + QStringList aPropertyValueList = aPropertyValue.split( gPathSep, QString::SkipEmptyParts ); + if( aPropertyValueList.size() != 2 ) + continue; - std::string aMarkerFileName = aPropertyValueList[0].toStdString(); - QString aMarkerTextureString = aPropertyValueList[1]; - QStringList aMarkerTextureStringList = aMarkerTextureString.split( gDigitsSep, QString::SkipEmptyParts ); - if( aMarkerTextureStringList.size() != 3 ) - continue; + std::string aMarkerFileName = aPropertyValueList[0].toStdString(); + QString aMarkerTextureString = aPropertyValueList[1]; + QStringList aMarkerTextureStringList = aMarkerTextureString.split( gDigitsSep, QString::SkipEmptyParts ); + if( aMarkerTextureStringList.size() != 3 ) + continue; - ok = false; - ushort aWidth = aMarkerTextureStringList[0].toUShort( &ok ); - if( !ok ) - continue; + ok = false; + ushort aWidth = aMarkerTextureStringList[0].toUShort( &ok ); + if( !ok ) + continue; - ok = false; - ushort aHeight = aMarkerTextureStringList[1].toUShort( &ok ); - if( !ok ) - continue; + ok = false; + ushort aHeight = aMarkerTextureStringList[1].toUShort( &ok ); + if( !ok ) + continue; - VTK::MarkerTexture aMarkerTexture; - aMarkerTexture.push_back( aWidth ); - aMarkerTexture.push_back( aHeight ); + VTK::MarkerTexture aMarkerTexture; + aMarkerTexture.push_back( aWidth ); + aMarkerTexture.push_back( aHeight ); - QString aMarkerTextureData = aMarkerTextureStringList[2]; - for( int i = 0, n = aMarkerTextureData.length(); i < n; i++ ) - { - QChar aChar = aMarkerTextureData.at( i ); - if( aChar.isDigit() ) - aMarkerTexture.push_back( aChar.digitValue() ); + QString aMarkerTextureData = aMarkerTextureStringList[2]; + for( int i = 0, n = aMarkerTextureData.length(); i < n; i++ ) + { + QChar aChar = aMarkerTextureData.at( i ); + if( aChar.isDigit() ) + aMarkerTexture.push_back( aChar.digitValue() ); + } + + aMarkerMap[ anId ] = VTK::MarkerData( aMarkerFileName, aMarkerTexture ); } + else if( aPropertyType == "ClippingPlane" ) + { + if( aPropertyNameList.size() != 3 ) + continue; + + bool ok = false; + int aViewId = aPropertyNameList[1].toInt( &ok ); + if( !ok || aViewId < 0 ) + continue; + + ok = false; + int aClippingPlaneId = aPropertyNameList[2].toInt( &ok ); + if( !ok || aClippingPlaneId < 0 ) + continue; + + QStringList aPropertyValueList = aPropertyValue.split( gDigitsSep, QString::SkipEmptyParts ); + if( aPropertyValueList.size() != 4 ) + continue; + + TPlaneData aPlaneData; + aPlaneData.Id = aClippingPlaneId; + + ok = false; + aPlaneData.Orientation = aPropertyValueList[0].toInt( &ok ); + if( !ok ) + continue; + + ok = false; + aPlaneData.Distance = aPropertyValueList[1].toDouble( &ok ); + if( !ok ) + continue; - aMarkerMap[ anId ] = VTK::MarkerData( aMarkerFileName, aMarkerTexture ); + ok = false; + aPlaneData.Angle[0] = aPropertyValueList[2].toDouble( &ok ); + if( !ok ) + continue; + + ok = false; + aPlaneData.Angle[1] = aPropertyValueList[3].toDouble( &ok ); + if( !ok ) + continue; + + TPlaneDataList& aPlaneDataList = aPlaneDataMap[ aViewId ]; + aPlaneDataList.push_back( aPlaneData ); + } } + TPlaneInfoMap aPlaneInfoMap; + std::vector entries = ip->getEntries(); for (std::vector::iterator entIt = entries.begin(); entIt != entries.end(); ++entIt) @@ -4659,39 +5140,40 @@ void SMESHGUI::restoreVisualParameters (int savePoint) if (vtkActors.IsBound(viewIndex)) aSmeshActor = vtkActors.Find(viewIndex); + QList lst; + getApp()->viewManagers(viewerTypStr, lst); + + // SVTK ViewManager always has 1 ViewWindow, so view index is index of view manager + SUIT_ViewManager* vman = NULL; + if (viewIndex >= 0 && viewIndex < lst.count()) + vman = lst.at(viewIndex); + if (paramNameStr == "Visibility") { - if (!aSmeshActor && displayer()) + if (!aSmeshActor && displayer() && vman) { - QList lst; - getApp()->viewManagers(viewerTypStr, lst); - - // SVTK ViewManager always has 1 ViewWindow, so view index is index of view manager - if (viewIndex >= 0 && viewIndex < lst.count()) { - SUIT_ViewManager* vman = lst.at(viewIndex); - SUIT_ViewModel* vmodel = vman->getViewModel(); - // SVTK view model can be casted to SALOME_View - displayer()->Display(entry, true, dynamic_cast(vmodel)); - - // store displayed actor in a temporary map for quicker - // access later when restoring other parameters - SVTK_ViewWindow* vtkView = (SVTK_ViewWindow*) vman->getActiveView(); - vtkRenderer* Renderer = vtkView->getRenderer(); - VTK::ActorCollectionCopy aCopy(Renderer->GetActors()); - vtkActorCollection* theActors = aCopy.GetActors(); - theActors->InitTraversal(); - bool isFound = false; - vtkActor *ac = theActors->GetNextActor(); - for (; ac != NULL && !isFound; ac = theActors->GetNextActor()) { - if (ac->IsA("SMESH_Actor")) { - SMESH_Actor* aGeomAc = SMESH_Actor::SafeDownCast(ac); - if (aGeomAc->hasIO()) { - Handle(SALOME_InteractiveObject) io = - Handle(SALOME_InteractiveObject)::DownCast(aGeomAc->getIO()); - if (io->hasEntry() && strcmp(io->getEntry(), entry.toLatin1().data()) == 0) { - isFound = true; - vtkActors.Bind(viewIndex, aGeomAc); - } + SUIT_ViewModel* vmodel = vman->getViewModel(); + // SVTK view model can be casted to SALOME_View + displayer()->Display(entry, true, dynamic_cast(vmodel)); + + // store displayed actor in a temporary map for quicker + // access later when restoring other parameters + SVTK_ViewWindow* vtkView = (SVTK_ViewWindow*) vman->getActiveView(); + vtkRenderer* Renderer = vtkView->getRenderer(); + VTK::ActorCollectionCopy aCopy(Renderer->GetActors()); + vtkActorCollection* theActors = aCopy.GetActors(); + theActors->InitTraversal(); + bool isFound = false; + vtkActor *ac = theActors->GetNextActor(); + for (; ac != NULL && !isFound; ac = theActors->GetNextActor()) { + if (ac->IsA("SMESH_Actor")) { + SMESH_Actor* aGeomAc = SMESH_Actor::SafeDownCast(ac); + if (aGeomAc->hasIO()) { + Handle(SALOME_InteractiveObject) io = + Handle(SALOME_InteractiveObject)::DownCast(aGeomAc->getIO()); + if (io->hasEntry() && strcmp(io->getEntry(), entry.toLatin1().data()) == 0) { + isFound = true; + vtkActors.Bind(viewIndex, aGeomAc); } } } @@ -4808,14 +5290,16 @@ void SMESHGUI::restoreVisualParameters (int savePoint) } // Clipping else if (paramNameStr.startsWith("ClippingPlane")) { - cout << "$$$ ClippingPlane 1" << endl; - if (paramNameStr == "ClippingPlane1" || val == "Off") - aSmeshActor->RemoveAllClippingPlanes(); - if (val != "Off") { - cout << "$$$ ClippingPlane 2" << endl; - QStringList vals = val.split(gDigitsSep, QString::SkipEmptyParts); - if (vals.count() == 4) { // format check: 4 values - cout << "$$$ ClippingPlane 3" << endl; + QStringList vals = val.split(gDigitsSep, QString::SkipEmptyParts); + // old format - val looks like "Off" or "0:0.5:0:0" (orientation, distance, two angles) + // new format - val looks like "Off" or "0" (plane id) + // (note: in new format "Off" value is used only for consistency, + // so it is processed together with values in old format) + bool anIsOldFormat = ( vals.count() == 4 || val == "Off" ); + if( anIsOldFormat ) { + if (paramNameStr == "ClippingPlane1" || val == "Off") + aSmeshActor->RemoveAllClippingPlanes(); + if (val != "Off") { SMESH::Orientation anOrientation = (SMESH::Orientation)vals[0].toInt(); double aDistance = vals[1].toFloat(); vtkFloatingPointType anAngle[2]; @@ -4828,8 +5312,43 @@ void SMESHGUI::restoreVisualParameters (int savePoint) if (viewIndex >= 0 && viewIndex < lst.count()) { SUIT_ViewManager* vman = lst.at(viewIndex); SVTK_ViewWindow* vtkView = (SVTK_ViewWindow*) vman->getActiveView(); - SMESHGUI_ClippingDlg::AddPlane(aSmeshActor, vtkView, - anOrientation, aDistance, anAngle); + + SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = myClippingPlaneInfoMap[ vman ]; + + SMESH::TActorList anActorList; + anActorList.push_back( aSmeshActor ); + SMESH::OrientedPlane* aPlane = + SMESHGUI_ClippingDlg::AddPlane(anActorList, vtkView, anOrientation, aDistance, anAngle); + if( aPlane ) { + SMESH::ClippingPlaneInfo aClippingPlaneInfo; + aClippingPlaneInfo.Plane = aPlane; + aClippingPlaneInfo.ActorList = anActorList; + aClippingPlaneInfoList.push_back( aClippingPlaneInfo ); + } + } + } + } + else { + bool ok = false; + int aPlaneId = val.toInt( &ok ); + if( ok && aPlaneId >= 0 ) { + bool anIsDefinedPlane = false; + TPlaneInfoList& aPlaneInfoList = aPlaneInfoMap[ viewIndex ]; + TPlaneInfoList::iterator anIter = aPlaneInfoList.begin(); + for( ; anIter != aPlaneInfoList.end(); anIter++ ) { + TPlaneInfo& aPlaneInfo = *anIter; + if( aPlaneInfo.PlaneId == aPlaneId ) { + aPlaneInfo.ActorList.push_back( aSmeshActor ); + anIsDefinedPlane = true; + break; + } + } + if( !anIsDefinedPlane ) { + TPlaneInfo aPlaneInfo; + aPlaneInfo.PlaneId = aPlaneId; + aPlaneInfo.ActorList.push_back( aSmeshActor ); + aPlaneInfo.ViewManager = vman; + aPlaneInfoList.push_back( aPlaneInfo ); } } } @@ -4840,6 +5359,55 @@ void SMESHGUI::restoreVisualParameters (int savePoint) } // for names/parameters iterator } // for entries iterator + // add clipping planes to actors according to the restored parameters + // and update the clipping plane map + TPlaneInfoMap::const_iterator anIter1 = aPlaneInfoMap.begin(); + for( ; anIter1 != aPlaneInfoMap.end(); anIter1++ ) { + int aViewId = anIter1->first; + const TPlaneInfoList& aPlaneInfoList = anIter1->second; + + TPlaneDataMap::const_iterator anIter2 = aPlaneDataMap.find( aViewId ); + if( anIter2 == aPlaneDataMap.end() ) + continue; + const TPlaneDataList& aPlaneDataList = anIter2->second; + + TPlaneInfoList::const_iterator anIter3 = aPlaneInfoList.begin(); + for( ; anIter3 != aPlaneInfoList.end(); anIter3++ ) { + const TPlaneInfo& aPlaneInfo = *anIter3; + int aPlaneId = aPlaneInfo.PlaneId; + const TActorList& anActorList = aPlaneInfo.ActorList; + SUIT_ViewManager* aViewManager = aPlaneInfo.ViewManager; + if( !aViewManager ) + continue; + + SVTK_ViewWindow* aViewWindow = dynamic_cast( aViewManager->getActiveView() ); + if( !aViewWindow ) + continue; + + SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = myClippingPlaneInfoMap[ aViewManager ]; + + TPlaneDataList::const_iterator anIter4 = aPlaneDataList.begin(); + for( ; anIter4 != aPlaneDataList.end(); anIter4++ ) { + const TPlaneData& aPlaneData = *anIter4; + if( aPlaneData.Id == aPlaneId ) { + SMESH::OrientedPlane* aPlane = + SMESHGUI_ClippingDlg::AddPlane( anActorList, + aViewWindow, + (SMESH::Orientation)aPlaneData.Orientation, + aPlaneData.Distance, + aPlaneData.Angle ); + if( aPlane ) { + SMESH::ClippingPlaneInfo aClippingPlaneInfo; + aClippingPlaneInfo.Plane = aPlane; + aClippingPlaneInfo.ActorList = anActorList; + aClippingPlaneInfoList.push_back( aClippingPlaneInfo ); + } + break; + } + } + } + } + // update all VTK views QList lst; getApp()->viewManagers(lst); @@ -4863,7 +5431,7 @@ void SMESHGUI::restoreVisualParameters (int savePoint) int SMESHGUI::addVtkFontPref( const QString& label, const int pId, const QString& param ) { int tfont = addPreference( label, pId, LightApp_Preferences::Font, "VISU", param ); - + setPreferenceProperty( tfont, "mode", QtxFontEdit::Custom ); QStringList fam; diff --git a/src/SMESHGUI/SMESHGUI.h b/src/SMESHGUI/SMESHGUI.h index 0099a20bd..7aa14367f 100644 --- a/src/SMESHGUI/SMESHGUI.h +++ b/src/SMESHGUI/SMESHGUI.h @@ -39,6 +39,14 @@ #include #include CORBA_SERVER_HEADER(SMESH_Gen) +// VTK includes +#include +#include + +class vtkActor; +class vtkCallbackCommand; +class vtkObject; + class QDialog; class SUIT_Desktop; @@ -52,10 +60,24 @@ class SalomeApp_Study; class LightApp_Selection; class LightApp_SelectionMgr; +class SMESH_Actor; class SMESHGUI_FilterLibraryDlg; typedef std::map SMESHGUI_StudyId2MarkerMap; +namespace SMESH +{ + class OrientedPlane; + struct ClippingPlaneInfo + { + OrientedPlane* Plane; + std::list ActorList; + }; +} + +typedef std::list SMESHGUI_ClippingPlaneInfoList; +typedef std::map SMESHGUI_ClippingPlaneInfoMap; + //================================================================================= // class : SMESHGUI // purpose : @@ -77,7 +99,7 @@ public : bool isActiveStudyLocked(); - static bool automaticUpdate(); + static bool automaticUpdate(unsigned int requestedSize = 0, bool* limitExceeded = 0); static void Modified( bool = true ); @@ -122,6 +144,10 @@ public : virtual void storeVisualParameters (int savePoint); virtual void restoreVisualParameters(int savePoint); + virtual void addActorAsObserver( SMESH_Actor* theActor ); + + SMESHGUI_ClippingPlaneInfoMap& getClippingPlaneInfoMap() { return myClippingPlaneInfoMap; } + public slots: virtual bool deactivateModule( SUIT_Study* ); virtual bool activateModule( SUIT_Study* ); @@ -130,6 +156,7 @@ public slots: private slots: void OnGUIEvent(); void onViewManagerActivated( SUIT_ViewManager* ); + void onViewManagerRemoved( SUIT_ViewManager* ); void onOperationCommited( SUIT_Operation* ); void onOperationAborted( SUIT_Operation* ); void onHypothesisEdit( int result ); @@ -145,7 +172,8 @@ protected: const QString&, const QString& = QString(), const int = 0, - const bool = false ); + const bool = false, + const QString& = QString() ); void createPopupItem( const int, const QString&, const QString&, @@ -158,6 +186,11 @@ protected: virtual bool reusableOperation( const int id ); + static void ProcessEvents( vtkObject* theObject, + unsigned long theEvent, + void* theClientData, + void* theCallData ); + private: void OnEditDelete(); int addVtkFontPref( const QString& label, @@ -174,6 +207,10 @@ private : SMESHGUI_FilterLibraryDlg* myFilterLibraryDlg; SMESHGUI_StudyId2MarkerMap myMarkerMap; + SMESHGUI_ClippingPlaneInfoMap myClippingPlaneInfoMap; + + vtkSmartPointer myEventCallbackCommand; + vtkFloatingPointType myPriority; }; #endif // SMESHGUI_H diff --git a/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx b/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx index a5d12e559..b2cd9e46d 100644 --- a/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx @@ -492,19 +492,19 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply() if( addToGroup ) { aGroupName = ComboBox_GroupName->currentText(); for ( int i = 1; i < ComboBox_GroupName->count(); i++ ) { - QString aName = ComboBox_GroupName->itemText( i ); - if ( aGroupName == aName && ( i == ComboBox_GroupName->currentIndex() || idx == 0 ) ) - idx = i; + QString aName = ComboBox_GroupName->itemText( i ); + if ( aGroupName == aName && ( i == ComboBox_GroupName->currentIndex() || idx == 0 ) ) + idx = i; } if ( idx > 0 ) { - SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] ); - if ( !aGeomGroup->_is_nil() ) { - int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ), - tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ), - tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 ); - if ( res == 1 ) return; - } - aGroup = myGroups[idx-1]; + SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] ); + if ( !aGeomGroup->_is_nil() ) { + int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ), + tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ), + tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 ); + if ( res == 1 ) return; + } + aGroup = myGroups[idx-1]; } } @@ -530,24 +530,24 @@ void SMESHGUI_AddMeshElementDlg::ClickOnApply() if ( anElemId != -1 && addToGroup && !aGroupName.isEmpty() ) { SMESH::SMESH_Group_var aGroupUsed; if ( aGroup->_is_nil() ) { - // create new group - aGroupUsed = SMESH::AddGroup( myMesh, (SMESH::ElementType)myElementType, aGroupName ); - if ( !aGroupUsed->_is_nil() ) { - myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed)); - ComboBox_GroupName->addItem( aGroupName ); - } + // create new group + aGroupUsed = SMESH::AddGroup( myMesh, (SMESH::ElementType)myElementType, aGroupName ); + if ( !aGroupUsed->_is_nil() ) { + myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed)); + ComboBox_GroupName->addItem( aGroupName ); + } } else { - SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup ); - if ( !aGeomGroup->_is_nil() ) { - aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup ); - if ( !aGroupUsed->_is_nil() && idx > 0 ) { - myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed); - SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser(); - } - } - else - aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup ); + SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup ); + if ( !aGeomGroup->_is_nil() ) { + aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup ); + if ( !aGroupUsed->_is_nil() && idx > 0 ) { + myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed); + SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser(); + } + } + else + aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup ); } if ( !aGroupUsed->_is_nil() ) { @@ -736,11 +736,11 @@ void SMESHGUI_AddMeshElementDlg::SelectionIntoArgument() for ( int i = 0, n = aListOfGroups.length(); i < n; i++ ) { SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i]; if ( !aGroup->_is_nil() && aGroup->GetType() == (SMESH::ElementType)myElementType ) { - QString aGroupName( aGroup->GetName() ); - if ( !aGroupName.isEmpty() ) { - myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup)); - ComboBox_GroupName->addItem( aGroupName ); - } + QString aGroupName( aGroup->GetName() ); + if ( !aGroupName.isEmpty() ) { + myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup)); + ComboBox_GroupName->addItem( aGroupName ); + } } } } diff --git a/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx b/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx index d190c35e3..f75dd31d8 100644 --- a/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_AddQuadraticElementDlg.cxx @@ -731,15 +731,15 @@ void SMESHGUI_AddQuadraticElementDlg::ClickOnApply() for ( int i = 1; i < ComboBox_GroupName->count(); i++ ) { QString aName = ComboBox_GroupName->itemText( i ); if ( aGroupName == aName && ( i == ComboBox_GroupName->currentIndex() || idx == 0 ) ) - idx = i; + idx = i; } if ( idx > 0 ) { SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] ); if ( !aGeomGroup->_is_nil() ) { - int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ), - tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ), - tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 ); - if ( res == 1 ) return; + int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ), + tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ), + tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 ); + if ( res == 1 ) return; } aGroup = myGroups[idx-1]; } @@ -771,21 +771,21 @@ void SMESHGUI_AddQuadraticElementDlg::ClickOnApply() // create new group aGroupUsed = SMESH::AddGroup( myMesh, anElementType, aGroupName ); if ( !aGroupUsed->_is_nil() ) { - myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed)); - ComboBox_GroupName->addItem( aGroupName ); + myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed)); + ComboBox_GroupName->addItem( aGroupName ); } } else { SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup ); if ( !aGeomGroup->_is_nil() ) { - aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup ); - if ( !aGroupUsed->_is_nil() && idx > 0 ) { - myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed); - SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser(); - } + aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup ); + if ( !aGroupUsed->_is_nil() && idx > 0 ) { + myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed); + SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser(); + } } else - aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup ); + aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup ); } if ( !aGroupUsed->_is_nil() ) { @@ -974,11 +974,11 @@ void SMESHGUI_AddQuadraticElementDlg::SelectionIntoArgument() for ( int i = 0, n = aListOfGroups.length(); i < n; i++ ) { SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i]; if ( !aGroup->_is_nil() && aGroup->GetType() == anElementType ) { - QString aGroupName( aGroup->GetName() ); - if ( !aGroupName.isEmpty() ) { - myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup)); - ComboBox_GroupName->addItem( aGroupName ); - } + QString aGroupName( aGroup->GetName() ); + if ( !aGroupName.isEmpty() ) { + myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup)); + ComboBox_GroupName->addItem( aGroupName ); + } } } } diff --git a/src/SMESHGUI/SMESHGUI_BuildCompoundDlg.cxx b/src/SMESHGUI/SMESHGUI_BuildCompoundDlg.cxx index bc6c1daf5..4fceb54be 100644 --- a/src/SMESHGUI/SMESHGUI_BuildCompoundDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_BuildCompoundDlg.cxx @@ -19,12 +19,11 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_BuildCompoundDlg.cxx +// Author : Alexander KOVALEV, Open CASCADE S.A.S. +// SMESH includes -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_BuildCompoundDlg.cxx -// Author : Alexander KOVALEV, Open CASCADE S.A.S. -// SMESH includes -// #include "SMESHGUI_BuildCompoundDlg.h" #include "SMESHGUI.h" @@ -67,6 +66,10 @@ #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 + //================================================================================= // name : SMESHGUI_BuildCompoundDlg // Purpose : @@ -143,7 +146,7 @@ SMESHGUI_BuildCompoundDlg::SMESHGUI_BuildCompoundDlg( SMESHGUI* theModule ) GroupArgsLayout->addWidget(TextLabelMeshes, 0, 0); GroupArgsLayout->addWidget(SelectButton, 0, 1); GroupArgsLayout->addWidget(LineEditMeshes, 0, 2, 1, 2); - GroupArgsLayout->addWidget(TextLabelUnion, 1, 0, 1, 3); + GroupArgsLayout->addWidget(TextLabelUnion, 1, 0, 1, 3); GroupArgsLayout->addWidget(ComboBoxUnion, 1, 3); GroupArgsLayout->addWidget(CheckBoxCommon, 2, 0, 1, 4); GroupArgsLayout->addWidget(CheckBoxMerge, 3, 0, 1, 4); @@ -301,16 +304,16 @@ bool SMESHGUI_BuildCompoundDlg::ClickOnApply() SMESH::SMESH_Gen_var aSMESHGen = SMESHGUI::GetSMESHGen(); // concatenate meshes if(CheckBoxCommon->isChecked()) - aCompoundMesh = aSMESHGen->ConcatenateWithGroups(myMeshArray, - !(ComboBoxUnion->currentIndex()), - CheckBoxMerge->isChecked(), + aCompoundMesh = aSMESHGen->ConcatenateWithGroups(myMeshArray, + !(ComboBoxUnion->currentIndex()), + CheckBoxMerge->isChecked(), SpinBoxTol->GetValue()); else - aCompoundMesh = aSMESHGen->Concatenate(myMeshArray, - !(ComboBoxUnion->currentIndex()), - CheckBoxMerge->isChecked(), + aCompoundMesh = aSMESHGen->Concatenate(myMeshArray, + !(ComboBoxUnion->currentIndex()), + CheckBoxMerge->isChecked(), SpinBoxTol->GetValue()); - + aCompoundMesh->SetParameters( aParameters.join(":").toLatin1().constData() ); SMESH::SetName( SMESH::FindSObject( aCompoundMesh ), LineEditName->text() ); @@ -325,7 +328,7 @@ bool SMESHGUI_BuildCompoundDlg::ClickOnApply() if ( SMESHGUI::automaticUpdate() ) { mySelectionMgr->clearSelected(); SMESH::UpdateView(); - + _PTR(SObject) aSO = SMESH::FindSObject(aCompoundMesh.in()); if ( SMESH_Actor* anActor = SMESH::CreateActor(aSO->GetStudy(), aSO->GetID().c_str()) ) SMESH::DisplayActor(SMESH::GetActiveWindow(), anActor); @@ -333,6 +336,14 @@ bool SMESHGUI_BuildCompoundDlg::ClickOnApply() SMESHGUI::Modified(); +#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 + if (!CORBA::is_nil(aCompoundMesh)) + aCompoundMesh->Destroy(); +#endif + return true; } return false; @@ -368,7 +379,7 @@ void SMESHGUI_BuildCompoundDlg::ClickOnCancel() void SMESHGUI_BuildCompoundDlg::ClickOnHelp() { LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); - if (app) + if (app) app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); else { SUIT_MessageBox::warning(this, tr("WRN_WARNING"), @@ -503,7 +514,6 @@ void SMESHGUI_BuildCompoundDlg::keyPressEvent( QKeyEvent* e ) //================================================================================= void SMESHGUI_BuildCompoundDlg::onSelectMerge(bool toMerge) { - TextLabelTol->setEnabled(toMerge); SpinBoxTol->setEnabled(toMerge); if(!toMerge) diff --git a/src/SMESHGUI/SMESHGUI_ClippingDlg.cxx b/src/SMESHGUI/SMESHGUI_ClippingDlg.cxx index 13bdc8eb4..ac190be77 100644 --- a/src/SMESHGUI/SMESHGUI_ClippingDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ClippingDlg.cxx @@ -41,11 +41,15 @@ #include #include #include +#include #include +#include + #include -#include + +#include #include @@ -59,139 +63,138 @@ #include #include #include +#include // VTK includes #include -#include #include #include #include #include +#include #define SPACING 6 #define MARGIN 11 -class OrientedPlane: public vtkPlane +//================================================================================= +// class : OrientedPlane +// purpose : +//================================================================================= +SMESH::OrientedPlane* SMESH::OrientedPlane::New() { - QPointer myViewWindow; - - vtkDataSetMapper* myMapper; - -public: - static OrientedPlane *New() - { - return new OrientedPlane(); - } - static OrientedPlane *New(SVTK_ViewWindow* theViewWindow) - { - return new OrientedPlane(theViewWindow); - } - vtkTypeMacro (OrientedPlane, vtkPlane); - - SMESH::Orientation myOrientation; - float myDistance; - double myAngle[2]; + return new OrientedPlane(); +} - vtkPlaneSource* myPlaneSource; - SALOME_Actor *myActor; +SMESH::OrientedPlane* SMESH::OrientedPlane::New(SVTK_ViewWindow* theViewWindow) +{ + return new OrientedPlane(theViewWindow); +} - void SetOrientation (SMESH::Orientation theOrientation) { myOrientation = theOrientation; } - SMESH::Orientation GetOrientation() { return myOrientation; } +void SMESH::OrientedPlane::ShallowCopy(SMESH::OrientedPlane* theOrientedPlane) +{ + SetNormal(theOrientedPlane->GetNormal()); + SetOrigin(theOrientedPlane->GetOrigin()); - void SetDistance (float theDistance) { myDistance = theDistance; } - float GetDistance() { return myDistance; } + myOrientation = theOrientedPlane->GetOrientation(); + myDistance = theOrientedPlane->GetDistance(); - void ShallowCopy (OrientedPlane* theOrientedPlane) - { - SetNormal(theOrientedPlane->GetNormal()); - SetOrigin(theOrientedPlane->GetOrigin()); + myAngle[0] = theOrientedPlane->myAngle[0]; + myAngle[1] = theOrientedPlane->myAngle[1]; - myOrientation = theOrientedPlane->GetOrientation(); - myDistance = theOrientedPlane->GetDistance(); + myPlaneSource->SetNormal(theOrientedPlane->myPlaneSource->GetNormal()); + myPlaneSource->SetOrigin(theOrientedPlane->myPlaneSource->GetOrigin()); + myPlaneSource->SetPoint1(theOrientedPlane->myPlaneSource->GetPoint1()); + myPlaneSource->SetPoint2(theOrientedPlane->myPlaneSource->GetPoint2()); +} - myAngle[0] = theOrientedPlane->myAngle[0]; - myAngle[1] = theOrientedPlane->myAngle[1]; +SMESH::OrientedPlane::OrientedPlane(SVTK_ViewWindow* theViewWindow): + myViewWindow(theViewWindow), + myOrientation(SMESH::XY), + myDistance(0.5) +{ + Init(); + myViewWindow->AddActor(myActor); +} - myPlaneSource->SetNormal(theOrientedPlane->myPlaneSource->GetNormal()); - myPlaneSource->SetOrigin(theOrientedPlane->myPlaneSource->GetOrigin()); - myPlaneSource->SetPoint1(theOrientedPlane->myPlaneSource->GetPoint1()); - myPlaneSource->SetPoint2(theOrientedPlane->myPlaneSource->GetPoint2()); - } +SMESH::OrientedPlane::OrientedPlane(): + myOrientation(SMESH::XY), + myViewWindow(NULL), + myDistance(0.5) +{ + Init(); +} -protected: - OrientedPlane(SVTK_ViewWindow* theViewWindow): - myViewWindow(theViewWindow), - myOrientation(SMESH::XY), - myDistance(0.5) - { - Init(); - myViewWindow->AddActor(myActor); - } +void SMESH::OrientedPlane::Init() +{ + myPlaneSource = vtkPlaneSource::New(); + + myAngle[0] = myAngle[1] = 0.0; + + // Create and display actor + myMapper = vtkDataSetMapper::New(); + myMapper->SetInput(myPlaneSource->GetOutput()); + + myActor = SALOME_Actor::New(); + myActor->VisibilityOff(); + myActor->PickableOff(); + myActor->SetInfinitive(true); + myActor->SetMapper(myMapper); + + vtkFloatingPointType anRGB[3]; + vtkProperty* aProp = vtkProperty::New(); + SMESH::GetColor( "SMESH", "fill_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) ); + aProp->SetColor(anRGB[0],anRGB[1],anRGB[2]); + aProp->SetOpacity(0.75); + myActor->SetProperty(aProp); + aProp->Delete(); + + vtkProperty* aBackProp = vtkProperty::New(); + SMESH::GetColor( "SMESH", "backface_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 0, 255 ) ); + aBackProp->SetColor(anRGB[0],anRGB[1],anRGB[2]); + aBackProp->SetOpacity(0.75); + myActor->SetBackfaceProperty(aBackProp); + aBackProp->Delete(); +} - OrientedPlane(): - myOrientation(SMESH::XY), - myViewWindow(NULL), - myDistance(0.5) - { - Init(); - } +SMESH::OrientedPlane::~OrientedPlane() +{ + if (myViewWindow) + myViewWindow->RemoveActor(myActor); + myActor->Delete(); + + myMapper->RemoveAllInputs(); + myMapper->Delete(); - void Init() - { - myPlaneSource = vtkPlaneSource::New(); - - myAngle[0] = myAngle[1] = 0.0; - - // Create and display actor - myMapper = vtkDataSetMapper::New(); - myMapper->SetInput(myPlaneSource->GetOutput()); - - myActor = SALOME_Actor::New(); - myActor->VisibilityOff(); - myActor->PickableOff(); - myActor->SetInfinitive(true); - myActor->SetMapper(myMapper); - - vtkFloatingPointType anRGB[3]; - vtkProperty* aProp = vtkProperty::New(); - SMESH::GetColor( "SMESH", "fill_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 170, 255 ) ); - aProp->SetColor(anRGB[0],anRGB[1],anRGB[2]); - aProp->SetOpacity(0.75); - myActor->SetProperty(aProp); - aProp->Delete(); - - vtkProperty* aBackProp = vtkProperty::New(); - SMESH::GetColor( "SMESH", "backface_color", anRGB[0], anRGB[1], anRGB[2], QColor( 0, 0, 255 ) ); - aBackProp->SetColor(anRGB[0],anRGB[1],anRGB[2]); - aBackProp->SetOpacity(0.75); - myActor->SetBackfaceProperty(aBackProp); - aBackProp->Delete(); - } + // commented: porting to vtk 5.0 + // myPlaneSource->UnRegisterAllOutputs(); + myPlaneSource->Delete(); +} - ~OrientedPlane(){ - if (myViewWindow) - myViewWindow->RemoveActor(myActor); - myActor->Delete(); - - myMapper->RemoveAllInputs(); - myMapper->Delete(); +//================================================================================= +// class : ActorItem +// purpose : +//================================================================================= +class ActorItem : public QListWidgetItem +{ +public: + ActorItem( SMESH_Actor* theActor, const QString& theName, QListWidget* theListWidget ) : + QListWidgetItem( theName, theListWidget ), + myActor( theActor ) {} - // commented: porting to vtk 5.0 - // myPlaneSource->UnRegisterAllOutputs(); - myPlaneSource->Delete(); - }; + SMESH_Actor* getActor() const { return myActor; } private: - // Not implemented. - OrientedPlane (const OrientedPlane&); - void operator= (const OrientedPlane&); - + SMESH_Actor* myActor; }; -struct TSetVisiblity { - TSetVisiblity(int theIsVisible): myIsVisible(theIsVisible){} - void operator()(SMESH::TVTKPlane& theOrientedPlane){ - theOrientedPlane->myActor->SetVisibility(myIsVisible); +//================================================================================= +// class : TSetVisibility +// purpose : +//================================================================================= +struct TSetVisibility { + TSetVisibility(int theIsVisible): myIsVisible(theIsVisible){} + void operator()(SMESH::TPlaneData& thePlaneData){ + thePlaneData.Plane.GetPointer()->myActor->SetVisibility(myIsVisible); } int myIsVisible; }; @@ -200,13 +203,13 @@ struct TSetVisiblity { // used in SMESHGUI::restoreVisualParameters() to avoid // declaration of OrientedPlane outside of SMESHGUI_ClippingDlg.cxx //================================================================================= -void SMESHGUI_ClippingDlg::AddPlane (SMESH_Actor* theActor, - SVTK_ViewWindow* theViewWindow, - SMESH::Orientation theOrientation, - double theDistance, - vtkFloatingPointType theAngle[2]) +SMESH::OrientedPlane* SMESHGUI_ClippingDlg::AddPlane (SMESH::TActorList theActorList, + SVTK_ViewWindow* theViewWindow, + SMESH::Orientation theOrientation, + double theDistance, + const vtkFloatingPointType theAngle[2]) { - OrientedPlane* aPlane = OrientedPlane::New(theViewWindow); + SMESH::OrientedPlane* aPlane = SMESH::OrientedPlane::New(theViewWindow); aPlane->myAngle[0] = theAngle[0]; aPlane->myAngle[1] = theAngle[1]; @@ -256,14 +259,26 @@ void SMESHGUI_ClippingDlg::AddPlane (SMESH_Actor* theActor, vtkMath::Cross(aNormal,aDir[1],aDir[0]); } - // ??? - theActor->SetPlaneParam(aNormal, theDistance, aPlane); + vtkFloatingPointType aBounds[6]; + vtkFloatingPointType anOrigin[3]; + bool anIsOk = SMESH::ComputeClippingPlaneParameters( theActorList, + aNormal, + theDistance, + aBounds, + anOrigin ); + if( !anIsOk ) + return NULL; - vtkDataSet* aDataSet = theActor->GetInput(); - vtkFloatingPointType *aPnt = aDataSet->GetCenter(); + aPlane->SetNormal( aNormal ); + aPlane->SetOrigin( anOrigin ); - vtkFloatingPointType* anOrigin = aPlane->GetOrigin(); - vtkFloatingPointType aDel = aDataSet->GetLength()/2.0; + vtkFloatingPointType aPnt[3] = { ( aBounds[0] + aBounds[1] ) / 2., + ( aBounds[2] + aBounds[3] ) / 2., + ( aBounds[4] + aBounds[5] ) / 2. }; + + vtkFloatingPointType aDel = pow( pow( aBounds[1] - aBounds[0], 2 ) + + pow( aBounds[3] - aBounds[2], 2 ) + + pow( aBounds[5] - aBounds[4], 2 ), 0.5 ); vtkFloatingPointType aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel}, {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}}; @@ -299,28 +314,13 @@ void SMESHGUI_ClippingDlg::AddPlane (SMESH_Actor* theActor, aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]); aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]); - theActor->AddClippingPlane(aPlane); - aPlane->Delete(); -} + SMESH::TActorList::iterator anIter = theActorList.begin(); + for ( ; anIter != theActorList.end(); anIter++ ) + if( vtkActor* aVTKActor = *anIter ) + if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) + anActor->AddClippingPlane( aPlane ); -//================================================================================= -// used in SMESHGUI::restoreVisualParameters() to avoid -// declaration of OrientedPlane outside of SMESHGUI_ClippingDlg.cxx -//================================================================================= -void SMESHGUI_ClippingDlg::GetPlaneParam (SMESH_Actor* theActor, - int thePlaneIndex, - SMESH::Orientation& theOrientation, - double& theDistance, - vtkFloatingPointType* theAngle) -{ - if (vtkPlane* aPln = theActor->GetClippingPlane(thePlaneIndex)) { - if (OrientedPlane* aPlane = OrientedPlane::SafeDownCast(aPln)) { - theOrientation = aPlane->GetOrientation(); - theDistance = aPlane->GetDistance(); - theAngle[0] = aPlane->myAngle[0]; - theAngle[1] = aPlane->myAngle[1]; - } - } + return aPlane; } //================================================================================= @@ -328,11 +328,10 @@ void SMESHGUI_ClippingDlg::GetPlaneParam (SMESH_Actor* theActor, // purpose : // //================================================================================= -SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ): +SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule, SVTK_ViewWindow* theViewWindow ): QDialog( SMESH::GetDesktop(theModule) ), - mySelector(SMESH::GetViewWindow(theModule)->GetSelector()), - mySelectionMgr(SMESH::GetSelectionMgr(theModule)), - mySMESHGUI(theModule) + mySMESHGUI(theModule), + myViewWindow(theViewWindow) { setModal( false ); setAttribute( Qt::WA_DeleteOnClose, true ); @@ -345,7 +344,7 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ): // Controls for selecting, creating, deleting planes QGroupBox* GroupPlanes = new QGroupBox(tr("CLIP_PLANES"), this); - QHBoxLayout* GroupPlanesLayout = new QHBoxLayout(GroupPlanes); + QGridLayout* GroupPlanesLayout = new QGridLayout(GroupPlanes); GroupPlanesLayout->setSpacing(SPACING); GroupPlanesLayout->setMargin(MARGIN); @@ -355,10 +354,21 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ): buttonDelete = new QPushButton(tr("SMESH_BUT_DELETE"), GroupPlanes); - GroupPlanesLayout->addWidget(ComboBoxPlanes); - GroupPlanesLayout->addStretch(); - GroupPlanesLayout->addWidget(buttonNew); - GroupPlanesLayout->addWidget(buttonDelete); + QLabel* aLabel = new QLabel(tr("MESHES_SUBMESHES_GROUPS"), GroupPlanes); + + ActorList = new QListWidget(GroupPlanes); + ActorList->setSelectionMode(QAbstractItemView::SingleSelection); + + SelectAllCheckBox = new QCheckBox(tr("SELECT_ALL"), GroupPlanes); + + GroupPlanesLayout->addWidget(ComboBoxPlanes, 0, 0); + GroupPlanesLayout->addWidget(new QWidget(), 0, 1); + GroupPlanesLayout->addWidget(buttonNew, 0, 2); + GroupPlanesLayout->addWidget(buttonDelete, 0, 3); + GroupPlanesLayout->addWidget(aLabel, 1, 0, 1, 4); + GroupPlanesLayout->addWidget(ActorList, 2, 0, 1, 4); + GroupPlanesLayout->addWidget(SelectAllCheckBox, 3, 0, 1, 4); + GroupPlanesLayout->setColumnStretch( 1, 1 ); // Controls for defining plane parameters QGroupBox* GroupParameters = new QGroupBox(tr("SMESH_PARAMETERS"), this); @@ -437,9 +447,10 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ): SpinBoxDistance->SetValue(0.5); - myActor = 0; myIsSelectPlane = false; - onSelectionChanged(); + + initializePlaneData(); + synchronize(); myHelpFileName = "clipping_page.html"; @@ -447,6 +458,8 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ): connect(ComboBoxPlanes, SIGNAL(activated(int)), this, SLOT(onSelectPlane(int))); connect(buttonNew, SIGNAL(clicked()), this, SLOT(ClickOnNew())); connect(buttonDelete, SIGNAL(clicked()), this, SLOT(ClickOnDelete())); + connect(ActorList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(onActorItemChanged(QListWidgetItem*))); + connect(SelectAllCheckBox, SIGNAL(stateChanged(int)), this, SLOT(onSelectAll(int))); connect(ComboBoxOrientation, SIGNAL(activated(int)), this, SLOT(onSelectOrientation(int))); connect(SpinBoxDistance, SIGNAL(valueChanged(double)), this, SLOT(SetCurrentPlaneParam())); connect(SpinBoxRot1, SIGNAL(valueChanged(double)), this, SLOT(SetCurrentPlaneParam())); @@ -458,7 +471,6 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ): connect(buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnApply())); connect(buttonHelp, SIGNAL(clicked()), this, SLOT(ClickOnHelp())); connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel())); - connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(onSelectionChanged())); /* to close dialog if study frame change */ connect(mySMESHGUI, SIGNAL (SignalStudyFrameChanged()), this, SLOT(ClickOnCancel())); @@ -472,10 +484,9 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule ): SMESHGUI_ClippingDlg::~SMESHGUI_ClippingDlg() { // no need to delete child widgets, Qt does it all for us - std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false)); - if (mySMESHGUI) - if (SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI)) - SMESH::RenderViewWindow(aViewWindow); + std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisibility(false)); + if (myViewWindow) + SMESH::RenderViewWindow(myViewWindow); } double SMESHGUI_ClippingDlg::getDistance() const @@ -504,27 +515,56 @@ double SMESHGUI_ClippingDlg::getRotation2() const //======================================================================= void SMESHGUI_ClippingDlg::ClickOnApply() { - if (!myActor) - return; - - if (SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI)) { + if (myViewWindow) { SUIT_OverrideCursor wc; QWidget *aCurrWid = this->focusWidget(); aCurrWid->clearFocus(); aCurrWid->setFocus(); - myActor->RemoveAllClippingPlanes(); - - SMESH::TPlanes::iterator anIter = myPlanes.begin(); - for ( ; anIter != myPlanes.end(); anIter++) { - OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow); - anOrientedPlane->ShallowCopy(anIter->GetPointer()); - myActor->AddClippingPlane(anOrientedPlane); - anOrientedPlane->Delete(); + SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = mySMESHGUI->getClippingPlaneInfoMap(); + SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = aClippingPlaneInfoMap[ myViewWindow->getViewManager() ]; + + // clean memory allocated for planes + SMESHGUI_ClippingPlaneInfoList::iterator anIter1 = aClippingPlaneInfoList.begin(); + for( ; anIter1 != aClippingPlaneInfoList.end(); anIter1++ ) + if( SMESH::OrientedPlane* aPlane = (*anIter1).Plane ) + aPlane->Delete(); + + aClippingPlaneInfoList.clear(); + + VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() ); + vtkActorCollection* anAllActors = aCopy.GetActors(); + anAllActors->InitTraversal(); + while( vtkActor* aVTKActor = anAllActors->GetNextActor() ) + if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) + anActor->RemoveAllClippingPlanes(); + + SMESH::TPlaneDataVector::iterator anIter2 = myPlanes.begin(); + for( ; anIter2 != myPlanes.end(); anIter2++ ) { + SMESH::TPlaneData aPlaneData = *anIter2; + SMESH::TPlane aPlane = aPlaneData.Plane; + SMESH::TActorList anActorList = aPlaneData.ActorList; + if( anActorList.empty() ) + continue; + + SMESH::OrientedPlane* anOrientedPlane = SMESH::OrientedPlane::New(myViewWindow); + anOrientedPlane->ShallowCopy(aPlane.GetPointer()); + + SMESH::TActorList::iterator anIter3 = anActorList.begin(); + for( ; anIter3 != anActorList.end(); anIter3++ ) + if( vtkActor* aVTKActor = *anIter3 ) + if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) + anActor->AddClippingPlane(anOrientedPlane); + + SMESH::ClippingPlaneInfo aClippingPlaneInfo; + aClippingPlaneInfo.Plane = anOrientedPlane; + aClippingPlaneInfo.ActorList = anActorList; + + aClippingPlaneInfoList.push_back( aClippingPlaneInfo ); } - SMESH::RenderViewWindow(aViewWindow); + SMESH::RenderViewWindow( myViewWindow ); } } @@ -571,53 +611,17 @@ void SMESHGUI_ClippingDlg::ClickOnHelp() } } -//================================================================================= -// function : onSelectionChanged() -// purpose : Called when selection is changed -//================================================================================= -void SMESHGUI_ClippingDlg::onSelectionChanged() -{ - if (SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI)) { - const SALOME_ListIO& aList = mySelector->StoredIObjects(); - if (aList.Extent() > 0) { - Handle(SALOME_InteractiveObject) IOS = aList.First(); - myActor = SMESH::FindActorByEntry(IOS->getEntry()); - if (myActor) { - std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(false)); - myPlanes.clear(); - - vtkIdType anId = 0, anEnd = myActor->GetNumberOfClippingPlanes(); - for ( ; anId < anEnd; anId++) { - if (vtkImplicitFunction* aFunction = myActor->GetClippingPlane(anId)) { - if(OrientedPlane* aPlane = OrientedPlane::SafeDownCast(aFunction)){ - OrientedPlane* anOrientedPlane = OrientedPlane::New(aViewWindow); - SMESH::TVTKPlane aTVTKPlane(anOrientedPlane); - anOrientedPlane->Delete(); - aTVTKPlane->ShallowCopy(aPlane); - myPlanes.push_back(aTVTKPlane); - } - } - } - - std::for_each(myPlanes.begin(),myPlanes.end(), - TSetVisiblity(PreviewCheckBox->isChecked())); - } - } - SMESH::RenderViewWindow(aViewWindow); - } - Sinchronize(); -} - //======================================================================= // function : onSelectPlane() // purpose : //======================================================================= void SMESHGUI_ClippingDlg::onSelectPlane (int theIndex) { - if (!myActor || myPlanes.empty()) + if (myPlanes.empty()) return; - OrientedPlane* aPlane = myPlanes[theIndex].GetPointer(); + SMESH::TPlaneData aPlaneData = myPlanes[theIndex]; + SMESH::OrientedPlane* aPlane = aPlaneData.Plane.GetPointer(); // Orientation SMESH::Orientation anOrientation = aPlane->GetOrientation(); @@ -644,6 +648,11 @@ void SMESHGUI_ClippingDlg::onSelectPlane (int theIndex) break; } myIsSelectPlane = false; + + // Actors + bool anIsBlocked = ActorList->blockSignals( true ); + updateActorList(); + ActorList->blockSignals( anIsBlocked ); } //======================================================================= @@ -652,19 +661,31 @@ void SMESHGUI_ClippingDlg::onSelectPlane (int theIndex) //======================================================================= void SMESHGUI_ClippingDlg::ClickOnNew() { - if (!myActor) - return; + if(myViewWindow){ + SMESH::OrientedPlane* aPlane = SMESH::OrientedPlane::New(myViewWindow); + SMESH::TPlane aTPlane(aPlane); + + SMESH::TActorList anActorList; + VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() ); + vtkActorCollection* anAllActors = aCopy.GetActors(); + anAllActors->InitTraversal(); + while( vtkActor* aVTKActor = anAllActors->GetNextActor() ) + if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) + anActorList.push_back( anActor ); - if(SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(mySMESHGUI)){ - OrientedPlane* aPlane = OrientedPlane::New(aViewWindow); - SMESH::TVTKPlane aTVTKPlane(aPlane); - myPlanes.push_back(aTVTKPlane); + SMESH::TPlaneData aPlaneData(aTPlane, anActorList); + + myPlanes.push_back(aPlaneData); if (PreviewCheckBox->isChecked()) - aTVTKPlane->myActor->VisibilityOn(); - - Sinchronize(); + aTPlane->myActor->VisibilityOn(); + + bool anIsBlocked = ActorList->blockSignals( true ); + + synchronize(); SetCurrentPlaneParam(); + + ActorList->blockSignals( anIsBlocked ); } } @@ -674,20 +695,105 @@ void SMESHGUI_ClippingDlg::ClickOnNew() //======================================================================= void SMESHGUI_ClippingDlg::ClickOnDelete() { - if (!myActor || myPlanes.empty()) + if (myPlanes.empty()) return; int aPlaneIndex = ComboBoxPlanes->currentIndex(); - SMESH::TPlanes::iterator anIter = myPlanes.begin() + aPlaneIndex; - anIter->GetPointer()->myActor->SetVisibility(false); + SMESH::TPlaneDataVector::iterator anIter = myPlanes.begin() + aPlaneIndex; + SMESH::TPlaneData aPlaneData = *anIter; + aPlaneData.Plane.GetPointer()->myActor->SetVisibility(false); myPlanes.erase(anIter); if(AutoApplyCheckBox->isChecked()) ClickOnApply(); - Sinchronize(); - SMESH::RenderViewWindow(SMESH::GetCurrentVtkView()); + synchronize(); + SMESH::RenderViewWindow( myViewWindow ); +} + +//======================================================================= +// function : updateActorItem() +// purpose : +//======================================================================= +void SMESHGUI_ClippingDlg::updateActorItem( QListWidgetItem* theItem, + bool theUpdateSelectAll, + bool theUpdateClippingPlaneMap ) +{ + // update Select All check box + if( theUpdateSelectAll ) { + int aNbItems = ActorList->count(), aNbChecked = 0; + for( int i = 0; i < aNbItems; i++ ) + if( QListWidgetItem* anItem = ActorList->item( i ) ) + if( anItem->checkState() == Qt::Checked ) + aNbChecked++; + + Qt::CheckState aCheckState = Qt::Unchecked; + if( aNbChecked == aNbItems ) + aCheckState = Qt::Checked; + else if( aNbChecked > 0 ) + aCheckState = Qt::PartiallyChecked; + + bool anIsBlocked = SelectAllCheckBox->blockSignals( true ); + SelectAllCheckBox->setCheckState( aCheckState ); + SelectAllCheckBox->blockSignals( anIsBlocked ); + } + + // update clipping plane map + if( theUpdateClippingPlaneMap ) { + int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); + if( ActorItem* anItem = dynamic_cast( theItem ) ) { + if( SMESH_Actor* anActor = anItem->getActor() ) { + SMESH::TPlaneData& aPlaneData = myPlanes[ aCurPlaneIndex ]; + SMESH::TActorList& anActorList = aPlaneData.ActorList; + bool anIsPushed = false; + SMESH::TActorList::iterator anIter = anActorList.begin(); + for ( ; anIter != anActorList.end(); anIter++ ) { + if( anActor == *anIter ) { + anIsPushed = true; + break; + } + } + if( theItem->checkState() == Qt::Checked && !anIsPushed ) + anActorList.push_back( anActor ); + else if( theItem->checkState() == Qt::Unchecked && anIsPushed ) + anActorList.remove( anActor ); + } + } + } +} + +//======================================================================= +// function : onActorItemChanged() +// purpose : +//======================================================================= +void SMESHGUI_ClippingDlg::onActorItemChanged( QListWidgetItem* theItem ) +{ + updateActorItem( theItem, true, true ); + SetCurrentPlaneParam(); +} + +//======================================================================= +// function : onSelectAll() +// purpose : +//======================================================================= +void SMESHGUI_ClippingDlg::onSelectAll( int theState ) +{ + if( theState == Qt::PartiallyChecked ) { + SelectAllCheckBox->setCheckState( Qt::Checked ); + return; + } + + bool anIsBlocked = ActorList->blockSignals( true ); + for( int i = 0, n = ActorList->count(); i < n; i++ ) { + if( QListWidgetItem* anItem = ActorList->item( i ) ) { + anItem->setCheckState( theState == Qt::Checked ? Qt::Checked : Qt::Unchecked ); + updateActorItem( anItem, false, true ); + } + } + SelectAllCheckBox->setTristate( false ); + ActorList->blockSignals( anIsBlocked ); + SetCurrentPlaneParam(); } //======================================================================= @@ -717,10 +823,10 @@ void SMESHGUI_ClippingDlg::onSelectOrientation (int theItem) } //======================================================================= -// function : Sinchronize() +// function : synchronize() // purpose : //======================================================================= -void SMESHGUI_ClippingDlg::Sinchronize() +void SMESHGUI_ClippingDlg::synchronize() { int aNbPlanes = myPlanes.size(); ComboBoxPlanes->clear(); @@ -737,17 +843,22 @@ void SMESHGUI_ClippingDlg::Sinchronize() bool anIsControlsEnable = (aPos >= 0); if (anIsControlsEnable) { onSelectPlane(aPos); + updateActorList(); } else { ComboBoxPlanes->addItem(tr("NO_PLANES")); + ActorList->clear(); SpinBoxRot1->SetValue(0.0); SpinBoxRot2->SetValue(0.0); SpinBoxDistance->SetValue(0.5); } + ActorList->setEnabled(anIsControlsEnable); + SelectAllCheckBox->setEnabled(anIsControlsEnable); buttonDelete->setEnabled(anIsControlsEnable); - buttonApply->setEnabled(anIsControlsEnable); - PreviewCheckBox->setEnabled(anIsControlsEnable); - AutoApplyCheckBox->setEnabled(anIsControlsEnable); + // the following 3 controls should be enabled + //buttonApply->setEnabled(anIsControlsEnable); + //PreviewCheckBox->setEnabled(anIsControlsEnable); + //AutoApplyCheckBox->setEnabled(anIsControlsEnable); ComboBoxOrientation->setEnabled(anIsControlsEnable); SpinBoxDistance->setEnabled(anIsControlsEnable); SpinBoxRot1->setEnabled(anIsControlsEnable); @@ -775,7 +886,8 @@ void SMESHGUI_ClippingDlg::SetCurrentPlaneParam() int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); - OrientedPlane* aPlane = myPlanes[aCurPlaneIndex].GetPointer(); + SMESH::TPlaneData aPlaneData = myPlanes[aCurPlaneIndex]; + SMESH::OrientedPlane* aPlane = aPlaneData.Plane.GetPointer(); vtkFloatingPointType aNormal[3]; SMESH::Orientation anOrientation; @@ -833,52 +945,69 @@ void SMESHGUI_ClippingDlg::SetCurrentPlaneParam() aPlane->SetOrientation(anOrientation); aPlane->SetDistance(getDistance()); - myActor->SetPlaneParam(aNormal, getDistance(), aPlane); - - vtkDataSet* aDataSet = myActor->GetInput(); - vtkFloatingPointType *aPnt = aDataSet->GetCenter(); - - vtkFloatingPointType* anOrigin = aPlane->GetOrigin(); - vtkFloatingPointType aDel = aDataSet->GetLength()/2.0; - - vtkFloatingPointType aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel}, - {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}}; - vtkFloatingPointType aParam, aPnt0[3], aPnt1[3], aPnt2[3]; - - vtkFloatingPointType aPnt01[3] = {aPnt[0] - aDelta[0][0] - aDelta[1][0], - aPnt[1] - aDelta[0][1] - aDelta[1][1], - aPnt[2] - aDelta[0][2] - aDelta[1][2]}; - vtkFloatingPointType aPnt02[3] = {aPnt01[0] + aNormal[0], - aPnt01[1] + aNormal[1], - aPnt01[2] + aNormal[2]}; - vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0); - - vtkFloatingPointType aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0], - aPnt[1] - aDelta[0][1] + aDelta[1][1], - aPnt[2] - aDelta[0][2] + aDelta[1][2]}; - vtkFloatingPointType aPnt12[3] = {aPnt11[0] + aNormal[0], - aPnt11[1] + aNormal[1], - aPnt11[2] + aNormal[2]}; - vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1); - - vtkFloatingPointType aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0], - aPnt[1] + aDelta[0][1] - aDelta[1][1], - aPnt[2] + aDelta[0][2] - aDelta[1][2]}; - vtkFloatingPointType aPnt22[3] = {aPnt21[0] + aNormal[0], - aPnt21[1] + aNormal[1], - aPnt21[2] + aNormal[2]}; - vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2); - - vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource; - aPlaneSource->SetNormal(aNormal[0],aNormal[1],aNormal[2]); - aPlaneSource->SetOrigin(aPnt0[0],aPnt0[1],aPnt0[2]); - aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]); - aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]); + SMESH::TActorList anActorList = aPlaneData.ActorList; + + vtkFloatingPointType aBounds[6]; + vtkFloatingPointType anOrigin[3]; + bool anIsOk = SMESH::ComputeClippingPlaneParameters( anActorList, + aNormal, + getDistance(), + aBounds, + anOrigin ); + + aPlane->myActor->SetVisibility( anIsOk && PreviewCheckBox->isChecked() ); + + if( anIsOk ) { + aPlane->SetNormal( aNormal ); + aPlane->SetOrigin( anOrigin ); + + vtkFloatingPointType aPnt[3] = { ( aBounds[0] + aBounds[1] ) / 2., + ( aBounds[2] + aBounds[3] ) / 2., + ( aBounds[4] + aBounds[5] ) / 2. }; + + vtkFloatingPointType aDel = pow( pow( aBounds[1] - aBounds[0], 2 ) + + pow( aBounds[3] - aBounds[2], 2 ) + + pow( aBounds[5] - aBounds[4], 2 ), 0.5 ); + + vtkFloatingPointType aDelta[2][3] = {{aDir[0][0]*aDel, aDir[0][1]*aDel, aDir[0][2]*aDel}, + {aDir[1][0]*aDel, aDir[1][1]*aDel, aDir[1][2]*aDel}}; + vtkFloatingPointType aParam, aPnt0[3], aPnt1[3], aPnt2[3]; + + vtkFloatingPointType aPnt01[3] = {aPnt[0] - aDelta[0][0] - aDelta[1][0], + aPnt[1] - aDelta[0][1] - aDelta[1][1], + aPnt[2] - aDelta[0][2] - aDelta[1][2]}; + vtkFloatingPointType aPnt02[3] = {aPnt01[0] + aNormal[0], + aPnt01[1] + aNormal[1], + aPnt01[2] + aNormal[2]}; + vtkPlane::IntersectWithLine(aPnt01,aPnt02,aNormal,anOrigin,aParam,aPnt0); + + vtkFloatingPointType aPnt11[3] = {aPnt[0] - aDelta[0][0] + aDelta[1][0], + aPnt[1] - aDelta[0][1] + aDelta[1][1], + aPnt[2] - aDelta[0][2] + aDelta[1][2]}; + vtkFloatingPointType aPnt12[3] = {aPnt11[0] + aNormal[0], + aPnt11[1] + aNormal[1], + aPnt11[2] + aNormal[2]}; + vtkPlane::IntersectWithLine(aPnt11,aPnt12,aNormal,anOrigin,aParam,aPnt1); + + vtkFloatingPointType aPnt21[3] = {aPnt[0] + aDelta[0][0] - aDelta[1][0], + aPnt[1] + aDelta[0][1] - aDelta[1][1], + aPnt[2] + aDelta[0][2] - aDelta[1][2]}; + vtkFloatingPointType aPnt22[3] = {aPnt21[0] + aNormal[0], + aPnt21[1] + aNormal[1], + aPnt21[2] + aNormal[2]}; + vtkPlane::IntersectWithLine(aPnt21,aPnt22,aNormal,anOrigin,aParam,aPnt2); + + vtkPlaneSource* aPlaneSource = aPlane->myPlaneSource; + aPlaneSource->SetNormal(aNormal[0],aNormal[1],aNormal[2]); + aPlaneSource->SetOrigin(aPnt0[0],aPnt0[1],aPnt0[2]); + aPlaneSource->SetPoint1(aPnt1[0],aPnt1[1],aPnt1[2]); + aPlaneSource->SetPoint2(aPnt2[0],aPnt2[1],aPnt2[2]); + } if(AutoApplyCheckBox->isChecked()) ClickOnApply(); - SMESH::RenderViewWindow(SMESH::GetCurrentVtkView()); + SMESH::RenderViewWindow( myViewWindow ); } //======================================================================= @@ -887,8 +1016,8 @@ void SMESHGUI_ClippingDlg::SetCurrentPlaneParam() //======================================================================= void SMESHGUI_ClippingDlg::OnPreviewToggle (bool theIsToggled) { - std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisiblity(theIsToggled)); - SMESH::RenderViewWindow(SMESH::GetCurrentVtkView()); + std::for_each(myPlanes.begin(),myPlanes.end(),TSetVisibility(theIsToggled)); + SMESH::RenderViewWindow( myViewWindow ); } //================================================================================= @@ -906,3 +1035,124 @@ void SMESHGUI_ClippingDlg::keyPressEvent( QKeyEvent* e ) ClickOnHelp(); } } + +//================================================================================= +// function : initializePlaneData() +// purpose : +//================================================================================= +void SMESHGUI_ClippingDlg::initializePlaneData() +{ + const SMESHGUI_ClippingPlaneInfoMap& aClippingPlaneInfoMap = mySMESHGUI->getClippingPlaneInfoMap(); + SMESHGUI_ClippingPlaneInfoMap::const_iterator anIter1 = aClippingPlaneInfoMap.find( myViewWindow->getViewManager() ); + if( anIter1 != aClippingPlaneInfoMap.end() ) { + const SMESHGUI_ClippingPlaneInfoList& aClippingPlaneInfoList = anIter1->second; + SMESHGUI_ClippingPlaneInfoList::const_iterator anIter2 = aClippingPlaneInfoList.begin(); + for( ; anIter2 != aClippingPlaneInfoList.end(); anIter2++ ) { + const SMESH::ClippingPlaneInfo& aClippingPlaneInfo = *anIter2; + SMESH::TPlane aTPlane( aClippingPlaneInfo.Plane ); + SMESH::TPlaneData aPlaneData( aTPlane, aClippingPlaneInfo.ActorList ); + myPlanes.push_back( aPlaneData ); + } + } + std::for_each( myPlanes.begin(),myPlanes.end(), TSetVisibility( PreviewCheckBox->isChecked() ) ); +} + +//================================================================================= +// function : updateActorList() +// purpose : +//================================================================================= +void SMESHGUI_ClippingDlg::updateActorList() +{ + ActorList->clear(); + + SalomeApp_Study* anAppStudy = SMESHGUI::activeStudy(); + if( !anAppStudy ) + return; + + _PTR(Study) aStudy = anAppStudy->studyDS(); + if( !aStudy ) + return; + + if( !myViewWindow ) + return; + + int aCurPlaneIndex = ComboBoxPlanes->currentIndex(); + const SMESH::TPlaneData& aPlaneData = myPlanes[ aCurPlaneIndex ]; + const SMESH::TActorList& anActorList = aPlaneData.ActorList; + + VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() ); + vtkActorCollection* anAllActors = aCopy.GetActors(); + anAllActors->InitTraversal(); + while( vtkActor* aVTKActor = anAllActors->GetNextActor() ) { + if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) { + if( anActor->hasIO() ) { + Handle(SALOME_InteractiveObject) anIO = anActor->getIO(); + if( _PTR(SObject) aSObj = aStudy->FindObjectID( anIO->getEntry() ) ) { + bool anIsChecked = false; + SMESH::TActorList::const_iterator anIter = anActorList.begin(); + for ( ; anIter != anActorList.end(); anIter++ ) { + if( vtkActor* aVTKActorRef = *anIter ) { + if( SMESH_Actor* anActorRef = SMESH_Actor::SafeDownCast( aVTKActorRef ) ) { + if( anActorRef == anActor ) { + anIsChecked = true; + break; + } + } + } + } + QString aName = QString( aSObj->GetName().c_str() ); + QListWidgetItem* anItem = new ActorItem( anActor, aName, ActorList ); + anItem->setCheckState( anIsChecked ? Qt::Checked : Qt::Unchecked ); + updateActorItem( anItem, true, false ); + } + } + } + } +} + +//================================================================================= +// function : getCurrentActors() +// purpose : +//================================================================================= +SMESH::TActorList SMESHGUI_ClippingDlg::getCurrentActors() +{ + SMESH::TActorList anActorList; + for( int i = 0, n = ActorList->count(); i < n; i++ ) + if( ActorItem* anItem = dynamic_cast( ActorList->item( i ) ) ) + if( anItem->checkState() == Qt::Checked ) + if( SMESH_Actor* anActor = anItem->getActor() ) + anActorList.push_back( anActor ); + return anActorList; +} + +//================================================================================= +// function : dumpPlaneData() +// purpose : +//================================================================================= +void SMESHGUI_ClippingDlg::dumpPlaneData() const +{ + printf( "----------- Plane Data -----------\n" ); + int anId = 1; + SMESH::TPlaneDataVector::const_iterator anIter1 = myPlanes.begin(); + for ( ; anIter1 != myPlanes.end(); anIter1++, anId++ ) { + SMESH::TPlaneData aPlaneData = *anIter1; + SMESH::TPlane aPlane = aPlaneData.Plane; + vtkFloatingPointType* aNormal = aPlane->GetNormal(); + vtkFloatingPointType* anOrigin = aPlane->GetOrigin(); + printf( "Plane N%d:\n", anId ); + printf( " Normal = ( %f, %f, %f )\n", aNormal[0], aNormal[1], aNormal[2] ); + printf( " Origin = ( %f, %f, %f )\n", anOrigin[0], anOrigin[1], anOrigin[2] ); + + SMESH::TActorList anActorList = aPlaneData.ActorList; + SMESH::TActorList::const_iterator anIter2 = anActorList.begin(); + for ( ; anIter2 != anActorList.end(); anIter2++ ) { + if( vtkActor* aVTKActor = *anIter2 ) { + if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) + printf( " - Actor: '%s'\n", anActor->getName() ); + } + else + printf( " - Actor: NULL\n"); + } + } + printf( "----------------------------------\n" ); +} diff --git a/src/SMESHGUI/SMESHGUI_ClippingDlg.h b/src/SMESHGUI/SMESHGUI_ClippingDlg.h index 0c70ca9c2..87a4b7b9d 100644 --- a/src/SMESHGUI/SMESHGUI_ClippingDlg.h +++ b/src/SMESHGUI/SMESHGUI_ClippingDlg.h @@ -35,31 +35,91 @@ // Qt includes #include +#include // VTK includes +#include #include // STL includes +#include +#include #include class QLabel; class QPushButton; class QCheckBox; class QComboBox; -class LightApp_SelectionMgr; -class SVTK_Selector; +class QListWidget; +class QListWidgetItem; +class SALOME_Actor; class SMESHGUI; class SMESH_Actor; -class OrientedPlane; class SMESHGUI_SpinBox; +class vtkActor; +class vtkDataSetMapper; +class vtkPlaneSource; namespace SMESH { - typedef vtkSmartPointer TVTKPlane; - typedef std::vector TPlanes; enum Orientation { XY, YZ, ZX }; -}; + class OrientedPlane: public vtkPlane + { + QPointer myViewWindow; + vtkDataSetMapper* myMapper; + + public: + static OrientedPlane *New(); + static OrientedPlane *New(SVTK_ViewWindow* theViewWindow); + vtkTypeMacro (OrientedPlane, vtkPlane); + + SMESH::Orientation myOrientation; + float myDistance; + double myAngle[2]; + + vtkPlaneSource* myPlaneSource; + SALOME_Actor *myActor; + + void SetOrientation (SMESH::Orientation theOrientation) { myOrientation = theOrientation; } + SMESH::Orientation GetOrientation() { return myOrientation; } + + void SetDistance (float theDistance) { myDistance = theDistance; } + float GetDistance() { return myDistance; } + + void ShallowCopy (OrientedPlane* theOrientedPlane); + + protected: + OrientedPlane(SVTK_ViewWindow* theViewWindow); + OrientedPlane(); + + void Init(); + + ~OrientedPlane(); + private: + // Not implemented. + OrientedPlane (const OrientedPlane&); + void operator= (const OrientedPlane&); + }; + + typedef vtkSmartPointer TPlane; + typedef std::list TActorList; + + struct TPlaneData + { + TPlaneData( TPlane thePlane, + TActorList theActorList ) + { + Plane = thePlane; + ActorList = theActorList; + } + TPlane Plane; + TActorList ActorList; + }; + + typedef std::vector TPlaneVector; + typedef std::vector TPlaneDataVector; +}; //================================================================================= // class : SMESHGUI_ClippingDlg @@ -70,7 +130,7 @@ class SMESHGUI_EXPORT SMESHGUI_ClippingDlg : public QDialog Q_OBJECT public: - SMESHGUI_ClippingDlg( SMESHGUI* ); + SMESHGUI_ClippingDlg( SMESHGUI*, SVTK_ViewWindow* ); ~SMESHGUI_ClippingDlg(); double getDistance() const; @@ -78,35 +138,42 @@ public: double getRotation1() const; double getRotation2() const; void setRotation( const double, const double ); - void Sinchronize(); // used in SMESHGUI::restoreVisualParameters() to avoid // declaration of OrientedPlane outside of SMESHGUI_ClippingDlg.cxx - static void AddPlane (SMESH_Actor* theActor, - SVTK_ViewWindow* theViewWindow, - SMESH::Orientation theOrientation, - double theDistance, - vtkFloatingPointType theAngle[2]); - - static void GetPlaneParam (SMESH_Actor* theActor, - int thePlaneIndex, - SMESH::Orientation& theOrientation, - double& theDistance, - vtkFloatingPointType* theAngle); + static SMESH::OrientedPlane* AddPlane (SMESH::TActorList theActorList, + SVTK_ViewWindow* theViewWindow, + SMESH::Orientation theOrientation, + double theDistance, + const vtkFloatingPointType theAngle[2]); protected: void keyPressEvent( QKeyEvent* ); private: - LightApp_SelectionMgr* mySelectionMgr; - SVTK_Selector* mySelector; + void initializePlaneData(); + + void synchronize(); + + void updateActorList(); + SMESH::TActorList getCurrentActors(); + + void updateActorItem( QListWidgetItem* theItem, + bool theUpdateSelectAll, + bool theUpdateClippingPlaneMap ); + + void dumpPlaneData() const; + +private: SMESHGUI* mySMESHGUI; - SMESH_Actor* myActor; - SMESH::TPlanes myPlanes; + SVTK_ViewWindow* myViewWindow; + SMESH::TPlaneDataVector myPlanes; QComboBox* ComboBoxPlanes; QPushButton* buttonNew; QPushButton* buttonDelete; + QListWidget* ActorList; + QCheckBox* SelectAllCheckBox; QLabel* TextLabelOrientation; QComboBox* ComboBoxOrientation; QLabel* TextLabelDistance; @@ -129,9 +196,10 @@ public slots: void onSelectPlane( int ); void ClickOnNew(); void ClickOnDelete(); + void onActorItemChanged( QListWidgetItem* ); + void onSelectAll( int ); void onSelectOrientation( int ); void SetCurrentPlaneParam(); - void onSelectionChanged(); void OnPreviewToggle( bool ); void ClickOnOk(); void ClickOnCancel(); diff --git a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx index ccd700190..b31a1b8e9 100644 --- a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx @@ -98,6 +98,7 @@ #define COLONIZE(str) (QString(str).contains(":") > 0 ? QString(str) : QString(str) + " :" ) +/* OBSOLETE static void addSeparator( QWidget* parent ) { QGridLayout* l = qobject_cast( parent->layout() ); @@ -109,6 +110,7 @@ static void addSeparator( QWidget* parent ) l->addWidget( hline, row, i ); } } +*/ enum TCol { COL_ALGO = 0, COL_SHAPE, COL_ERROR, COL_SHAPEID, COL_PUBLISHED, COL_BAD_MESH, NB_COLUMNS @@ -734,25 +736,38 @@ void SMESHGUI_BaseComputeOp::computeMesh() // SHOW MESH // NPAL16631: if ( getSMESHGUI()->automaticUpdate() ) - if ( !memoryLack && getSMESHGUI()->automaticUpdate() ) + SUIT_ResourceMgr* resMgr = SMESH::GetResourceMgr( SMESHGUI::GetSMESHGUI() ); + long newSize = myMesh->NbElements(); + long limitSize = resMgr->integerValue( "SMESH", "update_limit", 500000 ); + bool limitExceeded; + if ( !memoryLack ) { - try { + if ( getSMESHGUI()->automaticUpdate( newSize, &limitExceeded ) ) + { + try { #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100 - OCC_CATCH_SIGNALS; + OCC_CATCH_SIGNALS; #endif - SMESH::Update(myIObject, true); - } - catch (...) { + SMESH::Update(myIObject, true); + } + catch (...) { #ifdef _DEBUG_ - MESSAGE ( "Exception thrown during mesh visualization" ); + MESSAGE ( "Exception thrown during mesh visualization" ); #endif - if ( SMDS_Mesh::CheckMemory(true) ) { // has memory to show warning? - SMESH::OnVisuException(); - } - else { - memoryLack = true; - } + if ( SMDS_Mesh::CheckMemory(true) ) { // has memory to show warning? + SMESH::OnVisuException(); + } + else { + memoryLack = true; + } + } } + else if ( limitExceeded ) + { + SUIT_MessageBox::warning( desktop(), + tr( "SMESH_WRN_WARNING" ), + tr( "SMESH_WRN_SIZE_LIMIT_EXCEEDED" ).arg( newSize ).arg( limitSize ) ); + } } LightApp_SelectionMgr *Sel = selectionMgr(); if ( Sel ) @@ -804,7 +819,7 @@ void SMESHGUI_BaseComputeOp::computeMesh() void SMESHGUI_BaseComputeOp::showComputeResult( const bool theMemoryLack, const bool theNoCompError, SMESH::compute_error_array_var& theCompErrors, - const bool theNoHypoError, + const bool theNoHypoError, const QString& theHypErrors ) { bool hasShape = myMesh->HasShapeToMesh(); @@ -1562,6 +1577,7 @@ void SMESHGUI_PrecomputeOp::onPreview() SMESH::MeshPreviewStruct_var previewData = gen->Precompute(myMesh, myMainShape, (SMESH::Dimension)dim, aShapesId); + SMESH::MeshPreviewStruct* previewRes = previewData._retn(); if ( previewRes && previewRes->nodesXYZ.length() > 0 ) { diff --git a/src/SMESHGUI/SMESHGUI_ComputeDlg.h b/src/SMESHGUI/SMESHGUI_ComputeDlg.h index 618db50c5..ee268a4d4 100644 --- a/src/SMESHGUI/SMESHGUI_ComputeDlg.h +++ b/src/SMESHGUI/SMESHGUI_ComputeDlg.h @@ -53,8 +53,6 @@ class SMESHGUI_MeshInfosBox; class SMESHGUI_PrecomputeDlg; class SMESHGUI_MeshEditPreview; -class SMESH::compute_error_array; - namespace SMESH { class TShapeDisplayer; diff --git a/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.cxx b/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.cxx index 864537e84..7d65ad01d 100644 --- a/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.cxx @@ -456,22 +456,22 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::ClickOnApply() SMESH::SMESH_GroupBase_var aGroup; int idx = 0; if( addToGroup ) { - aGroupName = ComboBox_GroupName->currentText(); - for ( int i = 1; i < ComboBox_GroupName->count(); i++ ) { - QString aName = ComboBox_GroupName->itemText( i ); - if ( aGroupName == aName && ( i == ComboBox_GroupName->currentIndex() || idx == 0 ) ) - idx = i; - } - if ( idx > 0 ) { - SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] ); - if ( !aGeomGroup->_is_nil() ) { - int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ), - tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ), - tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 ); - if ( res == 1 ) return; - } - aGroup = myGroups[idx-1]; - } + aGroupName = ComboBox_GroupName->currentText(); + for ( int i = 1; i < ComboBox_GroupName->count(); i++ ) { + QString aName = ComboBox_GroupName->itemText( i ); + if ( aGroupName == aName && ( i == ComboBox_GroupName->currentIndex() || idx == 0 ) ) + idx = i; + } + if ( idx > 0 ) { + SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] ); + if ( !aGeomGroup->_is_nil() ) { + int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ), + tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ), + tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 ); + if ( res == 1 ) return; + } + aGroup = myGroups[idx-1]; + } } if (GetConstructorId() == 0) @@ -535,28 +535,28 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::ClickOnApply() } if ( anElemId != -1 && addToGroup && !aGroupName.isEmpty() ) { - SMESH::SMESH_Group_var aGroupUsed; - if ( aGroup->_is_nil() ) { - // create new group - aGroupUsed = SMESH::AddGroup( myMesh, SMESH::VOLUME, aGroupName ); - if ( !aGroupUsed->_is_nil() ) { - myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed)); - ComboBox_GroupName->addItem( aGroupName ); - } - } - else { - SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup ); - if ( !aGeomGroup->_is_nil() ) { - aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup ); - if ( !aGroupUsed->_is_nil() && idx > 0 ) { - myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed); - SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser(); - } - } - else - aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup ); - } - + SMESH::SMESH_Group_var aGroupUsed; + if ( aGroup->_is_nil() ) { + // create new group + aGroupUsed = SMESH::AddGroup( myMesh, SMESH::VOLUME, aGroupName ); + if ( !aGroupUsed->_is_nil() ) { + myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed)); + ComboBox_GroupName->addItem( aGroupName ); + } + } + else { + SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup ); + if ( !aGeomGroup->_is_nil() ) { + aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup ); + if ( !aGroupUsed->_is_nil() && idx > 0 ) { + myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed); + SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser(); + } + } + else + aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup ); + } + if ( !aGroupUsed->_is_nil() ) { SMESH::long_array_var anIdList = new SMESH::long_array; anIdList->length( 1 ); @@ -771,10 +771,10 @@ void SMESHGUI_CreatePolyhedralVolumeDlg::SelectionIntoArgument() for ( int i = 0, n = aListOfGroups.length(); i < n; i++ ) { SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i]; if ( !aGroup->_is_nil() && aGroup->GetType() == SMESH::VOLUME ) { - QString aGroupName( aGroup->GetName() ); - if ( !aGroupName.isEmpty() ) { - myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup)); - ComboBox_GroupName->addItem( aGroupName ); + QString aGroupName( aGroup->GetName() ); + if ( !aGroupName.isEmpty() ) { + myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup)); + ComboBox_GroupName->addItem( aGroupName ); } } } diff --git a/src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.cxx b/src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.cxx new file mode 100644 index 000000000..a2a0afd9c --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.cxx @@ -0,0 +1,580 @@ +// 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_DuplicateNodesDlg.cxx +// Author : Michael ZORIN, Open CASCADE S.A.S. + +// SMESH includes +#include "SMESHGUI_DuplicateNodesDlg.h" + +#include "SMESHGUI.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_VTKUtils.h" + +#include + +// SALOME GUI includes +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_MeshEditor) + +#define SPACING 6 +#define MARGIN 11 + + +/*! + \brief Constructor + \param theModule Mesh module instance +*/ +SMESHGUI_DuplicateNodesDlg::SMESHGUI_DuplicateNodesDlg( SMESHGUI* theModule ) + : QDialog( SMESH::GetDesktop( theModule ) ), + mySMESHGUI( theModule ), + mySelectionMgr( SMESH::GetSelectionMgr( theModule ) ) +{ + // Dialog attributes + setModal(false); + setAttribute(Qt::WA_DeleteOnClose, true); + setWindowTitle(tr("SMESH_DUPLICATE_TITLE")); + setSizeGripEnabled(true); + + // Icons for the dialog operation modes and selection button + SUIT_ResourceMgr* aResMgr = SMESH::GetResourceMgr( mySMESHGUI ); + QPixmap iconWithoutElem (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_DUPLICATE_NODES"))); + QPixmap iconWithElem (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_DUPLICATE_NODES_WITH_ELEM"))); + QPixmap iconSelect (aResMgr->loadPixmap("SMESH", tr("ICON_SELECT"))); + + // Main layout + QVBoxLayout* aMainLayout = new QVBoxLayout(this); + aMainLayout->setSpacing(SPACING); + aMainLayout->setMargin(MARGIN); + + // Operation modes selector + QGroupBox* aConstructorsBox = new QGroupBox(tr("DUPLICATION_MODE"), this); + myGroupConstructors = new QButtonGroup(this); + QHBoxLayout* aConstructorsBoxLayout = new QHBoxLayout(aConstructorsBox); + aConstructorsBoxLayout->setSpacing(SPACING); + aConstructorsBoxLayout->setMargin(MARGIN); + + QRadioButton* aRadioButton1 = new QRadioButton(aConstructorsBox); + aRadioButton1->setIcon(iconWithoutElem); + QRadioButton* aRadioButton2 = new QRadioButton(aConstructorsBox); + aRadioButton2->setIcon(iconWithElem); + + aConstructorsBoxLayout->addWidget(aRadioButton1); + aConstructorsBoxLayout->addWidget(aRadioButton2); + myGroupConstructors->addButton(aRadioButton1, 0); + myGroupConstructors->addButton(aRadioButton2, 1); + + // Arguments + myGroupArguments = new QGroupBox(this); + QGridLayout* aGroupArgumentsLayout = new QGridLayout(myGroupArguments); + aGroupArgumentsLayout->setSpacing(SPACING); + aGroupArgumentsLayout->setMargin(MARGIN); + + myTextLabel1 = new QLabel(myGroupArguments); + mySelectButton1 = new QPushButton(myGroupArguments); + mySelectButton1->setIcon(iconSelect); + myLineEdit1 = new QLineEdit(myGroupArguments); + myLineEdit1->setReadOnly(true); + + myTextLabel2 = new QLabel(myGroupArguments); + mySelectButton2 = new QPushButton(myGroupArguments); + mySelectButton2->setIcon(iconSelect); + myLineEdit2 = new QLineEdit(myGroupArguments); + myLineEdit2->setReadOnly(true); + + myTextLabel3 = new QLabel(myGroupArguments); + mySelectButton3 = new QPushButton(myGroupArguments); + mySelectButton3->setIcon(iconSelect); + myLineEdit3 = new QLineEdit(myGroupArguments); + myLineEdit3->setReadOnly(true); + + myCheckBoxNewGroup = new QCheckBox(tr("CONSTRUCT_NEW_GROUP_NODES"), myGroupArguments); + + aGroupArgumentsLayout->addWidget(myTextLabel1, 0, 0); + aGroupArgumentsLayout->addWidget(mySelectButton1, 0, 1); + aGroupArgumentsLayout->addWidget(myLineEdit1, 0, 2); + aGroupArgumentsLayout->addWidget(myTextLabel2, 1, 0); + aGroupArgumentsLayout->addWidget(mySelectButton2, 1, 1); + aGroupArgumentsLayout->addWidget(myLineEdit2, 1, 2); + aGroupArgumentsLayout->addWidget(myTextLabel3, 2, 0); + aGroupArgumentsLayout->addWidget(mySelectButton3, 2, 1); + aGroupArgumentsLayout->addWidget(myLineEdit3, 2, 2); + aGroupArgumentsLayout->addWidget(myCheckBoxNewGroup, 3, 0); + aGroupArgumentsLayout->setRowStretch(4, 1); + + // Buttons + QGroupBox* aGroupButtons = new QGroupBox(this); + QHBoxLayout* aGroupButtonsLayout = new QHBoxLayout(aGroupButtons); + aGroupButtonsLayout->setSpacing(SPACING); + aGroupButtonsLayout->setMargin(MARGIN); + + myButtonOk = new QPushButton(tr("SMESH_BUT_APPLY_AND_CLOSE"), aGroupButtons); + myButtonOk->setAutoDefault(true); + myButtonOk->setDefault(true); + myButtonApply = new QPushButton(tr("SMESH_BUT_APPLY"), aGroupButtons); + myButtonApply->setAutoDefault(true); + myButtonClose = new QPushButton(tr("SMESH_BUT_CLOSE"), aGroupButtons); + myButtonClose->setAutoDefault(true); + myButtonHelp = new QPushButton(tr("SMESH_BUT_HELP"), aGroupButtons); + myButtonHelp->setAutoDefault(true); + + aGroupButtonsLayout->addWidget(myButtonOk); + aGroupButtonsLayout->addSpacing(10); + aGroupButtonsLayout->addWidget(myButtonApply); + aGroupButtonsLayout->addSpacing(10); + aGroupButtonsLayout->addStretch(); + aGroupButtonsLayout->addWidget(myButtonClose); + aGroupButtonsLayout->addWidget(myButtonHelp); + + // Add mode selector, arguments and buttons to the main layout + aMainLayout->addWidget(aConstructorsBox); + aMainLayout->addWidget(myGroupArguments); + aMainLayout->addWidget(aGroupButtons); + + // Initialize the dialog + Init(); + + // Help file name + myHelpFileName = "double_nodes_page.html"; + + // Signals and slots connections + connect(myGroupConstructors, SIGNAL(buttonClicked(int)), SLOT(onConstructorsClicked(int))); + + connect(mySelectButton1, SIGNAL (clicked()), this, SLOT(onEditCurrentArgument())); + connect(mySelectButton2, SIGNAL (clicked()), this, SLOT(onEditCurrentArgument())); + connect(mySelectButton3, SIGNAL (clicked()), this, SLOT(onEditCurrentArgument())); + + connect(myButtonOk, SIGNAL(clicked()), this, SLOT(onOk())); + connect(myButtonClose, SIGNAL(clicked()), this, SLOT(onClose())); + connect(myButtonApply, SIGNAL(clicked()), this, SLOT(onApply())); + connect(myButtonHelp, SIGNAL(clicked()), this, SLOT(onHelp())); + + connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), SLOT(onSelectionChanged())); + + connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(onDeactivate())); + connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(onClose())); +} + +/*! + \brief Destructor +*/ +SMESHGUI_DuplicateNodesDlg::~SMESHGUI_DuplicateNodesDlg() +{ +} + +/*! + \brief Destructor +*/ +void SMESHGUI_DuplicateNodesDlg::Init() +{ + mySMESHGUI->SetActiveDialogBox((QDialog*)this); + + // Set initial parameters + myBusy = false; + myCurrentLineEdit = myLineEdit1; + + myGroup1 = SMESH::SMESH_GroupBase::_nil(); + myGroup2 = SMESH::SMESH_GroupBase::_nil(); + myGroup3 = SMESH::SMESH_GroupBase::_nil(); + + // Set selection mode + mySelectionMgr->installFilter(new SMESH_TypeFilter(GROUP)); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(ActorSelection); + + // Set construction mode + int operationMode = myGroupConstructors->checkedId(); + if (operationMode < 0) { + // The dialog has been just displayed + operationMode = 0; + myGroupConstructors->button(0)->setChecked(true); + } + onConstructorsClicked(operationMode); +} + +/*! + \brief SLOT called to change the dialog operation mode. + \param constructorId id of the radio button in mode selector button group +*/ +void SMESHGUI_DuplicateNodesDlg::onConstructorsClicked (int constructorId) +{ + // Clear all fields + myLineEdit1->clear(); + myLineEdit2->clear(); + myLineEdit3->clear(); + + // Checkbox should be checked by default + myCheckBoxNewGroup->setChecked(true); + + // Set the first field as current + myCurrentLineEdit = myLineEdit1; + myCurrentLineEdit->setFocus(); + + switch (constructorId) { + case 0: + { + // Set text to the group of arguments and to the first two labels + myGroupArguments->setTitle(tr("DUPLICATION_WITHOUT_ELEMS")); + myTextLabel1->setText(tr("GROUP_NODES_TO_DUPLICATE")); + myTextLabel2->setText(tr("GROUP_NODES_TO_REPLACE")); + + // Set checkbox title + myCheckBoxNewGroup->setText(tr("CONSTRUCT_NEW_GROUP_NODES")); + + // Hide the third field + myTextLabel3->hide(); + mySelectButton3->hide(); + myLineEdit3->hide(); + + break; + } + case 1: + { + // Set text to the group of arguments and to all the labels + myGroupArguments->setTitle(tr("DUPLICATION_WITH_ELEMS")); + myTextLabel1->setText(tr("GROUP_ELEMS_TO_DUPLICATE")); + myTextLabel2->setText(tr("GROUP_NODES_NOT_DUPLICATE")); + myTextLabel3->setText(tr("GROUP_ELEMS_TO_REPLACE")); + + // Set checkbox title + myCheckBoxNewGroup->setText(tr("CONSTRUCT_NEW_GROUP_ELEMENTS")); + + // Show the third field + myTextLabel3->show(); + mySelectButton3->show(); + myLineEdit3->show(); + + break; + } + } + + // Process selection + onSelectionChanged(); +} + +/*! + \brief SLOT called to apply changes. +*/ +bool SMESHGUI_DuplicateNodesDlg::onApply() +{ + if (mySMESHGUI->isActiveStudyLocked() || !isValid()) + return false; + + myBusy = true; + + bool toCreateGroup = myCheckBoxNewGroup->isChecked(); + int operationMode = myGroupConstructors->checkedId(); + + // Apply changes + bool result = false; + SUIT_OverrideCursor aWaitCursor; + + try { + SMESH::SMESH_Mesh_ptr aMesh = myGroup1->GetMesh(); + SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor(); + + if (operationMode == 0) { + if (toCreateGroup) { + SMESH::SMESH_GroupBase_ptr aNewGroup = + aMeshEditor->DoubleNodeGroupNew(myGroup1, myGroup2); + if (!CORBA::is_nil(aNewGroup)) + result = true; + } + else + result = aMeshEditor->DoubleNodeGroup(myGroup1, myGroup2); + } + else { + if (toCreateGroup) { + SMESH::SMESH_GroupBase_ptr aNewGroup = + aMeshEditor->DoubleNodeElemGroupNew(myGroup1, myGroup2, myGroup3); + if (!CORBA::is_nil(aNewGroup)) + result = true; + } + else + result = aMeshEditor->DoubleNodeElemGroup(myGroup1, myGroup2, myGroup3); + } + } + catch (const SALOME::SALOME_Exception& S_ex) { + SalomeApp_Tools::QtCatchCorbaException(S_ex); + } + catch ( const std::exception& exc ) { + INFOS( "Follow exception was cought:\n\t" << exc.what() ); + } + catch (...){ + INFOS( "Unknown exception was cought !!!" ); + } + + if (!result) { + SUIT_MessageBox::warning(this, + tr("SMESH_WRN_WARNING"), + tr("SMESH_OPERATION_FAILED")); + myBusy = false; + return false; + } + + // Update GUI + mySelectionMgr->clearSelected(); + SMESH::UpdateView(); + SMESHGUI::Modified(); + mySMESHGUI->updateObjBrowser(true); + + // Reinitialize the dialog + Init(); + + return true; +} + +/*! + \brief SLOT called to apply changes and close the dialog. +*/ +void SMESHGUI_DuplicateNodesDlg::onOk() +{ + if (onApply()) + onClose(); +} + +/*! + \brief SLOT called to close the dialog. +*/ +void SMESHGUI_DuplicateNodesDlg::onClose() +{ + disconnect(mySelectionMgr, 0, this, 0); + disconnect(mySMESHGUI, 0, this, 0); + mySMESHGUI->ResetState(); + mySelectionMgr->clearFilters(); + reject(); +} + +/*! + \brief SLOT called when selection changed. +*/ +void SMESHGUI_DuplicateNodesDlg::onSelectionChanged() +{ + if (myBusy || !isEnabled()) return; + + // Try to get selected group + SALOME_ListIO aList; + mySelectionMgr->selectedObjects( aList ); + int aNbSel = aList.Extent(); + + SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_nil(); + if (aNbSel == 1) { + Handle(SALOME_InteractiveObject) IO = aList.First(); + aGroup = SMESH::IObjectToInterface(IO); + + // Check group type + if (!CORBA::is_nil(aGroup)) { + int operationMode = myGroupConstructors->checkedId(); + SMESH::ElementType aGroupType = aGroup->GetType(); + bool isTypeValid = true; + + if (operationMode == 0) { + if ( (myCurrentLineEdit == myLineEdit1 && aGroupType != SMESH::NODE) || + (myCurrentLineEdit == myLineEdit2 && aGroupType == SMESH::NODE) ) + isTypeValid = false; + } + else if (operationMode == 1) { + if ( (myCurrentLineEdit == myLineEdit1 && aGroupType != SMESH::EDGE && + aGroupType != SMESH::FACE) || + (myCurrentLineEdit == myLineEdit2 && aGroupType != SMESH::NODE) || + (myCurrentLineEdit == myLineEdit3 && aGroupType == SMESH::NODE) ) + isTypeValid = false; + } + + if (!isTypeValid) + aGroup = SMESH::SMESH_GroupBase::_nil(); + } + } + + // Clear current field + myCurrentLineEdit->clear(); + + // Set corresponding SMESH group + if (myCurrentLineEdit == myLineEdit1) { + myGroup1 = SMESH::SMESH_Group::_narrow(aGroup); + } + else if (myCurrentLineEdit == myLineEdit2) { + myGroup2 = SMESH::SMESH_Group::_narrow(aGroup); + } + else if (myCurrentLineEdit == myLineEdit3) { + myGroup3 = SMESH::SMESH_Group::_narrow(aGroup); + } + + // Set group name + if (!CORBA::is_nil(aGroup)) + myCurrentLineEdit->setText(aGroup->GetName()); + + // Enable/disable "Apply and Close" and "Apply" buttons + bool isDataValid = isValid(); + myButtonOk->setEnabled(isDataValid); + myButtonApply->setEnabled(isDataValid); +} + +/*! + \brief SLOT called when selection button clicked. +*/ +void SMESHGUI_DuplicateNodesDlg::onEditCurrentArgument() +{ + QPushButton* send = (QPushButton*)sender(); + + // Set current field for edition + if (send == mySelectButton1) { + myCurrentLineEdit = myLineEdit1; + } + else if (send == mySelectButton2) { + myCurrentLineEdit = myLineEdit2; + } + else if (send == mySelectButton3) { + myCurrentLineEdit = myLineEdit3; + } + + myCurrentLineEdit->setFocus(); + onSelectionChanged(); +} + +/*! + \brief Check if the input data is valid. + \return \c true id the data is valid +*/ +bool SMESHGUI_DuplicateNodesDlg::isValid() +{ + // Only first group (nodes/elemets to duplicate) is mandatory + bool isValid = !CORBA::is_nil(myGroup1); + + // First (elements to duplicate) and last groups should be defined in the second operation mode + if (isValid && myGroupConstructors->checkedId() == 1) + isValid = !CORBA::is_nil(myGroup3); + + return isValid; +} + + +/*! + \brief SLOT called when dialog shoud be deativated. +*/ +void SMESHGUI_DuplicateNodesDlg::onDeactivate() +{ + if (isEnabled()) { + mySelectionMgr->clearFilters(); + setEnabled(false); + mySMESHGUI->ResetState(); + mySMESHGUI->SetActiveDialogBox(0); + } +} + +/*! + \brief Receive dialog enter events. + Activates the dialog when the mouse cursor enters. + Reimplemented from QWidget class. +*/ +void SMESHGUI_DuplicateNodesDlg::enterEvent (QEvent*) +{ + if ( !isEnabled() ) { + mySMESHGUI->EmitSignalDeactivateDialog(); + setEnabled(true); + mySMESHGUI->SetActiveDialogBox((QDialog*)this); + + // Set selection mode + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(ActorSelection); + mySelectionMgr->installFilter(new SMESH_TypeFilter (GROUP)); + } +} + +/*! + \brief Receive close events. + Reimplemented from QWidget class. +*/ +void SMESHGUI_DuplicateNodesDlg::closeEvent (QCloseEvent*) +{ + onClose(); +} + +/*! + \brief Receive key press events. + Reimplemented from QWidget class. +*/ +void SMESHGUI_DuplicateNodesDlg::keyPressEvent( QKeyEvent* e ) +{ + QDialog::keyPressEvent( e ); + if ( e->isAccepted() ) + return; + + if ( e->key() == Qt::Key_F1 ) { + e->accept(); + onHelp(); + } +} + +/*! + \brief Show the dialog help page. +*/ +void SMESHGUI_DuplicateNodesDlg::onHelp() +{ + 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)); + } +} diff --git a/src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.h b/src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.h new file mode 100644 index 000000000..974b7d7fa --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_DuplicateNodesDlg.h @@ -0,0 +1,119 @@ +// 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_DuplicateNodesDlg.h +// Author : Michael ZORIN, Open CASCADE S.A.S. +// +#ifndef SMESHGUI_DUPLICATENODESDLG_H +#define SMESHGUI_DUPLICATENODESDLG_H + +// SMESH includes +#include "SMESH_SMESHGUI.hxx" + +// Qt includes +#include + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_Group) + +class QButtonGroup; +class QGroupBox; +class QLabel; +class QLineEdit; +class QPushButton; +class QCheckBox; + +class LightApp_SelectionMgr; + +class SMESHGUI; + +/*! + \class SMESHGUI_DuplicateNodesDlg + \brief Dialog for duplication of nodes. +*/ +class SMESHGUI_EXPORT SMESHGUI_DuplicateNodesDlg : public QDialog +{ + Q_OBJECT + +public: + SMESHGUI_DuplicateNodesDlg( SMESHGUI* ); + ~SMESHGUI_DuplicateNodesDlg(); + +private: + void Init(); + + bool isValid(); + + void closeEvent( QCloseEvent* ); + void enterEvent( QEvent* ); + void keyPressEvent( QKeyEvent* ); + +private slots: + void onConstructorsClicked( int ); + + void onOk(); + void onClose(); + bool onApply(); + void onHelp(); + + void onEditCurrentArgument(); + void onSelectionChanged(); + + void onDeactivate(); + +private: + QLineEdit* myCurrentLineEdit; + + QButtonGroup* myGroupConstructors; + + QGroupBox* myGroupArguments; + QLabel* myTextLabel1; + QLabel* myTextLabel2; + QLabel* myTextLabel3; + QPushButton* mySelectButton1; + QPushButton* mySelectButton2; + QPushButton* mySelectButton3; + QLineEdit* myLineEdit1; + QLineEdit* myLineEdit2; + QLineEdit* myLineEdit3; + QCheckBox* myCheckBoxNewGroup; + + QPushButton* myButtonOk; + QPushButton* myButtonApply; + QPushButton* myButtonClose; + QPushButton* myButtonHelp; + + SMESHGUI* mySMESHGUI; + LightApp_SelectionMgr* mySelectionMgr; + + SMESH::SMESH_GroupBase_var myGroup1; + SMESH::SMESH_GroupBase_var myGroup2; + SMESH::SMESH_GroupBase_var myGroup3; + + bool myBusy; + + QString myHelpFileName; +}; + +#endif // SMESHGUI_DUPLICATENODESDLG_H diff --git a/src/SMESHGUI/SMESHGUI_EditMeshDlg.cxx b/src/SMESHGUI/SMESHGUI_EditMeshDlg.cxx deleted file mode 100644 index 64559a58a..000000000 --- a/src/SMESHGUI/SMESHGUI_EditMeshDlg.cxx +++ /dev/null @@ -1,1280 +0,0 @@ -// 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_EditMeshDlg.cxx -// Author : Open CASCADE S.A.S. -// SMESH includes -// -#include "SMESHGUI_EditMeshDlg.h" - -#include "SMESHGUI.h" -#include "SMESHGUI_Utils.h" -#include "SMESHGUI_VTKUtils.h" -#include "SMESHGUI_MeshUtils.h" -#include "SMESHGUI_SpinBox.h" - -#include -#include -#include -#include - -// SALOME GUI includes -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -// OCCT includes -#include -#include - -// IDL includes -#include -#include CORBA_SERVER_HEADER(SMESH_Group) -#include CORBA_SERVER_HEADER(SMESH_MeshEditor) - -// VTK includes -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if !defined(VTK_XVERSION) -#define VTK_XVERSION (VTK_MAJOR_VERSION<<16)+(VTK_MINOR_VERSION<<8)+(VTK_BUILD_VERSION) -#endif - -// Qt includes -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SPACING 6 -#define MARGIN 11 - -namespace SMESH -{ - class TIdPreview - { // to display in the viewer IDs of the selected elements - SVTK_ViewWindow* myViewWindow; - - vtkUnstructuredGrid* myIdGrid; - SALOME_Actor* myIdActor; - - vtkUnstructuredGrid* myPointsNumDataSet; - vtkMaskPoints* myPtsMaskPoints; - vtkSelectVisiblePoints* myPtsSelectVisiblePoints; - vtkLabeledDataMapper* myPtsLabeledDataMapper; - vtkTextProperty* aPtsTextProp; - bool myIsPointsLabeled; - vtkActor2D* myPointLabels; - - std::vector myIDs; - - public: - TIdPreview(SVTK_ViewWindow* theViewWindow): - myViewWindow(theViewWindow) - { - myIdGrid = vtkUnstructuredGrid::New(); - - // Create and display actor - vtkDataSetMapper* aMapper = vtkDataSetMapper::New(); - aMapper->SetInput( myIdGrid ); - - myIdActor = SALOME_Actor::New(); - myIdActor->SetInfinitive(true); - myIdActor->VisibilityOff(); - myIdActor->PickableOff(); - - myIdActor->SetMapper( aMapper ); - aMapper->Delete(); - - myViewWindow->AddActor(myIdActor); - - //Definition of points numbering pipeline - myPointsNumDataSet = vtkUnstructuredGrid::New(); - - myPtsMaskPoints = vtkMaskPoints::New(); - myPtsMaskPoints->SetInput(myPointsNumDataSet); - myPtsMaskPoints->SetOnRatio(1); - - myPtsSelectVisiblePoints = vtkSelectVisiblePoints::New(); - myPtsSelectVisiblePoints->SetInput(myPtsMaskPoints->GetOutput()); - myPtsSelectVisiblePoints->SelectInvisibleOff(); - myPtsSelectVisiblePoints->SetTolerance(0.1); - - myPtsLabeledDataMapper = vtkLabeledDataMapper::New(); - myPtsLabeledDataMapper->SetInput(myPtsSelectVisiblePoints->GetOutput()); -#if (VTK_XVERSION < 0x050200) - myPtsLabeledDataMapper->SetLabelFormat("%g"); -#endif - myPtsLabeledDataMapper->SetLabelModeToLabelScalars(); - - vtkTextProperty* aPtsTextProp = vtkTextProperty::New(); - aPtsTextProp->SetFontFamilyToTimes(); - static int aPointsFontSize = 12; - aPtsTextProp->SetFontSize(aPointsFontSize); - aPtsTextProp->SetBold(1); - aPtsTextProp->SetItalic(0); - aPtsTextProp->SetShadow(0); - myPtsLabeledDataMapper->SetLabelTextProperty(aPtsTextProp); - aPtsTextProp->Delete(); - - myIsPointsLabeled = false; - - myPointLabels = vtkActor2D::New(); - myPointLabels->SetMapper(myPtsLabeledDataMapper); - myPointLabels->GetProperty()->SetColor(1,1,1); - myPointLabels->SetVisibility(myIsPointsLabeled); - - AddToRender(myViewWindow->getRenderer()); - } - - void SetPointsData ( SMDS_Mesh* theMesh, - TColStd_MapOfInteger & theNodesIdMap ) - { - vtkPoints* aPoints = vtkPoints::New(); - aPoints->SetNumberOfPoints(theNodesIdMap.Extent()); - myIDs.clear(); - - TColStd_MapIteratorOfMapOfInteger idIter( theNodesIdMap ); - for( int i = 0; idIter.More(); idIter.Next(), i++ ) { - const SMDS_MeshNode* aNode = theMesh->FindNode(idIter.Key()); - aPoints->SetPoint( i, aNode->X(), aNode->Y(), aNode->Z() ); - myIDs.push_back(idIter.Key()); - } - - myIdGrid->SetPoints(aPoints); - - aPoints->Delete(); - - myIdActor->GetMapper()->Update(); - } - - void SetElemsData( TColStd_MapOfInteger & theElemsIdMap, - std::list & aGrCentersXYZ ) - { - vtkPoints* aPoints = vtkPoints::New(); - aPoints->SetNumberOfPoints(theElemsIdMap.Extent()); - myIDs.clear(); - - TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap ); - for( ; idIter.More(); idIter.Next() ) { - myIDs.push_back(idIter.Key()); - } - - gp_XYZ aXYZ; - std::list::iterator coordIt = aGrCentersXYZ.begin(); - for( int i = 0; coordIt != aGrCentersXYZ.end(); coordIt++, i++ ) { - aXYZ = *coordIt; - aPoints->SetPoint( i, aXYZ.X(), aXYZ.Y(), aXYZ.Z() ); - } - myIdGrid->SetPoints(aPoints); - aPoints->Delete(); - - myIdActor->GetMapper()->Update(); - } - - void AddToRender(vtkRenderer* theRenderer) - { - myIdActor->AddToRender(theRenderer); - - myPtsSelectVisiblePoints->SetRenderer(theRenderer); - theRenderer->AddActor2D(myPointLabels); - } - - void RemoveFromRender(vtkRenderer* theRenderer) - { - myIdActor->RemoveFromRender(theRenderer); - - myPtsSelectVisiblePoints->SetRenderer(theRenderer); - theRenderer->RemoveActor(myPointLabels); - } - - void SetPointsLabeled( bool theIsPointsLabeled, bool theIsActorVisible = true ) - { - myIsPointsLabeled = theIsPointsLabeled && myIdGrid->GetNumberOfPoints(); - - if ( myIsPointsLabeled ) { - myPointsNumDataSet->ShallowCopy(myIdGrid); - vtkDataSet *aDataSet = myPointsNumDataSet; - int aNbElem = myIDs.size(); - vtkIntArray *anArray = vtkIntArray::New(); - anArray->SetNumberOfValues( aNbElem ); - for ( int i = 0; i < aNbElem; i++ ) - anArray->SetValue( i, myIDs[i] ); - aDataSet->GetPointData()->SetScalars( anArray ); - anArray->Delete(); - myPtsMaskPoints->SetInput( aDataSet ); - myPointLabels->SetVisibility( theIsActorVisible ); - } - else { - myPointLabels->SetVisibility( false ); - } - } - - ~TIdPreview() - { - RemoveFromRender(myViewWindow->getRenderer()); - - myIdGrid->Delete(); - - myViewWindow->RemoveActor(myIdActor); - myIdActor->Delete(); - - //Deleting of points numbering pipeline - //--------------------------------------- - myPointsNumDataSet->Delete(); - - //myPtsLabeledDataMapper->RemoveAllInputs(); //vtk 5.0 porting - myPtsLabeledDataMapper->Delete(); - - //myPtsSelectVisiblePoints->UnRegisterAllOutputs(); //vtk 5.0 porting - myPtsSelectVisiblePoints->Delete(); - - //myPtsMaskPoints->UnRegisterAllOutputs(); //vtk 5.0 porting - myPtsMaskPoints->Delete(); - - myPointLabels->Delete(); - -// myTimeStamp->Delete(); - } - }; -} - -static const char * IconFirst[] = { -"18 10 2 1", -" g None", -". g #000000", -" . . ", -" .. .. .. ", -" .. ... ... ", -" .. .... .... ", -" .. ..... ..... ", -" .. ..... ..... ", -" .. .... .... ", -" .. ... ... ", -" .. .. .. ", -" . . "}; - -//================================================================================= -// class : SMESHGUI_EditMeshDlg() -// purpose : -//================================================================================= -SMESHGUI_EditMeshDlg::SMESHGUI_EditMeshDlg (SMESHGUI* theModule, - int theAction) - : QDialog(SMESH::GetDesktop(theModule)), - mySMESHGUI(theModule), - mySelectionMgr(SMESH::GetSelectionMgr(theModule)), - myAction(theAction) -{ - setModal(false); - setAttribute(Qt::WA_DeleteOnClose, true); - setWindowTitle(myAction == 1 ? tr("SMESH_MERGE_ELEMENTS") : tr("SMESH_MERGE_NODES")); - - myIdPreview = new SMESH::TIdPreview(SMESH::GetViewWindow( mySMESHGUI )); - - SUIT_ResourceMgr* aResMgr = SMESH::GetResourceMgr( mySMESHGUI ); - QPixmap IconMergeNodes (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_MERGE_NODES"))); - QPixmap IconMergeElems (aResMgr->loadPixmap("SMESH", tr("ICON_DLG_MERGE_ELEMENTS"))); - QPixmap IconSelect (aResMgr->loadPixmap("SMESH", tr("ICON_SELECT"))); - QPixmap IconAdd (aResMgr->loadPixmap("SMESH", tr("ICON_APPEND"))); - QPixmap IconRemove (aResMgr->loadPixmap("SMESH", tr("ICON_REMOVE"))); - - setSizeGripEnabled(true); - - QVBoxLayout* DlgLayout = new QVBoxLayout(this); - DlgLayout->setSpacing(SPACING); - DlgLayout->setMargin(MARGIN); - - /***************************************************************/ - GroupConstructors = new QGroupBox(myAction == 1 ? - tr("SMESH_MERGE_ELEMENTS") : - tr("SMESH_MERGE_NODES"), - this); - - QButtonGroup* ButtonGroup = new QButtonGroup(this); - QHBoxLayout* GroupConstructorsLayout = new QHBoxLayout(GroupConstructors); - GroupConstructorsLayout->setSpacing(SPACING); - GroupConstructorsLayout->setMargin(MARGIN); - - RadioButton = new QRadioButton(GroupConstructors); - RadioButton->setIcon(myAction == 1 ? IconMergeElems : IconMergeNodes); - RadioButton->setChecked(true); - GroupConstructorsLayout->addWidget(RadioButton); - ButtonGroup->addButton(RadioButton, 0); - - /***************************************************************/ - // Controls for mesh defining - GroupMesh = new QGroupBox(tr("SMESH_SELECT_WHOLE_MESH"), this); - QHBoxLayout* GroupMeshLayout = new QHBoxLayout(GroupMesh); - GroupMeshLayout->setSpacing(SPACING); - GroupMeshLayout->setMargin(MARGIN); - - TextLabelName = new QLabel(tr("SMESH_NAME"), GroupMesh); - SelectMeshButton = new QPushButton(GroupMesh); - SelectMeshButton->setIcon(IconSelect); - LineEditMesh = new QLineEdit(GroupMesh); - LineEditMesh->setReadOnly(true); - - GroupMeshLayout->addWidget(TextLabelName); - GroupMeshLayout->addWidget(SelectMeshButton); - GroupMeshLayout->addWidget(LineEditMesh); - - /***************************************************************/ - // Controls for switch dialog behaviour - - TypeBox = new QGroupBox( tr( "SMESH_MODE" ), this ); - GroupType = new QButtonGroup( this ); - QHBoxLayout* aTypeBoxLayout = new QHBoxLayout( TypeBox ); - aTypeBoxLayout->setMargin( MARGIN ); - aTypeBoxLayout->setSpacing( SPACING ); - - QRadioButton* rb1 = new QRadioButton( tr( "SMESH_AUTOMATIC" ), TypeBox ); - QRadioButton* rb2 = new QRadioButton( tr( "SMESH_MANUAL" ), TypeBox ); - GroupType->addButton( rb1, 0 ); - GroupType->addButton( rb2, 1 ); - aTypeBoxLayout->addWidget( rb1 ); - aTypeBoxLayout->addWidget( rb2 ); - - myTypeId = 0; - - /***************************************************************/ - // Controls for coincident elements detecting - GroupCoincident = new QGroupBox(myAction == 1 ? - tr("COINCIDENT_ELEMENTS") : - tr("COINCIDENT_NODES"), - this); - - QVBoxLayout* aCoincidentLayout = new QVBoxLayout(GroupCoincident); - - GroupCoincident->setLayout(aCoincidentLayout); - - QHBoxLayout* aSpinBoxLayout = new QHBoxLayout( GroupCoincident ); - - if (myAction == 0) { // case merge nodes - TextLabelTolerance = new QLabel(tr("SMESH_TOLERANCE"), GroupCoincident); - SpinBoxTolerance = new SMESHGUI_SpinBox(GroupCoincident); - SpinBoxTolerance->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); - - aSpinBoxLayout->addWidget(TextLabelTolerance); - aSpinBoxLayout->addWidget(SpinBoxTolerance); - aCoincidentLayout->addLayout(aSpinBoxLayout); - } - else { - TextLabelTolerance = 0; - SpinBoxTolerance = 0; - } - - GroupCoincidentWidget = new QWidget(GroupCoincident); - QGridLayout* GroupCoincidentLayout = new QGridLayout(GroupCoincidentWidget); - GroupCoincidentLayout->setSpacing(SPACING); - GroupCoincidentLayout->setMargin(MARGIN); - - ListCoincident = new QListWidget(GroupCoincidentWidget); - ListCoincident->setSelectionMode(QListWidget::ExtendedSelection); - - DetectButton = new QPushButton(tr("DETECT"), GroupCoincidentWidget); - AddGroupButton = new QPushButton(tr("SMESH_BUT_ADD"), GroupCoincidentWidget); - RemoveGroupButton = new QPushButton(tr("SMESH_BUT_REMOVE"), GroupCoincidentWidget); - - SelectAllCB = new QCheckBox(tr("SELECT_ALL"), GroupCoincidentWidget); - - if (myAction == 0) - GroupCoincidentWidget->hide(); - else - GroupCoincident->hide(); - - GroupCoincidentLayout->addWidget(ListCoincident, 0, 0, 4, 2); - GroupCoincidentLayout->addWidget(DetectButton, 0, 2); - GroupCoincidentLayout->addWidget(AddGroupButton, 2, 2); - GroupCoincidentLayout->addWidget(RemoveGroupButton, 3, 2); - GroupCoincidentLayout->addWidget(SelectAllCB, 4, 0, 1, 3); - GroupCoincidentLayout->setRowMinimumHeight(1, 10); - GroupCoincidentLayout->setRowStretch(1, 5); - - aCoincidentLayout->addWidget(GroupCoincidentWidget); - - /***************************************************************/ - // Controls for editing the selected group - GroupEdit = new QGroupBox(tr("EDIT_SELECTED_GROUP"), this); - QGridLayout* GroupEditLayout = new QGridLayout(GroupEdit); - GroupEditLayout->setSpacing(SPACING); - GroupEditLayout->setMargin(MARGIN); - - ListEdit = new QListWidget(GroupEdit); - //ListEdit->setRowMode(QListBox::FixedNumber); - //ListEdit->setHScrollBarMode(QScrollView::AlwaysOn); - //ListEdit->setVScrollBarMode(QScrollView::AlwaysOff); - ListEdit->setFlow( QListView::LeftToRight ); - ListEdit->setSelectionMode(QListWidget::ExtendedSelection); - - AddElemButton = new QPushButton(GroupEdit); - AddElemButton->setIcon(IconAdd); - RemoveElemButton = new QPushButton(GroupEdit); - RemoveElemButton->setIcon(IconRemove); - SetFirstButton = new QPushButton(GroupEdit); - SetFirstButton->setIcon(QPixmap(IconFirst)); - - GroupEditLayout->addWidget(ListEdit, 0, 0, 2, 1); - GroupEditLayout->addWidget(AddElemButton, 0, 1); - GroupEditLayout->addWidget(RemoveElemButton, 0, 2); - GroupEditLayout->addWidget(SetFirstButton, 1, 1, 1, 2); - - GroupEdit->hide(); - - /***************************************************************/ - 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); - - /***************************************************************/ - DlgLayout->addWidget(GroupConstructors); - DlgLayout->addWidget(GroupMesh); - DlgLayout->addWidget(TypeBox); - DlgLayout->addWidget(GroupCoincident); - DlgLayout->addWidget(GroupEdit); - DlgLayout->addWidget(GroupButtons); - - this->resize(10,10); - - Init(); // Initialisations -} - -//================================================================================= -// function : ~SMESHGUI_EditMeshDlg() -// purpose : Destroys the object and frees any allocated resources -//================================================================================= -SMESHGUI_EditMeshDlg::~SMESHGUI_EditMeshDlg() -{ - delete myIdPreview; -} - -//================================================================================= -// function : Init() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::Init() -{ - if (myAction == 0) { - SpinBoxTolerance->RangeStepAndValidator(0.0, COORD_MAX, 0.00001, "len_tol_precision"); - SpinBoxTolerance->SetValue(1e-05); - } - - RadioButton->setChecked(true); - - GroupType->button(0)->setChecked(true); - - myEditCurrentArgument = (QWidget*)LineEditMesh; - - myActor = 0; - mySubMeshOrGroup = SMESH::SMESH_subMesh::_nil(); - - mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector(); - - mySMESHGUI->SetActiveDialogBox((QDialog*)this); - myIsBusy = false; - - /* 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(SelectMeshButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument())); - connect(DetectButton, SIGNAL (clicked()), this, SLOT(onDetect())); - connect(ListCoincident, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectGroup())); - connect(AddGroupButton, SIGNAL (clicked()), this, SLOT(onAddGroup())); - connect(RemoveGroupButton, SIGNAL (clicked()), this, SLOT(onRemoveGroup())); - connect(SelectAllCB, SIGNAL(toggled(bool)), this, SLOT(onSelectAll(bool))); - connect(ListEdit, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectElementFromGroup())); - connect(AddElemButton, SIGNAL (clicked()), this, SLOT(onAddElement())); - connect(RemoveElemButton, SIGNAL (clicked()), this, SLOT(onRemoveElement())); - connect(SetFirstButton, SIGNAL( clicked() ), this, SLOT( onSetFirst() ) ); - connect(GroupType, SIGNAL(buttonClicked(int)), this, SLOT(onTypeChanged(int))); - - connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog())); - connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); - /* to close dialog if study change */ - connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel())); - - // Init Mesh field from selection - SelectionIntoArgument(); - - // Update Buttons - updateControls(); - - if (myAction == 0) - myHelpFileName = "merging_nodes_page.html"; - else - myHelpFileName = "merging_elements_page.html"; -} - -//================================================================================= -// function : FindGravityCenter() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::FindGravityCenter(TColStd_MapOfInteger & theElemsIdMap, - std::list< gp_XYZ > & theGrCentersXYZ) -{ - if (!myActor) - return; - - SMDS_Mesh* aMesh = 0; - aMesh = myActor->GetObject()->GetMesh(); - if (!aMesh) - return; - - int nbNodes; - - TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap ); - for( ; idIter.More(); idIter.Next() ) { - const SMDS_MeshElement* anElem = aMesh->FindElement(idIter.Key()); - if ( !anElem ) - continue; - - gp_XYZ anXYZ(0., 0., 0.); - SMDS_ElemIteratorPtr nodeIt = anElem->nodesIterator(); - for ( nbNodes = 0; nodeIt->more(); nbNodes++ ) { - const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - anXYZ.Add( gp_XYZ( node->X(), node->Y(), node->Z() ) ); - } - anXYZ.Divide( nbNodes ); - - theGrCentersXYZ.push_back( anXYZ ); - } -} - -//================================================================================= -// function : ClickOnApply() -// purpose : -//================================================================================= -bool SMESHGUI_EditMeshDlg::ClickOnApply() -{ - if (mySMESHGUI->isActiveStudyLocked() || myMesh->_is_nil()) - return false; - - try { - if (myTypeId == 0) - onDetect(); - - SUIT_OverrideCursor aWaitCursor; - SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); - - SMESH::long_array_var anIds = new SMESH::long_array; - SMESH::array_of_long_array_var aGroupsOfElements = new SMESH::array_of_long_array; - - if ( ListCoincident->count() == 0) { - if (myAction == 0) - SUIT_MessageBox::warning(this, - tr("SMESH_WARNING"), - tr("SMESH_NO_NODES_DETECTED")); - else - SUIT_MessageBox::warning(this, - tr("SMESH_WARNING"), - tr("SMESH_NO_ELEMENTS_DETECTED")); - return false; - } - - aGroupsOfElements->length(ListCoincident->count()); - - int anArrayNum = 0; - for (int i = 0; i < ListCoincident->count(); i++) { - QStringList aListIds = ListCoincident->item(i)->text().split(" ", QString::SkipEmptyParts); - - anIds->length(aListIds.count()); - for (int i = 0; i < aListIds.count(); i++) - anIds[i] = aListIds[i].toInt(); - - aGroupsOfElements[anArrayNum++] = anIds.inout(); - } - - if( myAction == 0 ) - aMeshEditor->MergeNodes (aGroupsOfElements.inout()); - else - aMeshEditor->MergeElements (aGroupsOfElements.inout()); - - if ( myTypeId == 0 ) { - if (myAction ==0) - SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INFORMATION"), - tr("SMESH_MERGED_NODES").arg(QString::number(ListCoincident->count()).toLatin1().data())); - else - SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INFORMATION"), - tr("SMESH_MERGED_ELEMENTS").arg(QString::number(ListCoincident->count()).toLatin1().data())); - } - - - } catch(...) { - } - - SMESH::UpdateView(); - SMESHGUI::Modified(); - - return true; -} - -//================================================================================= -// function : ClickOnOk() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::ClickOnOk() -{ - if (ClickOnApply()) - ClickOnCancel(); -} - -//================================================================================= -// function : ClickOnCancel() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::ClickOnCancel() -{ - myIdPreview->SetPointsLabeled(false); - SMESH::SetPointRepresentation(false); - disconnect(mySelectionMgr, 0, this, 0); - disconnect(mySMESHGUI, 0, this, 0); - mySMESHGUI->ResetState(); - - mySelectionMgr->clearFilters(); - //mySelectionMgr->clearSelected(); - - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(ActorSelection); - - reject(); -} - -//================================================================================= -// function : ClickOnHelp() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::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 : onEditGroup() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::onEditGroup() -{ - QList selItems = ListCoincident->selectedItems(); - if ( selItems.count() != 1 ) { - ListEdit->clear(); - return; - } - - QStringList aNewIds; - - for (int i = 0; i < ListEdit->count(); i++ ) - aNewIds.append(ListEdit->item(i)->text()); - - ListCoincident->clearSelection(); - selItems.first()->setText(aNewIds.join(" ")); - selItems.first()->setSelected(true); -} - -//================================================================================= -// function : updateControls() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::updateControls() -{ - if (ListEdit->count() == 0) - SetFirstButton->setEnabled(false); - bool enable = !(myMesh->_is_nil()) && (ListCoincident->count() || (myTypeId == 0)); - buttonOk->setEnabled(enable); - buttonApply->setEnabled(enable); -} - -//================================================================================= -// function : onDetect() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::onDetect() -{ - if ( myMesh->_is_nil() || LineEditMesh->text().isEmpty() ) - return; - - try { - SUIT_OverrideCursor aWaitCursor; - SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); - - ListCoincident->clear(); - ListEdit->clear(); - - SMESH::array_of_long_array_var aGroupsArray; - - switch (myAction) { - case 0 : - if(!mySubMeshOrGroup->_is_nil()) - aMeshEditor->FindCoincidentNodesOnPart(mySubMeshOrGroup, SpinBoxTolerance->GetValue(), aGroupsArray); - else - aMeshEditor->FindCoincidentNodes(SpinBoxTolerance->GetValue(), aGroupsArray); - break; - case 1 : - if(!mySubMeshOrGroup->_is_nil()) - aMeshEditor->FindEqualElements(mySubMeshOrGroup, aGroupsArray); - else - aMeshEditor->FindEqualElements(myMesh, aGroupsArray); - break; - } - - for (int i = 0; i < aGroupsArray->length(); i++) { - SMESH::long_array& aGroup = aGroupsArray[i]; - - QStringList anIDs; - for (int j = 0; j < aGroup.length(); j++) - anIDs.append(QString::number(aGroup[j])); - - ListCoincident->addItem(anIDs.join(" ")); - } - } catch(...) { - } - - ListCoincident->selectAll(); - updateControls(); -} - -//================================================================================= -// function : onSelectGroup() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::onSelectGroup() -{ - if (myIsBusy || !myActor) - return; - myEditCurrentArgument = (QWidget*)ListCoincident; - - ListEdit->clear(); - - TColStd_MapOfInteger anIndices; - QList selItems = ListCoincident->selectedItems(); - QListWidgetItem* anItem; - QStringList aListIds; - - ListEdit->clear(); - - foreach(anItem, selItems) { - aListIds = anItem->text().split(" ", QString::SkipEmptyParts); - for (int i = 0; i < aListIds.count(); i++) - anIndices.Add(aListIds[i].toInt()); - } - - if (selItems.count() == 1) { - ListEdit->addItems(aListIds); - ListEdit->selectAll(); - } - - mySelector->AddOrRemoveIndex(myActor->getIO(), anIndices, false); - SALOME_ListIO aList; - aList.Append(myActor->getIO()); - mySelectionMgr->setSelectedObjects(aList,false); - - if (myAction == 0) { - myIdPreview->SetPointsData(myActor->GetObject()->GetMesh(), anIndices); - myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility()); - } - else { - std::list< gp_XYZ > aGrCentersXYZ; - FindGravityCenter(anIndices, aGrCentersXYZ); - myIdPreview->SetElemsData( anIndices, aGrCentersXYZ); - myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility()); - } - - updateControls(); -} - -//================================================================================= -// function : onSelectAll() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::onSelectAll (bool isToggled) -{ - if ( isToggled ) - ListCoincident->selectAll(); - else - ListCoincident->clearSelection(); -} - -//================================================================================= -// function : onSelectElementFromGroup() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::onSelectElementFromGroup() -{ - if (myIsBusy || !myActor) - return; - - TColStd_MapOfInteger anIndices; - QList selItems = ListEdit->selectedItems(); - QListWidgetItem* anItem; - - foreach(anItem, selItems) - anIndices.Add(anItem->text().toInt()); - - SetFirstButton->setEnabled(selItems.count() == 1); - - mySelector->AddOrRemoveIndex(myActor->getIO(), anIndices, false); - SALOME_ListIO aList; - aList.Append(myActor->getIO()); - mySelectionMgr->setSelectedObjects(aList); - - if (myAction == 0) { - myIdPreview->SetPointsData(myActor->GetObject()->GetMesh(), anIndices); - myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility()); - } - else { - std::list< gp_XYZ > aGrCentersXYZ; - FindGravityCenter(anIndices, aGrCentersXYZ); - myIdPreview->SetElemsData(anIndices, aGrCentersXYZ); - myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility()); - } -} - -//================================================================================= -// function : onAddGroup() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::onAddGroup() -{ - if ( myMesh->_is_nil() || LineEditMesh->text().isEmpty() ) - return; - - QString anIDs = ""; - int aNbElements = 0; - aNbElements = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), anIDs); - - if (aNbElements < 1) - return; - - ListCoincident->clearSelection(); - ListCoincident->addItem(anIDs); - int nbGroups = ListCoincident->count(); - if (nbGroups) { - ListCoincident->setCurrentRow(nbGroups-1); - ListCoincident->item(nbGroups-1)->setSelected(true); - } - else { - // VSR ? this code seems to be never executed!!! - ListCoincident->setCurrentRow(0); - //ListCoincident->setSelected(0, true); // VSR: no items - no selection - } - - updateControls(); -} - -//================================================================================= -// function : onRemoveGroup() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::onRemoveGroup() -{ - if (myEditCurrentArgument != (QWidget*)ListCoincident) - return; - myIsBusy = true; - - QList selItems = ListCoincident->selectedItems(); - QListWidgetItem* anItem; - - foreach(anItem, selItems) - delete anItem; - - ListEdit->clear(); - updateControls(); - - myIsBusy = false; -} - -//================================================================================= -// function : onAddElement() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::onAddElement() -{ - if (!myActor) - return; - myIsBusy = true; - - QString aListStr = ""; - int aNbNnodes = 0; - - aNbNnodes = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aListStr); - if (aNbNnodes < 1) - return; - - QStringList aNodes = aListStr.split(" ", QString::SkipEmptyParts); - - for (QStringList::iterator it = aNodes.begin(); it != aNodes.end(); ++it) { - QList found = ListEdit->findItems(*it, Qt::MatchExactly); - if ( found.count() == 0 ) { - QListWidgetItem* anItem = new QListWidgetItem(*it); - ListEdit->addItem(anItem); - anItem->setSelected(true); - } - else { - QListWidgetItem* anItem; - foreach(anItem, found) anItem->setSelected(true); - } - } - - myIsBusy = false; - onEditGroup(); -} - -//================================================================================= -// function : onRemoveElement() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::onRemoveElement() -{ - if (myEditCurrentArgument != (QWidget*)ListCoincident) - return; - myIsBusy = true; - - QList selItems = ListEdit->selectedItems(); - QListWidgetItem* anItem; - - foreach(anItem, selItems) - delete anItem; - - myIsBusy = false; - onEditGroup(); -} - -//================================================================================= -// function : onSetFirst() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::onSetFirst() -{ - if (myEditCurrentArgument != (QWidget*)ListCoincident) - return; - myIsBusy = true; - - QList selItems = ListEdit->selectedItems(); - QListWidgetItem* anItem; - - foreach(anItem, selItems) { - ListEdit->takeItem(ListEdit->row(anItem)); - ListEdit->insertItem(0, anItem); - } - - myIsBusy = false; - onEditGroup(); -} - -//================================================================================= -// function : SetEditCurrentArgument() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::SetEditCurrentArgument() -{ - QPushButton* send = (QPushButton*)sender(); - - disconnect(mySelectionMgr, 0, this, 0); - mySelectionMgr->clearSelected(); - mySelectionMgr->clearFilters(); - - if (send == SelectMeshButton) { - myEditCurrentArgument = (QWidget*)LineEditMesh; - SMESH::SetPointRepresentation(false); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(ActorSelection); - if (myTypeId == 1) - mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter); - } - - myEditCurrentArgument->setFocus(); - connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); - SelectionIntoArgument(); -} - -//================================================================================= -// function : SelectionIntoArgument() -// purpose : Called when selection as changed or other case -//================================================================================= -void SMESHGUI_EditMeshDlg::SelectionIntoArgument() -{ - if (myEditCurrentArgument == (QWidget*)LineEditMesh) { - QString aString = ""; - LineEditMesh->setText(aString); - - ListCoincident->clear(); - ListEdit->clear(); - myActor = 0; - - int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString); - if (nbSel != 1) { - myIdPreview->SetPointsLabeled(false); - SMESH::SetPointRepresentation(false); - mySelectionMgr->clearFilters(); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(ActorSelection); - return; - } - - SALOME_ListIO aList; - mySelectionMgr->selectedObjects(aList); - - Handle(SALOME_InteractiveObject) IO = aList.First(); - myMesh = SMESH::GetMeshByIO(IO); - - if (myMesh->_is_nil()) - return; - - LineEditMesh->setText(aString); - - myActor = SMESH::FindActorByEntry(IO->getEntry()); - if (!myActor) - myActor = SMESH::FindActorByObject(myMesh); - - if ( myActor && myTypeId ==1 ) { - mySubMeshOrGroup = SMESH::SMESH_IDSource::_nil(); - mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter); - - if ((!SMESH::IObjectToInterface(IO)->_is_nil() || //SUBMESH OR GROUP - !SMESH::IObjectToInterface(IO)->_is_nil()) && - !SMESH::IObjectToInterface(IO)->_is_nil()) - mySubMeshOrGroup = SMESH::IObjectToInterface(IO); - - if (myAction == 0) { - SMESH::SetPointRepresentation(true); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(NodeSelection); - } - else - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(CellSelection); - } - - updateControls(); - } -} - -//================================================================================= -// function : DeactivateActiveDialog() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::DeactivateActiveDialog() -{ - if (GroupConstructors->isEnabled()) { - GroupConstructors->setEnabled(false); - TypeBox->setEnabled(false); - GroupMesh->setEnabled(false); - GroupCoincident->setEnabled(false); - GroupEdit->setEnabled(false); - GroupButtons->setEnabled(false); - mySMESHGUI->ResetState(); - mySMESHGUI->SetActiveDialogBox(0); - } - - mySelectionMgr->clearSelected(); - disconnect(mySelectionMgr, 0, this, 0); -} - -//================================================================================= -// function : ActivateThisDialog() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::ActivateThisDialog() -{ - /* Emit a signal to deactivate the active dialog */ - mySMESHGUI->EmitSignalDeactivateDialog(); - GroupConstructors->setEnabled(true); - TypeBox->setEnabled(true); - GroupMesh->setEnabled(true); - GroupCoincident->setEnabled(true); - GroupEdit->setEnabled(true); - GroupButtons->setEnabled(true); - - connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); - mySMESHGUI->SetActiveDialogBox((QDialog*)this); - SelectionIntoArgument(); -} - -//================================================================================= -// function : enterEvent() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::enterEvent(QEvent*) -{ - if (!GroupConstructors->isEnabled()) - ActivateThisDialog(); -} - -//================================================================================= -// function : closeEvent() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::closeEvent(QCloseEvent*) -{ - /* same than click on cancel button */ - ClickOnCancel(); -} - -//======================================================================= -//function : hideEvent -//purpose : caused by ESC key -//======================================================================= -void SMESHGUI_EditMeshDlg::hideEvent (QHideEvent *) -{ - if (!isMinimized()) - ClickOnCancel(); -} - -//================================================================================= -// function : keyPressEvent() -// purpose : -//================================================================================= -void SMESHGUI_EditMeshDlg::keyPressEvent( QKeyEvent* e) -{ - QDialog::keyPressEvent( e ); - if ( e->isAccepted() ) - return; - - if ( e->key() == Qt::Key_F1 ) { - e->accept(); - ClickOnHelp(); - } -} - -//================================================================================= -// function : onTypeChanged() -// purpose : the type radio button management -//================================================================================= -void SMESHGUI_EditMeshDlg::onTypeChanged (int id) -{ - if (myTypeId == id) - return; - - myTypeId = id; - switch (id) { - case 0: - myIdPreview->SetPointsLabeled(false); - SMESH::SetPointRepresentation(false); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(ActorSelection); - mySelectionMgr->clearFilters(); - if (myAction == 0) - GroupCoincidentWidget->hide(); - else - GroupCoincident->hide(); - GroupEdit->hide(); - break; - case 1: - SMESH::UpdateView(); - - // Costruction of the logical filter - SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH); - SMESH_TypeFilter* aSmeshGroupFilter = new SMESH_TypeFilter (GROUP); - - QList aListOfFilters; - if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter); - if (aSmeshGroupFilter) aListOfFilters.append(aSmeshGroupFilter); - - myMeshOrSubMeshOrGroupFilter = - new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR); - - if (myAction == 0) { - GroupCoincidentWidget->show(); - SMESH::SetPointRepresentation(true); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(NodeSelection); - } - else { - GroupCoincident->show(); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(CellSelection); - } - GroupEdit->show(); - break; - } - updateControls(); - - qApp->processEvents(); - updateGeometry(); - resize(10,10); - - SelectionIntoArgument(); -} diff --git a/src/SMESHGUI/SMESHGUI_EditMeshDlg.h b/src/SMESHGUI/SMESHGUI_EditMeshDlg.h deleted file mode 100644 index 4ff701452..000000000 --- a/src/SMESHGUI/SMESHGUI_EditMeshDlg.h +++ /dev/null @@ -1,167 +0,0 @@ -// 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_EditMeshDlg.h -// Author : Open CASCADE S.A.S. -// -#ifndef SMESHGUI_EDITMESHDLG_H -#define SMESHGUI_EDITMESHDLG_H - -// SMESH includes -#include "SMESH_SMESHGUI.hxx" - -// Qt includes -#include - -// OCCT includes -#include - -// STL includes -#include - -// IDL includes -#include -#include CORBA_SERVER_HEADER(SMESH_Mesh) - -class QGroupBox; -class QLabel; -class QLineEdit; -class QPushButton; -class QRadioButton; -class QCheckBox; -class QListWidget; -class QButtonGroup; -class SMESHGUI; -class SMESHGUI_SpinBox; -class SMESH_Actor; -class SVTK_Selector; -class LightApp_SelectionMgr; -class SUIT_SelectionFilter; -class TColStd_MapOfInteger; - -namespace SMESH -{ - struct TIdPreview; -} - -//================================================================================= -// class : SMESHGUI_EditMeshDlg -// purpose : -//================================================================================= -class SMESHGUI_EXPORT SMESHGUI_EditMeshDlg : public QDialog -{ - Q_OBJECT; - -public: - SMESHGUI_EditMeshDlg( SMESHGUI*, int ); - ~SMESHGUI_EditMeshDlg(); - -private: - void Init(); - void closeEvent( QCloseEvent* ); - void enterEvent( QEvent* ); /* mouse enter the QWidget */ - void hideEvent( QHideEvent* ); /* ESC key */ - void keyPressEvent( QKeyEvent* ); - void onEditGroup(); - - void FindGravityCenter( TColStd_MapOfInteger&, - std::list& ); - // add the centers of gravity of ElemsIdMap elements to the GrCentersXYZ list - -private: - SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ - LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ - SVTK_Selector* mySelector; - - QWidget* myEditCurrentArgument; - - SMESH::SMESH_Mesh_var myMesh; - SMESH::SMESH_IDSource_var mySubMeshOrGroup; - SMESH_Actor* myActor; - SUIT_SelectionFilter* myMeshOrSubMeshOrGroupFilter; - - SMESH::TIdPreview* myIdPreview; - - int myAction; - bool myIsBusy; - int myTypeId; - - // Widgets - QGroupBox* GroupConstructors; - QRadioButton* RadioButton; - - QGroupBox* GroupButtons; - QPushButton* buttonOk; - QPushButton* buttonCancel; - QPushButton* buttonApply; - QPushButton* buttonHelp; - - QGroupBox* GroupMesh; - QLabel* TextLabelName; - QPushButton* SelectMeshButton; - QLineEdit* LineEditMesh; - - QGroupBox* GroupCoincident; - QWidget* GroupCoincidentWidget; - QLabel* TextLabelTolerance; - SMESHGUI_SpinBox* SpinBoxTolerance; - QPushButton* DetectButton; - QListWidget* ListCoincident; - QPushButton* AddGroupButton; - QPushButton* RemoveGroupButton; - QCheckBox* SelectAllCB; - - QGroupBox* GroupEdit; - QListWidget* ListEdit; - QPushButton* AddElemButton; - QPushButton* RemoveElemButton; - QPushButton* SetFirstButton; - - QGroupBox* TypeBox; - QButtonGroup* GroupType; - - QString myHelpFileName; - - private slots: - void ClickOnOk(); - void ClickOnCancel(); - bool ClickOnApply(); - void ClickOnHelp(); - void updateControls(); - void onDetect(); - void onAddGroup(); - void onRemoveGroup(); - void onSelectGroup(); - void onSelectAll( bool ); - void onSelectElementFromGroup(); - void onAddElement(); - void onRemoveElement(); - void onSetFirst(); - void SetEditCurrentArgument(); - void SelectionIntoArgument(); - void DeactivateActiveDialog(); - void ActivateThisDialog(); - void onTypeChanged(int); -}; - -#endif // SMESHGUI_EDITMESHDLG_H diff --git a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx index f9b4af034..ee88f7662 100755 --- a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx @@ -33,6 +33,7 @@ #include "SMESHGUI_Filter.h" #include "SMESHGUI_FilterUtils.h" #include "SMESHGUI_FilterLibraryDlg.h" +#include "SMESHGUI_SpinBox.h" #include #include @@ -160,30 +161,32 @@ public: virtual void SetString(const int, const QString&); void SetEditable(const int, const bool); void SetEditable(const bool); + void SetPrecision(const int, const char* = 0); private: - QMap< int, QLineEdit* > myLineEdits; + QMap< int, QWidget* > myWidgets; }; SMESHGUI_FilterTable::AdditionalWidget::AdditionalWidget (QWidget* theParent) : QWidget(theParent) { QLabel* aLabel = new QLabel(tr("SMESH_TOLERANCE"), this); - myLineEdits[ Tolerance ] = new QLineEdit(this); - QDoubleValidator* aValidator = new QDoubleValidator(myLineEdits[ Tolerance ]); - aValidator->setBottom(0); - myLineEdits[ Tolerance ]->setValidator(aValidator); + + SMESHGUI_SpinBox* sb = new SMESHGUI_SpinBox(this); + sb->setAcceptNames( false ); // No Notebook variables allowed + sb->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); + sb->RangeStepAndValidator( 0., 1.e20, 0.1, "len_tol_precision" ); + myWidgets[ Tolerance ] = sb; QHBoxLayout* aLay = new QHBoxLayout(this); aLay->setSpacing(SPACING); aLay->setMargin(0); aLay->addWidget(aLabel); - aLay->addWidget(myLineEdits[ Tolerance ]); + aLay->addWidget(myWidgets[ Tolerance ]); aLay->addStretch(); - QString aText = QString("%1").arg(Precision::Confusion()); - myLineEdits[ Tolerance ]->setText(aText); + SetDouble( Tolerance, Precision::Confusion() ); } SMESHGUI_FilterTable::AdditionalWidget::~AdditionalWidget() @@ -205,13 +208,18 @@ bool SMESHGUI_FilterTable::AdditionalWidget::IsValid (const bool theMsg) const QList aParams = GetParameters(); QList::const_iterator anIter; for (anIter = aParams.begin(); anIter != aParams.end(); ++anIter) { - const QLineEdit* aWg = myLineEdits[ *anIter ]; - int p = 0; - QString aText = aWg->text(); - if (aWg->isEnabled() && aWg->validator()->validate(aText, p) != QValidator::Acceptable) { - if (theMsg) - SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), - tr("SMESHGUI_INVALID_PARAMETERS")); + if ( !myWidgets.contains( *anIter ) ) continue; + bool valid = true; + if ( qobject_cast( myWidgets[ *anIter ] ) ) { + valid = qobject_cast( myWidgets[ *anIter ] )->hasAcceptableInput(); + } + else if ( qobject_cast( myWidgets[ *anIter ] ) ) { + QString foo; + valid = qobject_cast( myWidgets[ *anIter ] )->isValid( foo, false ); + } + if (!valid && theMsg) { + SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), + tr("SMESHGUI_INVALID_PARAMETERS")); return false; } } @@ -221,41 +229,78 @@ bool SMESHGUI_FilterTable::AdditionalWidget::IsValid (const bool theMsg) const double SMESHGUI_FilterTable::AdditionalWidget::GetDouble (const int theId) const { - return myLineEdits.contains(theId) ? myLineEdits[ theId ]->text().toDouble() : 0; + double retval = 0; + if ( myWidgets.contains( theId ) ) { + if ( qobject_cast( myWidgets[ theId ] ) ) + retval = qobject_cast( myWidgets[ theId ] )->text().toDouble(); + if ( qobject_cast( myWidgets[ theId ] ) ) + retval = qobject_cast( myWidgets[ theId ] )->GetValue(); + } + return retval; } int SMESHGUI_FilterTable::AdditionalWidget::GetInteger (const int theId) const { - return myLineEdits.contains(theId) ? myLineEdits[ theId ]->text().toInt() : 0; + int retval = 0; + if ( myWidgets.contains( theId ) ) { + if ( qobject_cast( myWidgets[ theId ] ) ) + retval = qobject_cast( myWidgets[ theId ] )->text().toInt(); + if ( qobject_cast( myWidgets[ theId ] ) ) + retval = (int)( qobject_cast( myWidgets[ theId ] )->GetValue() ); + } + return retval; } QString SMESHGUI_FilterTable::AdditionalWidget::GetString (const int theId) const { - return myLineEdits.contains(theId) ? myLineEdits[ theId ]->text() : QString(""); + QString retval = ""; + if ( myWidgets.contains( theId ) ) { + if ( qobject_cast( myWidgets[ theId ] ) ) + retval = qobject_cast( myWidgets[ theId ] )->text(); + if ( qobject_cast( myWidgets[ theId ] ) ) + retval = QString::number( qobject_cast( myWidgets[ theId ] )->GetValue() ); + } + return retval; } void SMESHGUI_FilterTable::AdditionalWidget::SetDouble (const int theId, const double theVal) { - if (myLineEdits.contains(theId)) - myLineEdits[ theId ]->setText(QString("%1").arg(theVal)); + if ( myWidgets.contains( theId ) ) { + if ( qobject_cast( myWidgets[ theId ] ) ) + qobject_cast( myWidgets[ theId ] )->setText( QString::number( theVal ) ); + if ( qobject_cast( myWidgets[ theId ] ) ) + qobject_cast( myWidgets[ theId ] )->SetValue( theVal ); + } } void SMESHGUI_FilterTable::AdditionalWidget::SetInteger (const int theId, const int theVal) { - if (myLineEdits.contains(theId)) - myLineEdits[ theId ]->setText(QString("%1").arg(theVal)); + if ( myWidgets.contains( theId ) ) { + if ( qobject_cast( myWidgets[ theId ] ) ) + qobject_cast( myWidgets[ theId ] )->setText( QString::number( theVal ) ); + if ( qobject_cast( myWidgets[ theId ] ) ) + qobject_cast( myWidgets[ theId ] )->SetValue( (double)theVal ); + } } void SMESHGUI_FilterTable::AdditionalWidget::SetString (const int theId, const QString& theVal) { - if (myLineEdits.contains(theId)) - myLineEdits[ theId ]->setText(theVal); + if ( myWidgets.contains( theId ) ) { + if ( qobject_cast( myWidgets[ theId ] ) ) + qobject_cast( myWidgets[ theId ] )->setText( theVal ); + if ( qobject_cast( myWidgets[ theId ] ) ) + qobject_cast( myWidgets[ theId ] )->SetValue( theVal.toDouble() ); + } } void SMESHGUI_FilterTable::AdditionalWidget::SetEditable (const int theId, const bool isEditable) { - if (myLineEdits.contains(theId)) - myLineEdits[ theId ]->setReadOnly(!isEditable); + if ( myWidgets.contains( theId ) ) { + if ( qobject_cast( myWidgets[ theId ] ) ) + qobject_cast( myWidgets[ theId ] )->setReadOnly( !isEditable ); + if ( qobject_cast( myWidgets[ theId ] ) ) + qobject_cast( myWidgets[ theId ] )->setReadOnly( !isEditable ); + } } void SMESHGUI_FilterTable::AdditionalWidget::SetEditable (const bool isEditable) @@ -266,6 +311,19 @@ void SMESHGUI_FilterTable::AdditionalWidget::SetEditable (const bool isEditable) SetEditable( *anIter, isEditable ); } +void SMESHGUI_FilterTable::AdditionalWidget::SetPrecision(const int theId, const char* precision) +{ + if ( myWidgets.contains( theId ) ) { + if ( qobject_cast( myWidgets[ theId ] ) ) { + SMESHGUI_SpinBox* sb = qobject_cast( myWidgets[ theId ] ); + double val = sb->GetValue(); + double min = pow(10.0, -(sb->decimals())); + sb->RangeStepAndValidator( 0., 1.e20, 0.1, precision ? precision : "len_tol_precision" ); + sb->SetValue( qMax( val, min ) ); + } + } +} + /* Class : SMESHGUI_FilterTable::ComboItem Description : Combo table item. Identificator corresponding to string may be assigned @@ -910,13 +968,16 @@ bool SMESHGUI_FilterTable::IsValid (const bool theMess, const int theEntityType) QtxColorButton* clrBtn = qobject_cast(aTable->cellWidget(i, 2)); if (clrBtn && !clrBtn->color().isValid()) errMsg = tr( "GROUPCOLOR_ERROR" ); - } else if (aCriterion == SMESH::FT_RangeOfIds || - aCriterion == SMESH::FT_BelongToGeom || - aCriterion == SMESH::FT_BelongToPlane || - aCriterion == SMESH::FT_BelongToCylinder || - aCriterion == SMESH::FT_BelongToGenSurface || - aCriterion == SMESH::FT_ElemGeomType || - aCriterion == SMESH::FT_LyingOnGeom) { + } + else if (aCriterion == SMESH::FT_RangeOfIds || + aCriterion == SMESH::FT_BelongToGeom || + aCriterion == SMESH::FT_BelongToPlane || + aCriterion == SMESH::FT_BelongToCylinder || + aCriterion == SMESH::FT_BelongToGenSurface || + aCriterion == SMESH::FT_ElemGeomType || + aCriterion == SMESH::FT_CoplanarFaces || + aCriterion == SMESH::FT_LyingOnGeom) + { if (aTable->text(i, 2).isEmpty()) errMsg = tr( "ERROR" ); } @@ -930,8 +991,8 @@ bool SMESHGUI_FilterTable::IsValid (const bool theMess, const int theEntityType) if (!aRes && aTable->isEditable(i, 2)) errMsg = tr( "ERROR" ); else if (aType == SMESH::EDGE && - GetCriterionType(i, aType) == SMESH::FT_MultiConnection && - aThreshold == 1) + GetCriterionType(i, aType) == SMESH::FT_MultiConnection && + aThreshold == 1) errMsg = tr( "MULTIEDGES_ERROR" ); } @@ -1030,12 +1091,14 @@ void SMESHGUI_FilterTable::GetCriterion (const int theRow, } else if ( aCriterionType == SMESH::FT_ElemGeomType ) theCriterion.Threshold = (double)((ComboItem*)aTable->item(theRow, 2))->value(); + else if ( aCriterionType == SMESH::FT_CoplanarFaces ) + theCriterion.ThresholdID = aTable->text(theRow, 2).toLatin1().constData(); else if ( aCriterionType != SMESH::FT_RangeOfIds && aCriterionType != SMESH::FT_BelongToGeom && aCriterionType != SMESH::FT_BelongToPlane && aCriterionType != SMESH::FT_BelongToCylinder && aCriterionType != SMESH::FT_BelongToGenSurface && - aCriterionType != SMESH::FT_LyingOnGeom) + aCriterionType != SMESH::FT_LyingOnGeom ) { theCriterion.Compare = ((ComboItem*)aTable->item(theRow, 1))->value(); theCriterion.Threshold = aTable->item(theRow, 2)->text().toDouble(); @@ -1101,19 +1164,26 @@ void SMESHGUI_FilterTable::SetCriterion (const int theRow, ComboItem* typeBox = (ComboItem*)aTable->item(theRow, 2); typeBox->setValue( (int)(theCriterion.Threshold + 0.5) ); } + else if (theCriterion.Type == SMESH::FT_CoplanarFaces ) + { + 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_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_LinearOrQuadratic) + { aTable->item( theRow, 2 )->setText(QString("%1").arg(theCriterion.Threshold, 0, 'g', 15)); + } else { aTable->item( theRow, 2 )->setText(QString(theCriterion.ThresholdStr)); @@ -1121,24 +1191,25 @@ void SMESHGUI_FilterTable::SetCriterion (const int theRow, aTable->item( theRow, 5 )->setText( QString( theCriterion.ThresholdID ) ); } - if (theCriterion.Compare == SMESH::FT_EqualTo || - theCriterion.Type == SMESH::FT_BelongToPlane || - theCriterion.Type == SMESH::FT_BelongToCylinder || - theCriterion.Type == SMESH::FT_BelongToGenSurface || - theCriterion.Type == SMESH::FT_BelongToGeom || - theCriterion.Type == SMESH::FT_LyingOnGeom) + if (theCriterion.Compare == SMESH::FT_EqualTo || + theCriterion.Type == SMESH::FT_BelongToPlane || + theCriterion.Type == SMESH::FT_BelongToCylinder || + theCriterion.Type == SMESH::FT_BelongToGenSurface || + theCriterion.Type == SMESH::FT_BelongToGeom || + theCriterion.Type == SMESH::FT_LyingOnGeom || + theCriterion.Type == SMESH::FT_CoplanarFaces) { QTableWidgetItem* anItem = aTable->item(theRow, 0); if (!myAddWidgets.contains(anItem)) { myAddWidgets[ anItem ] = new AdditionalWidget(myWgStack); + myAddWidgets[ anItem ]->SetPrecision( AdditionalWidget::Tolerance, getPrecision( theCriterion.Type ) ); myWgStack->addWidget(myAddWidgets[ anItem ]); } myAddWidgets[ anItem ]->SetDouble(AdditionalWidget::Tolerance, theCriterion.Tolerance); } emit CriterionChanged(theRow, aType); - } //======================================================================= @@ -1266,11 +1337,13 @@ void SMESHGUI_FilterTable::updateAdditionalWidget() ComboItem* anItem = ((ComboItem*)aTable->item(aRow, 0)); int aCriterion = GetCriterionType(aRow); - bool toEnable = ((ComboItem*)aTable->item(aRow, 1))->value() == SMESH::FT_EqualTo && - aCriterion != SMESH::FT_RangeOfIds && - aCriterion != SMESH::FT_FreeEdges && - aCriterion != SMESH::FT_FreeFaces && - aCriterion != SMESH::FT_BadOrientedVolume; + bool toEnable = ((((ComboItem*)aTable->item(aRow, 1))->value() == SMESH::FT_EqualTo && + aCriterion != SMESH::FT_RangeOfIds && + aCriterion != SMESH::FT_FreeEdges && + aCriterion != SMESH::FT_FreeFaces && + aCriterion != SMESH::FT_BadOrientedVolume) + || + aCriterion == SMESH::FT_CoplanarFaces); if (!myAddWidgets.contains(anItem)) { @@ -1279,9 +1352,44 @@ void SMESHGUI_FilterTable::updateAdditionalWidget() } myWgStack->setCurrentWidget(myAddWidgets[ anItem ]); + myAddWidgets[ anItem ]->SetPrecision( AdditionalWidget::Tolerance, getPrecision( aCriterion ) ); myWgStack->setEnabled(toEnable); } +const char* SMESHGUI_FilterTable::getPrecision( const int aType ) +{ + const char* retval = 0; + switch ( aType ) { + case SMESH::FT_AspectRatio: + case SMESH::FT_AspectRatio3D: + case SMESH::FT_Taper: + retval = "parametric_precision"; break; + case SMESH::FT_Warping: + case SMESH::FT_MinimumAngle: + case SMESH::FT_Skew: + case SMESH::FT_CoplanarFaces: + retval = "angle_precision"; break; + case SMESH::FT_Area: + retval = "area_precision"; break; + case SMESH::FT_BelongToGeom: + case SMESH::FT_BelongToPlane: + case SMESH::FT_BelongToCylinder: + case SMESH::FT_BelongToGenSurface: + case SMESH::FT_LyingOnGeom: + retval = "len_tol_precision"; break; + case SMESH::FT_Length: + case SMESH::FT_Length2D: + case SMESH::FT_MaxElementLength2D: + case SMESH::FT_MaxElementLength3D: + retval = "length_precision"; break; + case SMESH::FT_Volume3D: + retval = "vol_precision"; break; + default: + break; + } + return retval; +} + //======================================================================= // name : SMESHGUI_FilterTable::removeAdditionalWidget // Purpose : Remove widgets containing additional parameters from widget @@ -1376,7 +1484,7 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con bool isComboItem = false; if (aTableItem) { int aTableType = aTable->item(row, 2)->type(); - isComboItem = aTableType == aComboType ? true : false; + isComboItem = ( aTableType == aComboType ); } if ( (aCriterionType != SMESH::FT_GroupColor && clrBtn) || @@ -1410,14 +1518,16 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con aTable->blockSignals( isSignalsBlocked ); } - if (aType == SMESH::NODE && aCriterionType == SMESH::FT_FreeNodes || - aType == SMESH::EDGE && aCriterionType == SMESH::FT_FreeBorders || - aType == SMESH::FACE && (aCriterionType == SMESH::FT_FreeEdges || - aCriterionType == SMESH::FT_FreeFaces) || - aType == SMESH::VOLUME && aCriterionType == SMESH::FT_BadOrientedVolume || + if ((aType == SMESH::NODE && aCriterionType == SMESH::FT_FreeNodes ) || + (aType == SMESH::EDGE && aCriterionType == SMESH::FT_FreeBorders ) || + (aType == SMESH::FACE && (aCriterionType == SMESH::FT_FreeEdges || + aCriterionType == SMESH::FT_FreeFaces)) || + (aType == SMESH::VOLUME && aCriterionType == SMESH::FT_BadOrientedVolume) || aCriterionType == SMESH::FT_LinearOrQuadratic || aCriterionType == SMESH::FT_GroupColor || - aCriterionType == SMESH::FT_ElemGeomType) + aCriterionType == SMESH::FT_ElemGeomType || + aCriterionType == SMESH::FT_CoplanarFaces + ) { bool isSignalsBlocked = aTable->signalsBlocked(); aTable->blockSignals( true ); @@ -1426,7 +1536,8 @@ void SMESHGUI_FilterTable::onCriterionChanged (const int row, const int col, con aCompareItem->clear(); aTable->setEditable(false, row, 1); aTable->setEditable(aCriterionType == SMESH::FT_GroupColor || - aCriterionType == SMESH::FT_ElemGeomType, row, 2); + aCriterionType == SMESH::FT_ElemGeomType || + aCriterionType == SMESH::FT_CoplanarFaces, row, 2); aTable->blockSignals( isSignalsBlocked ); } else if (aCriterionType == SMESH::FT_RangeOfIds || @@ -1686,6 +1797,7 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType) aCriteria[ SMESH::FT_Taper ] = tr("TAPER"); aCriteria[ SMESH::FT_Skew ] = tr("SKEW"); aCriteria[ SMESH::FT_Area ] = tr("AREA"); + aCriteria[ SMESH::FT_MaxElementLength2D ] = tr("MAX_ELEMENT_LENGTH_2D"); aCriteria[ SMESH::FT_FreeEdges ] = tr("FREE_EDGES"); aCriteria[ SMESH::FT_RangeOfIds ] = tr("RANGE_OF_IDS"); aCriteria[ SMESH::FT_BelongToGeom ] = tr("BELONG_TO_GEOM"); @@ -1699,6 +1811,7 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType) aCriteria[ SMESH::FT_LinearOrQuadratic ] = tr("LINEAR"); aCriteria[ SMESH::FT_GroupColor ] = tr("GROUP_COLOR"); aCriteria[ SMESH::FT_ElemGeomType ] = tr("GEOM_TYPE"); + aCriteria[ SMESH::FT_CoplanarFaces ] = tr("COPLANAR_FACES"); } return aCriteria; } @@ -1707,14 +1820,15 @@ const QMap& SMESHGUI_FilterTable::getCriteria (const int theType) static QMap 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_LinearOrQuadratic ] = tr("LINEAR"); - aCriteria[ SMESH::FT_GroupColor ] = tr("GROUP_COLOR"); + 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"); } return aCriteria; @@ -2026,8 +2140,8 @@ bool SMESHGUI_FilterTable::GetThreshold (const int theRow, // Purpose : Set text and internal value in cell of ID value //======================================================================= void SMESHGUI_FilterTable::SetID( const int theRow, - const QString& theText, - const int theEntityType ) + const QString& theText, + const int theEntityType ) { Table* aTable = myTables[ theEntityType == -1 ? GetType() : theEntityType ]; aTable->item( theRow, 5 )->setText( theText ); @@ -2548,7 +2662,8 @@ bool SMESHGUI_FilterDlg::isValid() const aType == SMESH::FT_BelongToPlane || aType == SMESH::FT_BelongToCylinder || aType == SMESH::FT_BelongToGenSurface || - aType == SMESH::FT_LyingOnGeom) { + aType == SMESH::FT_LyingOnGeom) + { QString aName; myTable->GetThreshold(i, aName); @@ -2597,6 +2712,29 @@ bool SMESHGUI_FilterDlg::isValid() const } } } + else if (aType == SMESH::FT_CoplanarFaces) + { + QString faceID; + myTable->GetThreshold(i, faceID); + if ( faceID.isEmpty() ) + { + SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), + tr("FACE_ID_NOT_SELECTED")); + return false; + } + if ( myMesh->_is_nil() ) + { + SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), + tr("MESH_IS_NOT_SELECTED")); + return false; + } + if ( myMesh->GetElementType( faceID.toLong(), /*iselem=*/true) != SMESH::FACE ) + { + SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INSUFFICIENT_DATA"), + tr("NOT_FACE_ID").arg(faceID)); + return false; + } + } } return true; @@ -2615,7 +2753,7 @@ void SMESHGUI_FilterDlg::SetSourceWg (QWidget* theWg, } //======================================================================= -// name : SMESHGUI_FilterDlg::SetGroupIds +// name : SMESHGUI_FilterDlg::SetMesh // Purpose : Set mesh //======================================================================= void SMESHGUI_FilterDlg::SetMesh (SMESH::SMESH_Mesh_var theMesh) @@ -2976,20 +3114,31 @@ void SMESHGUI_FilterDlg::onSelectionDone() QList types; types << SMESH::FT_BelongToGeom << SMESH::FT_BelongToPlane - << SMESH::FT_BelongToCylinder << SMESH::FT_BelongToGenSurface - << SMESH::FT_LyingOnGeom; + << SMESH::FT_BelongToCylinder << SMESH::FT_BelongToGenSurface + << SMESH::FT_LyingOnGeom << SMESH::FT_CoplanarFaces; if (aList.Extent() != 1 || !myTable->CurrentCell(aRow, aCol) || !types.contains(myTable->GetCriterionType(aRow))) return; - Handle(SALOME_InteractiveObject) anIO = aList.First(); - GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface(anIO); - if (!anObj->_is_nil()) + if ( myTable->GetCriterionType(aRow) == SMESH::FT_CoplanarFaces ) + { + QString aString; + int nbElems = SMESH::GetNameOfSelectedElements(mySelector,//myViewWindow->GetSelector(), + aList.First(), aString); + if (nbElems == 1) + myTable->SetThreshold(aRow, aString); + } + else + { + Handle(SALOME_InteractiveObject) anIO = aList.First(); + GEOM::GEOM_Object_var anObj = SMESH::IObjectToInterface(anIO); + if (!anObj->_is_nil()) { myTable->SetThreshold(aRow, GEOMBase::GetName(anObj)); //myTable->SetID( aRow, GEOMBase::GetIORFromObject(anObj)); myTable->SetID(aRow, anIO->getEntry()); } + } } @@ -3020,9 +3169,9 @@ void SMESHGUI_FilterDlg::updateSelection() if (mySelectionMgr == 0) return; - TColStd_MapOfInteger allTypes; - for( int i=0; i<10; i++ ) - allTypes.Add( i ); +// TColStd_MapOfInteger allTypes; +// for( int i=0; i<10; i++ ) +// allTypes.Add( i ); SalomeApp_Study* aStudy = dynamic_cast( mySMESHGUI->application()->activeStudy() ); if( !aStudy ) return; @@ -3038,8 +3187,8 @@ void SMESHGUI_FilterDlg::updateSelection() aCriterionType == SMESH::FT_BelongToPlane || aCriterionType == SMESH::FT_BelongToCylinder || aCriterionType == SMESH::FT_BelongToGenSurface || - aCriterionType == SMESH::FT_LyingOnGeom)) { - + aCriterionType == SMESH::FT_LyingOnGeom)) + { if (aCriterionType == SMESH::FT_BelongToGeom || aCriterionType == SMESH::FT_BelongToGenSurface || aCriterionType == SMESH::FT_LyingOnGeom) { @@ -3054,9 +3203,12 @@ void SMESHGUI_FilterDlg::updateSelection() } myIsSelectionChanged = true; - } else { + } + else + { if (myIsSelectionChanged) { - mySelectionMgr->installFilter( new GEOM_TypeFilter( aStudy, -1 ) ); // This filter deactivates selection + // mySelectionMgr->installFilter( new GEOM_TypeFilter( aStudy, -1 ) ); // This filter deactivates selection + // Impossible to select any object in the OB on the second opening of FilterDlg } } } diff --git a/src/SMESHGUI/SMESHGUI_FilterDlg.h b/src/SMESHGUI/SMESHGUI_FilterDlg.h index f94a0ed3e..17f0622fa 100755 --- a/src/SMESHGUI/SMESHGUI_FilterDlg.h +++ b/src/SMESHGUI/SMESHGUI_FilterDlg.h @@ -168,6 +168,7 @@ private: void updateBtnState(); void removeAdditionalWidget( QTableWidget*, const int ); void updateAdditionalWidget(); + const char* getPrecision( const int ); const QMap& getSupportedTypes() const; diff --git a/src/SMESHGUI/SMESHGUI_FindElemByPointDlg.cxx b/src/SMESHGUI/SMESHGUI_FindElemByPointDlg.cxx index f629fba64..a0888e3ff 100644 --- a/src/SMESHGUI/SMESHGUI_FindElemByPointDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_FindElemByPointDlg.cxx @@ -79,7 +79,7 @@ SMESHGUI_FindElemByPointDlg::SMESHGUI_FindElemByPointDlg() setWindowTitle(tr("CAPTION")); QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame()); - aDlgLay->setMargin(MARGIN);; + aDlgLay->setMargin(0); aDlgLay->setSpacing(SPACING); QWidget* aMainFrame = createMainFrame (mainFrame()); @@ -164,6 +164,8 @@ QWidget* SMESHGUI_FindElemByPointDlg::createMainFrame (QWidget* theParent) QVBoxLayout* aLay = new QVBoxLayout(aFrame); + aLay->setMargin( 0 ); + aLay->setSpacing( SPACING ); aLay->addWidget(aMeshGrp); aLay->addWidget(aCoordGrp); aLay->addWidget(elementGrp); diff --git a/src/SMESHGUI/SMESHGUI_GroupDlg.cxx b/src/SMESHGUI/SMESHGUI_GroupDlg.cxx index 28461ee4f..1aab1f908 100644 --- a/src/SMESHGUI/SMESHGUI_GroupDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_GroupDlg.cxx @@ -99,6 +99,19 @@ #define SPACING 6 #define MARGIN 11 +enum grpSelectionMode { + grpNoSelection = -1, + grpNodeSelection = 0, + grpEdgeSelection = 1, + grpFaceSelection = 2, + grpVolumeSelection = 3, + grpSubMeshSelection = 4, + grpGroupSelection = 5, + grpMeshSelection = 6, + grpGeomSelection = 7, + grpAllSelection = 8, +}; + //================================================================================= // function : SMESHGUI_GroupDlg() // purpose : @@ -147,7 +160,7 @@ SMESHGUI_GroupDlg::SMESHGUI_GroupDlg( SMESHGUI* theModule, mySelectGroup->setEnabled( false ); myCurrentLineEdit = myMeshGroupLine; - setSelectionMode( 5 ); + setSelectionMode( grpGroupSelection ); } } @@ -241,59 +254,62 @@ void SMESHGUI_GroupDlg::initDialog( bool create) aContentBoxLayout->setMargin( MARGIN ); aContentBoxLayout->setSpacing( SPACING ); - QLabel* aLabel = new QLabel( tr( "SMESH_ID_ELEMENTS" ), aContentBox ); + mySelectAll = new QCheckBox( tr( "SELECT_ALL" ), aContentBox ); + + myElementsLab = new QLabel( tr( "SMESH_ID_ELEMENTS" ), aContentBox ); myElements = new QListWidget( aContentBox ); myElements->setSelectionMode( QListWidget::ExtendedSelection ); myFilter = new QPushButton( tr( "SMESH_BUT_FILTER" ), aContentBox ); - QPushButton* aAddBtn = new QPushButton( tr( "SMESH_BUT_ADD" ), aContentBox ); - QPushButton* aRemoveBtn = new QPushButton( tr( "SMESH_BUT_REMOVE" ), aContentBox ); - QPushButton* aSortBtn = new QPushButton( tr( "SMESH_BUT_SORT" ), aContentBox ); - - aContentBoxLayout->addWidget( aLabel, 0, 0 ); - aContentBoxLayout->addWidget( myElements, 1, 0, 6, 1 ); - aContentBoxLayout->addWidget( myFilter, 1, 1 ); - aContentBoxLayout->addWidget( aAddBtn, 3, 1 ); - aContentBoxLayout->addWidget( aRemoveBtn, 4, 1 ); - aContentBoxLayout->addWidget( aSortBtn, 6, 1 ); + myAddBtn = new QPushButton( tr( "SMESH_BUT_ADD" ), aContentBox ); + myRemoveBtn = new QPushButton( tr( "SMESH_BUT_REMOVE" ), aContentBox ); + mySortBtn = new QPushButton( tr( "SMESH_BUT_SORT" ), aContentBox ); + + aContentBoxLayout->addWidget( mySelectAll, 0, 0 ); + aContentBoxLayout->addWidget( myElementsLab, 1, 0 ); + aContentBoxLayout->addWidget( myElements, 2, 0, 6, 1 ); + aContentBoxLayout->addWidget( myFilter, 2, 1 ); + aContentBoxLayout->addWidget( myAddBtn, 4, 1 ); + aContentBoxLayout->addWidget( myRemoveBtn, 5, 1 ); + aContentBoxLayout->addWidget( mySortBtn, 7, 1 ); aContentBoxLayout->setColumnStretch( 0, 1 ); - aContentBoxLayout->setRowStretch( 2, 1 ); - aContentBoxLayout->setRowStretch( 5, 1 ); + aContentBoxLayout->setRowStretch( 3, 1 ); + aContentBoxLayout->setRowStretch( 6, 1 ); /***************************************************************/ - QGroupBox* aSelectBox = new QGroupBox( tr( "SMESH_SELECT_FROM" ), wg1 ); - QGridLayout* aSelectBoxLayout = new QGridLayout( aSelectBox ); - aSelectBoxLayout->setMargin( MARGIN ); - aSelectBoxLayout->setSpacing( SPACING ); + mySelectBox = new QGroupBox( tr( "SMESH_SELECT_FROM" ), wg1 ); + QGridLayout* mySelectBoxLayout = new QGridLayout( mySelectBox ); + mySelectBoxLayout->setMargin( MARGIN ); + mySelectBoxLayout->setSpacing( SPACING ); - mySelectSubMesh = new QCheckBox( tr( "SMESH_SUBMESH" ), aSelectBox ); - mySubMeshBtn = new QPushButton( aSelectBox ); + mySelectSubMesh = new QCheckBox( tr( "SMESH_SUBMESH" ), mySelectBox ); + mySubMeshBtn = new QPushButton( mySelectBox ); mySubMeshBtn->setIcon( image0 ); - mySubMeshLine = new QLineEdit( aSelectBox ); + mySubMeshLine = new QLineEdit( mySelectBox ); mySubMeshLine->setReadOnly( true ); onSelectSubMesh( false ); - mySelectGroup = new QCheckBox( tr( "SMESH_GROUP" ), aSelectBox ); - myGroupBtn = new QPushButton( aSelectBox ); + mySelectGroup = new QCheckBox( tr( "SMESH_GROUP" ), mySelectBox ); + myGroupBtn = new QPushButton( mySelectBox ); myGroupBtn->setIcon( image0 ); - myGroupLine = new QLineEdit( aSelectBox ); + myGroupLine = new QLineEdit( mySelectBox ); myGroupLine->setReadOnly( true ); onSelectGroup( false ); - aSelectBoxLayout->addWidget( mySelectSubMesh, 0, 0 ); - aSelectBoxLayout->addWidget( mySubMeshBtn, 0, 1 ); - aSelectBoxLayout->addWidget( mySubMeshLine, 0, 2 ); - aSelectBoxLayout->addWidget( mySelectGroup, 1, 0 ); - aSelectBoxLayout->addWidget( myGroupBtn, 1, 1 ); - aSelectBoxLayout->addWidget( myGroupLine, 1, 2 ); + mySelectBoxLayout->addWidget( mySelectSubMesh, 0, 0 ); + mySelectBoxLayout->addWidget( mySubMeshBtn, 0, 1 ); + mySelectBoxLayout->addWidget( mySubMeshLine, 0, 2 ); + mySelectBoxLayout->addWidget( mySelectGroup, 1, 0 ); + mySelectBoxLayout->addWidget( myGroupBtn, 1, 1 ); + mySelectBoxLayout->addWidget( myGroupLine, 1, 2 ); /***************************************************************/ QVBoxLayout* wg1Layout = new QVBoxLayout( wg1 ); wg1Layout->setMargin( 0 ); wg1Layout->setSpacing( SPACING ); wg1Layout->addWidget( aContentBox ); - wg1Layout->addWidget( aSelectBox ); + wg1Layout->addWidget( mySelectBox ); wg1Layout->setStretchFactor( aContentBox, 10 ); /***************************************************************/ @@ -374,36 +390,37 @@ void SMESHGUI_GroupDlg::initDialog( bool create) aMainLayout->addWidget(aButtons, 6, 0, 1, 3); /* signals and slots connections */ - connect(myMeshGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); - connect(myGrpTypeGroup, SIGNAL(buttonClicked(int)), this, SLOT(onGrpTypeChanged(int))); - connect(myTypeGroup, SIGNAL(buttonClicked(int)), this, SLOT(onTypeChanged(int))); + connect(myMeshGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); + connect(myGrpTypeGroup, SIGNAL(buttonClicked(int)), this, SLOT(onGrpTypeChanged(int))); + connect(myTypeGroup, SIGNAL(buttonClicked(int)), this, SLOT(onTypeChanged(int))); - connect(myName, SIGNAL(textChanged(const QString&)), this, SLOT(onNameChanged(const QString&))); - connect(myElements, SIGNAL(itemSelectionChanged()), this, SLOT(onListSelectionChanged())); + connect(myName, SIGNAL(textChanged(const QString&)), this, SLOT(onNameChanged(const QString&))); + connect(myElements, SIGNAL(itemSelectionChanged()), this, SLOT(onListSelectionChanged())); - connect(myFilter, SIGNAL(clicked()), this, SLOT(setFilters())); - connect(aAddBtn, SIGNAL(clicked()), this, SLOT(onAdd())); - connect(aRemoveBtn, SIGNAL(clicked()), this, SLOT(onRemove())); - connect(aSortBtn, SIGNAL(clicked()), this, SLOT(onSort())); + connect(myFilter, SIGNAL(clicked()), this, SLOT(setFilters())); + connect(mySelectAll, SIGNAL(toggled(bool)), this, SLOT(onSelectAll())); + connect(myAddBtn, SIGNAL(clicked()), this, SLOT(onAdd())); + connect(myRemoveBtn, SIGNAL(clicked()), this, SLOT(onRemove())); + connect(mySortBtn, SIGNAL(clicked()), this, SLOT(onSort())); connect(mySelectSubMesh, SIGNAL(toggled(bool)), this, SLOT(onSelectSubMesh(bool))); connect(mySelectGroup, SIGNAL(toggled(bool)), this, SLOT(onSelectGroup(bool))); - connect(mySubMeshBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); - connect(myGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); + connect(mySubMeshBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); + connect(myGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); connect(myGeomGroupBtn, SIGNAL(toggled(bool)), this, SLOT(onGeomSelectionButton(bool))); - connect(myColorBtn, SIGNAL(changed( QColor )), this, SLOT(onColorChanged( QColor ))); + connect(myColorBtn, SIGNAL(changed( QColor )), this, SLOT(onColorChanged( QColor ))); - connect(myOKBtn, SIGNAL(clicked()), this, SLOT(onOK())); - connect(myApplyBtn, SIGNAL(clicked()), this, SLOT(onApply())); - connect(myCloseBtn, SIGNAL(clicked()), this, SLOT(onClose())); - connect(myHelpBtn, SIGNAL(clicked()), this, SLOT(onHelp())); + connect(myOKBtn, SIGNAL(clicked()), this, SLOT(onOK())); + connect(myApplyBtn, SIGNAL(clicked()), this, SLOT(onApply())); + connect(myCloseBtn, SIGNAL(clicked()), this, SLOT(onClose())); + connect(myHelpBtn, SIGNAL(clicked()), this, SLOT(onHelp())); /* Init selection */ mySMESHGUI->SetActiveDialogBox(this); mySMESHGUI->SetState(800); - mySelectionMode = -1; + mySelectionMode = grpNoSelection; myMeshFilter = new SMESH_TypeFilter(MESH); mySubMeshFilter = new SMESH_TypeFilter(SUBMESH); myGroupFilter = new SMESH_TypeFilter(GROUP); @@ -612,7 +629,7 @@ void SMESHGUI_GroupDlg::updateButtons() bool enable = !myName->text().trimmed().isEmpty(); if (myGrpTypeId == 0) { - enable = enable && myElements->count() > 0; + enable = enable && (mySelectAll->isChecked() || myElements->count() > 0); enable = enable && (!myGroup->_is_nil() || !myMesh->_is_nil()); } else if (myGrpTypeId == 1) { @@ -620,7 +637,7 @@ void SMESHGUI_GroupDlg::updateButtons() enable = enable && myGeomObjects->length() > 0 && !myMesh->_is_nil(); } } - + myOKBtn->setEnabled(enable); myApplyBtn->setEnabled(enable); } @@ -685,6 +702,8 @@ void SMESHGUI_GroupDlg::setSelectionMode (int theMode) // PAL7314 if (myMesh->_is_nil()) return; + SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ); + bool isSelectAll = mySelectAll->isChecked(); if (mySelectionMode != theMode) { // [PAL10408] mySelectionMgr->clearSelected(); mySelectionMgr->clearFilters(); @@ -693,46 +712,51 @@ void SMESHGUI_GroupDlg::setSelectionMode (int theMode) while ( it.hasNext() ) it.next()->SetPointRepresentation(false); } - else + else { SMESH::SetPointRepresentation(false); - if (theMode < 4) { - switch (theMode) { - case 0: - if (myActorsList.count() > 0) { - QListIterator it( myActorsList ); - while ( it.hasNext() ) - it.next()->SetPointRepresentation(true); - } - else - SMESH::SetPointRepresentation(true); - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(NodeSelection); - break; - case 1: - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(EdgeSelection); - break; - case 2: - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(FaceSelection); - break; - default: - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(VolumeSelection); + } + switch (theMode) { + case grpNodeSelection: + if (myActorsList.count() > 0) { + QListIterator it( myActorsList ); + while ( it.hasNext() ) + it.next()->SetPointRepresentation(true); } - } else { - if (theMode == 4) - mySelectionMgr->installFilter(mySubMeshFilter); - else if (theMode == 5) - mySelectionMgr->installFilter(myGroupFilter); - else if (theMode == 6) - mySelectionMgr->installFilter(myMeshFilter); - else if (theMode == 7) - mySelectionMgr->installFilter(myGeomFilter); - - if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) - aViewWindow->SetSelectionMode(ActorSelection); + else { + SMESH::SetPointRepresentation(true); + } + if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : NodeSelection); + break; + case grpEdgeSelection: + if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : EdgeSelection); + break; + case grpFaceSelection: + if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : FaceSelection); + break; + case grpVolumeSelection: + if ( aViewWindow ) aViewWindow->SetSelectionMode(isSelectAll ? ActorSelection : VolumeSelection); + break; + case grpSubMeshSelection: + mySelectionMgr->installFilter(mySubMeshFilter); + if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection); + break; + case grpGroupSelection: + mySelectionMgr->installFilter(myGroupFilter); + if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection); + break; + case grpMeshSelection: + mySelectionMgr->installFilter(myMeshFilter); + if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection); + break; + case grpGeomSelection: + mySelectionMgr->installFilter(myGeomFilter); + if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection); + break; + default: + if ( aViewWindow ) aViewWindow->SetSelectionMode(ActorSelection); + break; } + if ( aViewWindow ) aViewWindow->Repaint(); mySelectionMode = theMode; } } @@ -750,7 +774,7 @@ bool SMESHGUI_GroupDlg::onApply() return false; if (myGrpTypeId == 0) { // on mesh elements - if (!myElements->count()) + if (!mySelectAll->isChecked() && !myElements->count()) return false; mySelectionMgr->clearSelected(); @@ -778,15 +802,23 @@ bool SMESHGUI_GroupDlg::onApply() case 3: aType = SMESH::VOLUME; break; } - SMESH::long_array_var anIdList = new SMESH::long_array; - int i, k = myElements->count(); - anIdList->length(k); - for (i = 0; i < k; i++) { - anIdList[i] = myElements->item(i)->text().toInt(); - } - myGroup = SMESH::AddGroup(myMesh, aType, myName->text()); - myGroup->Add(anIdList.inout()); + + if ( mySelectAll->isChecked() ) { + // select all + myGroup->AddFrom(myMesh.in()); + } + else { + // select manually + SMESH::long_array_var anIdList = new SMESH::long_array; + int i, k = myElements->count(); + anIdList->length(k); + for (i = 0; i < k; i++) { + anIdList[i] = myElements->item(i)->text().toInt(); + } + + myGroup->Add(anIdList.inout()); + } SALOMEDS::Color aColor = getGroupColor(); myGroup->SetColor(aColor); @@ -818,37 +850,44 @@ bool SMESHGUI_GroupDlg::onApply() } } - QList aAddList; - - int i, total = myElements->count(); - for (i = 0; i < total; i++) { - int anId = myElements->item(i)->text().toInt(); - int idx = myIdList.indexOf(anId); - if ( idx == -1 ) - aAddList.append(anId); - else - myIdList.removeAt(idx); - } - if (!aAddList.empty()) { - SMESH::long_array_var anIdList = new SMESH::long_array; - int added = aAddList.count(); - anIdList->length(added); - for (i = 0; i < added; i++) - anIdList[i] = aAddList[i]; - myGroup->Add(anIdList.inout()); + if ( mySelectAll->isChecked() ) { + // select all + myGroup->Clear(); + myGroup->AddFrom(myMesh.in()); } - if (!myIdList.empty()) { - SMESH::long_array_var anIdList = new SMESH::long_array; - int removed = myIdList.count(); - anIdList->length(removed); - for (i = 0; i < removed; i++) - anIdList[i] = myIdList[i]; - myGroup->Remove(anIdList.inout()); - } - /* init for next operation */ - myIdList.clear(); - for (i = 0; i < total; i++) { - myIdList.append(myElements->item(i)->text().toInt()); + else { + QList aAddList; + + int i, total = myElements->count(); + for (i = 0; i < total; i++) { + int anId = myElements->item(i)->text().toInt(); + int idx = myIdList.indexOf(anId); + if ( idx == -1 ) + aAddList.append(anId); + else + myIdList.removeAt(idx); + } + if (!aAddList.empty()) { + SMESH::long_array_var anIdList = new SMESH::long_array; + int added = aAddList.count(); + anIdList->length(added); + for (i = 0; i < added; i++) + anIdList[i] = aAddList[i]; + myGroup->Add(anIdList.inout()); + } + if (!myIdList.empty()) { + SMESH::long_array_var anIdList = new SMESH::long_array; + int removed = myIdList.count(); + anIdList->length(removed); + for (i = 0; i < removed; i++) + anIdList[i] = myIdList[i]; + myGroup->Remove(anIdList.inout()); + } + /* init for next operation */ + myIdList.clear(); + for (i = 0; i < total; i++) { + myIdList.append(myElements->item(i)->text().toInt()); + } } } @@ -1336,6 +1375,24 @@ void SMESHGUI_GroupDlg::onObjectSelectionChanged() myIsBusy = false; } +//================================================================================= +// function : onSelectSubMesh() +// purpose : Called when selection in 3D view or ObjectBrowser is changed +//================================================================================= +void SMESHGUI_GroupDlg::onSelectAll() +{ + myElementsLab->setEnabled( !mySelectAll->isChecked() ); + myElements->setEnabled( !mySelectAll->isChecked() ); + myFilter->setEnabled( !mySelectAll->isChecked() ); + myAddBtn->setEnabled( !mySelectAll->isChecked() ); + myRemoveBtn->setEnabled( !mySelectAll->isChecked() ); + mySortBtn->setEnabled( !mySelectAll->isChecked() ); + mySelectBox->setEnabled( !mySelectAll->isChecked() ); + int selMode = mySelectionMode; + mySelectionMode = grpNoSelection; + setSelectionMode( selMode ); +} + //================================================================================= // function : onSelectSubMesh() // purpose : Called when selection in 3D view or ObjectBrowser is changed @@ -1350,7 +1407,7 @@ void SMESHGUI_GroupDlg::onSelectSubMesh(bool on) //VSR: mySelectGeomGroup->setChecked(false); //VSR: } myCurrentLineEdit = mySubMeshLine; - setSelectionMode(4); + setSelectionMode(grpSubMeshSelection); } else { mySubMeshLine->setText( "" ); @@ -1374,7 +1431,7 @@ void SMESHGUI_GroupDlg::onSelectGroup(bool on) mySelectSubMesh->setChecked(false); } myCurrentLineEdit = myGroupLine; - setSelectionMode(5); + setSelectionMode(grpGroupSelection); } else { myGroupLine->setText( "" ); @@ -1402,7 +1459,7 @@ void SMESHGUI_GroupDlg::onSelectGeomGroup(bool on) } myCurrentLineEdit = myGeomGroupLine; updateGeomPopup(); - setSelectionMode(8); + setSelectionMode(grpAllSelection); } else { myGeomGroupBtn->setChecked(false); @@ -1427,9 +1484,9 @@ void SMESHGUI_GroupDlg::setCurrentSelection() disconnect(myMeshGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); mySelectionMgr->clearSelected(); if (myCreate) - setSelectionMode(6); + setSelectionMode(grpMeshSelection); else - setSelectionMode(5); + setSelectionMode(grpGroupSelection); connect(myMeshGroupBtn, SIGNAL(clicked()), this, SLOT(setCurrentSelection())); myCurrentLineEdit = myMeshGroupLine; onObjectSelectionChanged(); @@ -1960,7 +2017,7 @@ void SMESHGUI_GroupDlg::enterEvent (QEvent*) if (!isEnabled()) { mySMESHGUI->EmitSignalDeactivateDialog(); setEnabled(true); - mySelectionMode = -1; + mySelectionMode = grpNoSelection; setSelectionMode(myTypeId); //mySMESHGUI->SetActiveDialogBox((QDialog*)this); mySMESHGUI->SetActiveDialogBox(this); @@ -2038,12 +2095,12 @@ void SMESHGUI_GroupDlg::onGeomSelectionButton(bool isBtnOn) myCurrentLineEdit = myGeomGroupLine; QAction* a = myGeomPopup->exec( QCursor::pos() ); if (!a || myActions[a] == DIRECT_GEOM_INDEX) - setSelectionMode(7); + setSelectionMode(grpGeomSelection); } else if (!isBtnOn) { myCurrentLineEdit = 0; - setSelectionMode(8); + setSelectionMode(grpAllSelection); } } @@ -2056,7 +2113,7 @@ void SMESHGUI_GroupDlg::onGeomPopup( QAction* a ) int index = myActions[a]; if ( index == GEOM_BY_MESH_INDEX ) { - mySelectionMode = -1; + mySelectionMode = grpNoSelection; if ( !myShapeByMeshOp ) { myShapeByMeshOp = new SMESHGUI_ShapeByMeshOp(true); connect(myShapeByMeshOp, SIGNAL(committed(SUIT_Operation*)), @@ -2117,7 +2174,7 @@ void SMESHGUI_GroupDlg::onCloseShapeByMeshDlg(SUIT_Operation* op) if ( myShapeByMeshOp == op ) { show(); - setSelectionMode(7); + setSelectionMode(grpGeomSelection); } } diff --git a/src/SMESHGUI/SMESHGUI_GroupDlg.h b/src/SMESHGUI/SMESHGUI_GroupDlg.h index 31c93d812..92f749110 100644 --- a/src/SMESHGUI/SMESHGUI_GroupDlg.h +++ b/src/SMESHGUI/SMESHGUI_GroupDlg.h @@ -40,6 +40,8 @@ #include CORBA_SERVER_HEADER(SMESH_Mesh) #include CORBA_SERVER_HEADER(SMESH_Group) +class QGroupBox; +class QLabel; class QLineEdit; class QButtonGroup; class QListWidget; @@ -96,6 +98,7 @@ private slots: void onListSelectionChanged(); void onObjectSelectionChanged(); + void onSelectAll(); void onSelectSubMesh( bool ); void onSelectGroup( bool ); void onSelectGeomGroup( bool ); @@ -157,13 +160,18 @@ private: QButtonGroup* myGrpTypeGroup; QStackedWidget* myWGStack; + QCheckBox* mySelectAll; + QLabel* myElementsLab; QListWidget* myElements; QPushButton* myFilter; + QPushButton* myAddBtn; + QPushButton* myRemoveBtn; + QPushButton* mySortBtn; + QGroupBox* mySelectBox; QCheckBox* mySelectSubMesh; QPushButton* mySubMeshBtn; QLineEdit* mySubMeshLine; - QCheckBox* mySelectGroup; QPushButton* myGroupBtn; QLineEdit* myGroupLine; diff --git a/src/SMESHGUI/SMESHGUI_GroupOnShapeDlg.cxx b/src/SMESHGUI/SMESHGUI_GroupOnShapeDlg.cxx index 9fefa98da..581aa5326 100644 --- a/src/SMESHGUI/SMESHGUI_GroupOnShapeDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_GroupOnShapeDlg.cxx @@ -301,7 +301,7 @@ bool SMESHGUI_GroupOnShapeOp::onApply() if ( !aStudy ) return false; // mesh - _PTR(SObject) meshSO = aStudy->FindObjectID( myMeshID.toLatin1().data() ); + _PTR(SObject) meshSO = aStudy->FindObjectID( myMeshID.toLatin1().data() ); SMESH::SMESH_Mesh_var mesh = SMESH::SObjectToInterface( meshSO ); if ( mesh->_is_nil() ) return false; @@ -352,7 +352,15 @@ bool SMESHGUI_GroupOnShapeOp::onApply() update( UF_ObjBrowser | UF_Model ); - init(); + // Re-init controls to create the next group + myElemGeoIDs.clear(); + myNodeGeoIDs.clear(); + removeCustomFilters(); + myDlg->myNodeGeomList->clear(); + myDlg->myElemGeomList->clear(); + myDlg->myElemGeomBtn->setChecked(false); + myDlg->myNodeGeomBtn->setChecked(false); + myDlg->updateButtons(); return !group->_is_nil(); } diff --git a/src/SMESHGUI/SMESHGUI_Hypotheses.cxx b/src/SMESHGUI/SMESHGUI_Hypotheses.cxx index b6e28773a..a964d8cfc 100644 --- a/src/SMESHGUI/SMESHGUI_Hypotheses.cxx +++ b/src/SMESHGUI/SMESHGUI_Hypotheses.cxx @@ -19,12 +19,11 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_Hypotheses.cxx +// Author : Julia DOROVSKIKH, Open CASCADE S.A.S. +// SMESH includes -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_Hypotheses.cxx -// Author : Julia DOROVSKIKH, Open CASCADE S.A.S. -// SMESH includes -// #include "SMESHGUI_Hypotheses.h" #include "SMESHGUI.h" @@ -53,6 +52,10 @@ #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 + SMESHGUI_GenericHypothesisCreator::SMESHGUI_GenericHypothesisCreator( const QString& theHypType ) : myHypType( theHypType ), myIsCreate( false ), myDlg( 0 ) { @@ -86,14 +89,22 @@ void SMESHGUI_GenericHypothesisCreator::create( bool isAlgo, myIsCreate = true; // Create hypothesis/algorithm - if (isAlgo) - SMESH::CreateHypothesis( hypType(), theHypName, isAlgo ); - - else - { - SMESH::SMESH_Hypothesis_var aHypothesis = + if (isAlgo) { + SMESH::SMESH_Hypothesis_var anAlgo = + SMESH::CreateHypothesis( hypType(), theHypName, isAlgo ); +#ifdef WITHGENERICOBJ + if (!CORBA::is_nil(anAlgo)) + anAlgo->Destroy(); +#endif + } + else { + SMESH::SMESH_Hypothesis_var aHypothesis = SMESH::CreateHypothesis( hypType(), theHypName, false ); editHypothesis( aHypothesis.in(), theHypName, theParent, obj, slot ); +#ifdef WITHGENERICOBJ + if (!CORBA::is_nil(aHypothesis)) + aHypothesis->Destroy(); +#endif } } @@ -111,13 +122,16 @@ void SMESHGUI_GenericHypothesisCreator::edit( SMESH::SMESH_Hypothesis_ptr theHyp editHypothesis( theHypothesis, theHypName, theParent, obj, slot ); } -void SMESHGUI_GenericHypothesisCreator::editHypothesis( SMESH::SMESH_Hypothesis_ptr h, +void SMESHGUI_GenericHypothesisCreator::editHypothesis( SMESH::SMESH_Hypothesis_ptr h, const QString& theHypName, QWidget* theParent, QObject* obj, const QString& slot ) { myHypName = theHypName; myHypo = SMESH::SMESH_Hypothesis::_duplicate( h ); +#ifdef WITHGENERICOBJ + myHypo->Register(); +#endif SMESHGUI_HypothesisDlg* Dlg = new SMESHGUI_HypothesisDlg( this, theParent ); connect( Dlg, SIGNAL( finished( int ) ), this, SLOT( onDialogFinished( int ) ) ); @@ -140,7 +154,7 @@ void SMESHGUI_GenericHypothesisCreator::editHypothesis( SMESH::SMESH_Hypothesis_ else emit finished( QDialog::Accepted ); } - + QFrame* SMESHGUI_GenericHypothesisCreator::buildStdFrame() { if( CORBA::is_nil( hypothesis() ) ) @@ -169,7 +183,7 @@ QFrame* SMESHGUI_GenericHypothesisCreator::buildStdFrame() GroupC1Layout->addWidget( lab, i, 0 ); QWidget* w = getCustomWidget( *anIt, GroupC1, i ); - if ( !w ) + if ( !w ) switch( (*anIt).myValue.type() ) { case QVariant::Int: @@ -287,6 +301,9 @@ void SMESHGUI_GenericHypothesisCreator::onDialogFinished( int result ) } } SMESHGUI::GetSMESHGUI()->updateObjBrowser( true, 0 ); +#ifdef WITHGENERICOBJ + myHypo->Destroy(); +#endif myHypo = SMESH::SMESH_Hypothesis::_nil(); myInitParamsHypo = SMESH::SMESH_Hypothesis::_nil(); @@ -316,26 +333,22 @@ bool SMESHGUI_GenericHypothesisCreator::getStdParamFromDlg( ListOfStdParams& par item.myValue = sb->value(); params.append( item ); } - else if( (*anIt)->inherits( "SalomeApp_DoubleSpinBox" ) ) { SalomeApp_DoubleSpinBox* sb = ( SalomeApp_DoubleSpinBox* )( *anIt ); item.myValue = sb->value(); params.append( item ); } - else if( (*anIt)->inherits( "QLineEdit" ) ) { QLineEdit* line = ( QLineEdit* )( *anIt ); item.myValue = line->text(); params.append( item ); } - else if ( getParamFromCustomWidget( item, *anIt )) { params.append( item ); } - else res = false; } @@ -351,7 +364,7 @@ QStringList SMESHGUI_GenericHypothesisCreator::getVariablesFromDlg() const if( (*anIt)->inherits( "QAbstractSpinBox" ) ) { QAbstractSpinBox* sb = ( QAbstractSpinBox* )( *anIt ); aResult.append(sb->text()); - } + } } return aResult; } @@ -440,7 +453,7 @@ SMESHGUI_GenericHypothesisCreator::ListOfWidgets& SMESHGUI_GenericHypothesisCrea } QtxDialog* SMESHGUI_GenericHypothesisCreator:: dlg() const -{ +{ return myDlg; } @@ -565,7 +578,7 @@ SMESHGUI_HypothesisDlg::SMESHGUI_HypothesisDlg( SMESHGUI_GenericHypothesisCreato QHBoxLayout* titLay = new QHBoxLayout( titFrame ); titLay->setMargin( 0 ); titLay->setSpacing( SPACING ); - + myIconLabel = new QLabel( titFrame ); myIconLabel->setScaledContents( false ); myIconLabel->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); @@ -634,7 +647,7 @@ void SMESHGUI_HypothesisDlg::onHelp() #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", + arg(app->resourceMgr()->stringValue("ExternalBrowser", platform)). arg(myHelpFileName)); } @@ -642,7 +655,7 @@ void SMESHGUI_HypothesisDlg::onHelp() void SMESHGUI_HypothesisDlg::setHIcon( const QPixmap& p ) { - myIconLabel->setPixmap( p ); + myIconLabel->setPixmap( p ); } void SMESHGUI_HypothesisDlg::setType( const QString& t ) @@ -672,7 +685,7 @@ HypothesisData::HypothesisData( const QString& theTypeName, IconId( theIconId ), Dim( theDim ), IsAux( theIsAux ), - NeededHypos( theNeededHypos ), + NeededHypos( theNeededHypos ), OptionalHypos( theOptionalHypos ), InputTypes( theInputTypes ), OutputTypes( theOutputTypes ), @@ -681,7 +694,7 @@ HypothesisData::HypothesisData( const QString& theTypeName, { } -HypothesesSet::HypothesesSet( const QString& theSetName ) +HypothesesSet::HypothesesSet( const QString& theSetName ) : myHypoSetName( theSetName ), myIsAlgo( false ) { @@ -690,8 +703,8 @@ HypothesesSet::HypothesesSet( const QString& theSetName ) HypothesesSet::HypothesesSet( const QString& theSetName, const QStringList& theHypoList, const QStringList& theAlgoList ) - : myHypoSetName( theSetName ), - myHypoList( theHypoList ), + : myHypoSetName( theSetName ), + myHypoList( theHypoList ), myAlgoList( theAlgoList ), myIsAlgo( false ) { @@ -747,4 +760,3 @@ QString HypothesesSet::current() const { return list()->at(myIndex); } - diff --git a/src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.cxx b/src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.cxx index ffbc3b80d..4ffc3f09e 100644 --- a/src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.cxx +++ b/src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.cxx @@ -16,235 +16,389 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// File : SMESHGUI_Make2DFrom3D.cxx +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) -// File : SMESHGUI_Make2DFrom3DOp.cxx -// Author : Open CASCADE S.A.S. -// SMESH includes -// #include "SMESHGUI_Make2DFrom3DOp.h" #include "SMESHGUI.h" #include "SMESHGUI_Utils.h" -#include "SMESHGUI_VTKUtils.h" #include "SMESHGUI_MeshUtils.h" -#include "SMESHGUI_MeshInfosBox.h" +#include "SMESH_TypeFilter.hxx" +#include "SMESH_LogicalFilter.hxx" // SALOME GUI includes -#include - +#include +#include +#include #include #include -#include #include -#include - -// SALOME KERNEL includes -#include -#include - -// Qt includes // IDL includes #include -#include CORBA_SERVER_HEADER(SMESH_Gen) -#include CORBA_SERVER_HEADER(SMESH_MeshEditor) +#include CORBA_SERVER_HEADER(SMESH_Group) -#include -#include -#include +// Qt includes #include -#include -#include - -// MESH includes -#include "SMDSAbs_ElementType.hxx" -#include "SMDSAbs_ElementType.hxx" - +#include +#include +#include +#include +#include #define SPACING 6 #define MARGIN 11 -// ========================================================================================= /*! - * \brief Dialog to show creted mesh statistic - */ -//======================================================================= + \class SMESHGUI_Make2DFrom3DDlg + \brief Copy Mesh dialog box +*/ SMESHGUI_Make2DFrom3DDlg::SMESHGUI_Make2DFrom3DDlg( QWidget* parent ) - : SMESHGUI_Dialog( parent, false, true, Close/* | Help*/ ) + : SMESHGUI_Dialog( parent, false, true, OK | Apply | Close | Help ) { + // title setWindowTitle( tr("CAPTION") ); - QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame()); + + // mesh + setObjectPixmap( "SMESH", tr( "ICON_SELECT" ) ); + createObject( tr( "MESH" ), mainFrame(), Mesh ); + + // mode + QGroupBox* aModeGrp = new QGroupBox( tr( "MODE" ), mainFrame() ); + QHBoxLayout* aModeGrpLayout = new QHBoxLayout( aModeGrp ); + aModeGrpLayout->setMargin( MARGIN ); + aModeGrpLayout->setSpacing( SPACING ); + my2dFrom3dRB = new QRadioButton( tr( "2D_FROM_3D" ), aModeGrp ); + my1dFrom2dRB = new QRadioButton( tr( "1D_FROM_2D" ), aModeGrp ); + my1dFrom3dRB = new QRadioButton( tr( "1D_FROM_3D" ), aModeGrp ); + aModeGrpLayout->addWidget( my2dFrom3dRB ); + aModeGrpLayout->addWidget( my1dFrom2dRB ); + aModeGrpLayout->addWidget( my1dFrom3dRB ); + + // target + QGroupBox* aTargetGrp = new QGroupBox( tr( "TARGET" ), mainFrame() ); + QGridLayout* aTargetGrpLayout = new QGridLayout( aTargetGrp ); + aTargetGrpLayout->setMargin( MARGIN ); + aTargetGrpLayout->setSpacing( SPACING ); + myThisMeshRB = new QRadioButton( tr( "THIS_MESH" ), aTargetGrp ); + myNewMeshRB = new QRadioButton( tr( "NEW_MESH" ), aTargetGrp ); + myMeshName = new QLineEdit( aTargetGrp ); + myCopyCheck = new QCheckBox( tr( "COPY_SRC" ), aTargetGrp ); + myMissingCheck = new QCheckBox( tr( "MISSING_ONLY" ), aTargetGrp ); + aTargetGrpLayout->addWidget( myThisMeshRB, 0, 0 ); + aTargetGrpLayout->addWidget( myNewMeshRB, 1, 0 ); + aTargetGrpLayout->addWidget( myMeshName, 1, 1 ); + aTargetGrpLayout->addWidget( myCopyCheck, 2, 0 ); + aTargetGrpLayout->addWidget( myMissingCheck, 2, 1 ); + myGroupCheck = new QCheckBox( tr( "CREATE_GROUP" ), mainFrame() ); + myGroupName = new QLineEdit( mainFrame() ); + + // layout + QGridLayout* aDlgLay = new QGridLayout( mainFrame() ); aDlgLay->setMargin( 0 ); aDlgLay->setSpacing( SPACING ); - QFrame* aMainFrame = createMainFrame(mainFrame()); - aDlgLay->addWidget(aMainFrame); - aDlgLay->setStretchFactor(aMainFrame, 1); + aDlgLay->addWidget( objectWg( Mesh, Label ), 0, 0 ); + aDlgLay->addWidget( objectWg( Mesh, Btn ), 0, 1 ); + aDlgLay->addWidget( objectWg( Mesh, Control ), 0, 2 ); + aDlgLay->addWidget( aModeGrp, 1, 0, 1, 3 ); + aDlgLay->addWidget( aTargetGrp, 2, 0, 1, 3 ); + aDlgLay->addWidget( myGroupCheck, 3, 0 ); + aDlgLay->addWidget( myGroupName, 3, 1, 1, 2 ); + + // connect signals + connect( myThisMeshRB, SIGNAL( clicked() ), this, SLOT( onTargetChanged() ) ); + connect( myNewMeshRB, SIGNAL( clicked() ), this, SLOT( onTargetChanged() ) ); + connect( myGroupCheck, SIGNAL( clicked() ), this, SLOT( onGroupChecked() ) ); + + // init dlg + my2dFrom3dRB->setChecked( true ); + myThisMeshRB->setChecked( true ); + myMissingCheck->setChecked( true ); + onTargetChanged(); + onGroupChecked(); } -// ========================================================================================= -/*! - * \brief Dialog destructor - */ -//======================================================================= - SMESHGUI_Make2DFrom3DDlg::~SMESHGUI_Make2DFrom3DDlg() { } -//======================================================================= -// function : createMainFrame() -// purpose : Create frame containing dialog's fields -//======================================================================= - -QFrame* SMESHGUI_Make2DFrom3DDlg::createMainFrame (QWidget* theParent) +SMESH::Bnd_Dimension SMESHGUI_Make2DFrom3DDlg::mode() const { - QFrame* aFrame = new QFrame(theParent); + if ( my2dFrom3dRB->isChecked() ) + return SMESH::BND_2DFROM3D; + else if ( my1dFrom2dRB->isChecked() ) + return SMESH::BND_1DFROM2D; + else + return SMESH::BND_1DFROM3D; +} - SUIT_ResourceMgr* rm = resourceMgr(); - QPixmap iconCompute (rm->loadPixmap("SMESH", tr("ICON_2D_FROM_3D"))); +bool SMESHGUI_Make2DFrom3DDlg::needNewMesh() const +{ + return myNewMeshRB->isChecked(); +} - // Mesh name - QGroupBox* nameBox = new QGroupBox(tr("SMESH_MESHINFO_NAME"), aFrame ); - QHBoxLayout* nameBoxLayout = new QHBoxLayout(nameBox); - nameBoxLayout->setMargin(MARGIN); nameBoxLayout->setSpacing(SPACING); - myMeshName = new QLabel(nameBox); - nameBoxLayout->addWidget(myMeshName); +QString SMESHGUI_Make2DFrom3DDlg::getNewMeshName() const +{ + return myMeshName->text().trimmed(); +} - // Mesh Info +void SMESHGUI_Make2DFrom3DDlg::setNewMeshName( const QString& name ) +{ + myMeshName->setText( name ); +} - myFullInfo = new SMESHGUI_MeshInfosBox(true, aFrame); +bool SMESHGUI_Make2DFrom3DDlg::needGroup() const +{ + return myGroupCheck->isChecked(); +} - // add all widgets to aFrame - QVBoxLayout* aLay = new QVBoxLayout(aFrame); - aLay->setMargin( 0 ); - aLay->setSpacing( 0 ); - aLay->addWidget( nameBox ); - aLay->addWidget( myFullInfo ); +QString SMESHGUI_Make2DFrom3DDlg::getGroupName() const +{ + return myGroupName->text().trimmed(); +} - ((QPushButton*) button( OK ))->setDefault( true ); - return aFrame; +void SMESHGUI_Make2DFrom3DDlg::setGroupName( const QString& name ) +{ + myGroupName->setText( name ); } -//================================================================================ -/*! - * \brief set name of the mesh -*/ -//================================================================================ +bool SMESHGUI_Make2DFrom3DDlg::copySource() const +{ + return myCopyCheck->isChecked(); +} -void SMESHGUI_Make2DFrom3DDlg::SetMeshName(const QString& theName) +bool SMESHGUI_Make2DFrom3DDlg::copyMissingOnly() const { - myMeshName->setText( theName ); + return myMissingCheck->isChecked(); } -//================================================================================ -/*! - * \brief set mesh info -*/ -//================================================================================ +void SMESHGUI_Make2DFrom3DDlg::onTargetChanged() +{ + myMeshName->setEnabled( myNewMeshRB->isChecked() ); + myCopyCheck->setEnabled( myNewMeshRB->isChecked() ); + myMissingCheck->setEnabled( myNewMeshRB->isChecked() ); +} -void SMESHGUI_Make2DFrom3DDlg::SetMeshInfo(const SMESH::long_array& theInfo) +void SMESHGUI_Make2DFrom3DDlg::onGroupChecked() { - myFullInfo->SetMeshInfo( theInfo ); + myGroupName->setEnabled( myGroupCheck->isChecked() ); } -//================================================================================ /*! - * \brief Constructor + \class SMESHGUI_Make2DFrom3DOp + \brief Copy Mesh operation class */ -//================================================================================ SMESHGUI_Make2DFrom3DOp::SMESHGUI_Make2DFrom3DOp() - : SMESHGUI_Operation() + : SMESHGUI_SelectionOp() { - myDlg = new SMESHGUI_Make2DFrom3DDlg(desktop()); } -//================================================================================ -/*! - * \brief Desctructor -*/ -//================================================================================ - SMESHGUI_Make2DFrom3DOp::~SMESHGUI_Make2DFrom3DOp() { + if ( myDlg ) + delete myDlg; } -//================================================================================ -/*! - * \brief perform it's intention action: compute 2D mesh on 3D - */ -//================================================================================ +LightApp_Dialog* SMESHGUI_Make2DFrom3DOp::dlg() const +{ + return myDlg; +} void SMESHGUI_Make2DFrom3DOp::startOperation() { - myMesh = SMESH::SMESH_Mesh::_nil(); + if( !myDlg ) + myDlg = new SMESHGUI_Make2DFrom3DDlg( desktop() ); + + mySrc = SMESH::SMESH_IDSource::_nil(); - // check selection - LightApp_SelectionMgr *Sel = selectionMgr(); - SALOME_ListIO selected; Sel->selectedObjects( selected ); + myHelpFileName = "make_2dmesh_from_3d_page.html"; - int nbSel = selected.Extent(); - if (nbSel != 1) { - SUIT_MessageBox::warning(desktop(), - tr("SMESH_WRN_WARNING"), - tr("SMESH_WRN_NO_AVAILABLE_DATA")); - onCancel(); - return; - } + SMESHGUI_SelectionOp::startOperation(); + + myDlg->activateObject( SMESHGUI_Make2DFrom3DDlg::Mesh ); + myDlg->setNewMeshName( SMESH::UniqueName( "Mesh_1" ) ); + myDlg->setGroupName( SMESH::UniqueName( "Group" ) ); + myDlg->show(); + + selectionDone(); +} - Handle(SALOME_InteractiveObject) anIO = selected.First(); - myMesh = SMESH::GetMeshByIO(anIO); - if (myMesh->_is_nil()) { - SUIT_MessageBox::warning(desktop(), - tr("SMESH_WRN_WARNING"), - tr("SMESH_WRN_NO_AVAILABLE_DATA")); - onCancel(); - return; +void SMESHGUI_Make2DFrom3DOp::selectionDone() +{ + if ( !dlg() ) return; + + if ( dlg()->isVisible() ) { + try { + QStringList names, ids; + LightApp_Dialog::TypesList types; + selected( names, types, ids ); + if ( names.count() == 1 ) + myDlg->selectObject( names, types, ids ); + else + myDlg->clearSelection(); + } + catch ( const SALOME::SALOME_Exception& S_ex ) { + SalomeApp_Tools::QtCatchCorbaException( S_ex ); + } + catch ( ... ) { + } } +} - SMESHGUI_Operation::startOperation(); +SUIT_SelectionFilter* SMESHGUI_Make2DFrom3DOp::createFilter( const int theId ) const +{ + SUIT_SelectionFilter* f = 0; + if ( theId == SMESHGUI_Make2DFrom3DDlg::Mesh ) { + QList filters; + filters.append( new SMESH_TypeFilter( MESHorSUBMESH ) ); + filters.append( new SMESH_TypeFilter( GROUP ) ); + f = new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR ); + } + return f; +} +bool SMESHGUI_Make2DFrom3DOp::isValid( QString& msg ) const +{ + if ( !dlg() ) return false; + + // check if any source data is selected + QString entry = myDlg->selectedObject( SMESHGUI_Make2DFrom3DDlg::Mesh ); + SMESH::SMESH_IDSource_var obj; + _PTR(SObject) sobj = SMESHGUI::activeStudy()->studyDS()->FindObjectID( entry.toLatin1().constData() ); + if ( sobj ) + obj = SMESH::SObjectToInterface( sobj ); + + if ( obj->_is_nil() ) { + msg = tr( "SMESH_ERR_NO_INPUT_MESH" ); + return false; + } - // backup mesh info before 2D mesh computation - SMESH::long_array_var anOldInfo = myMesh->GetMeshInfo(); + // check if source contains elements of required type + SMESH::Bnd_Dimension mode = myDlg->mode(); + SMESH::array_of_ElementType_var types = obj->GetTypes(); + bool has3d = false; + bool has2d = false; + for ( int i = 0; i < types->length(); i++ ) { + if ( types[i] == SMESH::VOLUME ) has3d = true; + else if ( types[i] == SMESH::FACE ) has2d = true; + } - if (!compute2DMesh()) { - SUIT_MessageBox::warning(desktop(), - tr("SMESH_WRN_WARNING"), - tr("SMESH_WRN_COMPUTE_FAILED")); - onCancel(); - return; - } - // get new mesh statistic - SMESH::long_array_var aNewInfo = myMesh->GetMeshInfo(); - // get difference in mesh statistic from old to new - for ( int i = SMDSEntity_Node; i < SMDSEntity_Last; i++ ) - aNewInfo[i] -= anOldInfo[i]; - - // update presentation - SMESH::Update(anIO, SMESH::eDisplay); - - // show computated result - _PTR(SObject) aMeshSObj = SMESH::FindSObject(myMesh); - if ( aMeshSObj ) - myDlg->SetMeshName( aMeshSObj->GetName().c_str() ); - myDlg->SetMeshInfo( aNewInfo ); - myDlg->show(); /*exec();*/ - commit(); - SMESHGUI::Modified(); -} - -//================================================================================ -/*! - * \brief compute 2D mesh on initial 3D - */ -//================================================================================ + if ( ( mode == SMESH::BND_2DFROM3D || mode == SMESH::BND_1DFROM3D ) && !has3d ) { + msg = tr( "SMESH_ERR_NO_3D_ELEMENTS" ); + return false; + } + else if ( mode == SMESH::BND_1DFROM2D && !has2d ) { + msg = tr( "SMESH_ERR_NO_2D_ELEMENTS" ); + return false; + } + + // check if new mesh name is specified + if ( myDlg->needNewMesh() && myDlg->getNewMeshName().isEmpty() ) { + msg = tr( "SMESH_ERR_MESH_NAME_NOT_SPECIFIED" ); + return false; + } + + // check if group name is specified + if ( myDlg->needGroup() && myDlg->getGroupName().isEmpty() ) { + msg = tr( "SMESH_ERR_GRP_NAME_NOT_SPECIFIED" ); + return false; + } + + return true; +} bool SMESHGUI_Make2DFrom3DOp::compute2DMesh() { SUIT_OverrideCursor wc; - SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); - return aMeshEditor->Make2DMeshFrom3D(); + + bool ok = false; + try { + QString entry = myDlg->selectedObject( SMESHGUI_Make2DFrom3DDlg::Mesh ); + _PTR(SObject) sobj = SMESHGUI::activeStudy()->studyDS()->FindObjectID( entry.toLatin1().constData() ); + SMESH::SMESH_IDSource_var obj = SMESH::SObjectToInterface( sobj ); + + SMESH::Bnd_Dimension mode = myDlg->mode(); + QString meshName = myDlg->needNewMesh() ? myDlg->getNewMeshName() : QString(); + QString groupName = myDlg->needGroup() ? myDlg->getGroupName() : QString(); + bool copySrc = myDlg->copySource(); + bool copyAll = !myDlg->copyMissingOnly(); + + SMESH::SMESH_Mesh_var srcMesh = SMESH::SMESH_Mesh::_narrow( obj ); + if ( CORBA::is_nil( srcMesh ) ) { + SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_narrow( obj ); + if ( !CORBA::is_nil( subMesh ) ) + srcMesh = subMesh->GetFather(); + } + if ( CORBA::is_nil( srcMesh ) ) { + SMESH::SMESH_GroupBase_var grp = SMESH::SMESH_GroupBase::_narrow( obj ); + if ( !CORBA::is_nil( grp ) ) + srcMesh = grp->GetMesh(); + } + + if ( !CORBA::is_nil( srcMesh ) ) { + SMESH::SMESH_MeshEditor_var aMeshEditor = srcMesh->GetMeshEditor(); + SMESH::SMESH_Group_var newGrp; + SMESH::SMESH_Mesh_var mesh = aMeshEditor->MakeBoundaryMesh( obj.in(), + mode, + groupName.toLatin1().constData(), + meshName.toLatin1().constData(), + copySrc, + copyAll, + newGrp.out() ); + if ( !mesh->_is_nil() ) { +#ifdef WITHGENERICOBJ + mesh->Destroy(); +#endif + } + if ( !newGrp->_is_nil() ) { +#ifdef WITHGENERICOBJ + newGrp->Destroy(); +#endif + } + ok = true; + } + } + catch ( ... ) { + } + return ok; +} + +bool SMESHGUI_Make2DFrom3DOp::onApply() +{ + if ( isStudyLocked() ) + return false; + + QString msg; + if ( !isValid( msg ) ) { + dlg()->show(); + if ( msg != "" ) + SUIT_MessageBox::warning( myDlg, tr( "SMESH_ERROR" ), msg ); + return false; + } + + bool res = false; + try { + res = compute2DMesh(); + } + catch ( const SALOME::SALOME_Exception& S_ex ) { + SalomeApp_Tools::QtCatchCorbaException( S_ex ); + } + catch ( ... ) { + } + + if ( res ) { + SMESHGUI::Modified(); + update( UF_ObjBrowser | UF_Model ); + myDlg->setNewMeshName( SMESH::UniqueName( "Mesh_1" ) ); + myDlg->setGroupName( SMESH::UniqueName( "Group" ) ); + } + else { + SUIT_MessageBox::warning( myDlg, tr( "SMESH_ERROR" ), tr( "SMESH_OPERATION_FAILED" ) ); + } + + return res; } diff --git a/src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.h b/src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.h index f2ef2d9fd..23bab5e61 100644 --- a/src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.h +++ b/src/SMESHGUI/SMESHGUI_Make2DFrom3DOp.h @@ -16,69 +16,96 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // - -// SMESH SMESHGUI : GUI for SMESH component // File : SMESHGUI_Make2DFrom3D.h -// Author : Open CASCADE S.A.S. -// +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) + #ifndef SMESHGUI_Make2DFrom3DOp_H #define SMESHGUI_Make2DFrom3DOp_H // SMESH includes #include "SMESH_SMESHGUI.hxx" - #include "SMESHGUI_Dialog.h" -#include "SMESHGUI_Operation.h" +#include "SMESHGUI_SelectionOp.h" -// IDL includes #include -#include CORBA_SERVER_HEADER(SMESH_Mesh) +#include CORBA_SERVER_HEADER(SMESH_MeshEditor) -class QFrame; -class SMESHGUI_MeshInfosBox; +class QCheckBox; +class QLineEdit; +class QRadioButton; /*! * \brief Dialog to show result mesh statistic */ -class SMESHGUI_Make2DFrom3DDlg : public SMESHGUI_Dialog +class SMESHGUI_EXPORT SMESHGUI_Make2DFrom3DDlg : public SMESHGUI_Dialog { Q_OBJECT - public: +public: + enum { Mesh }; + SMESHGUI_Make2DFrom3DDlg( QWidget* ); virtual ~SMESHGUI_Make2DFrom3DDlg(); - void SetMeshName(const QString& theName); - void SetMeshInfo(const SMESH::long_array& theInfo); - - private: - QFrame* createMainFrame( QWidget* ); - - private: - QLabel* myMeshName; - SMESHGUI_MeshInfosBox* myFullInfo; + SMESH::Bnd_Dimension mode() const; + + bool needNewMesh() const; + QString getNewMeshName() const; + void setNewMeshName( const QString& ); + + bool needGroup() const; + QString getGroupName() const; + void setGroupName( const QString& ); + + bool copySource() const; + bool copyMissingOnly() const; + +private slots: + void onTargetChanged(); + void onGroupChecked(); + +private: + QRadioButton* my2dFrom3dRB; + QRadioButton* my1dFrom2dRB; + QRadioButton* my1dFrom3dRB; + QRadioButton* myThisMeshRB; + QRadioButton* myNewMeshRB; + QLineEdit* myMeshName; + QCheckBox* myCopyCheck; + QCheckBox* myMissingCheck; + QCheckBox* myGroupCheck; + QLineEdit* myGroupName; }; - /*! * \brief Operation to compute 2D mesh on 3D */ -class SMESHGUI_Make2DFrom3DOp : public SMESHGUI_Operation +class SMESHGUI_EXPORT SMESHGUI_Make2DFrom3DOp : public SMESHGUI_SelectionOp { - public: + Q_OBJECT + +public: SMESHGUI_Make2DFrom3DOp(); virtual ~SMESHGUI_Make2DFrom3DOp(); - protected: + virtual LightApp_Dialog* dlg() const; + +protected: virtual void startOperation(); + virtual void selectionDone(); + virtual SUIT_SelectionFilter* createFilter( const int ) const; + bool isValid( QString& ) const; + +protected slots: + virtual bool onApply(); - private: +private: bool compute2DMesh(); - private: - SMESH::SMESH_Mesh_var myMesh; +private: + SMESH::SMESH_IDSource_var mySrc; QPointer myDlg; }; diff --git a/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx b/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx index ee35301f0..36aa22bb4 100644 --- a/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.cxx @@ -92,7 +92,7 @@ SMESHGUI_MakeNodeAtPointDlg::SMESHGUI_MakeNodeAtPointDlg() setWindowTitle(tr("CAPTION")); QVBoxLayout* aDlgLay = new QVBoxLayout (mainFrame()); - aDlgLay->setMargin(MARGIN);; + aDlgLay->setMargin(0); aDlgLay->setSpacing(SPACING); QWidget* aMainFrame = createMainFrame (mainFrame()); @@ -116,7 +116,7 @@ QWidget* SMESHGUI_MakeNodeAtPointDlg::createMainFrame (QWidget* theParent) // constructor - QGroupBox* aPixGrp = new QGroupBox(tr("MESH_PASS_THROUGH_POINT"), aFrame); + QGroupBox* aPixGrp = new QGroupBox(tr("MOVE_NODE"), aFrame); QButtonGroup* aBtnGrp = new QButtonGroup(this); QHBoxLayout* aPixGrpLayout = new QHBoxLayout(aPixGrp); aPixGrpLayout->setMargin(MARGIN); @@ -130,7 +130,7 @@ QWidget* SMESHGUI_MakeNodeAtPointDlg::createMainFrame (QWidget* theParent) // coordinates - QGroupBox* aCoordGrp = new QGroupBox(tr("SMESH_COORDINATES"), aFrame); + QGroupBox* aCoordGrp = new QGroupBox(tr("DESTINATION"), aFrame); QHBoxLayout* aCoordGrpLayout = new QHBoxLayout(aCoordGrp); aCoordGrpLayout->setMargin(MARGIN); aCoordGrpLayout->setSpacing(SPACING); @@ -160,19 +160,6 @@ QWidget* SMESHGUI_MakeNodeAtPointDlg::createMainFrame (QWidget* theParent) aCoordGrpLayout->addWidget(aZLabel); aCoordGrpLayout->addWidget(myZ); - // Method selection - - QGroupBox* aMethodGrp = new QGroupBox(tr("METHOD"), aFrame); - QHBoxLayout* aMethodGrpLayout = new QHBoxLayout(aMethodGrp); - aMethodGrpLayout->setMargin(MARGIN); - aMethodGrpLayout->setSpacing(SPACING); - - myMoveRBtn = new QRadioButton(tr("MOVE_EXISTING_METHOD"), aMethodGrp); - myCreateRBtn = new QRadioButton(tr("CREATE_NEW_METHOD"), aMethodGrp); - - aMethodGrpLayout->addWidget(myMoveRBtn); - aMethodGrpLayout->addWidget(myCreateRBtn); - // node ID myNodeToMoveGrp = new QGroupBox(tr("NODE_2MOVE"), aFrame); @@ -183,6 +170,62 @@ QWidget* SMESHGUI_MakeNodeAtPointDlg::createMainFrame (QWidget* theParent) myIdBtn->setCheckable(true); myId = new QLineEdit(myNodeToMoveGrp); myId->setValidator(new SMESHGUI_IdValidator(this, 1)); + + QWidget* aCoordWidget = new QWidget(myNodeToMoveGrp); + + QLabel* aCurrentXLabel = new QLabel(tr("SMESH_X"), aCoordWidget); + myCurrentX = new SMESHGUI_SpinBox(aCoordWidget); + myCurrentX->setButtonSymbols(QAbstractSpinBox::NoButtons); + myCurrentX->setReadOnly(true); + + QLabel* aCurrentYLabel = new QLabel(tr("SMESH_Y"), aCoordWidget); + myCurrentY = new SMESHGUI_SpinBox(aCoordWidget); + myCurrentY->setButtonSymbols(QAbstractSpinBox::NoButtons); + myCurrentY->setReadOnly(true); + + QLabel* aCurrentZLabel = new QLabel(tr("SMESH_Z"), aCoordWidget); + myCurrentZ = new SMESHGUI_SpinBox(aCoordWidget); + myCurrentZ->setButtonSymbols(QAbstractSpinBox::NoButtons); + myCurrentZ->setReadOnly(true); + + QLabel* aDXLabel = new QLabel(tr("SMESH_DX"), aCoordWidget); + myDX = new SMESHGUI_SpinBox(aCoordWidget); + myDX->setButtonSymbols(QAbstractSpinBox::NoButtons); + myDX->setReadOnly(true); + + QLabel* aDYLabel = new QLabel(tr("SMESH_DY"), aCoordWidget); + myDY = new SMESHGUI_SpinBox(aCoordWidget); + myDY->setButtonSymbols(QAbstractSpinBox::NoButtons); + myDY->setReadOnly(true); + + QLabel* aDZLabel = new QLabel(tr("SMESH_DZ"), aCoordWidget); + myDZ = new SMESHGUI_SpinBox(aCoordWidget); + myDZ->setButtonSymbols(QAbstractSpinBox::NoButtons); + myDZ->setReadOnly(true); + + myCurrentX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + myCurrentY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + myCurrentZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + myDX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + myDY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + myDZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + + QGridLayout* aCoordLayout = new QGridLayout(aCoordWidget); + aCoordLayout->setMargin(0); + aCoordLayout->setSpacing(SPACING); + aCoordLayout->addWidget(aCurrentXLabel, 0, 0); + aCoordLayout->addWidget(myCurrentX, 0, 1); + aCoordLayout->addWidget(aCurrentYLabel, 0, 2); + aCoordLayout->addWidget(myCurrentY, 0, 3); + aCoordLayout->addWidget(aCurrentZLabel, 0, 4); + aCoordLayout->addWidget(myCurrentZ, 0, 5); + aCoordLayout->addWidget(aDXLabel, 1, 0); + aCoordLayout->addWidget(myDX, 1, 1); + aCoordLayout->addWidget(aDYLabel, 1, 2); + aCoordLayout->addWidget(myDY, 1, 3); + aCoordLayout->addWidget(aDZLabel, 1, 4); + aCoordLayout->addWidget(myDZ, 1, 5); + myAutoSearchChkBox = new QCheckBox( tr("AUTO_SEARCH"), myNodeToMoveGrp); myPreviewChkBox = new QCheckBox( tr("PREVIEW"), myNodeToMoveGrp); @@ -193,22 +236,19 @@ QWidget* SMESHGUI_MakeNodeAtPointDlg::createMainFrame (QWidget* theParent) myNodeToMoveGrpLayout->addWidget( idLabel, 0, 0 ); myNodeToMoveGrpLayout->addWidget( myIdBtn, 0, 1 ); myNodeToMoveGrpLayout->addWidget( myId, 0, 2 ); - myNodeToMoveGrpLayout->addWidget( myAutoSearchChkBox, 1, 0, 1, 3 ); - myNodeToMoveGrpLayout->addWidget( myPreviewChkBox, 2, 0, 1, 3 ); + myNodeToMoveGrpLayout->addWidget( aCoordWidget, 1, 0, 1, 3 ); + myNodeToMoveGrpLayout->addWidget( myAutoSearchChkBox, 2, 0, 1, 3 ); + myNodeToMoveGrpLayout->addWidget( myPreviewChkBox, 3, 0, 1, 3 ); QVBoxLayout* aLay = new QVBoxLayout(aFrame); aLay->addWidget(aPixGrp); aLay->addWidget(aCoordGrp); - aLay->addWidget(aMethodGrp); aLay->addWidget(myNodeToMoveGrp); connect(myCoordBtn, SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool))); - connect(myMoveRBtn, SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool))); - connect(myCreateRBtn, SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool))); connect(myIdBtn, SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool))); connect(myAutoSearchChkBox, SIGNAL (toggled(bool)), this, SLOT(ButtonToggled(bool))); - myMoveRBtn->setChecked(true); myIdBtn->setChecked(true); myAutoSearchChkBox->setChecked(true); @@ -235,19 +275,16 @@ void SMESHGUI_MakeNodeAtPointDlg::ButtonToggled (bool on) { myCoordBtn->setChecked( !on ); } - else if ( aSender == myMoveRBtn ) // move node method - { - myNodeToMoveGrp->setEnabled( true ); - } - else if ( aSender == myCreateRBtn ) // create node method - { - myNodeToMoveGrp->setEnabled( false ); - myCoordBtn->setChecked( true ); - } } if ( aSender == myAutoSearchChkBox ) // automatic node search { if ( on ) { + myCurrentX->SetValue(0); + myCurrentY->SetValue(0); + myCurrentZ->SetValue(0); + myDX->SetValue(0); + myDY->SetValue(0); + myDZ->SetValue(0); myId->setText(""); myId->setReadOnly ( true ); myIdBtn->setChecked( false ); @@ -281,8 +318,6 @@ SMESHGUI_MakeNodeAtPointOp::SMESHGUI_MakeNodeAtPointOp() connect(myDlg->myId,SIGNAL (textChanged(const QString&)),SLOT(redisplayPreview())); connect(myDlg->myPreviewChkBox, SIGNAL (toggled(bool)),SLOT(redisplayPreview())); connect(myDlg->myAutoSearchChkBox,SIGNAL (toggled(bool)),SLOT(redisplayPreview())); - connect(myDlg->myMoveRBtn, SIGNAL (toggled(bool)),SLOT(redisplayPreview())); - connect(myDlg->myCreateRBtn, SIGNAL (toggled(bool)),SLOT(redisplayPreview())); } //======================================================================= @@ -321,6 +356,12 @@ void SMESHGUI_MakeNodeAtPointOp::startOperation() myDlg->myX->SetValue(0); myDlg->myY->SetValue(0); myDlg->myZ->SetValue(0); + myDlg->myCurrentX->SetValue(0); + myDlg->myCurrentY->SetValue(0); + myDlg->myCurrentZ->SetValue(0); + myDlg->myDX->SetValue(0); + myDlg->myDY->SetValue(0); + myDlg->myDZ->SetValue(0); myDlg->myId->setText(""); myDlg->show(); @@ -394,21 +435,18 @@ bool SMESHGUI_MakeNodeAtPointOp::onApply() if (aMeshEditor->_is_nil()) return true; - int aResult = 0; - if ( myDlg->myCreateRBtn->isChecked() ) - { - aResult = aMeshEditor->AddNode(myDlg->myX->GetValue(), - myDlg->myY->GetValue(), - myDlg->myZ->GetValue()); - } - else - { - int anId = myDlg->myId->text().toInt(); - aResult = aMeshEditor->MoveClosestNodeToPoint(myDlg->myX->GetValue(), - myDlg->myY->GetValue(), - myDlg->myZ->GetValue(), - anId); - } + bool ok; + int anId = myDlg->myId->text().toInt( &ok ); + if( !ok || anId < 1 ) + anId = aMeshEditor->FindNodeClosestTo(myDlg->myX->GetValue(), + myDlg->myY->GetValue(), + myDlg->myZ->GetValue()); + + int aResult = aMeshEditor->MoveNode(anId, + myDlg->myX->GetValue(), + myDlg->myY->GetValue(), + myDlg->myZ->GetValue() ); + if (aResult) { QStringList aParameters; @@ -417,6 +455,12 @@ bool SMESHGUI_MakeNodeAtPointOp::onApply() aParameters << myDlg->myZ->text(); aMesh->SetParameters( aParameters.join(":").toLatin1().constData() ); + myDlg->myCurrentX->SetValue(0); + myDlg->myCurrentY->SetValue(0); + myDlg->myCurrentZ->SetValue(0); + myDlg->myDX->SetValue(0); + myDlg->myDY->SetValue(0); + myDlg->myDZ->SetValue(0); myDlg->myId->setText(""); SALOME_ListIO aList; @@ -446,7 +490,6 @@ bool SMESHGUI_MakeNodeAtPointOp::isValid( QString& msg ) { bool ok = true; if ( myMeshActor && - myDlg->myMoveRBtn->isChecked() && !myDlg->myAutoSearchChkBox->isChecked() ) { ok = false; @@ -525,6 +568,21 @@ void SMESHGUI_MakeNodeAtPointOp::onSelectionDone() myNoPreview = false; redisplayPreview(); } + + if (const SMDS_MeshNode* aCurrentNode = aMesh->FindNode(myDlg->myId->text().toInt())) { + double x = aCurrentNode->X(); + double y = aCurrentNode->Y(); + double z = aCurrentNode->Z(); + double dx = myDlg->myX->GetValue() - x; + double dy = myDlg->myY->GetValue() - y; + double dz = myDlg->myZ->GetValue() - z; + myDlg->myCurrentX->SetValue(x); + myDlg->myCurrentY->SetValue(y); + myDlg->myCurrentZ->SetValue(z); + myDlg->myDX->SetValue(dx); + myDlg->myDY->SetValue(dy); + myDlg->myDZ->SetValue(dz); + } } } } @@ -547,15 +605,22 @@ void SMESHGUI_MakeNodeAtPointOp::redisplayPreview() SMESH::MeshPreviewStruct_var aMeshPreviewStruct; bool moveShown = false; - if ( myDlg->myMoveRBtn->isChecked() && // Move method - myMeshActor) + if ( myMeshActor) { const bool autoSearch = myDlg->myAutoSearchChkBox->isChecked(); const bool preview = myDlg->myPreviewChkBox->isChecked(); if ( autoSearch ) + { + myDlg->myCurrentX->SetValue(0); + myDlg->myCurrentY->SetValue(0); + myDlg->myCurrentZ->SetValue(0); + myDlg->myDX->SetValue(0); + myDlg->myDY->SetValue(0); + myDlg->myDZ->SetValue(0); myDlg->myId->setText(""); + } QString msg; - if ( preview && ( autoSearch || isValid( msg ) )) + if ( autoSearch || isValid( msg ) ) { try { SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(myMeshActor->getIO()); @@ -565,11 +630,19 @@ void SMESHGUI_MakeNodeAtPointOp::redisplayPreview() { SUIT_OverrideCursor aWaitCursor; + int anId = 0; + if ( autoSearch ) + anId = aPreviewer->FindNodeClosestTo(myDlg->myX->GetValue(), + myDlg->myY->GetValue(), + myDlg->myZ->GetValue()); + else + anId = myDlg->myId->text().toInt(); + // find id and/or just compute preview - int anId = aPreviewer->MoveClosestNodeToPoint(myDlg->myX->GetValue(), - myDlg->myY->GetValue(), - myDlg->myZ->GetValue(), - myDlg->myId->text().toInt()); + aPreviewer->MoveNode(anId, + myDlg->myX->GetValue(), + myDlg->myY->GetValue(), + myDlg->myZ->GetValue()); if ( autoSearch ) { // set found id QString idTxt("%1"); if ( anId > 0 ) @@ -578,6 +651,24 @@ void SMESHGUI_MakeNodeAtPointOp::redisplayPreview() idTxt = ""; myDlg->myId->setText( idTxt ); } + + SMESH::double_array* aXYZ = aMesh->GetNodeXYZ( anId ); + if( aXYZ && aXYZ->length() >= 3 ) + { + double x = aXYZ->operator[](0); + double y = aXYZ->operator[](1); + double z = aXYZ->operator[](2); + double dx = myDlg->myX->GetValue() - x; + double dy = myDlg->myY->GetValue() - y; + double dz = myDlg->myZ->GetValue() - z; + myDlg->myCurrentX->SetValue(x); + myDlg->myCurrentY->SetValue(y); + myDlg->myCurrentZ->SetValue(z); + myDlg->myDX->SetValue(dx); + myDlg->myDY->SetValue(dy); + myDlg->myDZ->SetValue(dz); + } + if ( preview ) { // fill preview data aMeshPreviewStruct = aPreviewer->GetPreviewData(); moveShown = ( anId > 0 ); diff --git a/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.h b/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.h index 68408d990..8774c8bfa 100644 --- a/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.h +++ b/src/SMESHGUI/SMESHGUI_MakeNodeAtPointDlg.h @@ -36,7 +36,6 @@ class QGroupBox; class QLineEdit; class QPushButton; class QCheckBox; -class QRadioButton; class SMESHGUI_SpinBox; class SMESHGUI_MeshEditPreview; class SMESHGUI_MakeNodeAtPointDlg; @@ -98,11 +97,15 @@ private: SMESHGUI_SpinBox* myX; SMESHGUI_SpinBox* myY; SMESHGUI_SpinBox* myZ; - QRadioButton* myMoveRBtn; - QRadioButton* myCreateRBtn; QGroupBox* myNodeToMoveGrp; QPushButton* myIdBtn; QLineEdit* myId; + SMESHGUI_SpinBox* myCurrentX; + SMESHGUI_SpinBox* myCurrentY; + SMESHGUI_SpinBox* myCurrentZ; + SMESHGUI_SpinBox* myDX; + SMESHGUI_SpinBox* myDY; + SMESHGUI_SpinBox* myDZ; QCheckBox* myAutoSearchChkBox; QCheckBox* myPreviewChkBox; diff --git a/src/SMESHGUI/SMESHGUI_Measurements.cxx b/src/SMESHGUI/SMESHGUI_Measurements.cxx new file mode 100644 index 000000000..b07c08dc4 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_Measurements.cxx @@ -0,0 +1,1231 @@ +// 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 +// +// File : SMESHGUI_Measurements.cxx +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) + +#include "SMESHGUI_Measurements.h" + +#include "SMESH_Actor.h" +#include "SMESHGUI.h" +#include "SMESHGUI_IdValidator.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_VTKUtils.h" +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include CORBA_SERVER_HEADER(SMESH_MeshEditor) +#include CORBA_SERVER_HEADER(SMESH_Measurements) + +const int SPACING = 6; // layout spacing +const int MARGIN = 9; // layout margin +const int MAX_NB_FOR_EDITOR = 40; // max nb of items in the ID list editor field + +// Uncomment as soon as elements are supported by Min Distance operation +//#define MINDIST_ENABLE_ELEMENT + +// Uncomment as soon as objects are supported by Min Distance operation +//#define MINDIST_ENABLE_OBJECT + +/*! + \class SMESHGUI_MinDistance + \brief Minimum distance measurement widget. + + Widget to calculate minimum distance between two objects. +*/ + +/*! + \brief Constructor. + \param parent parent widget +*/ +SMESHGUI_MinDistance::SMESHGUI_MinDistance( QWidget* parent ) +: QWidget( parent ), myCurrentTgt( FirstTgt ), myFirstActor( 0 ), mySecondActor( 0 ), myPreview( 0 ) +{ + QGroupBox* aFirstTgtGrp = new QGroupBox( tr( "FIRST_TARGET" ), this ); + QRadioButton* aFNode = new QRadioButton( tr( "NODE" ), aFirstTgtGrp ); + QRadioButton* aFElem = new QRadioButton( tr( "ELEMENT" ), aFirstTgtGrp ); + QRadioButton* aFObject = new QRadioButton( tr( "OBJECT" ), aFirstTgtGrp ); + myFirstTgt = new QLineEdit( aFirstTgtGrp ); + + QGridLayout* fl = new QGridLayout( aFirstTgtGrp ); + fl->setMargin( MARGIN ); + fl->setSpacing( SPACING ); + fl->addWidget( aFNode, 0, 0 ); + fl->addWidget( aFElem, 0, 1 ); + fl->addWidget( aFObject, 0, 2 ); + fl->addWidget( myFirstTgt, 1, 0, 1, 3 ); + + myFirst = new QButtonGroup( this ); + myFirst->addButton( aFNode, NodeTgt ); + myFirst->addButton( aFElem, ElementTgt ); + myFirst->addButton( aFObject, ObjectTgt ); + + QGroupBox* aSecondTgtGrp = new QGroupBox( tr( "SECOND_TARGET" ), this ); + QRadioButton* aSOrigin = new QRadioButton( tr( "ORIGIN" ), aSecondTgtGrp ); + QRadioButton* aSNode = new QRadioButton( tr( "NODE" ), aSecondTgtGrp ); + QRadioButton* aSElem = new QRadioButton( tr( "ELEMENT" ), aSecondTgtGrp ); + QRadioButton* aSObject = new QRadioButton( tr( "OBJECT" ), aSecondTgtGrp ); + mySecondTgt = new QLineEdit( aSecondTgtGrp ); + + QGridLayout* sl = new QGridLayout( aSecondTgtGrp ); + sl->setMargin( MARGIN ); + sl->setSpacing( SPACING ); + sl->addWidget( aSOrigin, 0, 0 ); + sl->addWidget( aSNode, 0, 1 ); + sl->addWidget( aSElem, 0, 2 ); + sl->addWidget( aSObject, 0, 3 ); + sl->addWidget( mySecondTgt, 1, 0, 1, 4 ); + + mySecond = new QButtonGroup( this ); + mySecond->addButton( aSOrigin, OriginTgt ); + mySecond->addButton( aSNode, NodeTgt ); + mySecond->addButton( aSElem, ElementTgt ); + mySecond->addButton( aSObject, ObjectTgt ); + + QPushButton* aCompute = new QPushButton( tr( "COMPUTE" ), this ); + + QGroupBox* aResults = new QGroupBox( tr( "RESULT" ), this ); + QLabel* aDxLab = new QLabel( "dX", aResults ); + myDX = new QLineEdit( aResults ); + QLabel* aDyLab = new QLabel( "dY", aResults ); + myDY = new QLineEdit( aResults ); + QLabel* aDzLab = new QLabel( "dZ", aResults ); + myDZ = new QLineEdit( aResults ); + QLabel* aDistLab = new QLabel( tr( "DISTANCE" ), aResults ); + myDistance = new QLineEdit( aResults ); + + QGridLayout* rl = new QGridLayout( aResults ); + rl->setMargin( MARGIN ); + rl->setSpacing( SPACING ); + rl->addWidget( aDxLab, 0, 0 ); + rl->addWidget( myDX, 0, 1 ); + rl->addWidget( aDyLab, 1, 0 ); + rl->addWidget( myDY, 1, 1 ); + rl->addWidget( aDzLab, 2, 0 ); + rl->addWidget( myDZ, 2, 1 ); + rl->addWidget( aDistLab, 0, 2 ); + rl->addWidget( myDistance, 0, 3 ); + + QGridLayout* l = new QGridLayout( this ); + l->setMargin( MARGIN ); + l->setSpacing( SPACING ); + + l->addWidget( aFirstTgtGrp, 0, 0, 1, 2 ); + l->addWidget( aSecondTgtGrp, 1, 0, 1, 2 ); + l->addWidget( aCompute, 2, 0 ); + l->addWidget( aResults, 3, 0, 1, 2 ); + l->setColumnStretch( 1, 5 ); + l->setRowStretch( 4, 5 ); + + aFNode->setChecked( true ); + aSOrigin->setChecked( true ); +#ifndef MINDIST_ENABLE_ELEMENT + aFElem->setEnabled( false ); // NOT AVAILABLE YET + aSElem->setEnabled( false ); // NOT AVAILABLE YET +#endif +#ifndef MINDIST_ENABLE_OBJECT + aFObject->setEnabled( false ); // NOT AVAILABLE YET + aSObject->setEnabled( false ); // NOT AVAILABLE YET +#endif + myDX->setReadOnly( true ); + myDY->setReadOnly( true ); + myDZ->setReadOnly( true ); + myDistance->setReadOnly( true ); + + myValidator = new SMESHGUI_IdValidator( this, 1 ); + + myFirstTgt->installEventFilter( this ); + mySecondTgt->installEventFilter( this ); + + connect( myFirst, SIGNAL( buttonClicked( int ) ), this, SLOT( firstChanged() ) ); + connect( mySecond, SIGNAL( buttonClicked( int ) ), this, SLOT( secondChanged() ) ); + connect( aCompute, SIGNAL( clicked() ), this, SLOT( compute() ) ); + connect( myFirstTgt, SIGNAL( textEdited( QString ) ), this, SLOT( firstEdited() ) ); + connect( mySecondTgt, SIGNAL( textEdited( QString ) ), this, SLOT( secondEdited() ) ); + + QList filters; + filters.append( new SMESH_TypeFilter( MESHorSUBMESH ) ); + filters.append( new SMESH_TypeFilter( GROUP ) ); + myFilter = new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR ); + + mySecondTgt->setEnabled( mySecond->checkedId() != OriginTgt ); + clear(); + + //setTarget( FirstTgt ); +} + +/*! + \brief Destructor +*/ +SMESHGUI_MinDistance::~SMESHGUI_MinDistance() +{ + erasePreview(); + if ( myPreview ) + myPreview->Delete(); +} + +/*! + \brief Event filter + \param o object + \param o event + \return \c true if event is filtered or \c false otherwise +*/ +bool SMESHGUI_MinDistance::eventFilter( QObject* o, QEvent* e ) +{ + if ( e->type() == QEvent::FocusIn ) { + if ( o == myFirstTgt ) + setTarget( FirstTgt ); + else if ( o == mySecondTgt ) + setTarget( SecondTgt ); + } + return QWidget::eventFilter( o, e ); +} + +/*! + \brief Setup selection mode depending on the current widget state +*/ +void SMESHGUI_MinDistance::updateSelection() +{ + LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr(); + + disconnect( selMgr, 0, this, 0 ); + selMgr->clearFilters(); + + bool nodeMode = ( myCurrentTgt == FirstTgt && myFirst->checkedId() == NodeTgt ) || + ( myCurrentTgt == SecondTgt && mySecond->checkedId() == NodeTgt ); + bool elemMode = ( myCurrentTgt == FirstTgt && myFirst->checkedId() == ElementTgt ) || + ( myCurrentTgt == SecondTgt && mySecond->checkedId() == ElementTgt ); + bool objMode = ( myCurrentTgt == FirstTgt && myFirst->checkedId() == ObjectTgt ) || + ( myCurrentTgt == SecondTgt && mySecond->checkedId() == ObjectTgt ) || + ( myCurrentTgt == NoTgt ); + + if ( nodeMode ) { + SMESH::SetPointRepresentation( true ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( NodeSelection ); + } + else if ( elemMode ) { + SMESH::SetPointRepresentation( false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( CellSelection ); + } + else if ( objMode ) { + SMESH::SetPointRepresentation( false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( ActorSelection ); + selMgr->installFilter( myFilter ); + } + + connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( selectionChanged() ) ); + + if ( myCurrentTgt == FirstTgt ) + firstEdited(); + else if ( myCurrentTgt == SecondTgt ) + secondEdited(); + + //selectionChanged(); +} + +/*! + \brief Deactivate widget +*/ +void SMESHGUI_MinDistance::deactivate() +{ + disconnect( SMESHGUI::selectionMgr(), 0, this, 0 ); +} + +/*! + \brief Set current target for selection + \param target new target ID +*/ +void SMESHGUI_MinDistance::setTarget( int target ) +{ + if ( myCurrentTgt != target ) { + myCurrentTgt = target; + updateSelection(); + } +} + +/*! + \brief Erase preview actor +*/ +void SMESHGUI_MinDistance::erasePreview() +{ + SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(); + if ( aViewWindow && myPreview ) { + aViewWindow->RemoveActor( myPreview ); + aViewWindow->Repaint(); + } +} + +/*! + \brief Display preview actor +*/ +void SMESHGUI_MinDistance::displayPreview() +{ + SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(); + if ( aViewWindow && myPreview ) { + aViewWindow->AddActor( myPreview ); + aViewWindow->Repaint(); + } +} + +/*! + \brief Create preview actor + \param x1 X coordinate of first point + \param y1 X coordinate of first point + \param z1 Y coordinate of first point + \param x2 Y coordinate of second point + \param y2 Z coordinate of second point + \param z2 Z coordinate of second point +*/ +void SMESHGUI_MinDistance::createPreview( double x1, double y1, double z1, double x2, double y2, double z2 ) +{ + if ( myPreview ) + myPreview->Delete(); + + vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New(); + // create points + vtkPoints* aPoints = vtkPoints::New(); + aPoints->SetNumberOfPoints( 2 ); + aPoints->SetPoint( 0, x1, y1, z1 ); + aPoints->SetPoint( 1, x2, y2, z2 ); + aGrid->SetPoints( aPoints ); + aPoints->Delete(); + // create cells + vtkIdList* anIdList = vtkIdList::New(); + anIdList->SetNumberOfIds( 2 ); + vtkCellArray* aCells = vtkCellArray::New(); + aCells->Allocate( 2, 0); + vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New(); + aCellTypesArray->SetNumberOfComponents( 1 ); + aCellTypesArray->Allocate( 1 ); + anIdList->SetId( 0, 0 ); anIdList->SetId( 1, 1 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->Delete(); + VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New(); + aCellLocationsArray->SetNumberOfComponents( 1 ); + aCellLocationsArray->SetNumberOfTuples( 1 ); + aCells->InitTraversal(); + for( vtkIdType idType = 0, *pts, npts; aCells->GetNextCell( npts, pts ); idType++ ) + aCellLocationsArray->SetValue( idType, aCells->GetTraversalLocation( npts ) ); + aGrid->SetCells( aCellTypesArray, aCellLocationsArray, aCells ); + aCellLocationsArray->Delete(); + aCellTypesArray->Delete(); + aCells->Delete(); + // create actor + vtkDataSetMapper* aMapper = vtkDataSetMapper::New(); + aMapper->SetInput( aGrid ); + aGrid->Delete(); + myPreview = SALOME_Actor::New(); + myPreview->PickableOff(); + myPreview->SetMapper( aMapper ); + aMapper->Delete(); + vtkProperty* aProp = vtkProperty::New(); + aProp->SetRepresentationToWireframe(); + aProp->SetColor( 250, 0, 250 ); + aProp->SetPointSize( 5 ); + aProp->SetLineWidth( 3 ); + myPreview->SetProperty( aProp ); + aProp->Delete(); +} + +/*! + \brief Called when selection is changed +*/ +void SMESHGUI_MinDistance::selectionChanged() +{ + SUIT_OverrideCursor wc; + + SALOME_ListIO selected; + SMESHGUI::selectionMgr()->selectedObjects( selected ); + + if ( selected.Extent() == 1 ) { + Handle(SALOME_InteractiveObject) IO = selected.First(); + SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( IO ); + if ( !CORBA::is_nil( obj ) ) { + if ( myCurrentTgt == FirstTgt ) { + myFirstSrc = obj; + myFirstActor = SMESH::FindActorByEntry( IO->getEntry() ); + if ( myFirst->checkedId() == ObjectTgt ) { + QString aName; + SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName ); + myFirstTgt->setText( aName ); + } + else { + SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector(); + QString ID; + int nb = 0; + if ( myFirstActor && selector ) { + nb = myFirst->checkedId() == NodeTgt ? + SMESH::GetNameOfSelectedElements( selector, IO, ID ) : + SMESH::GetNameOfSelectedNodes( selector, IO, ID ); + } + if ( nb == 1 ) + myFirstTgt->setText( ID.trimmed() ); + else + myFirstTgt->clear(); + } + } + else if ( myCurrentTgt == SecondTgt ) { + mySecondSrc = obj; + mySecondActor = SMESH::FindActorByEntry( IO->getEntry() ); + if ( mySecond->checkedId() == ObjectTgt ) { + QString aName; + SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName ); + mySecondTgt->setText( aName ); + } + else { + SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector(); + QString ID; + int nb = 0; + if ( mySecondActor && selector ) { + nb = mySecond->checkedId() == NodeTgt ? + SMESH::GetNameOfSelectedElements( selector, IO, ID ) : + SMESH::GetNameOfSelectedNodes( selector, IO, ID ); + } + if ( nb == 1 ) + mySecondTgt->setText( ID.trimmed() ); + else + mySecondTgt->clear(); + } + } + } + } + clear(); +} + +/*! + \brief Called when first target mode is changed by the user +*/ +void SMESHGUI_MinDistance::firstChanged() +{ + myFirstSrc = SMESH::SMESH_IDSource::_nil(); + myFirstTgt->clear(); + myFirstTgt->setReadOnly( myFirst->checkedId() == ObjectTgt ); + myFirstTgt->setValidator( myFirst->checkedId() == ObjectTgt ? 0 : myValidator ); + setTarget( FirstTgt ); + updateSelection(); + clear(); +} + +/*! + \brief Called when second target mode is changed by the user +*/ +void SMESHGUI_MinDistance::secondChanged() +{ + mySecondSrc = SMESH::SMESH_IDSource::_nil(); + mySecondTgt->setEnabled( mySecond->checkedId() != OriginTgt ); + mySecondTgt->setReadOnly( mySecond->checkedId() == ObjectTgt ); + mySecondTgt->setValidator( mySecond->checkedId() == ObjectTgt ? 0 : myValidator ); + mySecondTgt->clear(); + setTarget( mySecond->checkedId() != OriginTgt ? SecondTgt : NoTgt ); + updateSelection(); + clear(); +} + +/*! + \brief Called when first target is edited by the user +*/ +void SMESHGUI_MinDistance::firstEdited() +{ + setTarget( FirstTgt ); + if ( sender() == myFirstTgt ) + clear(); + SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector(); + if ( myFirstActor && selector ) { + Handle(SALOME_InteractiveObject) IO = myFirstActor->getIO(); + if ( myFirst->checkedId() == NodeTgt || myFirst->checkedId() == ElementTgt ) { + TColStd_MapOfInteger ID; + ID.Add( myFirstTgt->text().toLong() ); + selector->AddOrRemoveIndex( IO, ID, false ); + } + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->highlight( IO, true, true ); + } +} + +/*! + \brief Called when second target is edited by the user +*/ +void SMESHGUI_MinDistance::secondEdited() +{ + setTarget( SecondTgt ); + if ( sender() == mySecondTgt ) + clear(); + SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector(); + if ( mySecondActor && selector ) { + Handle(SALOME_InteractiveObject) IO = mySecondActor->getIO(); + if ( mySecond->checkedId() == NodeTgt || mySecond->checkedId() == ElementTgt ) { + TColStd_MapOfInteger ID; + ID.Add( mySecondTgt->text().toLong() ); + selector->AddOrRemoveIndex( IO, ID, false ); + } + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->highlight( IO, true, true ); + } +} + +/*! + \brief Compute the minimum distance between targets +*/ +void SMESHGUI_MinDistance::compute() +{ + SUIT_OverrideCursor wc; + SMESH::SMESH_IDSource_var s1; + SMESH::SMESH_IDSource_var s2; + bool isOrigin = mySecond->checkedId() == OriginTgt; + + // process first target + if ( !CORBA::is_nil( myFirstSrc ) ) { + if ( myFirst->checkedId() == NodeTgt || myFirst->checkedId() == ElementTgt ) { + SMESH::SMESH_Mesh_var m = myFirstSrc->GetMesh(); + long id = myFirstTgt->text().toLong(); + if ( !CORBA::is_nil( m ) && id ) { + SMESH::long_array_var ids = new SMESH::long_array(); + ids->length( 1 ); + ids[0] = id; + SMESH::SMESH_MeshEditor_var me = m->GetMeshEditor(); + s1 = me->MakeIDSource( ids.in(), myFirst->checkedId() == NodeTgt ? SMESH::NODE : SMESH::FACE ); + } + } + else { + s1 = myFirstSrc; + } + } + + // process second target + if ( !CORBA::is_nil( mySecondSrc ) ) { + if ( mySecond->checkedId() == NodeTgt || mySecond->checkedId() == ElementTgt ) { + SMESH::SMESH_Mesh_var m = mySecondSrc->GetMesh(); + long id = mySecondTgt->text().toLong(); + if ( !CORBA::is_nil( m ) && id ) { + SMESH::long_array_var ids = new SMESH::long_array(); + ids->length( 1 ); + ids[0] = id; + SMESH::SMESH_MeshEditor_var me = m->GetMeshEditor(); + s2 = me->MakeIDSource( ids.in(), mySecond->checkedId() == NodeTgt ? SMESH::NODE : SMESH::FACE ); + } + } + else { + s2 = mySecondSrc; + } + } + + if ( !CORBA::is_nil( s1 ) && ( !CORBA::is_nil( s2 ) || isOrigin ) ) { + // compute min distance + int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 ); + SMESH::Measurements_var measure = SMESHGUI::GetSMESHGen()->CreateMeasurements(); + SMESH::Measure result = measure->MinDistance( s1.in(), s2.in() ); + measure->Destroy(); + myDX->setText( QString::number( result.minX, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + myDY->setText( QString::number( result.minY, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + myDZ->setText( QString::number( result.minZ, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + myDistance->setText( QString::number( result.value, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + // update preview actor + erasePreview(); + double x1, y1, z1, x2, y2, z2; + SMESH::double_array_var coord = s1->GetMesh()->GetNodeXYZ( result.node1 ); + x1 = coord[0]; y1 = coord[1]; z1 = coord[2]; + if ( isOrigin ) { + x2 = y2 = z2 = 0.; + } + else { + coord = s2->GetMesh()->GetNodeXYZ( result.node2 ); + x2 = coord[0]; y2 = coord[1]; z2 = coord[2]; + } + createPreview( x1, y1, z1, x2, y2, z2 ); + displayPreview(); + } + else { + clear(); + } +} + +/*! + \brief Reset the widget to the initial state (nullify result fields) +*/ +void SMESHGUI_MinDistance::clear() +{ + myDX->clear(); + myDY->clear(); + myDZ->clear(); + myDistance->clear(); + erasePreview(); +} + +/*! + \class SMESHGUI_BoundingBox + \brief Bounding box measurement widget. + + Widget to calculate bounding box of the selected object(s). +*/ + +/*! + \brief Constructor. + \param parent parent widget +*/ +SMESHGUI_BoundingBox::SMESHGUI_BoundingBox( QWidget* parent ) +: QWidget( parent ), myActor( 0 ), myPreview( 0 ) +{ + QGroupBox* aSourceGrp = new QGroupBox( tr( "SOURCE" ), this ); + QRadioButton* aObjects = new QRadioButton( tr( "OBJECTS" ), aSourceGrp ); + QRadioButton* aNodes = new QRadioButton( tr( "NODES" ), aSourceGrp ); + QRadioButton* aElements = new QRadioButton( tr( "ELEMENTS" ), aSourceGrp ); + mySource = new QLineEdit( aSourceGrp ); + + QGridLayout* fl = new QGridLayout( aSourceGrp ); + fl->setMargin( MARGIN ); + fl->setSpacing( SPACING ); + fl->addWidget( aObjects, 0, 0 ); + fl->addWidget( aNodes, 0, 1 ); + fl->addWidget( aElements, 0, 2 ); + fl->addWidget( mySource, 1, 0, 1, 3 ); + + mySourceMode = new QButtonGroup( this ); + mySourceMode->addButton( aObjects, ObjectsSrc ); + mySourceMode->addButton( aNodes, NodesSrc ); + mySourceMode->addButton( aElements, ElementsSrc ); + + QPushButton* aCompute = new QPushButton( tr( "COMPUTE" ), this ); + + QGroupBox* aResults = new QGroupBox( tr( "RESULT" ), this ); + QLabel* aXminLab = new QLabel( "Xmin", aResults ); + myXmin = new QLineEdit( aResults ); + QLabel* aXmaxLab = new QLabel( "Xmax", aResults ); + myXmax = new QLineEdit( aResults ); + QLabel* aDxLab = new QLabel( "dX", aResults ); + myDX = new QLineEdit( aResults ); + QLabel* aYminLab = new QLabel( "Ymin", aResults ); + myYmin = new QLineEdit( aResults ); + QLabel* aYmaxLab = new QLabel( "Ymax", aResults ); + myYmax = new QLineEdit( aResults ); + QLabel* aDyLab = new QLabel( "dY", aResults ); + myDY = new QLineEdit( aResults ); + QLabel* aZminLab = new QLabel( "Zmin", aResults ); + myZmin = new QLineEdit( aResults ); + QLabel* aZmaxLab = new QLabel( "Zmax", aResults ); + myZmax = new QLineEdit( aResults ); + QLabel* aDzLab = new QLabel( "dZ", aResults ); + myDZ = new QLineEdit( aResults ); + + QGridLayout* rl = new QGridLayout( aResults ); + rl->setMargin( MARGIN ); + rl->setSpacing( SPACING ); + rl->addWidget( aXminLab, 0, 0 ); + rl->addWidget( myXmin, 0, 1 ); + rl->addWidget( aXmaxLab, 0, 2 ); + rl->addWidget( myXmax, 0, 3 ); + rl->addWidget( aDxLab, 0, 4 ); + rl->addWidget( myDX, 0, 5 ); + rl->addWidget( aYminLab, 1, 0 ); + rl->addWidget( myYmin, 1, 1 ); + rl->addWidget( aYmaxLab, 1, 2 ); + rl->addWidget( myYmax, 1, 3 ); + rl->addWidget( aDyLab, 1, 4 ); + rl->addWidget( myDY, 1, 5 ); + rl->addWidget( aZminLab, 2, 0 ); + rl->addWidget( myZmin, 2, 1 ); + rl->addWidget( aZmaxLab, 2, 2 ); + rl->addWidget( myZmax, 2, 3 ); + rl->addWidget( aDzLab, 2, 4 ); + rl->addWidget( myDZ, 2, 5 ); + + QGridLayout* l = new QGridLayout( this ); + l->setMargin( MARGIN ); + l->setSpacing( SPACING ); + + l->addWidget( aSourceGrp, 0, 0, 1, 2 ); + l->addWidget( aCompute, 1, 0 ); + l->addWidget( aResults, 2, 0, 1, 2 ); + l->setColumnStretch( 1, 5 ); + l->setRowStretch( 3, 5 ); + + aObjects->setChecked( true ); + myXmin->setReadOnly( true ); + myXmax->setReadOnly( true ); + myDX->setReadOnly( true ); + myYmin->setReadOnly( true ); + myYmax->setReadOnly( true ); + myDY->setReadOnly( true ); + myZmin->setReadOnly( true ); + myZmax->setReadOnly( true ); + myDZ->setReadOnly( true ); + + myValidator = new SMESHGUI_IdValidator( this ); + + connect( mySourceMode, SIGNAL( buttonClicked( int ) ), this, SLOT( sourceChanged() ) ); + connect( aCompute, SIGNAL( clicked() ), this, SLOT( compute() ) ); + connect( mySource, SIGNAL( textEdited( QString ) ), this, SLOT( sourceEdited() ) ); + + QList filters; + filters.append( new SMESH_TypeFilter( MESHorSUBMESH ) ); + filters.append( new SMESH_TypeFilter( GROUP ) ); + myFilter = new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR ); + + clear(); +} + +/*! + \brief Destructor +*/ +SMESHGUI_BoundingBox::~SMESHGUI_BoundingBox() +{ + erasePreview(); + if ( myPreview ) + myPreview->Delete(); +} + +/*! + \brief Setup selection mode depending on the current widget state +*/ +void SMESHGUI_BoundingBox::updateSelection() +{ + LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr(); + + disconnect( selMgr, 0, this, 0 ); + selMgr->clearFilters(); + + bool nodeMode = mySourceMode->checkedId() == NodesSrc; + bool elemMode = mySourceMode->checkedId() == ElementsSrc; + bool objMode = mySourceMode->checkedId() == ObjectsSrc; + + if ( nodeMode ) { + SMESH::SetPointRepresentation( true ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( NodeSelection ); + } + else if ( elemMode ) { + SMESH::SetPointRepresentation( false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( CellSelection ); + } + else if ( objMode ) { + SMESH::SetPointRepresentation( false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( ActorSelection ); + selMgr->installFilter( myFilter ); + } + + connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( selectionChanged() ) ); + + sourceEdited(); + + //selectionChanged(); +} + +/*! + \brief Deactivate widget +*/ +void SMESHGUI_BoundingBox::deactivate() +{ + disconnect( SMESHGUI::selectionMgr(), 0, this, 0 ); +} + +/*! + \brief Erase preview actor +*/ +void SMESHGUI_BoundingBox::erasePreview() +{ + SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(); + if ( aViewWindow && myPreview ) { + aViewWindow->RemoveActor( myPreview ); + aViewWindow->Repaint(); + } +} + +/*! + \brief Display preview actor +*/ +void SMESHGUI_BoundingBox::displayPreview() +{ + SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow(); + if ( aViewWindow && myPreview ) { + aViewWindow->AddActor( myPreview ); + aViewWindow->Repaint(); + } +} + +/*! + \brief Create preview actor + \param minX min X coordinate of bounding box + \param maxX max X coordinate of bounding box + \param minY min Y coordinate of bounding box + \param maxY max Y coordinate of bounding box + \param minZ min Z coordinate of bounding box + \param maxZ max Z coordinate of bounding box +*/ +void SMESHGUI_BoundingBox::createPreview( double minX, double maxX, double minY, double maxY, double minZ, double maxZ ) +{ + if ( myPreview ) + myPreview->Delete(); + + vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::New(); + // create points + vtkPoints* aPoints = vtkPoints::New(); + aPoints->SetNumberOfPoints( 8 ); + aPoints->SetPoint( 0, minX, minY, minZ ); + aPoints->SetPoint( 1, maxX, minY, minZ ); + aPoints->SetPoint( 2, minX, maxY, minZ ); + aPoints->SetPoint( 3, maxX, maxY, minZ ); + aPoints->SetPoint( 4, minX, minY, maxZ ); + aPoints->SetPoint( 5, maxX, minY, maxZ ); + aPoints->SetPoint( 6, minX, maxY, maxZ ); + aPoints->SetPoint( 7, maxX, maxY, maxZ ); + aGrid->SetPoints( aPoints ); + aPoints->Delete(); + // create cells + // connectivity: 0-1 0-4 0-2 1-5 1-3 2-6 2-3 3-7 4-6 4-5 5-7 6-7 + vtkIdList* anIdList = vtkIdList::New(); + anIdList->SetNumberOfIds( 2 ); + vtkCellArray* aCells = vtkCellArray::New(); + aCells->Allocate( 2*12, 0); + vtkUnsignedCharArray* aCellTypesArray = vtkUnsignedCharArray::New(); + aCellTypesArray->SetNumberOfComponents( 1 ); + aCellTypesArray->Allocate( 12 ); + anIdList->SetId( 0, 0 ); anIdList->SetId( 1, 1 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->SetId( 0, 0 ); anIdList->SetId( 1, 4 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->SetId( 0, 0 ); anIdList->SetId( 1, 2 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->SetId( 0, 1 ); anIdList->SetId( 1, 5 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->SetId( 0, 1 ); anIdList->SetId( 1, 3 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->SetId( 0, 2 ); anIdList->SetId( 1, 6 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->SetId( 0, 2 ); anIdList->SetId( 1, 3 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->SetId( 0, 3 ); anIdList->SetId( 1, 7 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->SetId( 0, 4 ); anIdList->SetId( 1, 6 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->SetId( 0, 4 ); anIdList->SetId( 1, 5 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->SetId( 0, 5 ); anIdList->SetId( 1, 7 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->SetId( 0, 6 ); anIdList->SetId( 1, 7 ); + aCells->InsertNextCell( anIdList ); + aCellTypesArray->InsertNextValue( VTK_LINE ); + anIdList->Delete(); + VTKViewer_CellLocationsArray* aCellLocationsArray = VTKViewer_CellLocationsArray::New(); + aCellLocationsArray->SetNumberOfComponents( 1 ); + aCellLocationsArray->SetNumberOfTuples( 12 ); + aCells->InitTraversal(); + for( vtkIdType idType = 0, *pts, npts; aCells->GetNextCell( npts, pts ); idType++ ) + aCellLocationsArray->SetValue( idType, aCells->GetTraversalLocation( npts ) ); + aGrid->SetCells( aCellTypesArray, aCellLocationsArray, aCells ); + aCellLocationsArray->Delete(); + aCellTypesArray->Delete(); + aCells->Delete(); + // create actor + vtkDataSetMapper* aMapper = vtkDataSetMapper::New(); + aMapper->SetInput( aGrid ); + aGrid->Delete(); + myPreview = SALOME_Actor::New(); + myPreview->PickableOff(); + myPreview->SetMapper( aMapper ); + aMapper->Delete(); + vtkProperty* aProp = vtkProperty::New(); + aProp->SetRepresentationToWireframe(); + aProp->SetColor( 250, 0, 250 ); + aProp->SetPointSize( 5 ); + aProp->SetLineWidth( 3 ); + myPreview->SetProperty( aProp ); + aProp->Delete(); +} + +/*! + \brief Called when selection is changed +*/ +void SMESHGUI_BoundingBox::selectionChanged() +{ + SUIT_OverrideCursor wc; + + SALOME_ListIO selected; + SMESHGUI::selectionMgr()->selectedObjects( selected ); + + if ( selected.Extent() == 1 ) { + Handle(SALOME_InteractiveObject) IO = selected.First(); + SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( IO ); + if ( !CORBA::is_nil( obj ) ) { + mySrc.clear(); + mySrc.append( obj ); + myActor = SMESH::FindActorByEntry( IO->getEntry() ); + if ( mySourceMode->checkedId() == ObjectsSrc ) { + QString aName; + SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName ); + mySource->setText( aName ); + } + else { + SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector(); + QString ID; + int nb = 0; + if ( myActor && selector ) { + nb = mySourceMode->checkedId() == NodesSrc ? + SMESH::GetNameOfSelectedElements( selector, IO, ID ) : + SMESH::GetNameOfSelectedNodes( selector, IO, ID ); + } + if ( nb > 0 ) { + myIDs = ID.trimmed(); + if ( nb < MAX_NB_FOR_EDITOR ) { + mySource->setReadOnly( false ); + if ( mySource->validator() != myValidator ) + mySource->setValidator( myValidator ); + mySource->setText( ID.trimmed() ); + } + else { + mySource->setReadOnly( true ); + mySource->setValidator( 0 ); + mySource->setText( tr( "SELECTED_NB_OBJ" ).arg( nb ) + .arg( mySourceMode->checkedId() == NodesSrc ? tr( "NB_NODES" ) : tr( "NB_ELEMENTS") ) ); + } + } + else { + myIDs = ""; + mySource->clear(); + mySource->setReadOnly( false ); + mySource->setValidator( myValidator ); + } + } + } + } + else if ( selected.Extent() > 1 ) { + myIDs = ""; + SALOME_ListIteratorOfListIO It( selected ); + mySrc.clear(); + myActor = 0; + if ( mySourceMode->checkedId() == ObjectsSrc ) { + for( ; It.More(); It.Next()){ + Handle(SALOME_InteractiveObject) IO = It.Value(); + SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( IO ); + if ( !CORBA::is_nil( obj ) ) { + mySrc.append( obj ); + } + } + QString aName; + SMESH::GetNameOfSelectedIObjects( SMESHGUI::selectionMgr(), aName ); + mySource->setText( aName ); + } + else { + mySource->clear(); + } + } + clear(); +} + +/*! + \brief Called when source mode is changed by the user +*/ +void SMESHGUI_BoundingBox::sourceChanged() +{ + myIDs = ""; + mySource->clear(); + mySource->setReadOnly( mySourceMode->checkedId() == ObjectsSrc ); + mySource->setValidator( mySourceMode->checkedId() == ObjectsSrc ? 0 : myValidator ); + updateSelection(); + clear(); +} + +/*! + \brief Called when source mode is edited by the user +*/ +void SMESHGUI_BoundingBox::sourceEdited() +{ + if ( sender() == mySource ) + clear(); + SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector(); + if ( myActor && selector ) { + Handle(SALOME_InteractiveObject) IO = myActor->getIO(); + if ( mySourceMode->checkedId() == NodesSrc || mySourceMode->checkedId() == ElementsSrc ) { + TColStd_MapOfInteger ID; + if ( !mySource->isReadOnly() ) + myIDs = mySource->text(); + QStringList ids = myIDs.split( " ", QString::SkipEmptyParts ); + foreach ( QString id, ids ) + ID.Add( id.trimmed().toLong() ); + selector->AddOrRemoveIndex( IO, ID, false ); + } + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->highlight( IO, true, true ); + } +} + +/*! + \brief Calculate bounding box of the selected object(s) +*/ +void SMESHGUI_BoundingBox::compute() +{ + SUIT_OverrideCursor wc; + SMESH::ListOfIDSources_var srcList = new SMESH::ListOfIDSources(); + if ( mySourceMode->checkedId() == NodesSrc || mySourceMode->checkedId() == ElementsSrc ) { + if ( mySrc.count() > 0 && !CORBA::is_nil( mySrc[0] ) ) { + SMESH::SMESH_Mesh_var m = mySrc[0]->GetMesh(); + QStringList ids = myIDs.split( " ", QString::SkipEmptyParts ); + if ( !CORBA::is_nil( m ) && ids.count() > 0 ) { + SMESH::long_array_var ids_in = new SMESH::long_array(); + ids_in->length( ids.count() ); + for( int i = 0; i < ids.count(); i++ ) + ids_in[i] = ids[i].trimmed().toLong(); + SMESH::SMESH_MeshEditor_var me = m->GetMeshEditor(); + SMESH::SMESH_IDSource_var s = me->MakeIDSource( ids_in.in(), mySourceMode->checkedId() == NodesSrc ? SMESH::NODE : SMESH::FACE ); + srcList->length( 1 ); + srcList[0] = s; + } + } + } + else { + srcList->length( mySrc.count() ); + for( int i = 0; i < mySrc.count(); i++ ) + srcList[i] = mySrc[i]; + } + if ( srcList->length() > 0 ) { + // compute bounding box + int precision = SMESHGUI::resourceMgr()->integerValue( "SMESH", "length_precision", 6 ); + SMESH::Measurements_var measure = SMESHGUI::GetSMESHGen()->CreateMeasurements(); + SMESH::Measure result = measure->BoundingBox( srcList.in() ); + measure->Destroy(); + myXmin->setText( QString::number( result.minX, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + myXmax->setText( QString::number( result.maxX, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + myDX->setText( QString::number( result.maxX-result.minX, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + myYmin->setText( QString::number( result.minY, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + myYmax->setText( QString::number( result.maxY, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + myDY->setText( QString::number( result.maxY-result.minY, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + myZmin->setText( QString::number( result.minZ, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + myZmax->setText( QString::number( result.maxZ, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + myDZ->setText( QString::number( result.maxZ-result.minZ, precision > 0 ? 'f' : 'g', qAbs( precision ) ) ); + // update preview actor + erasePreview(); + createPreview( result.minX, result.maxX, result.minY, result.maxY, result.minZ, result.maxZ ); + displayPreview(); + } + else { + clear(); + } +} + +/*! + \brief Reset the widget to the initial state (nullify result fields) +*/ +void SMESHGUI_BoundingBox::clear() +{ + myXmin->clear(); + myXmax->clear(); + myDX->clear(); + myYmin->clear(); + myYmax->clear(); + myDY->clear(); + myZmin->clear(); + myZmax->clear(); + myDZ->clear(); + erasePreview(); +} + +/*! + \class SMESHGUI_MeshInfoDlg + \brief Centralized dialog box for the measurements +*/ + +/*! + \brief Constructor + \param parent parent widget + \param page specifies the dialog page to be shown at the start-up +*/ +SMESHGUI_MeasureDlg::SMESHGUI_MeasureDlg( QWidget* parent, int page ) +: QDialog( parent ) +{ + setModal( false ); + setAttribute( Qt::WA_DeleteOnClose, true ); + setWindowTitle( tr( "MEASUREMENTS" ) ); + setSizeGripEnabled( true ); + + SUIT_ResourceMgr* resMgr = SMESHGUI::resourceMgr(); + + myTabWidget = new QTabWidget( this ); + + // min distance + + myMinDist = new SMESHGUI_MinDistance( myTabWidget ); + myTabWidget->addTab( myMinDist, resMgr->loadPixmap( "SMESH", tr( "ICON_MEASURE_MIN_DIST" ) ), tr( "MIN_DIST" ) ); + + // bounding box + + myBndBox = new SMESHGUI_BoundingBox( myTabWidget ); + myTabWidget->addTab( myBndBox, resMgr->loadPixmap( "SMESH", tr( "ICON_MEASURE_BND_BOX" ) ), tr( "BND_BOX" ) ); + + // buttons + QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this ); + okBtn->setAutoDefault( true ); + okBtn->setDefault( true ); + okBtn->setFocus(); + QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this ); + helpBtn->setAutoDefault( true ); + + QHBoxLayout* btnLayout = new QHBoxLayout; + btnLayout->setSpacing( SPACING ); + btnLayout->setMargin( 0 ); + btnLayout->addWidget( okBtn ); + btnLayout->addStretch( 10 ); + btnLayout->addWidget( helpBtn ); + + QVBoxLayout* l = new QVBoxLayout ( this ); + l->setMargin( MARGIN ); + l->setSpacing( SPACING ); + l->addWidget( myTabWidget ); + l->addStretch(); + l->addLayout( btnLayout ); + + myTabWidget->setCurrentIndex( qMax( (int)MinDistance, qMin( (int)BoundingBox, page ) ) ); + + connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) ); + connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) ); + connect( myTabWidget, SIGNAL( currentChanged( int ) ), this, SLOT( updateSelection() ) ); + connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) ); + connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) ); + + updateSelection(); +} + +/*! + \brief Destructor +*/ +SMESHGUI_MeasureDlg::~SMESHGUI_MeasureDlg() +{ +} + +/*! + \brief Perform clean-up actions on the dialog box closing. +*/ +void SMESHGUI_MeasureDlg::reject() +{ + LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr(); + selMgr->clearFilters(); + SMESH::SetPointRepresentation( false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( ActorSelection ); + QDialog::reject(); +} + +/*! + \brief Process keyboard event + \param e key press event +*/ +void SMESHGUI_MeasureDlg::keyPressEvent( QKeyEvent* e ) +{ + QDialog::keyPressEvent( e ); + if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) { + e->accept(); + help(); + } +} + +/*! + \brief Reactivate dialog box, when mouse pointer goes into it. +*/ +void SMESHGUI_MeasureDlg::enterEvent( QEvent* ) +{ + activate(); +} + +/*! + \brief Setup selection mode depending on the current dialog box state. +*/ +void SMESHGUI_MeasureDlg::updateSelection() +{ + if ( myTabWidget->currentIndex() == MinDistance ) + myMinDist->updateSelection(); + else if ( myTabWidget->currentIndex() == BoundingBox ) + myBndBox->updateSelection(); + +} + +/*! + \brief Show help page +*/ +void SMESHGUI_MeasureDlg::help() +{ + SMESH::ShowHelpFile( myTabWidget->currentIndex() == MinDistance ? + "measurements_page.html#min_distance_anchor" : + "measurements_page.html#bounding_box_anchor" ); +} + +/*! + \brief Activate dialog box +*/ +void SMESHGUI_MeasureDlg::activate() +{ + SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog(); + SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this ); + myTabWidget->setEnabled( true ); + updateSelection(); +} + +/*! + \brief Deactivate dialog box +*/ +void SMESHGUI_MeasureDlg::deactivate() +{ + myMinDist->deactivate(); + myBndBox->deactivate(); + myTabWidget->setEnabled( false ); + disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) ); +} diff --git a/src/SMESHGUI/SMESHGUI_Measurements.h b/src/SMESHGUI/SMESHGUI_Measurements.h new file mode 100644 index 000000000..b9b58c8be --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_Measurements.h @@ -0,0 +1,172 @@ +// 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 +// +// File : SMESHGUI_Measurements.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) + +#ifndef SMESHGUI_MEASUREMENTS_H +#define SMESHGUI_MEASUREMENTS_H + +#include "SMESH_SMESHGUI.hxx" + +#include + +class QButtonGroup; +class QLineEdit; +class QTabWidget; +class SUIT_SelectionFilter; +class SALOME_Actor; +class SMESH_Actor; +class SMESHGUI_IdValidator; + +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) + +class SMESHGUI_EXPORT SMESHGUI_MinDistance : public QWidget +{ + Q_OBJECT; + + enum { NoTgt, FirstTgt, SecondTgt }; + enum { OriginTgt, NodeTgt, ElementTgt, ObjectTgt }; + +public: + SMESHGUI_MinDistance( QWidget* = 0 ); + ~SMESHGUI_MinDistance(); + + bool eventFilter( QObject*, QEvent* ); + void updateSelection(); + void deactivate(); + +private: + void setTarget( int ); + void erasePreview(); + void displayPreview(); + void createPreview( double, double, double, double, double, double ); + +private slots: + void selectionChanged(); + void firstChanged(); + void secondChanged(); + void firstEdited(); + void secondEdited(); + void compute(); + void clear(); + +private: + QButtonGroup* myFirst; + QButtonGroup* mySecond; + QLineEdit* myFirstTgt; + QLineEdit* mySecondTgt; + QLineEdit* myDX; + QLineEdit* myDY; + QLineEdit* myDZ; + QLineEdit* myDistance; + int myCurrentTgt; + SMESH::SMESH_IDSource_var myFirstSrc; + SMESH::SMESH_IDSource_var mySecondSrc; + SMESH_Actor* myFirstActor; + SMESH_Actor* mySecondActor; + SMESHGUI_IdValidator* myValidator; + SUIT_SelectionFilter* myFilter; + SALOME_Actor* myPreview; +}; + +class SMESHGUI_EXPORT SMESHGUI_BoundingBox : public QWidget +{ + Q_OBJECT; + + enum { ObjectsSrc, NodesSrc, ElementsSrc }; + +public: + SMESHGUI_BoundingBox( QWidget* = 0 ); + ~SMESHGUI_BoundingBox(); + + void updateSelection(); + void deactivate(); + +private: + void erasePreview(); + void displayPreview(); + void createPreview( double, double, double, double, double, double ); + +private slots: + void selectionChanged(); + void sourceChanged(); + void sourceEdited(); + void compute(); + void clear(); + +private: + typedef QList SourceList; + QButtonGroup* mySourceMode; + QLineEdit* mySource; + QLineEdit* myXmin; + QLineEdit* myXmax; + QLineEdit* myDX; + QLineEdit* myYmin; + QLineEdit* myYmax; + QLineEdit* myDY; + QLineEdit* myZmin; + QLineEdit* myZmax; + QLineEdit* myDZ; + SourceList mySrc; + SMESH_Actor* myActor; + SMESHGUI_IdValidator* myValidator; + QString myIDs; + SUIT_SelectionFilter* myFilter; + SALOME_Actor* myPreview; +}; + +class SMESHGUI_EXPORT SMESHGUI_MeasureDlg : public QDialog +{ + Q_OBJECT; + + enum { NodeMode, ElemMode }; + +public: + //! Measurement type + enum { + MinDistance, //!< minimum distance + BoundingBox //!< bounding box + }; + + SMESHGUI_MeasureDlg( QWidget* = 0, int = MinDistance ); + ~SMESHGUI_MeasureDlg(); + + void reject(); + +protected: + void keyPressEvent( QKeyEvent* ); + void enterEvent( QEvent* ); + +private slots: + void help(); + void updateSelection(); + void activate(); + void deactivate(); + +private: + QTabWidget* myTabWidget; + SMESHGUI_MinDistance* myMinDist; + SMESHGUI_BoundingBox* myBndBox; +}; + +#endif // SMESHGUI_MEASUREMENTS_H diff --git a/src/SMESHGUI/SMESHGUI_MergeDlg.cxx b/src/SMESHGUI/SMESHGUI_MergeDlg.cxx new file mode 100644 index 000000000..26922e93d --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_MergeDlg.cxx @@ -0,0 +1,1323 @@ +// 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_MergeDlg.cxx +// Author : Open CASCADE S.A.S. +// SMESH includes +// +#include "SMESHGUI_MergeDlg.h" + +#include "SMESHGUI.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_VTKUtils.h" +#include "SMESHGUI_MeshUtils.h" +#include "SMESHGUI_SpinBox.h" + +#include +#include +#include +#include + +// SALOME GUI includes +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +// OCCT includes +#include +#include + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_Group) +#include CORBA_SERVER_HEADER(SMESH_MeshEditor) + +// VTK includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if !defined(VTK_XVERSION) +#define VTK_XVERSION (VTK_MAJOR_VERSION<<16)+(VTK_MINOR_VERSION<<8)+(VTK_BUILD_VERSION) +#endif + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SPACING 6 +#define MARGIN 11 + +namespace SMESH +{ + class TIdPreview + { // to display in the viewer IDs of the selected elements + SVTK_ViewWindow* myViewWindow; + + vtkUnstructuredGrid* myIdGrid; + SALOME_Actor* myIdActor; + + vtkUnstructuredGrid* myPointsNumDataSet; + vtkMaskPoints* myPtsMaskPoints; + vtkSelectVisiblePoints* myPtsSelectVisiblePoints; + vtkLabeledDataMapper* myPtsLabeledDataMapper; + vtkTextProperty* aPtsTextProp; + bool myIsPointsLabeled; + vtkActor2D* myPointLabels; + + std::vector myIDs; + + public: + TIdPreview(SVTK_ViewWindow* theViewWindow): + myViewWindow(theViewWindow) + { + myIdGrid = vtkUnstructuredGrid::New(); + + // Create and display actor + vtkDataSetMapper* aMapper = vtkDataSetMapper::New(); + aMapper->SetInput( myIdGrid ); + + myIdActor = SALOME_Actor::New(); + myIdActor->SetInfinitive(true); + myIdActor->VisibilityOff(); + myIdActor->PickableOff(); + + myIdActor->SetMapper( aMapper ); + aMapper->Delete(); + + myViewWindow->AddActor(myIdActor); + + //Definition of points numbering pipeline + myPointsNumDataSet = vtkUnstructuredGrid::New(); + + myPtsMaskPoints = vtkMaskPoints::New(); + myPtsMaskPoints->SetInput(myPointsNumDataSet); + myPtsMaskPoints->SetOnRatio(1); + + myPtsSelectVisiblePoints = vtkSelectVisiblePoints::New(); + myPtsSelectVisiblePoints->SetInput(myPtsMaskPoints->GetOutput()); + myPtsSelectVisiblePoints->SelectInvisibleOff(); + myPtsSelectVisiblePoints->SetTolerance(0.1); + + myPtsLabeledDataMapper = vtkLabeledDataMapper::New(); + myPtsLabeledDataMapper->SetInput(myPtsSelectVisiblePoints->GetOutput()); +#if (VTK_XVERSION < 0x050200) + myPtsLabeledDataMapper->SetLabelFormat("%g"); +#endif + myPtsLabeledDataMapper->SetLabelModeToLabelScalars(); + + vtkTextProperty* aPtsTextProp = vtkTextProperty::New(); + aPtsTextProp->SetFontFamilyToTimes(); + static int aPointsFontSize = 12; + aPtsTextProp->SetFontSize(aPointsFontSize); + aPtsTextProp->SetBold(1); + aPtsTextProp->SetItalic(0); + aPtsTextProp->SetShadow(0); + myPtsLabeledDataMapper->SetLabelTextProperty(aPtsTextProp); + aPtsTextProp->Delete(); + + myIsPointsLabeled = false; + + myPointLabels = vtkActor2D::New(); + myPointLabels->SetMapper(myPtsLabeledDataMapper); + myPointLabels->GetProperty()->SetColor(1,1,1); + myPointLabels->SetVisibility(myIsPointsLabeled); + + AddToRender(myViewWindow->getRenderer()); + } + + void SetPointsData ( SMDS_Mesh* theMesh, + TColStd_MapOfInteger & theNodesIdMap ) + { + vtkPoints* aPoints = vtkPoints::New(); + aPoints->SetNumberOfPoints(theNodesIdMap.Extent()); + myIDs.clear(); + + TColStd_MapIteratorOfMapOfInteger idIter( theNodesIdMap ); + for( int i = 0; idIter.More(); idIter.Next(), i++ ) { + const SMDS_MeshNode* aNode = theMesh->FindNode(idIter.Key()); + aPoints->SetPoint( i, aNode->X(), aNode->Y(), aNode->Z() ); + myIDs.push_back(idIter.Key()); + } + + myIdGrid->SetPoints(aPoints); + + aPoints->Delete(); + + myIdActor->GetMapper()->Update(); + } + + void SetElemsData( TColStd_MapOfInteger & theElemsIdMap, + std::list & aGrCentersXYZ ) + { + vtkPoints* aPoints = vtkPoints::New(); + aPoints->SetNumberOfPoints(theElemsIdMap.Extent()); + myIDs.clear(); + + TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap ); + for( ; idIter.More(); idIter.Next() ) { + myIDs.push_back(idIter.Key()); + } + + gp_XYZ aXYZ; + std::list::iterator coordIt = aGrCentersXYZ.begin(); + for( int i = 0; coordIt != aGrCentersXYZ.end(); coordIt++, i++ ) { + aXYZ = *coordIt; + aPoints->SetPoint( i, aXYZ.X(), aXYZ.Y(), aXYZ.Z() ); + } + myIdGrid->SetPoints(aPoints); + aPoints->Delete(); + + myIdActor->GetMapper()->Update(); + } + + void AddToRender(vtkRenderer* theRenderer) + { + myIdActor->AddToRender(theRenderer); + + myPtsSelectVisiblePoints->SetRenderer(theRenderer); + theRenderer->AddActor2D(myPointLabels); + } + + void RemoveFromRender(vtkRenderer* theRenderer) + { + myIdActor->RemoveFromRender(theRenderer); + + myPtsSelectVisiblePoints->SetRenderer(theRenderer); + theRenderer->RemoveActor(myPointLabels); + } + + void SetPointsLabeled( bool theIsPointsLabeled, bool theIsActorVisible = true ) + { + myIsPointsLabeled = theIsPointsLabeled && myIdGrid->GetNumberOfPoints(); + + if ( myIsPointsLabeled ) { + myPointsNumDataSet->ShallowCopy(myIdGrid); + vtkDataSet *aDataSet = myPointsNumDataSet; + int aNbElem = myIDs.size(); + vtkIntArray *anArray = vtkIntArray::New(); + anArray->SetNumberOfValues( aNbElem ); + for ( int i = 0; i < aNbElem; i++ ) + anArray->SetValue( i, myIDs[i] ); + aDataSet->GetPointData()->SetScalars( anArray ); + anArray->Delete(); + myPtsMaskPoints->SetInput( aDataSet ); + myPointLabels->SetVisibility( theIsActorVisible ); + } + else { + myPointLabels->SetVisibility( false ); + } + } + + ~TIdPreview() + { + RemoveFromRender(myViewWindow->getRenderer()); + + myIdGrid->Delete(); + + myViewWindow->RemoveActor(myIdActor); + myIdActor->Delete(); + + //Deleting of points numbering pipeline + //--------------------------------------- + myPointsNumDataSet->Delete(); + + //myPtsLabeledDataMapper->RemoveAllInputs(); //vtk 5.0 porting + myPtsLabeledDataMapper->Delete(); + + //myPtsSelectVisiblePoints->UnRegisterAllOutputs(); //vtk 5.0 porting + myPtsSelectVisiblePoints->Delete(); + + //myPtsMaskPoints->UnRegisterAllOutputs(); //vtk 5.0 porting + myPtsMaskPoints->Delete(); + + myPointLabels->Delete(); + +// myTimeStamp->Delete(); + } + }; +} + +static const char * IconFirst[] = { +"18 10 2 1", +" g None", +". g #000000", +" . . ", +" .. .. .. ", +" .. ... ... ", +" .. .... .... ", +" .. ..... ..... ", +" .. ..... ..... ", +" .. .... .... ", +" .. ... ... ", +" .. .. .. ", +" . . "}; + +//================================================================================= +// class : SMESHGUI_MergeDlg() +// purpose : +//================================================================================= +SMESHGUI_MergeDlg::SMESHGUI_MergeDlg (SMESHGUI* theModule, int theAction) + : QDialog(SMESH::GetDesktop(theModule)), + mySMESHGUI(theModule), + mySelectionMgr(SMESH::GetSelectionMgr(theModule)), + myAction(theAction) +{ + setModal(false); + setAttribute(Qt::WA_DeleteOnClose, true); + setWindowTitle(myAction == 1 ? tr("SMESH_MERGE_ELEMENTS") : tr("SMESH_MERGE_NODES")); + + myIdPreview = new SMESH::TIdPreview(SMESH::GetViewWindow( mySMESHGUI )); + + SUIT_ResourceMgr* aResMgr = SMESH::GetResourceMgr( mySMESHGUI ); + QPixmap IconMergeNodes (aResMgr->loadPixmap("SMESH", tr("ICON_SMESH_MERGE_NODES"))); + QPixmap IconMergeElems (aResMgr->loadPixmap("SMESH", tr("ICON_DLG_MERGE_ELEMENTS"))); + QPixmap IconSelect (aResMgr->loadPixmap("SMESH", tr("ICON_SELECT"))); + QPixmap IconAdd (aResMgr->loadPixmap("SMESH", tr("ICON_APPEND"))); + QPixmap IconRemove (aResMgr->loadPixmap("SMESH", tr("ICON_REMOVE"))); + + setSizeGripEnabled(true); + + QVBoxLayout* DlgLayout = new QVBoxLayout(this); + DlgLayout->setSpacing(SPACING); + DlgLayout->setMargin(MARGIN); + + /***************************************************************/ + GroupConstructors = new QGroupBox(myAction == 1 ? + tr("SMESH_MERGE_ELEMENTS") : + tr("SMESH_MERGE_NODES"), + this); + + QButtonGroup* ButtonGroup = new QButtonGroup(this); + QHBoxLayout* GroupConstructorsLayout = new QHBoxLayout(GroupConstructors); + GroupConstructorsLayout->setSpacing(SPACING); + GroupConstructorsLayout->setMargin(MARGIN); + + RadioButton = new QRadioButton(GroupConstructors); + RadioButton->setIcon(myAction == 1 ? IconMergeElems : IconMergeNodes); + RadioButton->setChecked(true); + GroupConstructorsLayout->addWidget(RadioButton); + ButtonGroup->addButton(RadioButton, 0); + + /***************************************************************/ + // Controls for mesh defining + GroupMesh = new QGroupBox(tr("SMESH_SELECT_WHOLE_MESH"), this); + QHBoxLayout* GroupMeshLayout = new QHBoxLayout(GroupMesh); + GroupMeshLayout->setSpacing(SPACING); + GroupMeshLayout->setMargin(MARGIN); + + TextLabelName = new QLabel(tr("SMESH_NAME"), GroupMesh); + SelectMeshButton = new QPushButton(GroupMesh); + SelectMeshButton->setIcon(IconSelect); + LineEditMesh = new QLineEdit(GroupMesh); + LineEditMesh->setReadOnly(true); + + GroupMeshLayout->addWidget(TextLabelName); + GroupMeshLayout->addWidget(SelectMeshButton); + GroupMeshLayout->addWidget(LineEditMesh); + + /***************************************************************/ + // Controls for switch dialog behaviour + + TypeBox = new QGroupBox( tr( "SMESH_MODE" ), this ); + GroupType = new QButtonGroup( this ); + QHBoxLayout* aTypeBoxLayout = new QHBoxLayout( TypeBox ); + aTypeBoxLayout->setMargin( MARGIN ); + aTypeBoxLayout->setSpacing( SPACING ); + + QRadioButton* rb1 = new QRadioButton( tr( "SMESH_AUTOMATIC" ), TypeBox ); + QRadioButton* rb2 = new QRadioButton( tr( "SMESH_MANUAL" ), TypeBox ); + GroupType->addButton( rb1, 0 ); + GroupType->addButton( rb2, 1 ); + aTypeBoxLayout->addWidget( rb1 ); + aTypeBoxLayout->addWidget( rb2 ); + + myTypeId = 0; + + /***************************************************************/ + // Controls for coincident elements detecting + GroupCoincident = new QGroupBox(myAction == 1 ? + tr("COINCIDENT_ELEMENTS") : + tr("COINCIDENT_NODES"), + this); + + QVBoxLayout* aCoincidentLayout = new QVBoxLayout(GroupCoincident); + aCoincidentLayout->setSpacing(SPACING); + aCoincidentLayout->setMargin(MARGIN); + + if (myAction == 0) { // case merge nodes + QWidget* foo = new QWidget(GroupCoincident); + TextLabelTolerance = new QLabel(tr("SMESH_TOLERANCE"), foo); + SpinBoxTolerance = new SMESHGUI_SpinBox(foo); + SpinBoxTolerance->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); + + GroupExclude = new QGroupBox(tr("EXCLUDE_GROUPS"), foo); + GroupExclude->setCheckable( true ); + GroupExclude->setChecked( false ); + ListExclude = new QListWidget( GroupExclude ); + QVBoxLayout* GroupExcludeLayout = new QVBoxLayout(GroupExclude); + GroupExcludeLayout->setSpacing(SPACING); + GroupExcludeLayout->setMargin(MARGIN); + GroupExcludeLayout->addWidget(ListExclude); + + QGridLayout* fooLayout = new QGridLayout( foo ); + fooLayout->setSpacing(SPACING); + fooLayout->setMargin(0); + fooLayout->addWidget(TextLabelTolerance, 0, 0 ); + fooLayout->addWidget(SpinBoxTolerance, 0, 1 ); + fooLayout->addWidget(GroupExclude, 1, 0, 1, 2 ); + aCoincidentLayout->addWidget(foo); + } + else { + TextLabelTolerance = 0; + SpinBoxTolerance = 0; + GroupExclude = 0; + ListExclude = 0; + } + + GroupCoincidentWidget = new QWidget(GroupCoincident); + QGridLayout* GroupCoincidentLayout = new QGridLayout(GroupCoincidentWidget); + GroupCoincidentLayout->setSpacing(SPACING); + GroupCoincidentLayout->setMargin(0); + + ListCoincident = new QListWidget(GroupCoincidentWidget); + ListCoincident->setSelectionMode(QListWidget::ExtendedSelection); + + DetectButton = new QPushButton(tr("DETECT"), GroupCoincidentWidget); + AddGroupButton = new QPushButton(tr("SMESH_BUT_ADD"), GroupCoincidentWidget); + RemoveGroupButton = new QPushButton(tr("SMESH_BUT_REMOVE"), GroupCoincidentWidget); + + SelectAllCB = new QCheckBox(tr("SELECT_ALL"), GroupCoincidentWidget); + + GroupCoincidentLayout->addWidget(ListCoincident, 0, 0, 4, 2); + GroupCoincidentLayout->addWidget(DetectButton, 0, 2); + GroupCoincidentLayout->addWidget(AddGroupButton, 2, 2); + GroupCoincidentLayout->addWidget(RemoveGroupButton, 3, 2); + GroupCoincidentLayout->addWidget(SelectAllCB, 4, 0, 1, 3); + GroupCoincidentLayout->setRowMinimumHeight(1, 10); + GroupCoincidentLayout->setRowStretch(1, 5); + + aCoincidentLayout->addWidget(GroupCoincidentWidget); + + /***************************************************************/ + // Controls for editing the selected group + GroupEdit = new QGroupBox(tr("EDIT_SELECTED_GROUP"), this); + QGridLayout* GroupEditLayout = new QGridLayout(GroupEdit); + GroupEditLayout->setSpacing(SPACING); + GroupEditLayout->setMargin(MARGIN); + + ListEdit = new QListWidget(GroupEdit); + //ListEdit->setRowMode(QListBox::FixedNumber); + //ListEdit->setHScrollBarMode(QScrollView::AlwaysOn); + //ListEdit->setVScrollBarMode(QScrollView::AlwaysOff); + ListEdit->setFlow( QListView::LeftToRight ); + ListEdit->setSelectionMode(QListWidget::ExtendedSelection); + + AddElemButton = new QPushButton(GroupEdit); + AddElemButton->setIcon(IconAdd); + RemoveElemButton = new QPushButton(GroupEdit); + RemoveElemButton->setIcon(IconRemove); + SetFirstButton = new QPushButton(GroupEdit); + SetFirstButton->setIcon(QPixmap(IconFirst)); + + GroupEditLayout->addWidget(ListEdit, 0, 0, 2, 1); + GroupEditLayout->addWidget(AddElemButton, 0, 1); + GroupEditLayout->addWidget(RemoveElemButton, 0, 2); + GroupEditLayout->addWidget(SetFirstButton, 1, 1, 1, 2); + + /***************************************************************/ + 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); + + /***************************************************************/ + DlgLayout->addWidget(GroupConstructors); + DlgLayout->addWidget(GroupMesh); + DlgLayout->addWidget(TypeBox); + DlgLayout->addWidget(GroupCoincident); + DlgLayout->addWidget(GroupEdit); + DlgLayout->addWidget(GroupButtons); + + GroupCoincidentWidget->setVisible( myAction != 0 ); + GroupCoincident->setVisible( myAction == 0 ); + //if GroupExclude->setVisible( myAction == 0 ); + GroupEdit->hide(); + + this->resize(10,10); + + Init(); // Initialisations +} + +//================================================================================= +// function : ~SMESHGUI_MergeDlg() +// purpose : Destroys the object and frees any allocated resources +//================================================================================= +SMESHGUI_MergeDlg::~SMESHGUI_MergeDlg() +{ + delete myIdPreview; +} + +//================================================================================= +// function : Init() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::Init() +{ + if (myAction == 0) { + SpinBoxTolerance->RangeStepAndValidator(0.0, COORD_MAX, 0.00001, "len_tol_precision"); + SpinBoxTolerance->SetValue(1e-05); + } + + RadioButton->setChecked(true); + + GroupType->button(0)->setChecked(true); + + myEditCurrentArgument = (QWidget*)LineEditMesh; + + myActor = 0; + mySubMeshOrGroup = SMESH::SMESH_subMesh::_nil(); + + mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector(); + + mySMESHGUI->SetActiveDialogBox((QDialog*)this); + myIsBusy = false; + + /* 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(SelectMeshButton, SIGNAL (clicked()), this, SLOT(SetEditCurrentArgument())); + connect(DetectButton, SIGNAL (clicked()), this, SLOT(onDetect())); + connect(ListCoincident, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectGroup())); + connect(AddGroupButton, SIGNAL (clicked()), this, SLOT(onAddGroup())); + connect(RemoveGroupButton, SIGNAL (clicked()), this, SLOT(onRemoveGroup())); + connect(SelectAllCB, SIGNAL(toggled(bool)), this, SLOT(onSelectAll(bool))); + connect(ListEdit, SIGNAL (itemSelectionChanged()), this, SLOT(onSelectElementFromGroup())); + connect(AddElemButton, SIGNAL (clicked()), this, SLOT(onAddElement())); + connect(RemoveElemButton, SIGNAL (clicked()), this, SLOT(onRemoveElement())); + connect(SetFirstButton, SIGNAL( clicked() ), this, SLOT( onSetFirst() ) ); + connect(GroupType, SIGNAL(buttonClicked(int)), this, SLOT(onTypeChanged(int))); + + connect(mySMESHGUI, SIGNAL (SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog())); + connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); + /* to close dialog if study change */ + connect(mySMESHGUI, SIGNAL (SignalCloseAllDialogs()), this, SLOT(ClickOnCancel())); + + // Init Mesh field from selection + SelectionIntoArgument(); + + // Update Buttons + updateControls(); + + if (myAction == 0) + myHelpFileName = "merging_nodes_page.html"; + else + myHelpFileName = "merging_elements_page.html"; +} + +//================================================================================= +// function : FindGravityCenter() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::FindGravityCenter(TColStd_MapOfInteger & theElemsIdMap, + std::list< gp_XYZ > & theGrCentersXYZ) +{ + if (!myActor) + return; + + SMDS_Mesh* aMesh = 0; + aMesh = myActor->GetObject()->GetMesh(); + if (!aMesh) + return; + + int nbNodes; + + TColStd_MapIteratorOfMapOfInteger idIter( theElemsIdMap ); + for( ; idIter.More(); idIter.Next() ) { + const SMDS_MeshElement* anElem = aMesh->FindElement(idIter.Key()); + if ( !anElem ) + continue; + + gp_XYZ anXYZ(0., 0., 0.); + SMDS_ElemIteratorPtr nodeIt = anElem->nodesIterator(); + for ( nbNodes = 0; nodeIt->more(); nbNodes++ ) { + const SMDS_MeshNode* node = static_cast( nodeIt->next() ); + anXYZ.Add( gp_XYZ( node->X(), node->Y(), node->Z() ) ); + } + anXYZ.Divide( nbNodes ); + + theGrCentersXYZ.push_back( anXYZ ); + } +} + +//================================================================================= +// function : ClickOnApply() +// purpose : +//================================================================================= +bool SMESHGUI_MergeDlg::ClickOnApply() +{ + if (mySMESHGUI->isActiveStudyLocked() || myMesh->_is_nil()) + return false; + + try { + if (myTypeId == 0) + onDetect(); + + SUIT_OverrideCursor aWaitCursor; + SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); + + SMESH::long_array_var anIds = new SMESH::long_array; + SMESH::array_of_long_array_var aGroupsOfElements = new SMESH::array_of_long_array; + + if ( ListCoincident->count() == 0) { + if (myAction == 0) + SUIT_MessageBox::warning(this, + tr("SMESH_WARNING"), + tr("SMESH_NO_NODES_DETECTED")); + else + SUIT_MessageBox::warning(this, + tr("SMESH_WARNING"), + tr("SMESH_NO_ELEMENTS_DETECTED")); + return false; + } + + aGroupsOfElements->length(ListCoincident->count()); + + int anArrayNum = 0; + for (int i = 0; i < ListCoincident->count(); i++) { + QStringList aListIds = ListCoincident->item(i)->text().split(" ", QString::SkipEmptyParts); + + anIds->length(aListIds.count()); + for (int i = 0; i < aListIds.count(); i++) + anIds[i] = aListIds[i].toInt(); + + aGroupsOfElements[anArrayNum++] = anIds.inout(); + } + + if( myAction == 0 ) + aMeshEditor->MergeNodes (aGroupsOfElements.inout()); + else + aMeshEditor->MergeElements (aGroupsOfElements.inout()); + + if ( myTypeId == 0 ) { + if (myAction ==0) + SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INFORMATION"), + tr("SMESH_MERGED_NODES").arg(QString::number(ListCoincident->count()).toLatin1().data())); + else + SUIT_MessageBox::information(SMESHGUI::desktop(), tr("SMESH_INFORMATION"), + tr("SMESH_MERGED_ELEMENTS").arg(QString::number(ListCoincident->count()).toLatin1().data())); + } + + + } catch(...) { + } + + SMESH::UpdateView(); + SMESHGUI::Modified(); + + return true; +} + +//================================================================================= +// function : ClickOnOk() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::ClickOnOk() +{ + if (ClickOnApply()) + ClickOnCancel(); +} + +//================================================================================= +// function : ClickOnCancel() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::ClickOnCancel() +{ + myIdPreview->SetPointsLabeled(false); + SMESH::SetPointRepresentation(false); + disconnect(mySelectionMgr, 0, this, 0); + disconnect(mySMESHGUI, 0, this, 0); + mySMESHGUI->ResetState(); + + mySelectionMgr->clearFilters(); + //mySelectionMgr->clearSelected(); + + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(ActorSelection); + + reject(); +} + +//================================================================================= +// function : ClickOnHelp() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::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 : onEditGroup() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::onEditGroup() +{ + QList selItems = ListCoincident->selectedItems(); + if ( selItems.count() != 1 ) { + ListEdit->clear(); + return; + } + + QStringList aNewIds; + + for (int i = 0; i < ListEdit->count(); i++ ) + aNewIds.append(ListEdit->item(i)->text()); + + ListCoincident->clearSelection(); + selItems.first()->setText(aNewIds.join(" ")); + selItems.first()->setSelected(true); +} + +//================================================================================= +// function : updateControls() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::updateControls() +{ + if (ListEdit->count() == 0) + SetFirstButton->setEnabled(false); + bool enable = !(myMesh->_is_nil()) && (ListCoincident->count() || (myTypeId == 0)); + buttonOk->setEnabled(enable); + buttonApply->setEnabled(enable); +} + +//================================================================================= +// function : onDetect() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::onDetect() +{ + if ( myMesh->_is_nil() || LineEditMesh->text().isEmpty() ) + return; + + try { + SUIT_OverrideCursor aWaitCursor; + SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); + + ListCoincident->clear(); + ListEdit->clear(); + + SMESH::array_of_long_array_var aGroupsArray; + SMESH::ListOfIDSources_var aExcludeGroups = new SMESH::ListOfIDSources; + + SMESH::SMESH_IDSource_var src; + if ( mySubMeshOrGroup->_is_nil() ) src = SMESH::SMESH_IDSource::_duplicate( myMesh ); + else src = SMESH::SMESH_IDSource::_duplicate( mySubMeshOrGroup ); + + switch (myAction) { + case 0 : + for ( int i = 0; GroupExclude->isChecked() && i < ListExclude->count(); i++ ) { + if ( ListExclude->item( i )->checkState() == Qt::Checked ) { + aExcludeGroups->length( aExcludeGroups->length()+1 ); + aExcludeGroups[ aExcludeGroups->length()-1 ] = SMESH::SMESH_IDSource::_duplicate( myGroups[i] ); + } + } + aMeshEditor->FindCoincidentNodesOnPartBut(src.in(), + SpinBoxTolerance->GetValue(), + aGroupsArray.out(), + aExcludeGroups.in()); + break; + case 1 : + aMeshEditor->FindEqualElements(src.in(), aGroupsArray.out()); + break; + } + + for (int i = 0; i < aGroupsArray->length(); i++) { + SMESH::long_array& aGroup = aGroupsArray[i]; + + QStringList anIDs; + for (int j = 0; j < aGroup.length(); j++) + anIDs.append(QString::number(aGroup[j])); + + ListCoincident->addItem(anIDs.join(" ")); + } + } catch(...) { + } + + ListCoincident->selectAll(); + updateControls(); +} + +//================================================================================= +// function : onSelectGroup() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::onSelectGroup() +{ + if (myIsBusy || !myActor) + return; + myEditCurrentArgument = (QWidget*)ListCoincident; + + ListEdit->clear(); + + TColStd_MapOfInteger anIndices; + QList selItems = ListCoincident->selectedItems(); + QListWidgetItem* anItem; + QStringList aListIds; + + ListEdit->clear(); + + foreach(anItem, selItems) { + aListIds = anItem->text().split(" ", QString::SkipEmptyParts); + for (int i = 0; i < aListIds.count(); i++) + anIndices.Add(aListIds[i].toInt()); + } + + if (selItems.count() == 1) { + ListEdit->addItems(aListIds); + ListEdit->selectAll(); + } + + mySelector->AddOrRemoveIndex(myActor->getIO(), anIndices, false); + SALOME_ListIO aList; + aList.Append(myActor->getIO()); + mySelectionMgr->setSelectedObjects(aList,false); + + if (myAction == 0) { + myIdPreview->SetPointsData(myActor->GetObject()->GetMesh(), anIndices); + myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility()); + } + else { + std::list< gp_XYZ > aGrCentersXYZ; + FindGravityCenter(anIndices, aGrCentersXYZ); + myIdPreview->SetElemsData( anIndices, aGrCentersXYZ); + myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility()); + } + + updateControls(); +} + +//================================================================================= +// function : onSelectAll() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::onSelectAll (bool isToggled) +{ + if ( isToggled ) + ListCoincident->selectAll(); + else + ListCoincident->clearSelection(); +} + +//================================================================================= +// function : onSelectElementFromGroup() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::onSelectElementFromGroup() +{ + if (myIsBusy || !myActor) + return; + + TColStd_MapOfInteger anIndices; + QList selItems = ListEdit->selectedItems(); + QListWidgetItem* anItem; + + foreach(anItem, selItems) + anIndices.Add(anItem->text().toInt()); + + SetFirstButton->setEnabled(selItems.count() == 1); + + mySelector->AddOrRemoveIndex(myActor->getIO(), anIndices, false); + SALOME_ListIO aList; + aList.Append(myActor->getIO()); + mySelectionMgr->setSelectedObjects(aList); + + if (myAction == 0) { + myIdPreview->SetPointsData(myActor->GetObject()->GetMesh(), anIndices); + myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility()); + } + else { + std::list< gp_XYZ > aGrCentersXYZ; + FindGravityCenter(anIndices, aGrCentersXYZ); + myIdPreview->SetElemsData(anIndices, aGrCentersXYZ); + myIdPreview->SetPointsLabeled(!anIndices.IsEmpty(), myActor->GetVisibility()); + } +} + +//================================================================================= +// function : onAddGroup() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::onAddGroup() +{ + if ( myMesh->_is_nil() || LineEditMesh->text().isEmpty() ) + return; + + QString anIDs = ""; + int aNbElements = 0; + aNbElements = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), anIDs); + + if (aNbElements < 1) + return; + + ListCoincident->clearSelection(); + ListCoincident->addItem(anIDs); + int nbGroups = ListCoincident->count(); + if (nbGroups) { + ListCoincident->setCurrentRow(nbGroups-1); + ListCoincident->item(nbGroups-1)->setSelected(true); + } + else { + // VSR ? this code seems to be never executed!!! + ListCoincident->setCurrentRow(0); + //ListCoincident->setSelected(0, true); // VSR: no items - no selection + } + + updateControls(); +} + +//================================================================================= +// function : onRemoveGroup() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::onRemoveGroup() +{ + if (myEditCurrentArgument != (QWidget*)ListCoincident) + return; + myIsBusy = true; + + QList selItems = ListCoincident->selectedItems(); + QListWidgetItem* anItem; + + foreach(anItem, selItems) + delete anItem; + + ListEdit->clear(); + updateControls(); + + myIsBusy = false; +} + +//================================================================================= +// function : onAddElement() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::onAddElement() +{ + if (!myActor) + return; + myIsBusy = true; + + QString aListStr = ""; + int aNbNnodes = 0; + + aNbNnodes = SMESH::GetNameOfSelectedNodes(mySelector, myActor->getIO(), aListStr); + if (aNbNnodes < 1) + return; + + QStringList aNodes = aListStr.split(" ", QString::SkipEmptyParts); + + for (QStringList::iterator it = aNodes.begin(); it != aNodes.end(); ++it) { + QList found = ListEdit->findItems(*it, Qt::MatchExactly); + if ( found.count() == 0 ) { + QListWidgetItem* anItem = new QListWidgetItem(*it); + ListEdit->addItem(anItem); + anItem->setSelected(true); + } + else { + QListWidgetItem* anItem; + foreach(anItem, found) anItem->setSelected(true); + } + } + + myIsBusy = false; + onEditGroup(); +} + +//================================================================================= +// function : onRemoveElement() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::onRemoveElement() +{ + if (myEditCurrentArgument != (QWidget*)ListCoincident) + return; + myIsBusy = true; + + QList selItems = ListEdit->selectedItems(); + QListWidgetItem* anItem; + + foreach(anItem, selItems) + delete anItem; + + myIsBusy = false; + onEditGroup(); +} + +//================================================================================= +// function : onSetFirst() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::onSetFirst() +{ + if (myEditCurrentArgument != (QWidget*)ListCoincident) + return; + myIsBusy = true; + + QList selItems = ListEdit->selectedItems(); + QListWidgetItem* anItem; + + foreach(anItem, selItems) { + ListEdit->takeItem(ListEdit->row(anItem)); + ListEdit->insertItem(0, anItem); + } + + myIsBusy = false; + onEditGroup(); +} + +//================================================================================= +// function : SetEditCurrentArgument() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::SetEditCurrentArgument() +{ + QPushButton* send = (QPushButton*)sender(); + + disconnect(mySelectionMgr, 0, this, 0); + mySelectionMgr->clearSelected(); + mySelectionMgr->clearFilters(); + + if (send == SelectMeshButton) { + myEditCurrentArgument = (QWidget*)LineEditMesh; + SMESH::SetPointRepresentation(false); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(ActorSelection); + if (myTypeId == 1) + mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter); + } + + myEditCurrentArgument->setFocus(); + connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); + SelectionIntoArgument(); +} + +//================================================================================= +// function : SelectionIntoArgument() +// purpose : Called when selection as changed or other case +//================================================================================= +void SMESHGUI_MergeDlg::SelectionIntoArgument() +{ + if (myEditCurrentArgument == (QWidget*)LineEditMesh) { + QString aString = ""; + LineEditMesh->setText(aString); + + ListCoincident->clear(); + ListEdit->clear(); + myActor = 0; + QString aCurrentEntry = myEntry; + + int nbSel = SMESH::GetNameOfSelectedIObjects(mySelectionMgr, aString); + if (nbSel != 1) { + myIdPreview->SetPointsLabeled(false); + SMESH::SetPointRepresentation(false); + mySelectionMgr->clearFilters(); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(ActorSelection); + return; + } + + SALOME_ListIO aList; + mySelectionMgr->selectedObjects(aList); + + Handle(SALOME_InteractiveObject) IO = aList.First(); + myEntry = IO->getEntry(); + myMesh = SMESH::GetMeshByIO(IO); + + if (myMesh->_is_nil()) + return; + + LineEditMesh->setText(aString); + + myActor = SMESH::FindActorByEntry(IO->getEntry()); + if (!myActor) + myActor = SMESH::FindActorByObject(myMesh); + + if ( myActor && myTypeId ==1 ) { + mySubMeshOrGroup = SMESH::SMESH_IDSource::_nil(); + mySelectionMgr->installFilter(myMeshOrSubMeshOrGroupFilter); + + if ((!SMESH::IObjectToInterface(IO)->_is_nil() || //SUBMESH OR GROUP + !SMESH::IObjectToInterface(IO)->_is_nil()) && + !SMESH::IObjectToInterface(IO)->_is_nil()) + mySubMeshOrGroup = SMESH::IObjectToInterface(IO); + + if (myAction == 0) { + SMESH::SetPointRepresentation(true); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(NodeSelection); + } + else + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(CellSelection); + } + + // process groups + if ( myAction == 0 && !myMesh->_is_nil() && myEntry != aCurrentEntry ) { + myGroups.clear(); + ListExclude->clear(); + SMESH::ListOfGroups_var aListOfGroups = myMesh->GetGroups(); + for( int i = 0, n = aListOfGroups->length(); i < n; i++ ) { + SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i]; + if ( !aGroup->_is_nil() ) { // && aGroup->GetType() == SMESH::NODE + QString aGroupName( aGroup->GetName() ); + if ( !aGroupName.isEmpty() ) { + myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup)); + QListWidgetItem* item = new QListWidgetItem( aGroupName ); + item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable ); + item->setCheckState( Qt::Unchecked ); + ListExclude->addItem( item ); + } + } + } + } + + updateControls(); + } +} + +//================================================================================= +// function : DeactivateActiveDialog() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::DeactivateActiveDialog() +{ + if (GroupConstructors->isEnabled()) { + GroupConstructors->setEnabled(false); + TypeBox->setEnabled(false); + GroupMesh->setEnabled(false); + GroupCoincident->setEnabled(false); + GroupEdit->setEnabled(false); + GroupButtons->setEnabled(false); + mySMESHGUI->ResetState(); + mySMESHGUI->SetActiveDialogBox(0); + } + + mySelectionMgr->clearSelected(); + disconnect(mySelectionMgr, 0, this, 0); +} + +//================================================================================= +// function : ActivateThisDialog() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::ActivateThisDialog() +{ + /* Emit a signal to deactivate the active dialog */ + mySMESHGUI->EmitSignalDeactivateDialog(); + GroupConstructors->setEnabled(true); + TypeBox->setEnabled(true); + GroupMesh->setEnabled(true); + GroupCoincident->setEnabled(true); + GroupEdit->setEnabled(true); + GroupButtons->setEnabled(true); + + connect(mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); + mySMESHGUI->SetActiveDialogBox((QDialog*)this); + SelectionIntoArgument(); +} + +//================================================================================= +// function : enterEvent() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::enterEvent(QEvent*) +{ + if (!GroupConstructors->isEnabled()) + ActivateThisDialog(); +} + +//================================================================================= +// function : closeEvent() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::closeEvent(QCloseEvent*) +{ + /* same than click on cancel button */ + ClickOnCancel(); +} + +//======================================================================= +//function : hideEvent +//purpose : caused by ESC key +//======================================================================= +void SMESHGUI_MergeDlg::hideEvent (QHideEvent *) +{ + if (!isMinimized()) + ClickOnCancel(); +} + +//================================================================================= +// function : keyPressEvent() +// purpose : +//================================================================================= +void SMESHGUI_MergeDlg::keyPressEvent( QKeyEvent* e) +{ + QDialog::keyPressEvent( e ); + if ( e->isAccepted() ) + return; + + if ( e->key() == Qt::Key_F1 ) { + e->accept(); + ClickOnHelp(); + } +} + +//================================================================================= +// function : onTypeChanged() +// purpose : the type radio button management +//================================================================================= +void SMESHGUI_MergeDlg::onTypeChanged (int id) +{ + if (myTypeId == id) + return; + + myTypeId = id; + switch (id) + { + case 0: // automatic + myIdPreview->SetPointsLabeled(false); + SMESH::SetPointRepresentation(false); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(ActorSelection); + mySelectionMgr->clearFilters(); + if (myAction == 0) + GroupCoincidentWidget->hide(); + else + GroupCoincident->hide(); + GroupEdit->hide(); + break; + + case 1: // manual + SMESH::UpdateView(); + + // Costruction of the logical filter + SMESH_TypeFilter* aMeshOrSubMeshFilter = new SMESH_TypeFilter (MESHorSUBMESH); + SMESH_TypeFilter* aSmeshGroupFilter = new SMESH_TypeFilter (GROUP); + + QList aListOfFilters; + if (aMeshOrSubMeshFilter) aListOfFilters.append(aMeshOrSubMeshFilter); + if (aSmeshGroupFilter) aListOfFilters.append(aSmeshGroupFilter); + + myMeshOrSubMeshOrGroupFilter = + new SMESH_LogicalFilter (aListOfFilters, SMESH_LogicalFilter::LO_OR); + + if (myAction == 0) { + GroupCoincidentWidget->show(); + SMESH::SetPointRepresentation(true); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(NodeSelection); + } + else { + GroupCoincident->show(); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) + aViewWindow->SetSelectionMode(CellSelection); + } + GroupEdit->show(); + break; + } + updateControls(); + + qApp->processEvents(); + updateGeometry(); + resize(10,10); + + SelectionIntoArgument(); +} diff --git a/src/SMESHGUI/SMESHGUI_MergeDlg.h b/src/SMESHGUI/SMESHGUI_MergeDlg.h new file mode 100644 index 000000000..73dce16c0 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_MergeDlg.h @@ -0,0 +1,175 @@ +// 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_MergeDlg.h +// Author : Open CASCADE S.A.S. +// +#ifndef SMESHGUI_MergeDlg_H +#define SMESHGUI_MergeDlg_H + +// SMESH includes +#include "SMESH_SMESHGUI.hxx" + +// Qt includes +#include + +// OCCT includes +#include + +// STL includes +#include + +// IDL includes +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) + +class QGroupBox; +class QLabel; +class QLineEdit; +class QPushButton; +class QRadioButton; +class QCheckBox; +class QListWidget; +class QButtonGroup; +class SMESHGUI; +class SMESHGUI_SpinBox; +class SMESH_Actor; +class SVTK_Selector; +class LightApp_SelectionMgr; +class SUIT_SelectionFilter; +class TColStd_MapOfInteger; + +namespace SMESH +{ + struct TIdPreview; +} + +//================================================================================= +// class : SMESHGUI_MergeDlg +// purpose : +//================================================================================= +class SMESHGUI_EXPORT SMESHGUI_MergeDlg : public QDialog +{ + Q_OBJECT; + +public: + SMESHGUI_MergeDlg( SMESHGUI*, int ); + ~SMESHGUI_MergeDlg(); + +private: + void Init(); + void closeEvent( QCloseEvent* ); + void enterEvent( QEvent* ); /* mouse enter the QWidget */ + void hideEvent( QHideEvent* ); /* ESC key */ + void keyPressEvent( QKeyEvent* ); + void onEditGroup(); + + void FindGravityCenter( TColStd_MapOfInteger&, + std::list& ); + // add the centers of gravity of ElemsIdMap elements to the GrCentersXYZ list + +private: + typedef QList GrpList; + + SMESHGUI* mySMESHGUI; /* Current SMESHGUI object */ + LightApp_SelectionMgr* mySelectionMgr; /* User shape selection */ + SVTK_Selector* mySelector; + + QWidget* myEditCurrentArgument; + + SMESH::SMESH_Mesh_var myMesh; + SMESH::SMESH_IDSource_var mySubMeshOrGroup; + SMESH_Actor* myActor; + SUIT_SelectionFilter* myMeshOrSubMeshOrGroupFilter; + + SMESH::TIdPreview* myIdPreview; + + int myAction; + bool myIsBusy; + int myTypeId; + + // Widgets + QGroupBox* GroupConstructors; + QRadioButton* RadioButton; + + QGroupBox* GroupButtons; + QPushButton* buttonOk; + QPushButton* buttonCancel; + QPushButton* buttonApply; + QPushButton* buttonHelp; + + QGroupBox* GroupMesh; + QLabel* TextLabelName; + QPushButton* SelectMeshButton; + QLineEdit* LineEditMesh; + + QGroupBox* GroupCoincident; + QWidget* GroupCoincidentWidget; + QLabel* TextLabelTolerance; + SMESHGUI_SpinBox* SpinBoxTolerance; + QPushButton* DetectButton; + QListWidget* ListCoincident; + QPushButton* AddGroupButton; + QPushButton* RemoveGroupButton; + QCheckBox* SelectAllCB; + + QGroupBox* GroupEdit; + QListWidget* ListEdit; + QPushButton* AddElemButton; + QPushButton* RemoveElemButton; + QPushButton* SetFirstButton; + + QGroupBox* GroupExclude; + QListWidget* ListExclude; + + QGroupBox* TypeBox; + QButtonGroup* GroupType; + + QString myHelpFileName; + + QString myEntry; + GrpList myGroups; + + private slots: + void ClickOnOk(); + void ClickOnCancel(); + bool ClickOnApply(); + void ClickOnHelp(); + void updateControls(); + void onDetect(); + void onAddGroup(); + void onRemoveGroup(); + void onSelectGroup(); + void onSelectAll( bool ); + void onSelectElementFromGroup(); + void onAddElement(); + void onRemoveElement(); + void onSetFirst(); + void SetEditCurrentArgument(); + void SelectionIntoArgument(); + void DeactivateActiveDialog(); + void ActivateThisDialog(); + void onTypeChanged(int); +}; + +#endif // SMESHGUI_MergeDlg_H diff --git a/src/SMESHGUI/SMESHGUI_MeshInfo.cxx b/src/SMESHGUI/SMESHGUI_MeshInfo.cxx new file mode 100644 index 000000000..16a33b199 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_MeshInfo.cxx @@ -0,0 +1,1335 @@ +// 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 +// +// File : SMESHGUI_MeshInfo.cxx +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) + +#include "SMESHGUI_MeshInfo.h" + +#include "SMESH_Actor.h" +#include "SMESHGUI.h" +#include "SMESHGUI_IdValidator.h" +#include "SMESHGUI_Utils.h" +#include "SMESHGUI_VTKUtils.h" +#include "SMDSAbs_ElementType.hxx" +#include "SMDS_Mesh.hxx" + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include CORBA_SERVER_HEADER(SMESH_Group) + +const int SPACING = 6; +const int MARGIN = 9; + +/*! + \class SMESHGUI_MeshInfo + \brief Base mesh information widget + + Displays the base information about mesh object: mesh, sub-mesh, group or arbitrary ID source. +*/ + +/*! + \brief Constructor. + \param parent parent widget +*/ +SMESHGUI_MeshInfo::SMESHGUI_MeshInfo( QWidget* parent ) + : QFrame( parent ), myWidgets( iElementsEnd ) +{ + setFrameStyle( StyledPanel | Sunken ); + + QGridLayout* l = new QGridLayout( this ); + l->setMargin( MARGIN ); + l->setSpacing( SPACING ); + + // object + QLabel* aNameLab = new QLabel( tr( "NAME_LAB" ), this ); + QLabel* aName = createField(); + aName->setMinimumWidth( 150 ); + QLabel* aObjLab = new QLabel( tr( "OBJECT_LAB" ), this ); + QLabel* aObj = createField(); + aObj->setMinimumWidth( 150 ); + myWidgets[0] << aNameLab << aName; + myWidgets[1] << aObjLab << aObj; + + // nodes + QWidget* aNodesLine = createLine(); + QLabel* aNodesLab = new QLabel( tr( "NODES_LAB" ), this ); + QLabel* aNodes = createField(); + myWidgets[2] << aNodesLine; + myWidgets[3] << aNodesLab << aNodes; + + // elements + QWidget* aElemLine = createLine(); + QLabel* aElemLab = new QLabel( tr( "ELEMENTS_LAB" ), this ); + QLabel* aElemTotal = new QLabel( tr( "TOTAL_LAB" ), this ); + QLabel* aElemLin = new QLabel( tr( "LINEAR_LAB" ), this ); + QLabel* aElemQuad = new QLabel( tr( "QUADRATIC_LAB" ), this ); + myWidgets[4] << aElemLine; + myWidgets[5] << aElemLab << aElemTotal << aElemLin << aElemQuad; + + // ... 0D elements + QWidget* a0DLine = createLine(); + QLabel* a0DLab = new QLabel( tr( "0D_LAB" ), this ); + QLabel* a0DTotal = createField(); + myWidgets[6] << a0DLine; + myWidgets[7] << a0DLab << a0DTotal; + + // ... 1D elements + QWidget* a1DLine = createLine(); + QLabel* a1DLab = new QLabel( tr( "1D_LAB" ), this ); + QLabel* a1DTotal = createField(); + QLabel* a1DLin = createField(); + QLabel* a1DQuad = createField(); + myWidgets[8] << a1DLine; + myWidgets[9] << a1DLab << a1DTotal << a1DLin << a1DQuad; + + // ... 2D elements + QWidget* a2DLine = createLine(); + QLabel* a2DLab = new QLabel( tr( "2D_LAB" ), this ); + QLabel* a2DTotal = createField(); + QLabel* a2DLin = createField(); + QLabel* a2DQuad = createField(); + QLabel* a2DTriLab = new QLabel( tr( "TRIANGLES_LAB" ), this ); + QLabel* a2DTriTotal = createField(); + QLabel* a2DTriLin = createField(); + QLabel* a2DTriQuad = createField(); + QLabel* a2DQuaLab = new QLabel( tr( "QUADRANGLES_LAB" ), this ); + QLabel* a2DQuaTotal = createField(); + QLabel* a2DQuaLin = createField(); + QLabel* a2DQuaQuad = createField(); + QLabel* a2DPolLab = new QLabel( tr( "POLYGONS_LAB" ), this ); + QLabel* a2DPolTotal = createField(); + myWidgets[10] << a2DLine; + myWidgets[11] << a2DLab << a2DTotal << a2DLin << a2DQuad; + myWidgets[12] << a2DTriLab << a2DTriTotal << a2DTriLin << a2DTriQuad; + myWidgets[13] << a2DQuaLab << a2DQuaTotal << a2DQuaLin << a2DQuaQuad; + myWidgets[14] << a2DPolLab << a2DPolTotal; + + // ... 3D elements + QWidget* a3DLine = createLine(); + QLabel* a3DLab = new QLabel( tr( "3D_LAB" ), this ); + QLabel* a3DTotal = createField(); + QLabel* a3DLin = createField(); + QLabel* a3DQuad = createField(); + QLabel* a3DTetLab = new QLabel( tr( "TETRAHEDRONS_LAB" ), this ); + QLabel* a3DTetTotal = createField(); + QLabel* a3DTetLin = createField(); + QLabel* a3DTetQuad = createField(); + QLabel* a3DHexLab = new QLabel( tr( "HEXAHEDONRS_LAB" ), this ); + QLabel* a3DHexTotal = createField(); + QLabel* a3DHexLin = createField(); + QLabel* a3DHexQuad = createField(); + QLabel* a3DPyrLab = new QLabel( tr( "PYRAMIDS_LAB" ), this ); + QLabel* a3DPyrTotal = createField(); + QLabel* a3DPyrLin = createField(); + QLabel* a3DPyrQuad = createField(); + QLabel* a3DPriLab = new QLabel( tr( "PRISMS_LAB" ), this ); + QLabel* a3DPriTotal = createField(); + QLabel* a3DPriLin = createField(); + QLabel* a3DPriQuad = createField(); + QLabel* a3DPolLab = new QLabel( tr( "POLYHEDRONS_LAB" ), this ); + QLabel* a3DPolTotal = createField(); + myWidgets[15] << a3DLine; + myWidgets[16] << a3DLab << a3DTotal << a3DLin << a3DQuad; + myWidgets[17] << a3DTetLab << a3DTetTotal << a3DTetLin << a3DTetQuad; + myWidgets[18] << a3DHexLab << a3DHexTotal << a3DHexLin << a3DHexQuad; + myWidgets[19] << a3DPyrLab << a3DPyrTotal << a3DPyrLin << a3DPyrQuad; + myWidgets[20] << a3DPriLab << a3DPriTotal << a3DPriLin << a3DPriQuad; + myWidgets[21] << a3DPolLab << a3DPolTotal; + + setFontAttributes( aNameLab, Bold ); + setFontAttributes( aObjLab, Bold ); + setFontAttributes( aNodesLab, Bold ); + setFontAttributes( aElemLab, Bold ); + setFontAttributes( aElemTotal, Italic ); + setFontAttributes( aElemLin, Italic ); + setFontAttributes( aElemQuad, Italic ); + setFontAttributes( a0DLab, Bold ); + setFontAttributes( a1DLab, Bold ); + setFontAttributes( a2DLab, Bold ); + setFontAttributes( a3DLab, Bold ); + + l->addWidget( aNameLab, 0, 0 ); + l->addWidget( aName, 0, 1, 1, 3 ); + l->addWidget( aObjLab, 1, 0 ); + l->addWidget( aObj, 1, 1, 1, 3 ); + l->addWidget( aNodesLine, 2, 0, 1, 4 ); + l->addWidget( aNodesLab, 3, 0 ); + l->addWidget( aNodes, 3, 1 ); + l->addWidget( aElemLine, 4, 0, 1, 4 ); + l->addWidget( aElemLab, 5, 0 ); + l->addWidget( aElemTotal, 5, 1 ); + l->addWidget( aElemLin, 5, 2 ); + l->addWidget( aElemQuad, 5, 3 ); + l->addWidget( a0DLine, 6, 1, 1, 3 ); + l->addWidget( a0DLab, 7, 0 ); + l->addWidget( a0DTotal, 7, 1 ); + l->addWidget( a1DLine, 8, 1, 1, 3 ); + l->addWidget( a1DLab, 9, 0 ); + l->addWidget( a1DTotal, 9, 1 ); + l->addWidget( a1DLin, 9, 2 ); + l->addWidget( a1DQuad, 9, 3 ); + l->addWidget( a2DLine, 10, 1, 1, 3 ); + l->addWidget( a2DLab, 11, 0 ); + l->addWidget( a2DTotal, 11, 1 ); + l->addWidget( a2DLin, 11, 2 ); + l->addWidget( a2DQuad, 11, 3 ); + l->addWidget( a2DTriLab, 12, 0 ); + l->addWidget( a2DTriTotal, 12, 1 ); + l->addWidget( a2DTriLin, 12, 2 ); + l->addWidget( a2DTriQuad, 12, 3 ); + l->addWidget( a2DQuaLab, 13, 0 ); + l->addWidget( a2DQuaTotal, 13, 1 ); + l->addWidget( a2DQuaLin, 13, 2 ); + l->addWidget( a2DQuaQuad, 13, 3 ); + l->addWidget( a2DPolLab, 14, 0 ); + l->addWidget( a2DPolTotal, 14, 1 ); + l->addWidget( a3DLine, 15, 1, 1, 3 ); + l->addWidget( a3DLab, 16, 0 ); + l->addWidget( a3DTotal, 16, 1 ); + l->addWidget( a3DLin, 16, 2 ); + l->addWidget( a3DQuad, 16, 3 ); + l->addWidget( a3DTetLab, 17, 0 ); + l->addWidget( a3DTetTotal, 17, 1 ); + l->addWidget( a3DTetLin, 17, 2 ); + l->addWidget( a3DTetQuad, 17, 3 ); + l->addWidget( a3DHexLab, 18, 0 ); + l->addWidget( a3DHexTotal, 18, 1 ); + l->addWidget( a3DHexLin, 18, 2 ); + l->addWidget( a3DHexQuad, 18, 3 ); + l->addWidget( a3DPyrLab, 19, 0 ); + l->addWidget( a3DPyrTotal, 19, 1 ); + l->addWidget( a3DPyrLin, 19, 2 ); + l->addWidget( a3DPyrQuad, 19, 3 ); + l->addWidget( a3DPriLab, 20, 0 ); + l->addWidget( a3DPriTotal, 20, 1 ); + l->addWidget( a3DPriLin, 20, 2 ); + l->addWidget( a3DPriQuad, 20, 3 ); + l->addWidget( a3DPolLab, 21, 0 ); + l->addWidget( a3DPolTotal, 21, 1 ); + l->setColumnStretch( 0, 0 ); + l->setColumnStretch( 1, 5 ); + l->setColumnStretch( 2, 5 ); + l->setColumnStretch( 3, 5 ); + l->setRowStretch( 22, 5 ); + + clear(); +} + +/*! + \brief Destructor +*/ +SMESHGUI_MeshInfo::~SMESHGUI_MeshInfo() +{ +} + +/*! + \brief Show information on the mesh object. + \param obj object being processed (mesh, sub-mesh, group, ID source) +*/ +void SMESHGUI_MeshInfo::showInfo( SMESH::SMESH_IDSource_ptr obj ) +{ + clear(); + if ( !CORBA::is_nil( obj ) ) { + _PTR(SObject) sobj = ObjectToSObject( obj ); + if ( sobj ) + myWidgets[iName][iSingle]->setProperty( "text", sobj->GetName().c_str() ); + SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( obj ); + SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( obj ); + SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow( obj ); + if ( !aMesh->_is_nil() ) { + myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_MESH" ) ); + } + else if ( !aSubMesh->_is_nil() ) { + myWidgets[iObject][iSingle]->setProperty( "text", tr( "OBJECT_SUBMESH" ) ); + } + else if ( !aGroup->_is_nil() ) { + QString objType; + switch( aGroup->GetType() ) { + case SMESH::NODE: + objType = tr( "OBJECT_GROUP_NODES" ); + break; + case SMESH::EDGE: + objType = tr( "OBJECT_GROUP_EDGES" ); + break; + case SMESH::FACE: + objType = tr( "OBJECT_GROUP_FACES" ); + break; + case SMESH::VOLUME: + objType = tr( "OBJECT_GROUP_VOLUMES" ); + break; + case SMESH::ELEM0D: + objType = tr( "OBJECT_GROUP_0DELEMS" ); + break; + default: + objType = tr( "OBJECT_GROUP" ); + break; + } + myWidgets[iObject][iSingle]->setProperty( "text", objType ); + } + SMESH::long_array_var info = obj->GetMeshInfo(); + myWidgets[iNodes][iTotal]->setProperty( "text", QString::number( info[SMDSEntity_Node] ) ); + myWidgets[i0D][iTotal]->setProperty( "text", QString::number( info[SMDSEntity_0D] ) ); + long nbEdges = info[SMDSEntity_Edge] + info[SMDSEntity_Quad_Edge]; + myWidgets[i1D][iTotal]->setProperty( "text", QString::number( nbEdges ) ); + myWidgets[i1D][iLinear]->setProperty( "text", QString::number( info[SMDSEntity_Edge] ) ); + myWidgets[i1D][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Edge] ) ); + long nbTriangles = info[SMDSEntity_Triangle] + info[SMDSEntity_Quad_Triangle]; + long nbQuadrangles = info[SMDSEntity_Quadrangle] + info[SMDSEntity_Quad_Quadrangle]; + long nb2DLinear = info[SMDSEntity_Triangle] + info[SMDSEntity_Quadrangle] + info[SMDSEntity_Polygon]; + long nb2DQuadratic = info[SMDSEntity_Quad_Triangle] + info[SMDSEntity_Quad_Quadrangle]; + myWidgets[i2D][iTotal]->setProperty( "text", QString::number( nb2DLinear + nb2DQuadratic ) ); + myWidgets[i2D][iLinear]->setProperty( "text", QString::number( nb2DLinear ) ); + myWidgets[i2D][iQuadratic]->setProperty( "text", QString::number( nb2DQuadratic ) ); + myWidgets[i2DTriangles][iTotal]->setProperty( "text", QString::number( nbTriangles ) ); + myWidgets[i2DTriangles][iLinear]->setProperty( "text", QString::number( info[SMDSEntity_Triangle] ) ); + myWidgets[i2DTriangles][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Triangle] ) ); + myWidgets[i2DQuadrangles][iTotal]->setProperty( "text", QString::number( nbQuadrangles ) ); + myWidgets[i2DQuadrangles][iLinear]->setProperty( "text", QString::number( info[SMDSEntity_Quadrangle] ) ); + myWidgets[i2DQuadrangles][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Quadrangle] ) ); + myWidgets[i2DPolygons][iTotal]->setProperty( "text", QString::number( info[SMDSEntity_Polygon] ) ); + long nbTetrahedrons = info[SMDSEntity_Tetra] + info[SMDSEntity_Quad_Tetra]; + long nbHexahedrons = info[SMDSEntity_Hexa] + info[SMDSEntity_Quad_Hexa]; + long nbPyramids = info[SMDSEntity_Pyramid] + info[SMDSEntity_Quad_Pyramid]; + long nbPrisms = info[SMDSEntity_Penta] + info[SMDSEntity_Quad_Penta]; + long nb3DLinear = info[SMDSEntity_Tetra] + info[SMDSEntity_Hexa] + info[SMDSEntity_Pyramid] + info[SMDSEntity_Penta] + info[SMDSEntity_Polyhedra]; + long nb3DQuadratic = info[SMDSEntity_Quad_Tetra] + info[SMDSEntity_Quad_Hexa] + info[SMDSEntity_Quad_Pyramid] + info[SMDSEntity_Quad_Penta]; + myWidgets[i3D][iTotal]->setProperty( "text", QString::number( nb3DLinear + nb3DQuadratic ) ); + myWidgets[i3D][iLinear]->setProperty( "text", QString::number( nb3DLinear ) ); + myWidgets[i3D][iQuadratic]->setProperty( "text", QString::number( nb3DQuadratic ) ); + myWidgets[i3DTetrahedrons][iTotal]->setProperty( "text", QString::number( nbTetrahedrons ) ); + myWidgets[i3DTetrahedrons][iLinear]->setProperty( "text", QString::number( info[SMDSEntity_Tetra] ) ); + myWidgets[i3DTetrahedrons][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Tetra] ) ); + myWidgets[i3DHexahedrons][iTotal]->setProperty( "text", QString::number( nbHexahedrons ) ); + myWidgets[i3DHexahedrons][iLinear]->setProperty( "text", QString::number( info[SMDSEntity_Hexa] ) ); + myWidgets[i3DHexahedrons][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Hexa] ) ); + myWidgets[i3DPyramids][iTotal]->setProperty( "text", QString::number( nbPyramids ) ); + myWidgets[i3DPyramids][iLinear]->setProperty( "text", QString::number( info[SMDSEntity_Pyramid] ) ); + myWidgets[i3DPyramids][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Pyramid] ) ); + myWidgets[i3DPrisms][iTotal]->setProperty( "text", QString::number( nbPrisms ) ); + myWidgets[i3DPrisms][iLinear]->setProperty( "text", QString::number( info[SMDSEntity_Penta] ) ); + myWidgets[i3DPrisms][iQuadratic]->setProperty( "text", QString::number( info[SMDSEntity_Quad_Penta] ) ); + myWidgets[i3DPolyhedrons][iTotal]->setProperty( "text", QString::number( info[SMDSEntity_Polyhedra] ) ); + } +} + +/*! + \brief Reset the widget to the initial state (nullify all fields). +*/ +void SMESHGUI_MeshInfo::clear() +{ + myWidgets[iName][iSingle]->setProperty( "text", QString() ); + myWidgets[iObject][iSingle]->setProperty( "text", QString() ); + myWidgets[iNodes][iTotal]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i0D][iTotal]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i1D][iTotal]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i1D][iLinear]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i1D][iQuadratic]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i2D][iTotal]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i2D][iLinear]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i2D][iQuadratic]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i2DTriangles][iTotal]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i2DTriangles][iLinear]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i2DTriangles][iQuadratic]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i2DQuadrangles][iTotal]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i2DQuadrangles][iLinear]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i2DQuadrangles][iQuadratic]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i2DPolygons][iTotal]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3D][iTotal]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3D][iLinear]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3D][iQuadratic]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DTetrahedrons][iTotal]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DTetrahedrons][iLinear]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DTetrahedrons][iQuadratic]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DHexahedrons][iTotal]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DHexahedrons][iLinear]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DHexahedrons][iQuadratic]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DPyramids][iTotal]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DPyramids][iLinear]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DPyramids][iQuadratic]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DPrisms][iTotal]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DPrisms][iLinear]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DPrisms][iQuadratic]->setProperty( "text", QString::number( 0 ) ); + myWidgets[i3DPolyhedrons][iTotal]->setProperty( "text", QString::number( 0 ) ); +} + +/*! + \brief Create info field + \return new info field +*/ +QLabel* SMESHGUI_MeshInfo::createField() +{ + QLabel* lab = new QLabel( this ); + lab->setFrameStyle( StyledPanel | Sunken ); + lab->setAlignment( Qt::AlignCenter ); + lab->setAutoFillBackground( true ); + QPalette pal = lab->palette(); + pal.setColor( QPalette::Window, QApplication::palette().color( QPalette::Active, QPalette::Base ) ); + lab->setPalette( pal ); + lab->setMinimumWidth( 70 ); + return lab; +} + +/*! + \brief Create horizontal rule. + \return new line object +*/ +QWidget* SMESHGUI_MeshInfo::createLine() +{ + QFrame* line = new QFrame( this ); + line->setFrameStyle( HLine | Sunken ); + return line; +} + +/*! + \brief Change widget font attributes (bold, italic, ...). + \param w widget + \param attr font attributes (XORed flags) + \param val value to be set to attributes +*/ +void SMESHGUI_MeshInfo::setFontAttributes( QWidget* w, int attr, bool val ) +{ + if ( w && attr ) { + QFont f = w->font(); + if ( attr & Bold ) f.setBold( val ); + if ( attr & Italic ) f.setItalic( val ); + w->setFont( f ); + } +} + +/*! + \brief Show/hide group(s) of fields. + \param start beginning of the block + \param end end of the block + \param on visibility flag +*/ +void SMESHGUI_MeshInfo::setFieldsVisible( int start, int end, bool on ) +{ + start = qMax( 0, start ); + end = qMin( end, (int)iElementsEnd ); + for ( int i = start; i < end; i++ ) { + wlist wl = myWidgets[i]; + foreach ( QWidget* w, wl ) w->setVisible( on ); + } +} + +/*! + \class SMESHGUI_ElemInfo + \brief Base class for the mesh element information widget. +*/ + +/*! + \brief Constructor + \param parent parent widget +*/ +SMESHGUI_ElemInfo::SMESHGUI_ElemInfo( QWidget* parent ) +: QWidget( parent ), myActor( 0 ), myID( 0 ), myIsElement( -1 ) +{ +} + +/*! + \brief Destructor +*/ +SMESHGUI_ElemInfo::~SMESHGUI_ElemInfo() +{ +} + +/*! + \brief Set mesh data source (actor) + \param actor mesh object actor +*/ +void SMESHGUI_ElemInfo::setSource( SMESH_Actor* actor ) +{ + if ( myActor != actor ) { + myActor = actor; + myID = 0; + myIsElement = -1; + clear(); + } +} + +/*! + \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 +*/ +void SMESHGUI_ElemInfo::showInfo( long id, bool isElem ) +{ + myID = id; + myIsElement = isElem; +} + +/*! + \fn void SMESHGUI_ElemInfo::clear() + \brief Clear mesh element information widget +*/ + +/*! + \brief Get node connectivity + \param node mesh node + \return node connectivity map +*/ +SMESHGUI_ElemInfo::Connectivity SMESHGUI_ElemInfo::nodeConnectivity( const SMDS_MeshNode* node ) +{ + Connectivity elmap; + if ( node ) { + SMDS_ElemIteratorPtr it = node->GetInverseElementIterator(); + while ( it && it->more() ) { + const SMDS_MeshElement* ne = it->next(); + elmap[ ne->GetType() ] << ne->GetID(); + } + } + return elmap; +} + +/*! + \brief Format connectivity data to string representation + \param connectivity connetivity map + \param type element type + \return string representation of the connectivity +*/ +QString SMESHGUI_ElemInfo::formatConnectivity( Connectivity connectivity, int type ) +{ + QStringList str; + if ( connectivity.contains( type ) ) { + QList elements = connectivity[ type ]; + qSort( elements ); + foreach( int id, elements ) + str << QString::number( id ); + } + return str.join( " " ); +} + +/*! + \brief Calculate gravity center of the mesh element + \param element mesh element +*/ +SMESHGUI_ElemInfo::XYZ SMESHGUI_ElemInfo::gravityCenter( const SMDS_MeshElement* element ) +{ + XYZ xyz; + if ( element ) { + SMDS_ElemIteratorPtr nodeIt = element->nodesIterator(); + while ( nodeIt->more() ) { + const SMDS_MeshNode* node = static_cast( nodeIt->next() ); + xyz.add( node->X(), node->Y(), node->Z() ); + } + xyz.divide( element->NbNodes() ); + } + return xyz; +} + +/*! + \class SMESHGUI_SimpleElemInfo + \brief Represents mesh element information in the simple text area. +*/ + +/*! + \brief Constructor + \param parent parent widget +*/ +SMESHGUI_SimpleElemInfo::SMESHGUI_SimpleElemInfo( QWidget* parent ) +: SMESHGUI_ElemInfo( parent ) +{ + myInfo = new QTextBrowser( this ); + QVBoxLayout* l = new QVBoxLayout( this ); + 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 +*/ +void SMESHGUI_SimpleElemInfo::showInfo( long id, bool isElem ) +{ + if ( myID == id && myIsElement == isElem ) return; + + SMESHGUI_ElemInfo::showInfo( id, isElem ); + + clear(); + + if ( myActor ) { + 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( e ); + + // node ID + myInfo->append( QString( "%1 #%2" ).arg( tr( "NODE" ) ).arg( id ) ); + // separator + myInfo->append( "" ); + // coordinates + myInfo->append( QString( "%1: (%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( "%1:" ).arg( tr( "CONNECTIVITY" ) ) ); + QString con = formatConnectivity( connectivity, SMDSAbs_0DElement ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "0D_ELEMENTS" ) ).arg( con ) ); + con = formatConnectivity( connectivity, SMDSAbs_Edge ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "EDGES" ) ).arg( con ) ); + con = formatConnectivity( connectivity, SMDSAbs_Face ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "FACES" ) ).arg( con ) ); + con = formatConnectivity( connectivity, SMDSAbs_Volume ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "VOLUMES" ) ).arg( con ) ); + } + else { + myInfo->append( QString( "%1" ).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( "%1 #%2" ).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( "QUADRANGLE" ); 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( "%1: %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( "%1? %2" ).arg( tr( "QUADRATIC" ) ).arg( e->IsQuadratic() ? tr( "YES" ) : tr( "NO" ) ) ); + // separator + myInfo->append( "" ); + // gravity center + XYZ gc = gravityCenter( e ); + myInfo->append( QString( "%1: (%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( nodeIt->next() ); + // node number and ID + myInfo->append( QString( "%1 %2/%3 - #%4" ).arg( tr( "NODE" ) ).arg( idx ).arg( e->NbNodes() ).arg( node->GetID() ) ); + // node coordinates + myInfo->append( QString( "%1: (%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( "%1:" ).arg( tr( "CONNECTIVITY" ) ) ); + QString con = formatConnectivity( connectivity, SMDSAbs_0DElement ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "0D_ELEMENTS" ) ).arg( con ) ); + con = formatConnectivity( connectivity, SMDSAbs_Edge ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "EDGES" ) ).arg( con ) ); + con = formatConnectivity( connectivity, SMDSAbs_Face ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "FACES" ) ).arg( con ) ); + con = formatConnectivity( connectivity, SMDSAbs_Volume ); + if ( !con.isEmpty() ) + myInfo->append( QString( "- %1: %2" ).arg( tr( "VOLUMES" ) ).arg( con ) ); + } + else { + myInfo->append( QString( "%1" ).arg( tr( "FREE_NODE" ) ).arg( id ) ); + } + // separator + myInfo->append( "" ); + } + } + } +} + +/*! + \brief Clear mesh element information widget +*/ +void SMESHGUI_SimpleElemInfo::clear() +{ + myInfo->clear(); +} + +/*! + \class SMESHGUI_TreeElemInfo::ItemDelegate + \brief Item delegate for tree mesh info widget + \internal +*/ +class SMESHGUI_TreeElemInfo::ItemDelegate : public QItemDelegate +{ +public: + ItemDelegate( QObject* ); + QWidget* createEditor( QWidget*, const QStyleOptionViewItem&, const QModelIndex& ) const; +}; + +/*! + \brief Constructor + \internal +*/ +SMESHGUI_TreeElemInfo::ItemDelegate::ItemDelegate( QObject* parent ) : QItemDelegate( parent ) +{ +} + +/*! + \brief Create item editor widget + \internal +*/ +QWidget* SMESHGUI_TreeElemInfo::ItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + QWidget* w = index.column() == 0 ? 0: QItemDelegate::createEditor( parent, option, index ); + if ( qobject_cast( w ) ) qobject_cast( w )->setReadOnly( true ); + return w; +} + +/*! + \class SMESHGUI_TreeElemInfo + \brief Represents mesh element information in the tree-like form. +*/ + +/*! + \brief Constructor + \param parent parent widget +*/ +SMESHGUI_TreeElemInfo::SMESHGUI_TreeElemInfo( QWidget* parent ) +: SMESHGUI_ElemInfo( parent ) +{ + myInfo = new QTreeWidget( this ); + 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 ); + 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 +*/ +void SMESHGUI_TreeElemInfo::showInfo( long id, bool isElem ) +{ + if ( myID == id && myIsElement == isElem ) return; + + SMESHGUI_ElemInfo::showInfo( id, isElem ); + + clear(); + + if ( myActor ) { + 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( 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( "QUADRANGLE" ); 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( 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 +*/ +void SMESHGUI_TreeElemInfo::clear() +{ + myInfo->clear(); + myInfo->repaint(); +} + +/*! + \brief Create new tree item. + \param parnt parent tree widget item + \param column item column to be set bold, if it is -1, bold font will be set for all columns + \return new tree widget item +*/ +QTreeWidgetItem* SMESHGUI_TreeElemInfo::createItem( QTreeWidgetItem* parent, int column ) +{ + QTreeWidgetItem* item; + if ( parent ) + item = new QTreeWidgetItem( parent ); + else + item = new QTreeWidgetItem( myInfo ); + + item->setFlags( item->flags() | Qt::ItemIsEditable ); + + QFont f = item->font( 0 ); + f.setBold( true ); + if ( column >= 0 && column < myInfo->columnCount() ) { + item->setFont( column, f ); + } + else if ( column == -1 ) { + for ( int i = 0; i < myInfo->columnCount(); i++ ) + item->setFont( i, f ); + } + return item; +} + +/*! + \class SMESHGUI_MeshInfoDlg + \brief Mesh information dialog box +*/ + +/*! + \brief Constructor + \param parent parent widget + \param page specifies the dialog page to be shown at the start-up +*/ +SMESHGUI_MeshInfoDlg::SMESHGUI_MeshInfoDlg( QWidget* parent, int page ) +: QDialog( parent ), myActor( 0 ) +{ + setModal( false ); + setAttribute( Qt::WA_DeleteOnClose, true ); + setWindowTitle( tr( "MESH_INFO" ) ); + setSizeGripEnabled( true ); + + myTabWidget = new QTabWidget( this ); + + // base info + + myBaseInfo = new SMESHGUI_MeshInfo( myTabWidget ); + myTabWidget->addTab( myBaseInfo, tr( "BASE_INFO" ) ); + + // elem info + + QWidget* w = new QWidget( myTabWidget ); + + myMode = new QButtonGroup( this ); + myMode->addButton( new QRadioButton( tr( "NODE_MODE" ), w ), NodeMode ); + 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 ) ); + + int mode = SMESHGUI::resourceMgr()->integerValue( "SMESH", "mesh_elem_info", 1 ); + mode = qMin( 1, qMax( 0, mode ) ); + + if ( mode == 0 ) + myElemInfo = new SMESHGUI_SimpleElemInfo( w ); + else + myElemInfo = new SMESHGUI_TreeElemInfo( w ); + + QGridLayout* elemLayout = new QGridLayout( w ); + elemLayout->setMargin( MARGIN ); + elemLayout->setSpacing( SPACING ); + elemLayout->addWidget( myMode->button( NodeMode ), 0, 0 ); + elemLayout->addWidget( myMode->button( ElemMode ), 0, 1 ); + elemLayout->addWidget( myID, 0, 2 ); + elemLayout->addWidget( myElemInfo, 1, 0, 1, 3 ); + + myTabWidget->addTab( w, tr( "ELEM_INFO" ) ); + + QPushButton* okBtn = new QPushButton( tr( "SMESH_BUT_OK" ), this ); + okBtn->setAutoDefault( true ); + okBtn->setDefault( true ); + okBtn->setFocus(); + QPushButton* helpBtn = new QPushButton( tr( "SMESH_BUT_HELP" ), this ); + helpBtn->setAutoDefault( true ); + + QHBoxLayout* btnLayout = new QHBoxLayout; + btnLayout->setSpacing( SPACING ); + btnLayout->setMargin( 0 ); + + btnLayout->addWidget( okBtn ); + btnLayout->addStretch( 10 ); + btnLayout->addWidget( helpBtn ); + + QVBoxLayout* l = new QVBoxLayout ( this ); + l->setMargin( MARGIN ); + l->setSpacing( SPACING ); + l->addWidget( myTabWidget ); + l->addStretch(); + l->addLayout( btnLayout ); + + myTabWidget->setCurrentIndex( qMax( (int)BaseInfo, qMin( (int)ElemInfo, page ) ) ); + + connect( okBtn, SIGNAL( clicked() ), this, SLOT( reject() ) ); + connect( helpBtn, SIGNAL( clicked() ), this, SLOT( help() ) ); + connect( myTabWidget, SIGNAL( currentChanged( int ) ), this, SLOT( updateSelection() ) ); + connect( myMode, SIGNAL( buttonClicked( int ) ), this, SLOT( modeChanged() ) ); + connect( myID, SIGNAL( textEdited( QString ) ), this, SLOT( idChanged() ) ); + connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalDeactivateActiveDialog() ), this, SLOT( deactivate() ) ); + connect( SMESHGUI::GetSMESHGUI(), SIGNAL( SignalCloseAllDialogs() ), this, SLOT( reject() ) ); + + updateSelection(); +} + +/*! + \brief Destructor +*/ +SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg() +{ +} + +/*! + \brief Show mesh information + \param IO interactive object +*/ +void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO ) +{ + SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( IO ); + if ( !CORBA::is_nil( obj ) ) { + myBaseInfo->showInfo( obj ); + + myActor = SMESH::FindActorByEntry( IO->getEntry() ); + SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector(); + QString ID; + int nb = 0; + if ( myActor && selector ) { + nb = myMode->checkedId() == NodeMode ? + SMESH::GetNameOfSelectedElements( selector, IO, ID ) : + SMESH::GetNameOfSelectedNodes( selector, IO, ID ); + } + if ( nb == 1 ) { + myID->setText( ID.trimmed() ); + myElemInfo->setSource( myActor ) ; + myElemInfo->showInfo( ID.toLong(), myMode->checkedId() == ElemMode ); + } + else { + myID->clear(); + myElemInfo->clear(); + } + } +} + +/*! + \brief Perform clean-up actions on the dialog box closing. +*/ +void SMESHGUI_MeshInfoDlg::reject() +{ + LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr(); + selMgr->clearFilters(); + SMESH::SetPointRepresentation( false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( ActorSelection ); + QDialog::reject(); +} + +/*! + \brief Process keyboard event + \param e key press event +*/ +void SMESHGUI_MeshInfoDlg::keyPressEvent( QKeyEvent* e ) +{ + QDialog::keyPressEvent( e ); + if ( !e->isAccepted() && e->key() == Qt::Key_F1 ) { + e->accept(); + help(); + } +} + +/*! + \brief Reactivate dialog box, when mouse pointer goes into it. +*/ +void SMESHGUI_MeshInfoDlg::enterEvent( QEvent* ) +{ + activate(); +} + +/*! + \brief Setup selection mode depending on the current dialog box state. +*/ +void SMESHGUI_MeshInfoDlg::updateSelection() +{ + LightApp_SelectionMgr* selMgr = SMESHGUI::selectionMgr(); + + disconnect( selMgr, 0, this, 0 ); + selMgr->clearFilters(); + + if ( myTabWidget->currentIndex() == BaseInfo ) { + SMESH::SetPointRepresentation( false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( ActorSelection ); + } + else { + if ( myMode->checkedId() == NodeMode ) { + SMESH::SetPointRepresentation( true ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( NodeSelection ); + } + else { + SMESH::SetPointRepresentation( false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->SetSelectionMode( CellSelection ); + } + } + + int oldID = myID->text().toLong(); + SMESH_Actor* oldActor = myActor; + myID->clear(); + + connect( selMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) ); + updateInfo(); + + if ( oldActor == myActor && myActor && oldID ) { + myID->setText( QString::number( oldID ) ); + idChanged(); + } +} + +/*! + \brief Show help page +*/ +void SMESHGUI_MeshInfoDlg::help() +{ + SMESH::ShowHelpFile( myTabWidget->currentIndex() == BaseInfo ? + "mesh_infos_page.html#advanced_mesh_infos_anchor" : + "mesh_infos_page.html#mesh_element_info_anchor" ); +} + +/*! + \brief Show mesh information +*/ +void SMESHGUI_MeshInfoDlg::updateInfo() +{ + SUIT_OverrideCursor wc; + + SALOME_ListIO selected; + SMESHGUI::selectionMgr()->selectedObjects( selected ); + + if ( selected.Extent() == 1 ) { + Handle(SALOME_InteractiveObject) IO = selected.First(); + showInfo( IO ); + } +// else { +// myBaseInfo->clear(); +// myElemInfo->clear(); +// } +} + +/*! + \brief Activate dialog box +*/ +void SMESHGUI_MeshInfoDlg::activate() +{ + SMESHGUI::GetSMESHGUI()->EmitSignalDeactivateDialog(); + SMESHGUI::GetSMESHGUI()->SetActiveDialogBox( this ); + myTabWidget->setEnabled( true ); + updateSelection(); +} + +/*! + \brief Deactivate dialog box +*/ +void SMESHGUI_MeshInfoDlg::deactivate() +{ + myTabWidget->setEnabled( false ); + disconnect( SMESHGUI::selectionMgr(), SIGNAL( currentSelectionChanged() ), this, SLOT( updateInfo() ) ); +} + +/*! + \brief Called when users switches between node / element modes. +*/ +void SMESHGUI_MeshInfoDlg::modeChanged() +{ + myID->clear(); + updateSelection(); +} + +/*! + \brief Caled when users prints mesh element ID in the corresponding field. +*/ +void SMESHGUI_MeshInfoDlg::idChanged() +{ + SVTK_Selector* selector = SMESH::GetViewWindow()->GetSelector(); + if ( myActor && selector ) { + Handle(SALOME_InteractiveObject) IO = myActor->getIO(); + TColStd_MapOfInteger ID; + ID.Add( myID->text().toLong() ); + selector->AddOrRemoveIndex( IO, ID, false ); + if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow() ) + aViewWindow->highlight( IO, true, true ); + myElemInfo->showInfo( myID->text().toLong(), myMode->checkedId() == ElemMode ); + } +} diff --git a/src/SMESHGUI/SMESHGUI_MeshInfo.h b/src/SMESHGUI/SMESHGUI_MeshInfo.h new file mode 100644 index 000000000..ae22e5ac0 --- /dev/null +++ b/src/SMESHGUI/SMESHGUI_MeshInfo.h @@ -0,0 +1,220 @@ +// 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 +// +// File : SMESHGUI_MeshInfo.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) + +#ifndef SMESHGUI_MESHINFO_H +#define SMESHGUI_MESHINFO_H + +#include "SMESH_SMESHGUI.hxx" +#include + +#include +#include +#include +#include +#include + +#include +#include CORBA_SERVER_HEADER(SMESH_Mesh) + +class QButtonGroup; +class QLabel; +class QLineEdit; +class QTabWidget; +class QTextBrowser; +class QTreeWidget; +class QTreeWidgetItem; +class SMESH_Actor; +class SMDS_MeshNode; +class SMDS_MeshElement; + +class SMESHGUI_EXPORT SMESHGUI_MeshInfo : public QFrame +{ + Q_OBJECT; + + enum { + iName, + iObject, + iNodesStart, + iNodes, + iNodesEnd, + iElementsStart = iNodesEnd, + iElements, + i0DStart, + i0D, + i0DEnd, + i1DStart = i0DEnd, + i1D, + i1DEnd, + i2DStart = i1DEnd, + i2D, + i2DTriangles, + i2DQuadrangles, + i2DPolygons, + i2DEnd, + i3DStart = i2DEnd, + i3D, + i3DTetrahedrons, + i3DHexahedrons, + i3DPyramids, + i3DPrisms, + i3DPolyhedrons, + i3DEnd, + iElementsEnd = i3DEnd + }; + + enum { + iSingle = 1, + iTotal = iSingle, + iLinear, + iQuadratic + }; + + typedef QList wlist; + typedef QVector iwlist; + +public: + SMESHGUI_MeshInfo( QWidget* = 0 ); + ~SMESHGUI_MeshInfo(); + + void showInfo( SMESH::SMESH_IDSource_ptr ); + void clear(); + +private: + enum { Bold = 0x01, Italic = 0x02 }; + + QLabel* createField(); + QWidget* createLine(); + void setFontAttributes( QWidget*, int, bool = true ); + void setFieldsVisible( int, int, bool ); + +private: + iwlist myWidgets; +}; + +class SMESHGUI_EXPORT SMESHGUI_ElemInfo : public QWidget +{ + Q_OBJECT; + +public: + SMESHGUI_ElemInfo( QWidget* = 0 ); + ~SMESHGUI_ElemInfo(); + + void setSource( SMESH_Actor* ); + virtual void showInfo( long, bool ); + virtual void clear() = 0; + +protected: + struct XYZ + { + double myX, myY, myZ; + XYZ() { myX = myY = myZ = 0.0; } + void add( double x, double y, double z ) { myX += x; myY += y; myZ += z; } + void divide( double a ) { if ( a != 0.) { myX /= a; myY /= a; myZ /= a; } } + double x() const { return myX; } + double y() const { return myY; } + double z() const { return myZ; } + }; + typedef QMap< int, QList > Connectivity; + + Connectivity nodeConnectivity( const SMDS_MeshNode* ); + QString formatConnectivity( Connectivity, int ); + XYZ gravityCenter( const SMDS_MeshElement* ); + +protected: + SMESH_Actor* myActor; + long myID; + int myIsElement; +}; + +class SMESHGUI_EXPORT SMESHGUI_SimpleElemInfo : public SMESHGUI_ElemInfo +{ +public: + SMESHGUI_SimpleElemInfo( QWidget* = 0 ); + + void showInfo( long, bool ); + void clear(); + +private: + QTextBrowser* myInfo; +}; + +class SMESHGUI_EXPORT SMESHGUI_TreeElemInfo : public SMESHGUI_ElemInfo +{ + class ItemDelegate; + +public: + SMESHGUI_TreeElemInfo( QWidget* = 0 ); + + void showInfo( long, bool ); + void clear(); + +private: + QTreeWidgetItem* createItem( QTreeWidgetItem* = 0, int = 100 ); + +private: + QTreeWidget* myInfo; +}; + +class SMESHGUI_EXPORT SMESHGUI_MeshInfoDlg : public QDialog +{ + Q_OBJECT; + + enum { NodeMode, ElemMode }; + +public: + //! Information type + enum { + BaseInfo, //!< base mesh information + ElemInfo //!< mesh element information + }; + + SMESHGUI_MeshInfoDlg( QWidget* = 0, int = BaseInfo ); + ~SMESHGUI_MeshInfoDlg(); + + void showInfo( const Handle(SALOME_InteractiveObject)& ); + void reject(); + +protected: + void keyPressEvent( QKeyEvent* ); + void enterEvent( QEvent* ); + +private slots: + void help(); + void updateSelection(); + void updateInfo(); + void activate(); + void deactivate(); + void modeChanged(); + void idChanged(); + +private: + QTabWidget* myTabWidget; + SMESHGUI_MeshInfo* myBaseInfo; + QButtonGroup* myMode; + QLineEdit* myID; + SMESHGUI_ElemInfo* myElemInfo; + SMESH_Actor* myActor; +}; + +#endif // SMESHGUI_MESHINFO_H diff --git a/src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx b/src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx index 01ba22253..40def53ab 100644 --- a/src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx @@ -141,7 +141,9 @@ SMESHGUI_MeshInfosDlg::SMESHGUI_MeshInfosDlg(SMESHGUI* theModule): // buttons --> OK and Help buttons myOkBtn = new QPushButton(tr("SMESH_BUT_OK" ), myButtonsGroup); - myOkBtn->setAutoDefault(true); myOkBtn->setDefault(true); + myOkBtn->setAutoDefault(true); + myOkBtn->setDefault(true); + myOkBtn->setFocus(); myHelpBtn = new QPushButton(tr("SMESH_BUT_HELP" ), myButtonsGroup); myHelpBtn->setAutoDefault(true); diff --git a/src/SMESHGUI/SMESHGUI_MeshOp.cxx b/src/SMESHGUI/SMESHGUI_MeshOp.cxx index 4ceb159ee..48b4fae6e 100644 --- a/src/SMESHGUI/SMESHGUI_MeshOp.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshOp.cxx @@ -19,12 +19,11 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_MeshOp.cxx +// Author : Sergey LITONIN, Open CASCADE S.A.S. -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_MeshOp.cxx -// Author : Sergey LITONIN, Open CASCADE S.A.S. // SMESH includes -// #include "SMESHGUI_MeshOp.h" #include "SMESHGUI.h" @@ -72,6 +71,10 @@ #include #include CORBA_CLIENT_HEADER(SMESH_Gen) +//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 @@ -280,7 +283,6 @@ SUIT_SelectionFilter* SMESHGUI_MeshOp::createFilter( const int theId ) const * \retval bool - check result */ //================================================================================ - bool SMESHGUI_MeshOp::isSubshapeOk() const { if ( !myToCreate || myIsMesh ) // not submesh creation @@ -343,11 +345,10 @@ bool SMESHGUI_MeshOp::isSubshapeOk() const //================================================================================ /*! * \brief Return name of the algorithm that does not support submeshes and makes - * submesh creation useless + * submesh creation useless * \retval char* - string is to be deleted!!! */ //================================================================================ - char* SMESHGUI_MeshOp::isSubmeshIgnored() const { if ( myToCreate && !myIsMesh ) { @@ -393,7 +394,6 @@ char* SMESHGUI_MeshOp::isSubmeshIgnored() const * \retval _PTR(SObject) - the found submesh SObject */ //================================================================================ - _PTR(SObject) SMESHGUI_MeshOp::getSubmeshByGeom() const { QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh ); @@ -581,7 +581,7 @@ void SMESHGUI_MeshOp::selectionDone() bool editSubmesh = ( !sm->_is_nil() && SUIT_MessageBox::question( myDlg, tr( "SMESH_WARNING" ), tr( "EDIT_SUBMESH_QUESTION"), - SUIT_MessageBox::Yes | + SUIT_MessageBox::Yes | SUIT_MessageBox::No, SUIT_MessageBox::No ) == SUIT_MessageBox::Yes ); @@ -743,7 +743,6 @@ bool SMESHGUI_MeshOp::isValid( QString& theMess ) const * \retval bool - check result */ //================================================================================ - static bool isCompatible(const HypothesisData* theAlgoData, const HypothesisData* theHypData, const int theHypType) @@ -861,6 +860,7 @@ void SMESHGUI_MeshOp::existingHyps( const int theDim, if ( !aHypVar->_is_nil() ) { HypothesisData* aData = SMESH::GetHypothesisData( aHypVar->GetName() ); + if ( !aData) continue; if ( ( theDim == -1 || aData->Dim.contains( theDim ) ) && ( isCompatible ( theAlgoData, aData, theHypType )) && ( isAux == aData->IsAux )) @@ -886,7 +886,6 @@ void SMESHGUI_MeshOp::existingHyps( const int theDim, * \retval SMESH::SMESH_Hypothesis_var - the hypothesis holding parameter values */ //================================================================================ - SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getInitParamsHypothesis( const QString& aHypType, const QString& aServerLib ) const @@ -972,7 +971,6 @@ SMESHGUI_MeshOp::getInitParamsHypothesis( const QString& aHypType, * \retval int - dimention */ //================================================================================ - static int getTabDim (const QObject* tab, SMESHGUI_MeshDlg* dlg ) { int aDim = -1; @@ -1030,7 +1028,6 @@ namespace * \param theTypeName - specifies hypothesis to be created */ //================================================================================ - void SMESHGUI_MeshOp::createHypothesis(const int theDim, const int theType, const QString& theTypeName) @@ -1064,7 +1061,12 @@ void SMESHGUI_MeshOp::createHypothesis(const int theDim, QString aClientLibName = aData->ClientLibName; if (aClientLibName == "") { // Call hypothesis creation server method (without GUI) - SMESH::CreateHypothesis(theTypeName, aHypName, false); + SMESH::SMESH_Hypothesis_var aHyp = + SMESH::CreateHypothesis(theTypeName, aHypName, false); +#ifdef WITHGENERICOBJ + if (!CORBA::is_nil(aHyp)) + aHyp->Destroy(); +#endif } else { // Get hypotheses creator client (GUI) // BUG 0020378 @@ -1086,13 +1088,13 @@ void SMESHGUI_MeshOp::createHypothesis(const int theDim, aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom ); aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh ); anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj ); - + if ( aMeshEntry != "" ) { // Get Geom object from Mesh _PTR(SObject) pObj = studyDS()->FindObjectID( aMeshEntry.toLatin1().data() ); GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj ); aMeshEntry = ( aGeomVar->_is_nil() ) ? "" : aMeshEntry = aGeomVar->GetStudyEntry(); } - + if ( aMeshEntry == "" && aGeomEntry == "" ) { _PTR(SObject) pObj = studyDS()->FindObjectID( anObjEntry.toLatin1().data() ); GEOM::GEOM_Object_var aGeomVar = SMESH::GetShapeOnMeshOrSubMesh( pObj ); @@ -1117,7 +1119,7 @@ void SMESHGUI_MeshOp::createHypothesis(const int theDim, } } } - + aCreator->setShapeEntry( aGeomEntry ); if ( aMeshEntry != "" ) aCreator->setMainShapeEntry( aMeshEntry ); @@ -1125,8 +1127,14 @@ void SMESHGUI_MeshOp::createHypothesis(const int theDim, aCreator->create(initParamHyp, aHypName, myDlg, this, SLOT( onHypoCreated( int ) ) ); dialog = true; } - else - SMESH::CreateHypothesis(theTypeName, aHypName, false); + else { + SMESH::SMESH_Hypothesis_var aHyp = + SMESH::CreateHypothesis(theTypeName, aHypName, false); +#ifdef WITHGENERICOBJ + if (!CORBA::is_nil(aHyp)) + aHyp->Destroy(); +#endif + } } if( !dialog ) @@ -1274,7 +1282,6 @@ void SMESHGUI_MeshOp::onHypoEdited( int result ) * \retval HypothesisData* - result data, may be 0 */ //================================================================================ - HypothesisData* SMESHGUI_MeshOp::hypData( const int theDim, const int theHypType, const int theIndex) @@ -1292,7 +1299,6 @@ HypothesisData* SMESHGUI_MeshOp::hypData( const int theDim, * \param theIndex - algorithm index */ //================================================================================ - void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex, const int theDim ) { @@ -1588,7 +1594,13 @@ bool SMESHGUI_MeshOp::createMesh( QString& theMess ) if ( !anAlgoVar->_is_nil() ) SMESH::AddHypothesisOnMesh( aMeshVar, anAlgoVar ); } - +#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 + if (aMeshSO) + aMeshVar->Destroy(); +#endif } return true; } @@ -1676,7 +1688,7 @@ bool SMESHGUI_MeshOp::createSubMesh( QString& theMess ) QString aNewGeomGroupName ("Auto_group_for_"); aNewGeomGroupName += aName; SALOMEDS::SObject_var aNewGroupSO = - geomGen->AddInStudy(aSMESHGen->GetCurrentStudy(), aGeomVar, + geomGen->AddInStudy(aSMESHGen->GetCurrentStudy(), aGeomVar, aNewGeomGroupName.toLatin1().data(), mainGeom); } } @@ -1846,7 +1858,12 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim ) if (aClientLibName == "") { // Call hypothesis creation server method (without GUI) - SMESH::CreateHypothesis(aHypName, aHypData->Label, true); + SMESH::SMESH_Hypothesis_var aHyp = + SMESH::CreateHypothesis(aHypName, aHypName, true); +#ifdef WITHGENERICOBJ + if (!CORBA::is_nil(aHyp)) + aHyp->Destroy(); +#endif } else { @@ -1858,8 +1875,14 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim ) // Create algorithm if (aCreator) aCreator->create(true, aHypName, myDlg, 0, QString::null ); - else - SMESH::CreateHypothesis(aHypName, aHypData->Label, true); + else { + SMESH::SMESH_Hypothesis_var aHyp = + SMESH::CreateHypothesis(aHypName, aHypName, true); +#ifdef WITHGENERICOBJ + if (!CORBA::is_nil(aHyp)) + aHyp->Destroy(); +#endif + } } QStringList tmpList; _PTR(SComponent) aFather = SMESH::GetActiveStudyDocument()->FindComponent( "SMESH" ); @@ -2160,14 +2183,14 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess ) //================================================================================ /*! * \brief Verifies whether given operator is valid for this one - * \param theOtherOp - other operation - * \return Returns TRUE if the given operator is valid for this one, FALSE otherwise -* -* method redefined from base class verifies whether given operator is valid for -* this one (i.e. can be started "above" this operator). In current implementation method -* retuns false if theOtherOp operation is not intended for deleting objects or mesh -* elements. -*/ + * \param theOtherOp - other operation + * \return Returns TRUE if the given operator is valid for this one, FALSE otherwise + * + * method redefined from base class verifies whether given operator is valid for + * this one (i.e. can be started "above" this operator). In current implementation method + * retuns false if theOtherOp operation is not intended for deleting objects or mesh + * elements. + */ //================================================================================ bool SMESHGUI_MeshOp::isValid( SUIT_Operation* theOp ) const { @@ -2177,10 +2200,9 @@ bool SMESHGUI_MeshOp::isValid( SUIT_Operation* theOp ) const //================================================================================ /*! * \brief SLOT. Is called when the user selects a way of geometry selection - * \param theByMesh - true if the user wants to find geometry by mesh element + * \param theByMesh - true if the user wants to find geometry by mesh element */ //================================================================================ - void SMESHGUI_MeshOp::onGeomSelectionByMesh( bool theByMesh ) { if ( theByMesh ) { @@ -2212,7 +2234,6 @@ void SMESHGUI_MeshOp::onGeomSelectionByMesh( bool theByMesh ) * \brief SLOT. Is called when Ok is pressed in SMESHGUI_ShapeByMeshDlg */ //================================================================================ - void SMESHGUI_MeshOp::onPublishShapeByMeshDlg(SUIT_Operation* op) { if ( myShapeByMeshOp == op ) { @@ -2236,7 +2257,6 @@ void SMESHGUI_MeshOp::onPublishShapeByMeshDlg(SUIT_Operation* op) * \brief SLOT. Is called when Close is pressed in SMESHGUI_ShapeByMeshDlg */ //================================================================================ - void SMESHGUI_MeshOp::onCloseShapeByMeshDlg(SUIT_Operation* op) { if ( myShapeByMeshOp == op && myDlg ) { @@ -2247,10 +2267,9 @@ void SMESHGUI_MeshOp::onCloseShapeByMeshDlg(SUIT_Operation* op) //================================================================================ /*! * \brief Selects a SObject - * \param theSObj - the SObject to select + * \param theSObj - the SObject to select */ //================================================================================ - void SMESHGUI_MeshOp::selectObject( _PTR(SObject) theSObj ) const { if ( LightApp_SelectionMgr* sm = selectionMgr() ) { diff --git a/src/SMESHGUI/SMESHGUI_MeshUtils.cxx b/src/SMESHGUI/SMESHGUI_MeshUtils.cxx index 0763be3ed..7d48093e2 100644 --- a/src/SMESHGUI/SMESHGUI_MeshUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshUtils.cxx @@ -27,6 +27,7 @@ // #include "SMESHGUI_MeshUtils.h" +#include "SMESHGUI.h" #include "SMESHGUI_Utils.h" // SALOME KERNEL includes @@ -38,6 +39,7 @@ // IDL includes #include #include CORBA_SERVER_HEADER(SMESH_Group) +#include CORBA_SERVER_HEADER(SMESH_Measurements) namespace SMESH { @@ -82,4 +84,53 @@ namespace SMESH } return baseName; } + + QString UniqueName(const QString& theBaseName, _PTR(SObject) theParent, const QString& thePostfix) + { + QString baseName = thePostfix.isEmpty() ? + theBaseName : theBaseName + "_" + thePostfix; + QString name = baseName; + if ( _PTR(Study) aStudy = GetActiveStudyDocument() ) { + _PTR(SObject) p = theParent; + if ( !p ) p = aStudy->FindComponent( "SMESH" ); + if ( p ) { + _PTR(ChildIterator) iter = aStudy->NewChildIterator( p ); + int idx = 0; + while( true ) { + bool found = false; + for ( ; iter->More(); iter->Next() ) { + _PTR(SObject) so = iter->Value(); + if ( !so ) continue; // skip bad objects + _PTR(SObject) ref; + if ( so->ReferencedObject( ref ) ) continue; // skip references + QString n = so->GetName().c_str(); + if ( !n.isEmpty() && n == name ) { + QStringList names = name.split("_", QString::KeepEmptyParts); + if ( names.count() > 0 ) { + bool ok; + names.last().toInt( &ok ); + if ( ok ) + names.removeLast(); + } + names.append( QString::number( ++idx ) ); + name = names.join( "_" ); + found = true; + break; + } + } + if ( !found ) break; + } + } + } + return name; + } + + SMESH::Measurements_var& GetMeasurements() + { + static SMESH::Measurements_var aMeasurements; + if (CORBA::is_nil(aMeasurements)) { + aMeasurements = SMESHGUI::GetSMESHGen()->CreateMeasurements(); + } + return aMeasurements; + } } // end of namespace SMESH diff --git a/src/SMESHGUI/SMESHGUI_MeshUtils.h b/src/SMESHGUI/SMESHGUI_MeshUtils.h index 5edffe9f3..a5371f56b 100644 --- a/src/SMESHGUI/SMESHGUI_MeshUtils.h +++ b/src/SMESHGUI/SMESHGUI_MeshUtils.h @@ -36,9 +36,15 @@ // SALOME GUI includes #include +// SALOME KERNEL includes +#include + // IDL includes #include #include CORBA_SERVER_HEADER(SMESH_Mesh) +#include CORBA_SERVER_HEADER(SMESH_Measurements) + +class SALOMEDSClient_SObject; namespace SMESH { @@ -47,6 +53,10 @@ namespace SMESH SMESHGUI_EXPORT QString UniqueMeshName( const QString&, const QString& = QString() ); + SMESHGUI_EXPORT + QString UniqueName( const QString&, _PTR(SObject) = _PTR(SObject)(), const QString& = QString() ); + + SMESHGUI_EXPORT SMESH::Measurements_var& GetMeasurements(); } #endif // SMESHGUI_MESHUTILS_H diff --git a/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx b/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx index 341ffb284..ad420496e 100755 --- a/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx @@ -1489,9 +1489,9 @@ SMESHGUI_CuttingIntoTetraDlg::SMESHGUI_CuttingIntoTetraDlg(SMESHGUI* theModule) if ( hasHexa ) { - myGroupChoice->button(2)->hide(); myGroupChoice->button(0)->setText( tr("SPLIT_HEX_TO_5_TETRA")); myGroupChoice->button(1)->setText( tr("SPLIT_HEX_TO_6_TETRA")); + myGroupChoice->button(2)->setText( tr("SPLIT_HEX_TO_24_TETRA")); myCriterionGrp->setTitle( tr("SPLIT_METHOD")); myCriterionGrp->show(); @@ -1512,7 +1512,7 @@ bool SMESHGUI_CuttingIntoTetraDlg::process (SMESH::SMESH_MeshEditor_ptr theEdito { SMESH::SMESH_IDSource_var obj = theObj; if ( CORBA::is_nil( obj )) - obj = theEditor->MakeIDSource( theIds ); + obj = theEditor->MakeIDSource( theIds, myEntityType ? SMESH::VOLUME : SMESH::FACE ); try { theEditor->SplitVolumesIntoTetra( obj, myGroupChoice->checkedId()+1 ); } diff --git a/src/SMESHGUI/SMESHGUI_NodesDlg.cxx b/src/SMESHGUI/SMESHGUI_NodesDlg.cxx index 84abe5242..2707c85d1 100644 --- a/src/SMESHGUI/SMESHGUI_NodesDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_NodesDlg.cxx @@ -452,15 +452,15 @@ bool SMESHGUI_NodesDlg::ClickOnApply() for ( int i = 1; i < ComboBox_GroupName->count(); i++ ) { QString aName = ComboBox_GroupName->itemText( i ); if ( aGroupName == aName && ( i == ComboBox_GroupName->currentIndex() || idx == 0 ) ) - idx = i; + idx = i; } if ( idx > 0 ) { SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( myGroups[idx-1] ); if ( !aGeomGroup->_is_nil() ) { - int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ), - tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ), - tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 ); - if ( res == 1 ) return false; + int res = SUIT_MessageBox::question( this, tr( "SMESH_WRN_WARNING" ), + tr( "MESH_STANDALONE_GRP_CHOSEN" ).arg( aGroupName ), + tr( "SMESH_BUT_YES" ), tr( "SMESH_BUT_NO" ), 0, 1 ); + if ( res == 1 ) return false; } aGroup = myGroups[idx-1]; } @@ -478,21 +478,21 @@ bool SMESHGUI_NodesDlg::ClickOnApply() // create new group aGroupUsed = SMESH::AddGroup( myMesh, SMESH::NODE, aGroupName ); if ( !aGroupUsed->_is_nil() ) { - myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed)); - ComboBox_GroupName->addItem( aGroupName ); + myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroupUsed)); + ComboBox_GroupName->addItem( aGroupName ); } } else { SMESH::SMESH_GroupOnGeom_var aGeomGroup = SMESH::SMESH_GroupOnGeom::_narrow( aGroup ); if ( !aGeomGroup->_is_nil() ) { - aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup ); - if ( !aGroupUsed->_is_nil() && idx > 0 ) { - myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed); - SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser(); - } + aGroupUsed = myMesh->ConvertToStandalone( aGeomGroup ); + if ( !aGroupUsed->_is_nil() && idx > 0 ) { + myGroups[idx-1] = SMESH::SMESH_GroupBase::_duplicate(aGroupUsed); + SMESHGUI::GetSMESHGUI()->getApp()->updateObjectBrowser(); + } } else - aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup ); + aGroupUsed = SMESH::SMESH_Group::_narrow( aGroup ); } if ( !aGroupUsed->_is_nil() ) { @@ -529,6 +529,8 @@ bool SMESHGUI_NodesDlg::ClickOnApply() } SMESHGUI::Modified(); + SMESH::UpdateView(); + mySimulation->SetVisibility(false); return true; } @@ -623,10 +625,10 @@ void SMESHGUI_NodesDlg::SelectionIntoArgument() for( int i = 0, n = aListOfGroups.length(); i < n; i++ ) { SMESH::SMESH_GroupBase_var aGroup = aListOfGroups[i]; if ( !aGroup->_is_nil() && aGroup->GetType() == SMESH::NODE ) { - QString aGroupName( aGroup->GetName() ); - if ( !aGroupName.isEmpty() ) { - myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup)); - ComboBox_GroupName->addItem( aGroupName ); + QString aGroupName( aGroup->GetName() ); + if ( !aGroupName.isEmpty() ) { + myGroups.append(SMESH::SMESH_GroupBase::_duplicate(aGroup)); + ComboBox_GroupName->addItem( aGroupName ); } } } diff --git a/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx b/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx index ec3a4d14f..43640501e 100644 --- a/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx @@ -33,6 +33,8 @@ #include "SMESHGUI_Utils.h" #include +#include +#include // SALOME GUI includes #include @@ -63,7 +65,6 @@ // VTK includes #include -#include #include #define MINIMUM_WIDTH 70 @@ -279,8 +280,35 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI* myOriginDimGrpLayout->addWidget( myHeightSpin, 1, 3 ); aTopLayout->addWidget( myOriginDimGrp ); + /******************************************************************************/ - /***************************************************************/ + // Destribution + myDistributionGrp = new QGroupBox ( tr( "SMESH_DISTRIBUTION_SCALARBAR" ), this ); + myDistributionGrp->setCheckable(true); + QHBoxLayout* aDistributionGrpLayout = new QHBoxLayout( myDistributionGrp ); + aDistributionGrpLayout->setSpacing( SPACING_SIZE ); aDistributionGrpLayout->setMargin( MARGIN_SIZE ); + + myDistribColorGrp = new QButtonGroup( this ); + + myDMonoColor = new QRadioButton( tr( "SMESH_MONOCOLOR" ) , myDistributionGrp ); + myDMultiColor = new QRadioButton( tr( "SMESH_MULTICOLOR" ), myDistributionGrp ); + myDMonoColor->setChecked( true ); + + myDistribColorGrp->addButton(myDMonoColor);myDistribColorGrp->setId(myDMonoColor,1); + myDistribColorGrp->addButton(myDMultiColor);myDistribColorGrp->setId(myDMultiColor,2); + + aDistributionGrpLayout->addWidget( myDMultiColor ); + aDistributionGrpLayout->addWidget( myDMonoColor ); + + //Color of the Distribution in monocolor case: + myDistributionColorLbl = new QLabel( tr( "SMESH_DISTRIBUTION_COLOR" ), myDistributionGrp ); + aDistributionGrpLayout->addWidget( myDistributionColorLbl ); + myMonoColorBtn = new QtxColorButton( myDistributionGrp ); + aDistributionGrpLayout->addWidget(myMonoColorBtn); + + aTopLayout->addWidget(myDistributionGrp); + + /******************************************************************************/ // Common buttons myButtonGrp = new QGroupBox( this ); QHBoxLayout* myButtonGrpLayout = new QHBoxLayout( myButtonGrp ); @@ -376,6 +404,25 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI* setOriginAndSize(myIniX, myIniY, myIniW, myIniH); + + bool distributionVisibility = mgr->booleanValue("SMESH","distribution_visibility"); + myDistributionGrp->setChecked(distributionVisibility); + + int coloringType = mgr->integerValue("SMESH", "distribution_coloring_type", 0); + if( coloringType == SMESH_MONOCOLOR_TYPE ) { + myDMultiColor->setChecked(true); + onDistributionChanged(myDistribColorGrp->id(myDMultiColor)); + } else { + myDMonoColor->setChecked(true); + onDistributionChanged(myDistribColorGrp->id(myDMonoColor)); + } + + QColor distributionColor = mgr->colorValue("SMESH", "distribution_color", + QColor(255, 255, 255)); + myMonoColorBtn->setColor(distributionColor); + + + // --> then init from selection if necessary onSelectionChanged(); @@ -388,10 +435,11 @@ SMESHGUI_Preferences_ScalarBarDlg::SMESHGUI_Preferences_ScalarBarDlg( SMESHGUI* connect( myXSpin, SIGNAL( valueChanged( double ) ), this, SLOT( onXYChanged() ) ); connect( myYSpin, SIGNAL( valueChanged( double ) ), this, SLOT( onXYChanged() ) ); connect( aOrientationGrp, SIGNAL( buttonClicked( int ) ), this, SLOT( onOrientationChanged() ) ); + connect( myDistribColorGrp, SIGNAL( buttonClicked( int ) ), this, SLOT( onDistributionChanged( int ) ) ); connect( mySelectionMgr, SIGNAL( currentSelectionChanged() ), this, SLOT( onSelectionChanged() ) ); connect( mySMESHGUI, SIGNAL( SignalCloseAllDialogs() ), this, SLOT( onCancel() ) ); - myHelpFileName = "about_quality_controls_page.html"; + myHelpFileName = "quality_page.html"; } //================================================================================================= @@ -430,7 +478,7 @@ bool SMESHGUI_Preferences_ScalarBarDlg::onApply() // Scalar Bar properties if (!myActor) return false; - vtkScalarBarActor* myScalarBarActor = myActor->GetScalarBarActor(); + SMESH_ScalarBarActor* myScalarBarActor = myActor->GetScalarBarActor(); vtkTextProperty* aTitleTextPrp = myScalarBarActor->GetTitleTextProperty(); QColor aTColor = myTitleColorBtn->color(); @@ -461,7 +509,18 @@ bool SMESHGUI_Preferences_ScalarBarDlg::onApply() myScalarBarActor->SetLabelTextProperty( aLabelsTextPrp ); myScalarBarActor->SetNumberOfLabels( myLabelsSpin->value() ); - myScalarBarActor->SetMaximumNumberOfColors( myColorsSpin->value() ); + if( myColorsSpin->value() != myScalarBarActor->GetMaximumNumberOfColors() ) { + myScalarBarActor->SetMaximumNumberOfColors( myColorsSpin->value() ); + SMESH::Controls::FunctorPtr fn = myActor->GetFunctor(); + SMESH::Controls::NumericalFunctor* aNumericalFunctor = dynamic_cast(fn.get()); + if( aNumericalFunctor ) { + int nbIntervals = myColorsSpin->value(); + std::vector nbEvents; + std::vector funValues; + aNumericalFunctor->GetHistogram(nbIntervals, nbEvents, funValues); + myScalarBarActor->SetDistribution(nbEvents); + } + } if ( myHorizRadioBtn->isChecked() ) myScalarBarActor->SetOrientationToHorizontal(); @@ -472,6 +531,21 @@ bool SMESHGUI_Preferences_ScalarBarDlg::onApply() myScalarBarActor->SetWidth( myWidthSpin->value() ); myScalarBarActor->SetHeight( myHeightSpin->value() ); + // Distribution + myScalarBarActor->SetDistributionVisibility((int)myDistributionGrp->isChecked()); + if( myDistributionGrp->isChecked() ) { + int ColoringType = myDMultiColor->isChecked() ? SMESH_MULTICOLOR_TYPE : SMESH_MONOCOLOR_TYPE; + myScalarBarActor->SetDistributionColoringType(ColoringType); + if( !myDMultiColor->isChecked() ) { + QColor aTColor = myMonoColorBtn->color(); + double rgb[3]; + rgb [0] = aTColor.red()/255.; + rgb [1] = aTColor.green()/255.; + rgb [2] = aTColor.blue()/255.; + myScalarBarActor->SetDistributionColor(rgb); + } + } + double aMin = myMinEdit->text().toDouble(); double aMax = myMaxEdit->text().toDouble(); vtkLookupTable* myLookupTable = @@ -540,7 +614,7 @@ void SMESHGUI_Preferences_ScalarBarDlg::onSelectionChanged() SMESH_Actor* anActor = SMESH::FindActorByEntry(anIO->getEntry()); if ( anActor && anActor->GetScalarBarActor() && anActor->GetControlMode() != SMESH_Actor::eNone ) { myActor = anActor; - vtkScalarBarActor* myScalarBarActor = myActor->GetScalarBarActor(); + SMESH_ScalarBarActor* myScalarBarActor = myActor->GetScalarBarActor(); if ( myScalarBarActor->GetLookupTable() ) { vtkFloatingPointType *range = myScalarBarActor->GetLookupTable()->GetRange(); @@ -581,6 +655,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)); + } myRangeGrp->setEnabled( true ); myFontGrp->setEnabled( true ); myLabColorGrp->setEnabled( true ); @@ -651,6 +736,19 @@ void SMESHGUI_Preferences_ScalarBarDlg::setOriginAndSize( const double x, onXYChanged(); } + +//================================================================================================= +/*! + * SMESHGUI_Preferences_ScalarBarDlg::onDistributionChanged + * + * Called when coloring type of the distribution is changed + */ +//================================================================================================= +void SMESHGUI_Preferences_ScalarBarDlg::onDistributionChanged( int id ) { + myMonoColorBtn->setEnabled(myDistribColorGrp->id(myDMonoColor) == id); + myDistributionColorLbl->setEnabled(myDistribColorGrp->id(myDMonoColor) == id); +} + //================================================================================================= /*! * SMESHGUI_Preferences_ScalarBarDlg::onOrientationChanged diff --git a/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.h b/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.h index c71c43cda..42058ee2b 100644 --- a/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.h +++ b/src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.h @@ -40,6 +40,8 @@ class QLineEdit; class QPushButton; class QToolButton; class QRadioButton; +class QButtonGroup; +class QLabel; class SMESHGUI; class SMESH_Actor; @@ -77,6 +79,7 @@ protected slots: void onSelectionChanged(); void onXYChanged(); void onOrientationChanged(); + void onDistributionChanged( int ); private: SMESHGUI* mySMESHGUI; @@ -117,7 +120,14 @@ private: SMESHGUI_SpinBox* myWidthSpin; SMESHGUI_SpinBox* myHeightSpin; + QGroupBox* myDistributionGrp; + QRadioButton* myDMonoColor; + QRadioButton* myDMultiColor; + QtxColorButton* myMonoColorBtn; + QLabel* myDistributionColorLbl; + QGroupBox* myButtonGrp; + QButtonGroup* myDistribColorGrp; QPushButton* myOkBtn; QPushButton* myApplyBtn; QPushButton* myCancelBtn; diff --git a/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx b/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx index a007feb0f..3556398a1 100644 --- a/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx @@ -371,24 +371,24 @@ void SMESHGUI_RemoveElementsDlg::SelectionIntoArgument() myActor = SMESH::FindActorByEntry(anIO->getEntry()); if (myActor) { - - // get selected nodes - QString aString = ""; - int nbElems = SMESH::GetNameOfSelectedElements(mySelector,anIO,aString); - if (nbElems > 0) { - myBusy = true; - myEditCurrentArgument->setText(aString); - myBusy = false; - - // OK - - myNbOkElements = nbElems; - } // if (nbElems > 0) + + // get selected nodes + QString aString = ""; + int nbElems = SMESH::GetNameOfSelectedElements(mySelector,anIO,aString); + if (nbElems > 0) { + myBusy = true; + myEditCurrentArgument->setText(aString); + myBusy = false; + + // OK + + myNbOkElements = nbElems; + } // if (nbElems > 0) } // if (myActor) } // if (!myMesh->_is_nil()) } // if (nbSel == 1) { - updateButtons(); + updateButtons(); } //================================================================================= diff --git a/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx b/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx index 58fd31fb3..bd2ef2188 100644 --- a/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx @@ -377,23 +377,23 @@ void SMESHGUI_RemoveNodesDlg::SelectionIntoArgument() myActor = SMESH::FindActorByEntry(anIO->getEntry()); if (myActor) { - // get selected nodes - QString aString = ""; - int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,anIO,aString); - if (nbNodes > 0) { - myBusy = true; - myEditCurrentArgument->setText(aString); - myBusy = false; - - // OK - - myNbOkNodes = nbNodes; - } // if (nbNodes > 0) + // get selected nodes + QString aString = ""; + int nbNodes = SMESH::GetNameOfSelectedNodes(mySelector,anIO,aString); + if (nbNodes > 0) { + myBusy = true; + myEditCurrentArgument->setText(aString); + myBusy = false; + + // OK + + myNbOkNodes = nbNodes; + } // if (nbNodes > 0) } // if (myActor) } // if (!myMesh->_is_nil()) } // if (nbSel == 1) - updateButtons(); + updateButtons(); } //================================================================================= diff --git a/src/SMESHGUI/SMESHGUI_RotationDlg.cxx b/src/SMESHGUI/SMESHGUI_RotationDlg.cxx index 1dc48b0b3..7e2f2af84 100644 --- a/src/SMESHGUI/SMESHGUI_RotationDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_RotationDlg.cxx @@ -19,12 +19,11 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_RotationDlg.cxx +// Author : Michael ZORIN, Open CASCADE S.A.S. +// SMESH includes -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_RotationDlg.cxx -// Author : Michael ZORIN, Open CASCADE S.A.S. -// SMESH includes -// #include "SMESHGUI_RotationDlg.h" #include "SMESHGUI.h" @@ -84,6 +83,10 @@ enum { MOVE_ELEMS_BUTTON = 0, COPY_ELEMS_BUTTON, MAKE_MESH_BUTTON }; //!< action #define SPACING 8 #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 + //================================================================================= // class : SMESHGUI_RotationDlg() // purpose : @@ -430,22 +433,31 @@ bool SMESHGUI_RotationDlg::ClickOnApply() else { if(CheckBoxMesh->isChecked()) aMeshEditor->RotateObject(mySelectedObject, anAxis, anAngle, true); - else + else aMeshEditor->Rotate(anElementsId, anAxis, anAngle, true); } if( !myMesh->_is_nil()) myMesh->SetParameters( aParameters.join(":").toLatin1().constData() ); break; - case MAKE_MESH_BUTTON: + case MAKE_MESH_BUTTON: { SMESH::SMESH_Mesh_var mesh; - if(CheckBoxMesh->isChecked()) + if (CheckBoxMesh->isChecked()) mesh = aMeshEditor->RotateObjectMakeMesh(mySelectedObject, anAxis, anAngle, makeGroups, LineEditNewMesh->text().toLatin1().data()); - else + else mesh = aMeshEditor->RotateMakeMesh(anElementsId, anAxis, anAngle, makeGroups, LineEditNewMesh->text().toLatin1().data()); - if( !mesh->_is_nil()) - mesh->SetParameters( aParameters.join(":").toLatin1().constData() ); + if (!mesh->_is_nil()) { + mesh->SetParameters(aParameters.join(":").toLatin1().constData()); +#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 + mesh->Destroy(); +#endif + } + break; + } } } catch (...) { } @@ -500,7 +512,7 @@ void SMESHGUI_RotationDlg::ClickOnCancel() void SMESHGUI_RotationDlg::ClickOnHelp() { LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); - if (app) + if (app) app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); else { QString platform; @@ -542,9 +554,9 @@ void SMESHGUI_RotationDlg::onTextChange (const QString& theNewText) if (aMesh) { if (send == LineEditElements) { Handle(SALOME_InteractiveObject) anIO = myActor->getIO(); - + TColStd_MapOfInteger newIndices; - + QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts); for (int i = 0; i < aListId.count(); i++) { const SMDS_MeshElement * e = aMesh->FindElement(aListId[ i ].toInt()); @@ -556,7 +568,7 @@ void SMESHGUI_RotationDlg::onTextChange (const QString& theNewText) mySelector->AddOrRemoveIndex( anIO, newIndices, false ); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) aViewWindow->highlight( anIO, true, true ); - + myElementsId = theNewText; } } @@ -649,7 +661,7 @@ void SMESHGUI_RotationDlg::SelectionIntoArgument() } else if (!SMESH::IObjectToInterface(IO)->_is_nil()) { //SUBMESH // get submesh SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface(IO); - + // get IDs from submesh SMESH::long_array_var anElementsIds = new SMESH::long_array; anElementsIds = aSubMesh->GetElementsId(); @@ -715,7 +727,7 @@ void SMESHGUI_RotationDlg::SelectionIntoArgument() LineEditElements->setText(aString); LineEditElements->repaint(); LineEditElements->setEnabled(false); // to update lineedit IPAL 19809 - LineEditElements->setEnabled(true); + LineEditElements->setEnabled(true); setNewMeshName(); } myBusy = false; diff --git a/src/SMESHGUI/SMESHGUI_ScaleDlg.cxx b/src/SMESHGUI/SMESHGUI_ScaleDlg.cxx index b9a5c1a0b..fc275baaa 100644 --- a/src/SMESHGUI/SMESHGUI_ScaleDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ScaleDlg.cxx @@ -16,12 +16,11 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_ScaleDlg.cxx +// Author : Michael ZORIN, Open CASCADE S.A.S. +// SMESH includes -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_ScaleDlg.cxx -// Author : Michael ZORIN, Open CASCADE S.A.S. -// SMESH includes -// #include "SMESHGUI_ScaleDlg.h" #include "SMESHGUI.h" @@ -99,6 +98,10 @@ private: #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 + //================================================================================= // class : SMESHGUI_ScaleDlg() // purpose : @@ -467,58 +470,49 @@ bool SMESHGUI_ScaleDlg::ClickOnApply() try { SUIT_OverrideCursor aWaitCursor; SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); + SMESH::SMESH_IDSource_var obj; + if ( CheckBoxMesh->isChecked() ) + obj = mySelectedObject; + else + obj = aMeshEditor->MakeIDSource(anElementsId, SMESH::ALL); + switch ( actionButton ) { + case MOVE_ELEMS_BUTTON: - if(CheckBoxMesh->isChecked()) { - aMeshEditor->Scale(mySelectedObject, aPoint, aScaleFact, false); - } - else { - SMESH::SMESH_IDSource_ptr anObj = aMeshEditor->MakeIDSource(anElementsId); - aMeshEditor->Scale(anObj, aPoint, aScaleFact, false); - } + aMeshEditor->Scale(obj, aPoint, aScaleFact, false); if( !myMesh->_is_nil()) myMesh->SetParameters( aParameters.join(":").toLatin1().constData() ); break; + case COPY_ELEMS_BUTTON: - if ( makeGroups ) { - SMESH::ListOfGroups_var groups; - if(CheckBoxMesh->isChecked()) { - groups = aMeshEditor->ScaleMakeGroups(mySelectedObject, aPoint, aScaleFact); - } - else { - groups = aMeshEditor->ScaleMakeGroups(aMeshEditor->MakeIDSource(anElementsId), - aPoint, aScaleFact); - } - } - else { - if(CheckBoxMesh->isChecked()) { - aMeshEditor->Scale(mySelectedObject, aPoint, aScaleFact, true); - } - else { - aMeshEditor->Scale(aMeshEditor->MakeIDSource(anElementsId), - aPoint, aScaleFact, true); - } - } + if ( makeGroups ) + SMESH::ListOfGroups_var groups = + aMeshEditor->ScaleMakeGroups(obj, aPoint, aScaleFact); + else + aMeshEditor->Scale(obj, aPoint, aScaleFact, true); if( !myMesh->_is_nil()) myMesh->SetParameters( aParameters.join(":").toLatin1().constData() ); break; - case MAKE_MESH_BUTTON: - SMESH::SMESH_Mesh_var mesh; - if(CheckBoxMesh->isChecked()) { - mesh = aMeshEditor->ScaleMakeMesh(mySelectedObject, aPoint, aScaleFact, makeGroups, - LineEditNewMesh->text().toLatin1().data()); - } - else { - mesh = aMeshEditor->ScaleMakeMesh(aMeshEditor->MakeIDSource(anElementsId), - aPoint, aScaleFact, makeGroups, - LineEditNewMesh->text().toLatin1().data()); + + case MAKE_MESH_BUTTON: { + SMESH::SMESH_Mesh_var mesh = + aMeshEditor->ScaleMakeMesh(obj, aPoint, aScaleFact, makeGroups, + LineEditNewMesh->text().toLatin1().data()); + if (!mesh->_is_nil()) { + mesh->SetParameters(aParameters.join(":").toLatin1().constData()); +#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 + mesh->Destroy(); +#endif } - if( !mesh->_is_nil()) - mesh->SetParameters( aParameters.join(":").toLatin1().constData() ); + break; + } } } catch (...) { } - + SMESH::UpdateView(); if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() || actionButton == MAKE_MESH_BUTTON ) @@ -530,7 +524,7 @@ bool SMESHGUI_ScaleDlg::ClickOnApply() SMESHGUI::Modified(); } - + return true; } @@ -570,7 +564,7 @@ void SMESHGUI_ScaleDlg::ClickOnCancel() void SMESHGUI_ScaleDlg::ClickOnHelp() { LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); - if (app) + if (app) app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); else { QString platform; @@ -581,7 +575,7 @@ void SMESHGUI_ScaleDlg::ClickOnHelp() #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", + arg(app->resourceMgr()->stringValue("ExternalBrowser", platform)). arg(myHelpFileName)); } @@ -611,7 +605,7 @@ void SMESHGUI_ScaleDlg::onTextChange (const QString& theNewText) if (aMesh) { Handle(SALOME_InteractiveObject) anIO = myActor->getIO(); - + TColStd_MapOfInteger newIndices; QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts); @@ -628,7 +622,7 @@ void SMESHGUI_ScaleDlg::onTextChange (const QString& theNewText) mySelector->AddOrRemoveIndex( anIO, newIndices, false ); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) aViewWindow->highlight( anIO, true, true ); - + myElementsId = theNewText; } @@ -745,7 +739,7 @@ void SMESHGUI_ScaleDlg::SelectionIntoArgument() aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString); myElementsId = aString; if (aNbUnits < 1) - return; + return; } myNbOkElements = true; @@ -782,7 +776,7 @@ void SMESHGUI_ScaleDlg::SelectionIntoArgument() LineEditElements->setText(aString); LineEditElements->repaint(); LineEditElements->setEnabled(false); // to fully update lineedit IPAL 19809 - LineEditElements->setEnabled(true); + LineEditElements->setEnabled(true); setNewMeshName(); } diff --git a/src/SMESHGUI/SMESHGUI_Selection.cxx b/src/SMESHGUI/SMESHGUI_Selection.cxx index 887cdea08..df7c9c1c6 100644 --- a/src/SMESHGUI/SMESHGUI_Selection.cxx +++ b/src/SMESHGUI/SMESHGUI_Selection.cxx @@ -34,6 +34,7 @@ #include #include +#include // SALOME GUI includes #include @@ -114,6 +115,7 @@ QVariant SMESHGUI_Selection::parameter( const int ind, const QString& p ) const else if ( p=="shrinkMode" ) val = QVariant( shrinkMode( ind ) ); else if ( p=="entityMode" ) val = QVariant( entityMode( ind ) ); else if ( p=="controlMode" ) val = QVariant( controlMode( ind ) ); + else if ( p=="isNumFunctor" ) val = QVariant( isNumFunctor( ind ) ); else if ( p=="displayMode" ) val = QVariant( displayMode( ind ) ); else if ( p=="isComputable" ) val = QVariant( isComputable( ind ) ); else if ( p=="isPreComputable" ) val = QVariant( isPreComputable( ind ) ); @@ -122,6 +124,7 @@ QVariant SMESHGUI_Selection::parameter( const int ind, const QString& p ) const else if ( p=="facesOrientationMode" ) val = QVariant( facesOrientationMode( ind ) ); else if ( p=="groupType" ) val = QVariant( groupType( ind ) ); else if ( p=="quadratic2DMode") val = QVariant(quadratic2DMode(ind)); + else if ( p=="isDistributionVisible") val = QVariant(isDistributionVisible(ind)); if( val.isValid() ) return val; @@ -216,6 +219,16 @@ QString SMESHGUI_Selection::quadratic2DMode( int ind ) const return "Unknown"; } +//======================================================================= +//function : isDistributionVisible +//purpose : Visible/Invisible distribution of the ScalarBar Actor +//======================================================================= + +bool SMESHGUI_Selection::isDistributionVisible(int ind) const { + SMESH_Actor* actor = getActor( ind ); + return (actor && actor->GetScalarBarActor() && actor->GetScalarBarActor()->GetDistributionVisibility()); +} + //======================================================================= //function : shrinkMode //purpose : return either 'IsSrunk', 'IsNotShrunk' or 'IsNotShrinkable' @@ -271,6 +284,8 @@ QString SMESHGUI_Selection::controlMode( int ind ) const case SMESH_Actor::eMultiConnection2D: return "eMultiConnection2D"; case SMESH_Actor::eArea: return "eArea"; case SMESH_Actor::eVolume3D: return "eVolume3D"; + case SMESH_Actor::eMaxElementLength2D: return "eMaxElementLength2D"; + case SMESH_Actor::eMaxElementLength3D: return "eMaxElementLength3D"; case SMESH_Actor::eTaper: return "eTaper"; case SMESH_Actor::eAspectRatio: return "eAspectRatio"; case SMESH_Actor::eAspectRatio3D: return "eAspectRatio3D"; @@ -283,6 +298,35 @@ QString SMESHGUI_Selection::controlMode( int ind ) const return "eNone"; } +bool SMESHGUI_Selection::isNumFunctor( int ind ) const +{ + bool result = false; + SMESH_Actor* actor = getActor( ind ); + if ( actor ) { + switch( actor->GetControlMode() ) { + case SMESH_Actor::eLength: + case SMESH_Actor::eLength2D: + case SMESH_Actor::eMultiConnection: + case SMESH_Actor::eMultiConnection2D: + case SMESH_Actor::eArea: + case SMESH_Actor::eVolume3D: + case SMESH_Actor::eMaxElementLength2D: + case SMESH_Actor::eMaxElementLength3D: + case SMESH_Actor::eTaper: + case SMESH_Actor::eAspectRatio: + case SMESH_Actor::eAspectRatio3D: + case SMESH_Actor::eMinimumAngle: + case SMESH_Actor::eWarping: + case SMESH_Actor::eSkew: + result = true; + break; + default: + break; + } + } + return result; +} + //======================================================================= //function : facesOrientationMode //purpose : @@ -590,4 +634,3 @@ QString SMESHGUI_Selection::groupType( int ind ) const } return type; } - diff --git a/src/SMESHGUI/SMESHGUI_Selection.h b/src/SMESHGUI/SMESHGUI_Selection.h index 2320041de..2ad545d98 100644 --- a/src/SMESHGUI/SMESHGUI_Selection.h +++ b/src/SMESHGUI/SMESHGUI_Selection.h @@ -61,6 +61,8 @@ public: virtual QString quadratic2DMode(int ) const; + virtual bool isDistributionVisible(int ) const; + // parameters got from actor return nothing if an actor is not visible virtual QList elemTypes( int ) const; virtual QList labeledTypes( int ) const; @@ -68,6 +70,7 @@ public: virtual QString shrinkMode( int ) const; virtual QList entityMode( int ) const; virtual QString controlMode( int ) const; + virtual bool isNumFunctor( int ) const; virtual QString facesOrientationMode( int ) const; virtual QString groupType( int ) const; diff --git a/src/SMESHGUI/SMESHGUI_SpinBox.cxx b/src/SMESHGUI/SMESHGUI_SpinBox.cxx index d34f9f8d7..03d53d830 100644 --- a/src/SMESHGUI/SMESHGUI_SpinBox.cxx +++ b/src/SMESHGUI/SMESHGUI_SpinBox.cxx @@ -66,7 +66,7 @@ void SMESHGUI_SpinBox::SetStep( double newStep ) //================================================================================= void SMESHGUI_SpinBox::SetValue( double v ) { - setValue(v); + setValue(valueFromText(textFromValue(v))); editor()->setCursorPosition( 0 ); } @@ -113,7 +113,7 @@ void SMESHGUI_SpinBox::RangeStepAndValidator( double min, setPrecision(precision); // PAL8769. Minus is for using 'g' double->string conversion specifier, // see QtxDoubleSpinBox::mapValueToText( double v ) // san: this can be achieved using preferences - setDecimals(qAbs(precision)); + setDecimals( 20 ); // qAbs(precision) setRange(min, max); setSingleStep( step ); setDefaultValue( min ); diff --git a/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx b/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx index 2a3562e3d..138235888 100644 --- a/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx @@ -19,12 +19,11 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_SymmetryDlg.cxx +// Author : Michael ZORIN, Open CASCADE S.A.S. +// SMESH includes -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_SymmetryDlg.cxx -// Author : Michael ZORIN, Open CASCADE S.A.S. -// SMESH includes -// #include "SMESHGUI_SymmetryDlg.h" #include "SMESHGUI.h" @@ -84,6 +83,10 @@ enum { MOVE_ELEMS_BUTTON = 0, COPY_ELEMS_BUTTON, MAKE_MESH_BUTTON }; //!< action #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 + //================================================================================= // class : SMESHGUI_SymmetryDlg() // purpose : @@ -500,7 +503,7 @@ bool SMESHGUI_SymmetryDlg::ClickOnApply() aMeshEditor->MirrorObject(mySelectedObject, aMirror, aMirrorType, false ); else aMeshEditor->Mirror(anElementsId, aMirror, aMirrorType, false ); - + if( !myMesh->_is_nil()) myMesh->SetParameters( aParameters.join(":").toLatin1().constData() ); break; @@ -525,20 +528,27 @@ bool SMESHGUI_SymmetryDlg::ClickOnApply() } case MAKE_MESH_BUTTON: { SMESH::SMESH_Mesh_var mesh; - if(CheckBoxMesh->isChecked()) + if (CheckBoxMesh->isChecked()) mesh = aMeshEditor->MirrorObjectMakeMesh(mySelectedObject, aMirror, aMirrorType, makeGroups, LineEditNewMesh->text().toLatin1().data()); else mesh = aMeshEditor->MirrorMakeMesh(anElementsId, aMirror, aMirrorType, makeGroups, LineEditNewMesh->text().toLatin1().data()); - if( !mesh->_is_nil()) - mesh->SetParameters( aParameters.join(":").toLatin1().constData() ); + if (!mesh->_is_nil()) { + mesh->SetParameters(aParameters.join(":").toLatin1().constData()); +#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 + mesh->Destroy(); +#endif + } break; } } } catch (...) { } - + SMESH::UpdateView(); if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() || actionButton == MAKE_MESH_BUTTON ) @@ -589,7 +599,7 @@ void SMESHGUI_SymmetryDlg::ClickOnCancel() void SMESHGUI_SymmetryDlg::ClickOnHelp() { LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); - if (app) + if (app) app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); else { QString platform; @@ -632,7 +642,7 @@ void SMESHGUI_SymmetryDlg::onTextChange (const QString& theNewText) Handle(SALOME_InteractiveObject) anIO = myActor->getIO(); TColStd_MapOfInteger newIndices; - + QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts); if (send == LineEditElements) { @@ -646,7 +656,7 @@ void SMESHGUI_SymmetryDlg::onTextChange (const QString& theNewText) mySelector->AddOrRemoveIndex( anIO, newIndices, false ); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) aViewWindow->highlight( anIO, true, true ); - + myElementsId = theNewText; } } @@ -736,7 +746,6 @@ void SMESHGUI_SymmetryDlg::SelectionIntoArgument() aNbUnits++; } } - } else if (!SMESH::IObjectToInterface(IO)->_is_nil()) { //SUBMESH // get submesh SMESH::SMESH_subMesh_var aSubMesh = SMESH::IObjectToInterface(IO); @@ -749,7 +758,6 @@ void SMESHGUI_SymmetryDlg::SelectionIntoArgument() myElementsId += QString(" %1").arg(anElementsIds[i]); } aNbUnits = anElementsIds->length(); - } else { // GROUP // get smesh group SMESH::SMESH_GroupBase_var aGroup = @@ -772,7 +780,7 @@ void SMESHGUI_SymmetryDlg::SelectionIntoArgument() if (aNbUnits < 1) return; } - + myNbOkElements = true; } else { aNbUnits = SMESH::GetNameOfSelectedNodes(mySelector, IO, aString); @@ -807,7 +815,7 @@ void SMESHGUI_SymmetryDlg::SelectionIntoArgument() LineEditElements->setText(aString); LineEditElements->repaint(); LineEditElements->setEnabled(false); // to update lineedit IPAL 19809 - LineEditElements->setEnabled(true); + LineEditElements->setEnabled(true); setNewMeshName(); } myBusy = false; diff --git a/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx b/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx index fac987991..14a5866e0 100644 --- a/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_TranslationDlg.cxx @@ -19,12 +19,11 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// SMESH SMESHGUI : GUI for SMESH component +// File : SMESHGUI_TranslationDlg.cxx +// Author : Michael ZORIN, Open CASCADE S.A.S. +// SMESH includes -// SMESH SMESHGUI : GUI for SMESH component -// File : SMESHGUI_TranslationDlg.cxx -// Author : Michael ZORIN, Open CASCADE S.A.S. -// SMESH includes -// #include "SMESHGUI_TranslationDlg.h" #include "SMESHGUI.h" @@ -102,6 +101,10 @@ private: #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 + //================================================================================= // class : SMESHGUI_TranslationDlg() // purpose : @@ -494,7 +497,7 @@ bool SMESHGUI_TranslationDlg::ClickOnApply() break; case COPY_ELEMS_BUTTON: if ( makeGroups ) { - SMESH::ListOfGroups_var groups; + SMESH::ListOfGroups_var groups; if(CheckBoxMesh->isChecked()) groups = aMeshEditor->TranslateObjectMakeGroups(mySelectedObject,aVector); else @@ -510,19 +513,26 @@ bool SMESHGUI_TranslationDlg::ClickOnApply() myMesh->SetParameters( aParameters.join(":").toLatin1().constData() ); break; case MAKE_MESH_BUTTON: - SMESH::SMESH_Mesh_var mesh; - if(CheckBoxMesh->isChecked()) + SMESH::SMESH_Mesh_var mesh; + if (CheckBoxMesh->isChecked()) mesh = aMeshEditor->TranslateObjectMakeMesh(mySelectedObject, aVector, makeGroups, LineEditNewMesh->text().toLatin1().data()); else mesh = aMeshEditor->TranslateMakeMesh(anElementsId, aVector, makeGroups, LineEditNewMesh->text().toLatin1().data()); - if( !mesh->_is_nil()) - mesh->SetParameters( aParameters.join(":").toLatin1().constData() ); + if (!mesh->_is_nil()) { + mesh->SetParameters(aParameters.join(":").toLatin1().constData()); +#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 + mesh->Destroy(); +#endif + } } } catch (...) { } - + SMESH::UpdateView(); if ( MakeGroupsCheck->isEnabled() && MakeGroupsCheck->isChecked() || actionButton == MAKE_MESH_BUTTON ) @@ -534,7 +544,7 @@ bool SMESHGUI_TranslationDlg::ClickOnApply() SMESHGUI::Modified(); } - + return true; } @@ -574,7 +584,7 @@ void SMESHGUI_TranslationDlg::ClickOnCancel() void SMESHGUI_TranslationDlg::ClickOnHelp() { LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication()); - if (app) + if (app) app->onHelpContextModule(mySMESHGUI ? app->moduleName(mySMESHGUI->moduleName()) : QString(""), myHelpFileName); else { QString platform; @@ -585,7 +595,7 @@ void SMESHGUI_TranslationDlg::ClickOnHelp() #endif SUIT_MessageBox::warning(this, tr("WRN_WARNING"), tr("EXTERNAL_BROWSER_CANNOT_SHOW_PAGE"). - arg(app->resourceMgr()->stringValue("ExternalBrowser", + arg(app->resourceMgr()->stringValue("ExternalBrowser", platform)). arg(myHelpFileName)); } @@ -615,7 +625,7 @@ void SMESHGUI_TranslationDlg::onTextChange (const QString& theNewText) if (aMesh) { Handle(SALOME_InteractiveObject) anIO = myActor->getIO(); - + TColStd_MapOfInteger newIndices; QStringList aListId = theNewText.split(" ", QString::SkipEmptyParts); @@ -632,7 +642,7 @@ void SMESHGUI_TranslationDlg::onTextChange (const QString& theNewText) mySelector->AddOrRemoveIndex( anIO, newIndices, false ); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) aViewWindow->highlight( anIO, true, true ); - + myElementsId = theNewText; } @@ -750,7 +760,7 @@ void SMESHGUI_TranslationDlg::SelectionIntoArgument() aNbUnits = SMESH::GetNameOfSelectedElements(mySelector, IO, aString); myElementsId = aString; if (aNbUnits < 1) - return; + return; } myNbOkElements = true; @@ -786,7 +796,7 @@ void SMESHGUI_TranslationDlg::SelectionIntoArgument() LineEditElements->setText(aString); LineEditElements->repaint(); LineEditElements->setEnabled(false); // to fully update lineedit IPAL 19809 - LineEditElements->setEnabled(true); + LineEditElements->setEnabled(true); setNewMeshName(); } diff --git a/src/SMESHGUI/SMESHGUI_Utils.cxx b/src/SMESHGUI/SMESHGUI_Utils.cxx index 6f921cd22..dfe778831 100644 --- a/src/SMESHGUI/SMESHGUI_Utils.cxx +++ b/src/SMESHGUI/SMESHGUI_Utils.cxx @@ -205,6 +205,20 @@ namespace SMESH return SObjectToObject(theSObject,aStudy); } + _PTR(SObject) ObjectToSObject( CORBA::Object_ptr theObject ) + { + _PTR(SObject) res; + SalomeApp_Application* app = dynamic_cast + (SUIT_Session::session()->activeApplication()); + if ( app ) { + QString IOR = app->orb()->object_to_string( theObject ); + SalomeApp_Study* study = dynamic_cast( app->activeStudy() ); + if ( study && !IOR.isEmpty() ) + res = study->studyDS()->FindObjectIOR( IOR.toLatin1().constData() ); + } + return res; + } + CORBA::Object_var IObjectToObject (const Handle(SALOME_InteractiveObject)& theIO) { if (!theIO.IsNull()) { diff --git a/src/SMESHGUI/SMESHGUI_Utils.h b/src/SMESHGUI/SMESHGUI_Utils.h index 555d23382..996a34761 100644 --- a/src/SMESHGUI/SMESHGUI_Utils.h +++ b/src/SMESHGUI/SMESHGUI_Utils.h @@ -129,6 +129,9 @@ SMESHGUI_EXPORT return TInterface::_nil(); } +SMESHGUI_EXPORT + _PTR(SObject) ObjectToSObject( CORBA::Object_ptr ); + SMESHGUI_EXPORT CORBA::Object_var IObjectToObject( const Handle(SALOME_InteractiveObject)& ); diff --git a/src/SMESHGUI/SMESHGUI_VTKUtils.cxx b/src/SMESHGUI/SMESHGUI_VTKUtils.cxx index e210f2c7f..c663c74da 100644 --- a/src/SMESHGUI/SMESHGUI_VTKUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_VTKUtils.cxx @@ -65,6 +65,7 @@ #include CORBA_CLIENT_HEADER(SMESH_Group) // VTK includes +#include #include #include #include @@ -204,13 +205,16 @@ namespace SMESH } } TVisualObjCont::iterator anIter = VISUAL_OBJ_CONT.begin(); - for ( ; anIter != VISUAL_OBJ_CONT.end(); ++anIter ) { + for ( ; anIter != VISUAL_OBJ_CONT.end(); ) { int curId = anIter->first.first; if ( curId == studyID ) { // for unknown reason, object destructor is not called, so clear object manually anIter->second->GetUnstructuredGrid()->SetCells(0,0,0); anIter->second->GetUnstructuredGrid()->SetPoints(0); - VISUAL_OBJ_CONT.erase( anIter-- ); // dercement occures before erase() + VISUAL_OBJ_CONT.erase( anIter++ ); // anIter++ returns a copy of self before incrementing + } + else { + anIter++; } } } @@ -602,6 +606,9 @@ namespace SMESH } } } + if( anActor ) + if( SMESHGUI* aSMESHGUI = SMESHGUI::GetSMESHGUI() ) + aSMESHGUI->addActorAsObserver( anActor ); return anActor; } @@ -1164,4 +1171,108 @@ namespace SMESH } } + + //---------------------------------------------------------------------------- + // internal function + void ComputeBoundsParam( vtkFloatingPointType theBounds[6], + vtkFloatingPointType theDirection[3], + vtkFloatingPointType theMinPnt[3], + vtkFloatingPointType& theMaxBoundPrj, + vtkFloatingPointType& theMinBoundPrj ) + { + //Enlarge bounds in order to avoid conflicts of precision + for(int i = 0; i < 6; i += 2){ + static double EPS = 1.0E-3; + vtkFloatingPointType aDelta = (theBounds[i+1] - theBounds[i])*EPS; + theBounds[i] -= aDelta; + theBounds[i+1] += aDelta; + } + + vtkFloatingPointType aBoundPoints[8][3] = { {theBounds[0],theBounds[2],theBounds[4]}, + {theBounds[1],theBounds[2],theBounds[4]}, + {theBounds[0],theBounds[3],theBounds[4]}, + {theBounds[1],theBounds[3],theBounds[4]}, + {theBounds[0],theBounds[2],theBounds[5]}, + {theBounds[1],theBounds[2],theBounds[5]}, + {theBounds[0],theBounds[3],theBounds[5]}, + {theBounds[1],theBounds[3],theBounds[5]}}; + + int aMaxId = 0, aMinId = aMaxId; + theMaxBoundPrj = vtkMath::Dot(theDirection,aBoundPoints[aMaxId]); + theMinBoundPrj = theMaxBoundPrj; + for(int i = 1; i < 8; i++){ + vtkFloatingPointType aTmp = vtkMath::Dot(theDirection,aBoundPoints[i]); + if(theMaxBoundPrj < aTmp){ + theMaxBoundPrj = aTmp; + aMaxId = i; + } + if(theMinBoundPrj > aTmp){ + theMinBoundPrj = aTmp; + aMinId = i; + } + } + vtkFloatingPointType *aMinPnt = aBoundPoints[aMaxId]; + theMinPnt[0] = aMinPnt[0]; + theMinPnt[1] = aMinPnt[1]; + theMinPnt[2] = aMinPnt[2]; + } + + // internal function + void DistanceToPosition( vtkFloatingPointType theBounds[6], + vtkFloatingPointType theDirection[3], + vtkFloatingPointType theDist, + vtkFloatingPointType thePos[3] ) + { + vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3]; + ComputeBoundsParam(theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj); + vtkFloatingPointType aLength = (aMaxBoundPrj-aMinBoundPrj)*theDist; + thePos[0] = aMinPnt[0]-theDirection[0]*aLength; + thePos[1] = aMinPnt[1]-theDirection[1]*aLength; + thePos[2] = aMinPnt[2]-theDirection[2]*aLength; + } + + // internal function (currently unused, left just in case) + void PositionToDistance( vtkFloatingPointType theBounds[6], + vtkFloatingPointType theDirection[3], + vtkFloatingPointType thePos[3], + vtkFloatingPointType& theDist ) + { + vtkFloatingPointType aMaxBoundPrj, aMinBoundPrj, aMinPnt[3]; + ComputeBoundsParam(theBounds,theDirection,aMinPnt,aMaxBoundPrj,aMinBoundPrj); + vtkFloatingPointType aPrj = vtkMath::Dot(theDirection,thePos); + theDist = (aPrj-aMinBoundPrj)/(aMaxBoundPrj-aMinBoundPrj); + } + + bool ComputeClippingPlaneParameters( std::list theActorList, + vtkFloatingPointType theNormal[3], + vtkFloatingPointType theDist, + vtkFloatingPointType theBounds[6], + vtkFloatingPointType theOrigin[3] ) + { + bool anIsOk = false; + theBounds[0] = theBounds[2] = theBounds[4] = VTK_DOUBLE_MAX; + theBounds[1] = theBounds[3] = theBounds[5] = -VTK_DOUBLE_MAX; + std::list::iterator anIter = theActorList.begin(); + for( ; anIter != theActorList.end(); anIter++ ) { + if( vtkActor* aVTKActor = *anIter ) { + if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) { + vtkFloatingPointType aBounds[6]; + anActor->GetUnstructuredGrid()->GetBounds( aBounds ); + theBounds[0] = std::min( theBounds[0], aBounds[0] ); + theBounds[1] = std::max( theBounds[1], aBounds[1] ); + theBounds[2] = std::min( theBounds[2], aBounds[2] ); + theBounds[3] = std::max( theBounds[3], aBounds[3] ); + theBounds[4] = std::min( theBounds[4], aBounds[4] ); + theBounds[5] = std::max( theBounds[5], aBounds[5] ); + anIsOk = true; + } + } + } + + if( !anIsOk ) + return false; + + DistanceToPosition( theBounds, theNormal, theDist, theOrigin ); + return true; + } } // end of namespace SMESH diff --git a/src/SMESHGUI/SMESHGUI_VTKUtils.h b/src/SMESHGUI/SMESHGUI_VTKUtils.h index 508ce767e..5a9b09c25 100644 --- a/src/SMESHGUI/SMESHGUI_VTKUtils.h +++ b/src/SMESHGUI/SMESHGUI_VTKUtils.h @@ -57,6 +57,8 @@ class SMESHGUI; class SMESH_Actor; class SALOME_Actor; +class vtkActor; + namespace SMESH { //---------------------------------------------------------------------------- @@ -185,6 +187,14 @@ SMESHGUI_EXPORT SMESHGUI_EXPORT void SetControlsPrecision( const long ); + + //---------------------------------------------------------------------------- +SMESHGUI_EXPORT + bool ComputeClippingPlaneParameters( std::list theActorList, + vtkFloatingPointType theNormal[3], + vtkFloatingPointType theDist, + vtkFloatingPointType theBounds[6], + vtkFloatingPointType theOrigin[3] ); }; #endif // SMESHGUI_VTKUTILS_H diff --git a/src/SMESHGUI/SMESH_images.ts b/src/SMESHGUI/SMESH_images.ts index 22b3fd7e8..856e88f32 100644 --- a/src/SMESHGUI/SMESH_images.ts +++ b/src/SMESHGUI/SMESH_images.ts @@ -205,6 +205,10 @@ ICON_DLG_REM_NODE mesh_rem_node.png + + ICON_DLG_REM_ORPHAN_NODES + mesh_rem_orphan_nodes.png + ICON_DLG_RENUMBERING_ELEMENTS mesh_renumbering_elements.png @@ -285,6 +289,14 @@ ICON_MAP mesh_pattern.png + + ICON_MAX_ELEMENT_LENGTH_2D + mesh_max_element_length_2d.png + + + ICON_MAX_ELEMENT_LENGTH_3D + mesh_max_element_length_3d.png + ICON_OBJBROWSER_SMESH mesh.png @@ -381,6 +393,14 @@ ICON_DLG_SCALE_ALONG_AXES scale_along_axes.png + + ICON_SMESH_DUPLICATE_NODES + mesh_duplicate_nodes.png + + + ICON_SMESH_DUPLICATE_NODES_WITH_ELEM + mesh_duplicate_nodes_with_elem.png + ICON_SMESH_TREE_ALGO mesh_tree_algo.png @@ -443,7 +463,7 @@ ICON_WHAT_IS - mesh_whatis.png + mesh_elem_info.png ICON_WIRE @@ -465,5 +485,13 @@ ICON_SPLIT_TO_TETRA split_into_tetra.png + + ICON_MEASURE_MIN_DIST + mesh_min_dist.png + + + ICON_MEASURE_BND_BOX + mesh_bounding_box.png + diff --git a/src/SMESHGUI/SMESH_msg_en.ts b/src/SMESHGUI/SMESH_msg_en.ts index 790b7c1a8..81e2619ee 100644 --- a/src/SMESHGUI/SMESH_msg_en.ts +++ b/src/SMESHGUI/SMESH_msg_en.ts @@ -1,5194 +1,5904 @@ + - - - - @default - - AREA_ELEMENTS - Area - - - ASPECTRATIO_3D_ELEMENTS - Aspect Ratio 3D - - - ASPECTRATIO_ELEMENTS - Aspect Ratio - - - COL_ALGO_HEADER - Algorithm - - - COL_ERROR_HEADER - Error - - - COL_SHAPE_HEADER - SubShape - - - COMPERR_ALGO_FAILED - Algorithm failed - - - COMPERR_BAD_INPUT_MESH - Invalid input mesh - - - COMPERR_BAD_SHAPE - Unexpected geometry - - - COMPERR_EXCEPTION - Unknown exception - - - COMPERR_MEMORY_PB - Memory allocation problem - - - COMPERR_OCC_EXCEPTION - OCC exception - - - COMPERR_OK - No errors - - - COMPERR_SLM_EXCEPTION - SALOME exception - - - COMPERR_STD_EXCEPTION - std::exception - - - SMESH_GEOM - Geometry - - - DIRECT_GEOM_SELECTION - Direct geometry selection - - - ELEMENT_ID - Element ID - - - FREE_BORDERS - Free Borders - - - GEOMETRY_NAME - Geometry name - - - GEOM_BY_MESH_ELEM_SELECTION - Find geometry by mesh element selection - - - GLOBAL_ALGO - Global - - - INF_SELECT_OBJECT - Select an object - - - LENGTH2D_EDGES - Length 2D - - - LENGTH_EDGES - Length - - - LOCAL_ALGO - Local - - - MEN_ADD - Add - - - MEN_ADV_INFO - Advanced Mesh Infos - - - MEN_ALL - All - - - MEN_AREA - Area - - - MEN_ASPECT - Aspect Ratio - - - MEN_ASPECT_3D - Aspect Ratio 3D - - - MEN_AUTO_COLOR - Auto Color - - - MEN_AUTO_UPD - Automatic Update - - - MEN_BUILD_COMPOUND - Build Compound - - - MEN_CLIP - Clipping - - - MEN_COLORS - Colors / Size - - - MEN_COMPUTE - Compute - - - MEN_PRECOMPUTE - Preview - - - MEN_EVALUATE - Evaluate - - - MEN_CONNECTION - Borders at Multi-Connection - - - MEN_CONNECTION_2D - Borders at Multi-Connection 2D - - - MEN_CONSTRUCT_GROUP - Construct Group - - - MEN_CONV_TO_QUAD - Convert to/from quadratic - - - MEN_2D_FROM_3D - Create 2D mesh from 3D - - - MEN_MESH_ORDER - Change submesh priority - - - MEN_CREATE_GROUP - Create Group - - - MEN_CREATE_GEO_GROUP - Create Groups from Geometry - - - MEN_CREATE_MESH - Create Mesh - - - MEN_CREATE_SUBMESH - Create Sub-mesh - - - MEN_CTRL - Controls - - - MEN_CUT - Cutting of Quadrangles - - - MEN_CUT_GROUP - Cut Groups - - - MEN_DAT - DAT File - - - MEN_DELETE - Delete - - - MEN_DEL_GROUP - Delete Groups - - - MEN_FACE_ORIENTATION - Orientation of Faces - - - MEN_DISABLE_AUTO_COLOR - Disable Auto Color - - - MEN_DISPLAY_ONLY - Show Only - - - MEN_DISPMODE - Display Mode - - - MEN_DISP_ENT - Display Entity - - - MEN_ELEM0D - 0D Element - - - MEN_ELEMS0D - 0D Elements - - - MEN_EDGE - Edge - - - MEN_EDGES - Edges - - - MEN_EDIT - Edit - - - MEN_EDIT_GROUP - Edit Group - - - MEN_EDIT_GEOMGROUP_AS_GROUP - Edit Group as Standalone - - - MEN_EDIT_HYPO - Edit Hypothesis - - - MEN_EDIT_MESHSUBMESH - Edit Mesh/Sub-mesh - - - MEN_EXPORT - Export - - - MEN_EXPORT_DAT - Export to DAT File - - - MEN_EXPORT_MED - Export to MED File - - - MEN_EXPORT_SAUV - Export to SAUV (ASCII) file - - - MEN_EXPORT_STL - Export to STL File - - - MEN_EXPORT_UNV - Export to UNV File - - - MEN_EXTRUSION - Extrusion - - - MEN_EXTRUSION_ALONG - Extrusion Along a Path - - - MEN_FACES - Faces - - - MEN_FILE - File - - - MEN_FIND_ELEM - Find Element by Point - - - TOP_FIND_ELEM - Find Element by Point - - - MEN_FREE_BORDER - Free Borders - - - MEN_FREE_EDGE - Free Edges - - - MEN_FREE_NODE - Free Nodes - - - MEN_FREE_FACES - Free Faces - - - MEN_GLOBAL_HYPO - Global Hypothesis - - - MEN_HEXA - Hexahedron - - - MEN_HIDE - Hide - - - MEN_HYPO - Hypotheses - - - MEN_IMPORT - Import - - - MEN_INT_GROUP - Intersect Groups - - - MEN_INV - Diagonal Inversion - - - MEN_LENGTH - Length - - - MEN_LENGTH_2D - Length 2D - - - MEN_MAP - Pattern Mapping - - - MEN_MED - MED file - - - MEN_SAUV - SAUV (ASCII) file - - - MEN_MERGE - Merge Nodes - - - MEN_MERGE_ELEMENTS - Merge Elements - - - - MEN_MESH - Mesh - - - MEN_MESH_THROU_POINT - Mesh to Pass Through a Point - - - MEN_MIN_ANG - Minimum Angle - - - MEN_MODIFY - Modification - - - MEN_MOVE - Move Node - - - MEN_NODE - Node - - - MEN_NODES - Nodes - - - MEN_NUM - Numbering - - - MEN_NUM_ELEMENTS - Display Elements # - - - MEN_NUM_NODES - Display Nodes # - - - MEN_ORIENT - Orientation - - - MEN_POLYGON - Polygon - - - MEN_POLYHEDRON - Polyhedron - - - MEN_PRECISION - Precision - - - MEN_PREF - Preferences - - - MEN_QUAD - Quadrangle - - - MEN_QUADRATIC_EDGE - Quadratic Edge - - - MEN_QUADRATIC_HEXAHEDRON - Quadratic Hexahedron - - - MEN_QUADRATIC_PENTAHEDRON - Quadratic Pentahedron - - - MEN_QUADRATIC_PYRAMID - Quadratic Pyramid - - - MEN_QUADRATIC_QUADRANGLE - Quadratic Quadrangle - - - MEN_QUADRATIC_TETRAHEDRON - Quadratic Tetrahedron - - - MEN_QUADRATIC_TRIANGLE - Quadratic Triangle - - - MEN_QUALITY - Quality Controls - - - MEN_REMOVE - Remove - - - MEN_REMOVE_ELEMENTS - Elements - - - MEN_REMOVE_NODES - Nodes - - - MEN_RENAME - Rename - - - MEN_RENUM - Renumbering - - - MEN_RENUM_ELEMENTS - Elements - - - MEN_RENUM_NODES - Nodes - - - MEN_RESET - Reset - - - MEN_REVOLUTION - Revolution - - - MEN_ROT - Rotation - - - MEN_SCALAR_BAR - Scalar Bar - - - MEN_SCALAR_BAR_PROP - Scalar Bar Properties - - - MEN_SELECTION - Selection - - - MEN_SEL_FILTER_LIB - Selection Filters Library - - - MEN_SEW - Sewing - - - MEN_SHADE - Shading - - - MEN_QUADRATIC_REPRESENT - 2D Quadratic - - - MEN_LINE_REPRESENTATION - Lines - - - MEN_ARC_REPRESENTATION - Arcs - - - MEN_SHOW - Show - - - MEN_SHRINK - Shrink - - - MEN_SKEW - Skew - - - MEN_SMOOTH - Smoothing - - - MEN_STD_INFO - Standard Mesh Infos - - - MEN_STL - STL File - - - MEN_SYM - Symmetry - - - MEN_TAPER - Taper - - - MEN_TETRA - Tetrahedron - - - MEN_TOOLS - Tools - - - MEN_TRANS - Translation - - - MEN_SCALE - Scale Transform - - - MEN_TRANSF - Transformation - - - MEN_TRANSP - Transparency - - - MEN_TRIANGLE - Triangle - - - MEN_UNASSIGN - Unassign - - - MEN_UNION - Union of Triangles - - - MEN_UNION2 - Union of Two Triangles - - - MEN_UNV - UNV File - - - MEN_UN_GROUP - Union Groups - - - MEN_UNDERLYING_ELEMS - Group of underlying entities - - - MEN_UPDATE - Update - - - MEN_VIEW - View - - - MEN_VOLUMES - Volumes - - - MEN_VOLUME_3D - Volume - - - MEN_WARP - Warping Angle - - - MEN_WHAT_IS - Mesh Element Info - - - MEN_WIRE - Wireframe - - - MEN_SPLIT_TO_TETRA - Split into Tetrahedra - - - TOP_SPLIT_TO_TETRA - Split into Tetrahedra - - - STB_SPLIT_TO_TETRA - Split into Tetrahedra - - - MESHERS_FILE_CANT_OPEN - Can not open resource file - - - MESHERS_FILE_CHECK_VARIABLE - Check environment variable SMESH_MeshersList - - - MESHERS_FILE_NO_VARIABLE - Environment variable SMESH_MeshersList is not defined - - - MESH_IS_NOT_SELECTED - There is no selected mesh -Please, select a mesh and try again - - - MESH_NODE - Node - - - MESH_NODE_TITLE - Add Node - - - MINIMUMANGLE_ELEMENTS - Minimum Angle - - - MULTI2D_BORDERS - Borders at Multi-Connections 2D - - - MULTI_BORDERS - Borders at Multi-Connections - - - GROUP_NAME_IS_EMPTY - Name of group is not specified. -Please enter a name of new group to be created or choose an existing one. - - - MESH_STANDALONE_GRP_CHOSEN - Group on geometry is chosen: %1. -Do you want to convert it to the standalone group? - - - NODE_ID - Node ID - - - NON_SMESH_OBJECTS_SELECTED - There are objects selected which do not belong to %1 component. - - - PREVIEW - Preview - - - SKEW_ELEMENTS - Skew - - - SMESHGUI_INVALID_PARAMETERS - Parameters are not correctly specified -Please enter correct values and try again - - - SMESH_ADD_ALGORITHM - Algorithms - - - SMESH_ADD_ALGORITHM_TITLE - Algorithms Assignation - - - SMESH_ADD_ELEM0D - Add 0D Element - - - SMESH_ADD_ELEM0D_TITLE - Add 0D Element - - - SMESH_ADD_EDGE - Add Edge - - - SMESH_ADD_EDGE_TITLE - Add Edge - - - SMESH_ADD_HEXAS - Add Hexahedron - - - SMESH_ADD_HEXAS_TITLE - Add Hexahedron - - - SMESH_ADD_HYPOTHESIS - Hypothesis - - - SMESH_ADD_HYPOTHESIS_TITLE - Hypothesis Assignation - - - SMESH_ADD_HYP_WRN - "%1" assigned but: - - - - SMESH_ADD_POLYGON - Add polygon - - - SMESH_ADD_POLYGON_TITLE - Add polygon - - - SMESH_ADD_QUADRANGLE - Add Quadrangle - - - SMESH_ADD_QUADRANGLE_TITLE - Add Quadrangle - - - SMESH_ADD_QUADRATIC_EDGE_TITLE - Add Quadratic Edge - - - SMESH_ADD_QUADRATIC_HEXAHEDRON_TITLE - Add Quadratic Hexahedron - - - SMESH_ADD_QUADRATIC_PENTAHEDRON_TITLE - Add Quadratic Pentahedron - - - SMESH_ADD_QUADRATIC_PYRAMID_TITLE - Add Quadratic Pyramid - - - SMESH_ADD_QUADRATIC_QUADRANGLE_TITLE - Add Quadratic Quadrangle - - - SMESH_ADD_QUADRATIC_TETRAHEDRON_TITLE - Add Quadratic Tetrahedron - - - SMESH_ADD_QUADRATIC_TRIANGLE_TITLE - Add Quadratic Triangle - - - SMESH_ADD_SUBMESH - SubMesh Construction - - - SMESH_ADD_TETRAS - Add Tetrahedron - - - SMESH_ADD_TETRAS_TITLE - Add Tetrahedron - - - SMESH_ADD_TO_GROUP - Add to group - - - SMESH_ADD_TRIANGLE - Add Triangle - - - SMESH_ADD_TRIANGLE_TITLE - Add Triangle - - - SMESH_ANGLE - Angle - - - SMESH_ARGUMENTS - Arguments - - - SMESH_AUTO_GROUPS - Automatically create groups - - - SMESH_AVAILABLE - Available - - - SMESH_AVAILABLE_ALGORITHMS - Available algorithms - - - SMESH_AVAILABLE_HYPOTHESES - Available hypotheses - - - SMESH_AXIS - Axis - - - SMESH_BAD_SELECTION - No valid selection - - - SMESH_BAD_MESH_SELECTION - No valid mesh selection - - - SMESH_BOUNDARYEDGES - Boundary Edges - - - SMESH_BUILD_COMPOUND_TITLE - Create a Compound - - - SMESH_BUT_ADD - A&dd - - - SMESH_BUT_APPLY - &Apply - - - SMESH_BUT_CANCEL - &Cancel - - - SMESH_BUT_CLOSE - &Close - - - SMESH_BUT_CREATE - Create - - - SMESH_BUT_DELETE - Delete - - - SMESH_BUT_FILTER - Set &Filters - - - SMESH_BUT_HELP - &Help - - - SMESH_BUT_NEW - New - - - SMESH_BUT_NO - &No - - - SMESH_BUT_OK - &Ok - - - SMESH_BUT_OVERWRITE - Over&write - - - SMESH_BUT_APPLY_AND_CLOSE - A&pply and Close - - - SMESH_BUT_REMOVE - &Remove - - - SMESH_BUT_SORT - &Sort List - - - SMESH_BUT_YES - &Yes - - - SMESH_CANT_ADD_HYP - Can not assign "%1": - - - - SMESH_CANT_RM_HYP - Can not unassign "%1": - - - - SMESH_CHECK_COLOR - Color - - - SMESH_CLIPPING_FROM - From <--- - - - SMESH_CLIPPING_INTO - ---> Into - - - SMESH_CLIPPING_TITLE - Change Clipping - - - SMESH_COMPUTE_SUCCEED - Mesh computation succeed - - - SMESH_EVALUATE_SUCCEED - Mesh evaluation succeed - - - SMESH_CONTENT - Content - - - SMESH_CONTINUE_MESH_VISUALIZATION - It seems that there is not enough memory to show the mesh -so that the application may crash. Do you wish to continue visualization? - - - SMESH_COORDINATES - Coordinates - - - SMESH_COPY_ELEMENTS - Copy Elements - - - SMESH_COPY_GROUPS - Copy groups - - - SMESH_CREATE_ALGORITHMS - Create algorithms - - - SMESH_CREATE_COPY - Create a copy - - - SMESH_CREATE_GROUP_TITLE - Create Group - - - SMESH_CREATE_GEO_GROUP - Create Groups from Geometry - - - SMESH_CREATE_HYPOTHESES - Create hypotheses - - - SMESH_CREATE_MESH - Create a new mesh - - - SMESH_CREATE_POLYHEDRAL_VOLUME_TITLE - Create polyhedral volume - - - SMESH_DIAGONAL - Diagonal Inversion - - - SMESH_DIAGONAL_INVERSION_TITLE - Diagonal Inversion - - - SMESH_DISTANCE - Distance - - - SMESH_DRS_1 - MED file contains no mesh with the given name - - - SMESH_DRS_2 - MED file has overlapped ranges of element numbers, the numbers from the file are ignored - - - SMESH_DRS_3 - Some elements were skipped due to incorrect file data - - - SMESH_DRS_4 - The file is incorrect, some data is missed - - - SMESH_DRS_EMPTY - The file is empty, there is nothing to be published - - - SMESH_DX - dX - - - SMESH_DY - dY - - - SMESH_DZ - dZ - - - SMESH_ELEM0D - 0D Element - - - SMESH_EDGE - Edge - - - SMESH_EDGES_CONNECTIVITY_TITLE - Edges Connectivity - - - SMESH_EDIT_GROUP_TITLE - Edit Group - - - SMESH_EDIT_GEOMGROUP_AS_GROUP_TITLE - Edit Group as Standalone - - - SMESH_EDIT_HYPOTHESES - Hypotheses Assignation - - - SMESH_EDIT_USED - Used - - - SMESH_ELEMENTS - Elements - - - SMESH_ELEMENTS_COLOR - Mesh Element Color - - - SMESH_ELEMENTS_TYPE - Elements Type - - - SMESH_ELEMENT_TYPE - Element Type - - - SMESH_ERROR - Error - - - SMESH_ERR_SCALARBAR_PARAMS - Warning! The parameters is incorrect - - - SMESH_EXPORT_FAILED - Mesh export failed. -Probably, there is not enough space on disk. - - - SMESH_EXPORT_MED_DUPLICATED_GRP - There are duplicated group names in mesh "%1". -You can cancel exporting and rename them, -otherwise some group names in the resulting MED file -will not match ones in the study. -Do you want to continue ? - - - SMESH_EXPORT_MED_DUPLICATED_MESH_NAMES - There are some meshes with the same names in the selection. -The result file may be incorrect. -Do you want to continue ? - - - SMESH_EXPORT_MED_V2_1 - During export mesh with name - "%1" to MED 2.1 -polygons and polyhedrons elements will be missed -For correct export use MED 2.2 -Are you sure want to export to MED 2.1 ? - - - SMESH_EXPORT_MED_VERSION_COLLISION - MED version of the file "%1" -is unknown or doesn't match the selected version. -Overwrite the file? - - - SMESH_EXPORT_MED_MESH_NAMES_COLLISION - The selected file already contains -meshes with the following names: %1 -The result file may be incorrect. -Overwrite the file? - - - SMESH_EXPORT_STL1 - Mesh - "%1" does not contain triangles - - - SMESH_EXPORT_STL2 - Mesh - "%1" contains another than triangles elements, they are ignored during writing to STL - - - SMESH_EXPORT_UNV - During export mesh with name - "%1" to UNV - pyramid's elements will be missed - - - SMESH_EXTRUSION - Extrusion - - - SMESH_EXTRUSION_TO_DISTANCE - Extrusion To Distance - - - SMESH_EXTRUSION_ALONG_VECTOR - Extrusion Along Vector - - - SMESH_FACE - Face - - - SMESH_FEATUREANGLE - Feature Angle - - - SMESH_FEATUREEDGES - Feature Edges - - - SMESH_FILE_EXISTS - The file "%1" already exists. -Do you want to overwrite it or -add the exported data to its contents? - - - SMESH_FONT_ARIAL - Arial - - - SMESH_FONT_BOLD - Bold - - - SMESH_FONT_COURIER - Courier - - - SMESH_FONT_ITALIC - Italic - - - SMESH_FONT_SCALARBAR - Font - - - SMESH_FONT_SHADOW - Shadow - - - SMESH_FONT_TIMES - Times - - - SMESH_GEOM_GROUP - Geometry group - - - SMESH_GROUP - Group - - - SMESH_GROUP_GEOMETRY - Group on geometry - - - SMESH_GROUP_SELECTED - %1 Groups - - - SMESH_GROUP_STANDALONE - Standalone group - - - SMESH_GROUP_TYPE - Group type - - - SMESH_HEIGHT - Height: - - - SMESH_HEXAS - Hexahedron - - - SMESH_HILIGHT_COLOR - Highlight Color - - - SMESH_HORIZONTAL - Horizontal - - - SMESH_HYPOTHESES - Hypotheses - - - SMESH_HYP_1 - Algorithm misses a hypothesis - - - SMESH_HYP_10 - Hypothesis and submesh dimensions mismatch - - - SMESH_HYP_11 - Shape is neither the main one, nor its subshape, nor a valid group - - - SMESH_HYP_12 - Geometry mismatches algorithm's expectation\nCheck algorithm documentation for supported geometry - - - SMESH_HYP_13 - Algorithm can't work without shape - - - SMESH_HYP_2 - There are concurrent hypotheses on a shape - - - SMESH_HYP_3 - Hypothesis has a bad parameter value - - - SMESH_HYP_4 - Submesh is ignored as there is another algorithm of upper dimension generating %1D elements - - - SMESH_HYP_5 - Algorithm hides algorithm(s) of lower dimension by generating all-dimensions elements - - - SMESH_HYP_6 - Unknown fatal error at hypothesis definition - - - SMESH_HYP_7 - Hypothesis is not suitable in the current context - - - SMESH_HYP_8 - Non-conform mesh is produced using applied hypotheses - - - SMESH_HYP_9 - Such dimention hypothesis is already assigned to the shape - - - SMESH_ID_DIAGONAL - Id Edges - - - SMESH_ID_ELEMENTS - Id Elements - - - SMESH_ID_FACES - Id Faces - - - SMESH_ID_NODES - Id Nodes - - - SMESH_INCORRECT_INPUT - Incorrect input data! - - - SMESH_INFORMATION - Information - - - SMESH_INIT - Mesh - - - SMESH_INIT_MESH - Mesh Construction - - - SMESH_INSUFFICIENT_DATA - Insufficient input value - - - SMESH_LABELS - Labels: - - - SMESH_LABELS_COLORS_SCALARBAR - Colors && Labels - - - SMESH_LENGTH - Length - - - SMESH_MAKE_GROUPS - Generate groups - - - SMESH_MANIFOLDEDGES - Manifold Edges - - - SMESH_MAX - Max - - - SMESH_MEN_ALGORITHMS - Algorithms - - - SMESH_MEN_APPLIED_ALGORIHTMS - Applied Algorithms - - - SMESH_MEN_APPLIED_HYPOTHESIS - Applied Hypotheses - - - SMESH_MEN_COMPONENT - SMESH - - - SMESH_MEN_HYPOTHESIS - Hypotheses - - - SMESH_MEN_SubMeshesOnCompound - SubMeshes On Compound - - - SMESH_MEN_SubMeshesOnEdge - SubMeshes On Edge - - - SMESH_MEN_SubMeshesOnFace - SubMeshes On Face - - - SMESH_MEN_SubMeshesOnSolid - SubMeshes On Solid - - - SMESH_MEN_SubMeshesOnVertex - SubMeshes On Vertex - - - SMESH_AUTOMATIC - Automatic - - - SMESH_MANUAL - Manual - - - SMESH_MERGE_ELEMENTS - Merge elements - - - SMESH_MODE - Mode - - - SMESH_MERGED_ELEMENTS - %1 elements successfully merged. - - - SMESH_MERGED_NODES - %1 nodes successfully merged. - - - SMESH_NO_ELEMENTS_DETECTED - There are no elements to merge. - - - SMESH_NO_NODES_DETECTED - There are no nodes to merge. - - - SMESH_MERGE_NODES - Merge nodes - - - SMESH_MESH - Mesh - - - SMESH_MESHINFO_0DELEMS - 0D Elements - - - SMESH_MESHINFO_ALL_TYPES - Heterogenous - - - SMESH_MESHINFO_EDGES - Edges - - - SMESH_MESHINFO_ELEMENTS - Elements - - - SMESH_MESHINFO_ENTITIES - Entities - - - SMESH_MESHINFO_FACES - Faces - - - SMESH_MESHINFO_HEXAS - Hexahedrons - - - SMESH_MESHINFO_NAME - Name - - - SMESH_MESHINFO_NODES - Nodes - - - SMESH_MESHINFO_ORDER0 - Total - - - SMESH_MESHINFO_ORDER1 - Linear - - - SMESH_MESHINFO_ORDER2 - Quadratic - - - SMESH_MESHINFO_POLYEDRES - Polyhedrons - - - SMESH_MESHINFO_POLYGONES - Polygons - - - SMESH_MESHINFO_PRISMS - Prisms - - - SMESH_MESHINFO_PYRAS - Pyramids - - - SMESH_MESHINFO_QUADRANGLES - Quadrangles - - - SMESH_MESHINFO_TETRAS - Tetrahedrons - - - SMESH_MESHINFO_TITLE - Mesh Infos - - - SMESH_MESHINFO_TOTAL - Total - - - SMESH_MESHINFO_TRIANGLES - Triangles - - - SMESH_MESHINFO_TYPE - Type - - - SMESH_MESHINFO_VOLUMES - Volumes - - - SMESH_MIN - Min - - - SMESH_MOVE - Move - - - SMESH_MOVE_ELEMENTS - Move Elements - - - SMESH_MOVE_NODES_TITLE - Move Node - - - SMESH_NAME - Name - - - SMESH_NODES - Nodes - - - SMESH_NONMANIFOLDEDGES - Non Manifold Edges - - - SMESH_NORMAL - Normal - - - SMESH_NO_MESH_VISUALIZATION - There is not enough memory to show the mesh - - - SMESH_NUMBEROFCOLORS - Nb of colors: - - - SMESH_NUMBEROFLABELS - Nb of labels: - - - SMESH_NUMBEROFSTEPS - Number of steps: - - - SMESH_OBJECTS_SELECTED - %1_objects - - - SMESH_OBJECT_ALGORITHM - Algorithm - - - SMESH_OBJECT_GEOM - Geometrical Object - - - SMESH_OBJECT_HYPOTHESIS - Hypothesis - - - SMESH_OBJECT_MESH - Mesh - - - SMESH_OBJECT_MESHorSUBMESH - Mesh or SubMesh - - - SMESH_OPERATION_FAILED - Operation failed - - - SMESH_ORIENTATION - Orientation - - - SMESH_ORIENTATION_ELEMENTS_TITLE - Change Orientation - - - SMESH_OUTLINE_COLOR - Mesh Object Color - - - SMESH_PARAMETERS - Parameters - - - SMESH_PLANE - Plane - - - SMESH_POINT - Point - - - SMESH_POINT_1 - Point 1 - - - SMESH_POINT_2 - Point 2 - - - SMESH_BASE_POINT - Base Point - - - SMESH_POLYEDRE_CREATE_ERROR - Polyedron creation error - - - SMESH_POLYEDRON - Polyhedron - - - SMESH_POLYGON - Polygon - - - SMESH_POSITION_SIZE_SCALARBAR - Origin && Size - - - SMESH_PRECISION - Precision - - - SMESH_PREFERENCES_SCALARBAR - Scalar Bar Preferences - - - SMESH_PREF_SELECTION - Preferences - Selection - - - SMESH_PRESELECTION - Preselection - - - SMESH_PRISM - Prism - - - SMESH_PROPERTIES_SCALARBAR - Scalar Bar Properties - - - SMESH_PYRAMID - Pyramid - - - SMESH_QUADRANGLE - Quadrangle - - - SMESH_QUADRATIC_EDGE - Quadratic Edge - - - SMESH_QUADRATIC_HEXAHEDRON - Quadratic Hexahedron - - - SMESH_QUADRATIC_PENTAHEDRON - Quadratic Pentahedron - - - SMESH_QUADRATIC_PYRAMID - Quadratic Pyramid - - - SMESH_QUADRATIC_QUADRANGLE - Quadratic Quadrangle - - - SMESH_QUADRATIC_TETRAHEDRON - Quadratic Tetrahedron - - - SMESH_QUADRATIC_TRIANGLE - Quadratic Triangle - - - SMESH_RANGE_MAX - Max value: - - - SMESH_RANGE_MIN - Min value: - - - SMESH_RANGE_SCALARBAR - Scalar Range - - - SMESH_REALLY_DELETE - Do you really want to delete this %1 object(s)? : %2 - - - SMESH_REMOVE - Remove - - - SMESH_REMOVE_ELEMENTS_TITLE - Remove Elements - - - SMESH_REMOVE_NODES_TITLE - Remove Nodes - - - SMESH_RENUMBERING - Renumbering - - - SMESH_RENUMBERING_ELEMENTS_TITLE - Renumbering elements - - - SMESH_RENUMBERING_NODES_TITLE - Renumbering nodes - - - SMESH_REVERSE - Reverse - - - SMESH_REVOLUTION - Revolution - - - SMESH_RM_HYP_WRN - "%1" unassigned but: - - - - SMESH_ROTATION - Rotation - - - SMESH_ROTATION_TITLE - Rotation about an axis - - - SMESH_SCALARBAR - Scalar Bar - - - SMESH_SEGMENTS - Segments - - - SMESH_SELECTION - Selection - - - SMESH_SELECT_FROM - Select From - - - SMESH_SELECT_WHOLE_MESH - Select whole mesh, submesh or group - - - SMESH_SET_COLOR - Color group - - - SMESH_SEWING - Sewing - - - SMESH_SMOOTHING - Smoothing - - - SMESH_STANDARD_MESHINFO_TITLE - Standard Mesh Infos - - - SMESH_SUBMESH - SubMesh - - - SMESH_SUBMESH_SELECTED - %1 SubMeshes - - - SMESH_SYMMETRY - Symmetry - - - SMESH_TETRAS - Tetrahedron - - - SMESH_TITLE - Title: - - - SMESH_TOLERANCE - Tolerance - - - SMESH_TRANSLATION - Translation - - - SMESH_SCALE_TITLE - Scale Transform - - - SMESH_SCALE - Scale - - - SMESH_SCALE_FACTOR - Scale Factor : - - - SMESH_SCALE_FACTOR_X - Scale Factor X : - - - SMESH_SCALE_FACTOR_Y - Scale Factor Y : - - - SMESH_SCALE_FACTOR_Z - Scale Factor Z : - - - SMESH_TRANSPARENCY_OPAQUE - ---> Opaque - - - SMESH_TRANSPARENCY_TITLE - Change Transparency - - - SMESH_TRANSPARENCY_TRANSPARENT - Transparent <--- - - - SMESH_TRIANGLE - Triangle - - - SMESH_UPDATEVIEW - Update View - - - SMESH_VALUE - Value - - - SMESH_VECTOR - Vector - - - SMESH_VERTICAL - Vertical - - - SMESH_VISU_PROBLEM - Mesh visualization failed, probably due to lack of memory - - - SMESH_VISU_PROBLEM_CLEAR - Mesh visualization failed, no memory even to show a message, -so all visual data have been removed to let the application live. -Consider saving your work before application crash - - - SMESH_VOLUME - Volume - - - SMESH_WARNING - Warning - - - SMESH_WHAT_IS_TITLE - Mesh Element Info - - - SMESH_WIDTH - Width: - - - SMESH_WRN_ALGORITHM_ALREADYEXIST - Algorithm already exists - - - SMESH_WRN_COMPUTE_FAILED - Mesh computation failed - - - SMESH_WRN_EVALUATE_FAILED - Mesh evaluation failed - - - SMESH_WRN_EMPTY_NAME - Empty name is not valid - - - SMESH_WRN_HYPOTHESIS_ALREADYEXIST - Hypothesis already exists - - - SMESH_WRN_HYPOTHESIS_NOTEXIST - Hypothesis or Algorithm not exists - - - SMESH_WRN_MISSING_PARAMETERS - Missing parameters - - - SMESH_WRN_NO_AVAILABLE_DATA - No available data in selection - - - SMESH_WRN_SELECTIONMODE_DIAGONAL - Activate Link Selection Mode - - - SMESH_WRN_SELECTIONMODE_ELEMENTS - Activate Elements Selection Mode - - - SMESH_WRN_SELECTIONMODE_NODES - Activate Nodes Selection Mode - - - SMESH_WRN_VIEWER_VTK - Study frame with VTK Viewer must be activated - - - SMESH_WRN_WARNING - Warning - - - SMESH_X - X - - - SMESH_X_SCALARBAR - X: - - - SMESH_Y - Y - - - SMESH_Y_SCALARBAR - Y: - - - SMESH_Z - Z - - - STATE_ALGO_MISSING - %3 %2D algorithm is missing - - - STATE_HYP_BAD_GEOMETRY - %3 %2D algorithm "%1" is assigned to geometry mismatching its expectation - - - STATE_HYP_BAD_PARAMETER - Hypothesis of %3 %2D algorithm "%1" has a bad parameter value - - - STATE_HYP_MISSING - %3 %2D algorithm "%1" misses %4D hypothesis - - - STATE_HYP_NOTCONFORM - %3 %2D algorithm "%1" would produce not conform mesh: global "Not Conform Mesh Allowed" hypotesis is missing - - - STB_ADV_INFO - Advanced Mesh Infos - - - STB_ALL - All - - - STB_AREA - Area - - - STB_ASPECT - Aspect Ratio - - - STB_ASPECT_3D - Aspect Ratio 3D - - - STB_AUTO_COLOR - Auto color - - - STB_AUTO_UPD - Automatic update - - - STB_BUILD_COMPOUND - Build Compound Mesh - - - STB_CLIP - Clipping - - - STB_COLORS - Colors / Size - - - STB_COMPUTE - Compute - - - STB_PRECOMPUTE - Preview - - - STB_EVALUATE - Evaluate - - - STB_CONNECTION - Borders at Multi-Connection - - - STB_CONNECTION_2D - Borders at Multi-Connection 2D - - - STB_CONSTRUCT_GROUP - Construct Group - - - STB_CONV_TO_QUAD - Convert to/from quadratic - - - STB_2D_FROM_3D - Create 2D mesh from 3D - - - STB_MESH_ORDER - Change submesh priority - - - STB_CREATE_GROUP - Create Group - - - STB_CREATE_GEO_GROUP - Create Groups from Geometry - - - STB_CREATE_MESH - Create Mesh - - - STB_CREATE_SUBMESH - Create Sub-mesh - - - STB_CUT - Cutting of quadrangles - - - STB_CUT_GROUP - Cut Groups - - - STB_DAT - Import DAT file - - - STB_DELETE - Delete - - - STB_DEL_GROUP - Delete Groups - - - STB_FACE_ORIENTATION - Orientation of faces - - - STB_DISABLE_AUTO_COLOR - Disable auto color - - - STB_DISPLAY_ONLY - Show only - - - STB_DISP_ENT - Display entity - - - STB_ELEM0D - 0D Element - - - STB_ELEMS0D - 0D Elements - - - STB_EDGE - Edge - - - STB_EDGES - Edges - - - STB_EDIT_GROUP - Edit Group - - - STB_EDIT_GEOMGROUP_AS_GROUP - Edit Group as Standalone - - - STB_EDIT_HYPO - Edit Hypothesis - - - STB_EDIT_MESHSUBMESH - Edit Mesh/Sub-mesh - - - STB_EXPORT_DAT - Export to DAT file - - - STB_EXPORT_MED - Export to MED file - - - STB_EXPORT_SAUV - Export to SAUV (ASCII) file - - - STB_EXPORT_STL - Export to STL file - - - STB_EXPORT_UNV - Export to UNV file - - - STB_EXTRUSION - Extrusion - - - STB_EXTRUSION_ALONG - Extrusion along a path - - - STB_FACES - Faces - - - STB_FREE_BORDER - Free Borders - - - STB_FREE_EDGE - Free Edges - - - STB_FREE_NODE - Free Nodes - - - - - STB_FREE_FACES - Free Faces - - - STB_GLOBAL_HYPO - Global Hypothesis - - - STB_HEXA - Hexahedron - - - STB_HIDE - Hide - - - STB_INT_GROUP - Intersect Groups - - - STB_INV - Diagonal Inversion - - - STB_LENGTH - Length - - - STB_LENGTH_2D - Length 2D - - - STB_MAP - Pattern mapping - - - STB_MED - Import MED file - - - STB_SAUV - Import SAUV (ASCII) file - - - STB_MERGE - Merge nodes - - - STB_MERGE_ELEMENTS - Merge elements - - - STB_MESH_THROU_POINT - Mesh to pass through a point - - - STB_MIN_ANG - Minimum Angle - - - STB_MOVE - Move Node - - - STB_NODE - Node - - - STB_NODES - Nodes - - - STB_NUM_ELEMENTS - Display Elements - - - STB_NUM_NODES - Display Nodes - - - STB_ORIENT - Orientation - - - STB_POLYGON - Polygon - - - STB_POLYHEDRON - Polyhedron - - - STB_PRECISION - Precision - - - STB_QUAD - Quadrangle - - - STB_QUADRATIC_EDGE - Quadratic Edge - - - STB_QUADRATIC_HEXAHEDRON - Quadratic Hexahedron - - - STB_QUADRATIC_PENTAHEDRON - Quadratic Pentahedron - - - STB_QUADRATIC_PYRAMID - Quadratic Pyramid - - - STB_QUADRATIC_QUADRANGLE - Quadratic Quadrangle - - - STB_QUADRATIC_TETRAHEDRON - Quadratic Tetrahedron - - - STB_QUADRATIC_TRIANGLE - Quadratic Triangle - - - STB_REMOVE_ELEMENTS - Remove elements - - - STB_REMOVE_NODES - Remove nodes - - - STB_RENAME - Rename - - - STB_RENUM_ELEMENTS - Renumbering elements - - - STB_RENUM_NODES - Renumbering nodes - - - STB_RESET - Reset - - - STB_REVOLUTION - Revolution - - - STB_ROT - Rotation - - - STB_SCALAR_BAR - Scalar bar - - - STB_SCALAR_BAR_PROP - Scalar bar Properties - - - STB_SELECTION - Selection - - - STB_SEL_FILTER_LIB - Selection filters library - - - STB_SEW - Sewing - - - STB_SHADE - Shading - - - STB_SHOW - Show - - - STB_SHRINK - Shrink - - - STB_SKEW - Skew - - - STB_SMOOTH - Smoothing - - - STB_STD_INFO - Standard Mesh Infos - - - STB_SYM - Symmetry - - - STB_TAPER - Taper - - - STB_TETRA - Tetrahedron - - - STB_TRANS - Translation - - - STB_SCALE - Scale Transform - - - STB_TRANSP - Transparency - - - STB_TRIANGLE - Triangle - - - STB_UNASSIGN - Unassign - - - STB_UNION - Union of triangles - - - STB_UNION2 - Union of two triangles - - - STB_UNV - Import UNV file - - - STB_UN_GROUP - Union Groups - - - STB_UNDERLYING_ELEMS - Create groups of entities from existing groups of superior dimensions - - - STB_UPDATE - Update - - - STB_VOLUMES - Volumes - - - STB_VOLUME_3D - Volume - - - STB_WARP - Warping angle - - - STB_WHAT_IS - Mesh Element Info - - - STB_WIRE - Wireframe - - - TAPER_ELEMENTS - Taper - - - TB_ADD_REMOVE - Add/Remove Toolbar - - - TB_CTRL - Controls Toolbar - - - TB_DISP_MODE - Display Mode Toolbar - - - TB_HYPO - Hypotheses Toolbar - - - TB_MESH - Mesh Toolbar - - - TB_MODIFY - Modification Toolbar - - - TOP_ADV_INFO - Advanced Mesh Infos - - - TOP_ALL - All - - - TOP_AREA - Area - - - TOP_ASPECT - Aspect Ratio - - - TOP_ASPECT_3D - Aspect Ratio 3D - - - TOP_AUTO_COLOR - Auto color - - - TOP_AUTO_UPD - Automatic update - - - TOP_BUILD_COMPOUND - Build Compound Mesh - - - TOP_CLIP - Clipping - - - TOP_COLORS - Colors / Size - - - TOP_COMPUTE - Compute - - - TOP_PRECOMPUTE - Preview - - - TOP_EVALUATE - Evaluate - - - TOP_CONNECTION - Borders at Multi-Connection - - - TOP_CONNECTION_2D - Borders at Multi-Connection 2D - - - TOP_CONSTRUCT_GROUP - Construct Group - - - TOP_CONV_TO_QUAD - Convert to/from quadratic - - - TOP_2D_FROM_3D - Create 2D mesh from 3D - - - TOP_MESH_ORDER - Change submesh priority - - - TOP_CREATE_GROUP - Create Group - - - TOP_CREATE_GEO_GROUP - Create Groups from Geometry - - - TOP_CREATE_MESH - Create Mesh - - - TOP_CREATE_SUBMESH - Create Sub-mesh - - - TOP_CUT - Cutting of quadrangles - - - TOP_CUT_GROUP - Cut Groups - - - TOP_DAT - Import DAT file - - - TOP_DELETE - Delete - - - TOP_DEL_GROUP - Delete Groups - - - TOP_FACE_ORIENTATION - Orientation of faces - - - TOP_DISABLE_AUTO_COLOR - Disable auto color - - - TOP_DISPLAY_ONLY - Show only - - - TOP_DISP_ENT - Display entity - - - TOP_ELEM0D - 0D Element - - - TOP_ELEMS0D - 0D Elements - - - TOP_EDGE - Edge - - - TOP_EDGES - Edges - - - TOP_EDIT_GROUP - Edit Group - - - TOP_EDIT_GEOMGROUP_AS_GROUP - Edit Group as Standalone - - - TOP_EDIT_HYPO - Edit Hypothesis - - - TOP_EDIT_MESHSUBMESH - Edit Mesh/Sub-mesh - - - TOP_EXPORT_DAT - Export to DAT file - - - TOP_EXPORT_MED - Export to MED file - - - TOP_EXPORT_SAUV - Export to SAUV (ASCII) file - - - TOP_EXPORT_STL - Export to STL file - - - TOP_EXPORT_UNV - Export to UNV file - - - TOP_EXTRUSION - Extrusion - - - TOP_EXTRUSION_ALONG - Extrusion along a path - - - TOP_FACES - Faces - - - TOP_FREE_BORDER - Free Borders - - - TOP_FREE_EDGE - Free Edges - - - TOP_FREE_NODE - Free Nodes - - - - - TOP_FREE_FACES - Free Faces - - - TOP_GLOBAL_HYPO - Global Hypothesis - - - TOP_HEXA - Hexahedron - - - TOP_HIDE - Hide - - - TOP_INT_GROUP - Intersect Groups - - - TOP_INV - Diagonal Inversion - - - TOP_LENGTH - Length - - - TOP_LENGTH_2D - Length 2D - - - TOP_MAP - Pattern mapping - - - TOP_MED - Import MED file - - - TOP_SAUV - Import SAUV (ASCII) file - - - TOP_MERGE - Merge nodes - - - TOP_MERGE_ELEMENTS - Merge elements - - - TOP_MESH_THROU_POINT - Mesh to pass through a point - - - TOP_MIN_ANG - Minimum Angle - - - TOP_MOVE - Move Node - - - TOP_NODE - Node - - - TOP_NODES - Nodes - - - TOP_NUM_ELEMENTS - Display Elements - - - TOP_NUM_NODES - Display Nodes - - - TOP_ORIENT - Orientation - - - TOP_POLYGON - Polygon - - - TOP_POLYHEDRON - Polyhedron - - - TOP_PRECISION - Precision - - - TOP_QUAD - Quadrangle - - - TOP_QUADRATIC_EDGE - Quadratic Edge - - - TOP_QUADRATIC_HEXAHEDRON - Quadratic Hexahedron - - - TOP_QUADRATIC_PENTAHEDRON - Quadratic Pentahedron - - - TOP_QUADRATIC_PYRAMID - Quadratic Pyramid - - - TOP_QUADRATIC_QUADRANGLE - Quadratic Quadrangle - - - TOP_QUADRATIC_TETRAHEDRON - Quadratic Tetrahedron - - - TOP_QUADRATIC_TRIANGLE - Quadratic Triangle - - - TOP_REMOVE_ELEMENTS - Remove elements - - - TOP_REMOVE_NODES - Remove nodes - - - TOP_RENAME - Rename - - - TOP_RENUM_ELEMENTS - Renumbering elements - - - TOP_RENUM_NODES - Renumbering nodes - - - TOP_RESET - Reset - - - TOP_REVOLUTION - Revolution - - - TOP_ROT - Rotation - - - TOP_SCALAR_BAR - Scalar bar - - - TOP_SCALAR_BAR_PROP - Scalar bar Properties - - - TOP_SELECTION - Selection - - - TOP_SEL_FILTER_LIB - Selection filters library - - - TOP_SEW - Sewing - - - TOP_SHADE - Shading - - - TOP_SHOW - Show - - - TOP_SHRINK - Shrink - - - TOP_SKEW - Skew - - - TOP_SMOOTH - Smoothing - - - TOP_STD_INFO - Standard Mesh Infos - - - TOP_SYM - Symmetry - - - TOP_TAPER - Taper - - - TOP_TETRA - Tetrahedron - - - TOP_TRANS - Translation - - - TOP_SCALE - Scale Transform - - - TOP_TRANSP - Transparency - - - TOP_TRIANGLE - Triangle - - - TOP_UNASSIGN - Unassign - - - TOP_UNION - Union of triangles - - - TOP_UNION2 - Union of two triangles - - - TOP_UNV - Import UNV file - - - TOP_UN_GROUP - Union Groups - - - TOP_UNDERLYING_ELEMS - Create groups of entities from existing groups of superior dimensions - - - TOP_UPDATE - Update - - - TOP_VOLUMES - Volumes - - - TOP_VOLUME_3D - Volume - - - TOP_WARP - Warping angle - - - TOP_WHAT_IS - Mesh Element Info - - - TOP_WIRE - Wireframe - - - VOLUME_3D_ELEMENTS - Area - - - WARP_ELEMENTS - Warping - - - MEN_FILE_INFO - MED File Information - - - SMESH_WRN_NO_APPROPRIATE_SELECTION - No appropriate objects selected - - - MEN_CLEAR_MESH - Clear Mesh Data - - - TOP_CLEAR_MESH - Clear Mesh Data - - - STB_CLEAR_MESH - Clear Mesh Data - - - SMESH_IMPORT_MESH - Import mesh data from files - - - SMESH_ERR_NOT_SUPPORTED_FORMAT - Unsupported file format - - - SMESH_ERR_UNKNOWN_IMPORT_ERROR - Unknown error - - - SMESH_IMPORT_ERRORS - Import operation has finished with errors: - - - SMESH_DRS_SOME_EMPTY - One or more mesh files were empty, data has not been published - - - NO_MESH_SELECTED - No mesh selected - - - SMESH_PREF_def_precision - Default precision - - - SMESH_PREF_length_precision - Length precision - - - SMESH_PREF_angle_precision - Angular precision - - - SMESH_PREF_len_tol_precision - Length tolerance precision - - - SMESH_PREF_parametric_precision - Parametric precision - - - SMESH_PREF_area_precision - Area precision - + + + @default + + SMESH_EXPORT_MESH + Export mesh + + + MED_FILES_FILTER + MED files + + + IDEAS_FILES_FILTER + IDEAS files + + + DAT_FILES_FILTER + DAT files + + + TEXT_FILES_FILTER + TXT files + + + MED_VX_FILES_FILTER + MED %1 files + + + STL_ASCII_FILES_FILTER + STL ASCII files + + + STL_BIN_FILES_FILTER + STL binary files + + + ALL_FILES_FILTER + All files + + + AREA_ELEMENTS + Area + + + ASPECTRATIO_3D_ELEMENTS + Aspect Ratio 3D + + + ASPECTRATIO_ELEMENTS + Aspect Ratio + + + COL_ALGO_HEADER + Algorithm + + + COL_ERROR_HEADER + Error + + + COL_SHAPE_HEADER + SubShape + + + COMPERR_ALGO_FAILED + Algorithm failed + + + COMPERR_BAD_INPUT_MESH + Invalid input mesh + + + COMPERR_BAD_SHAPE + Unexpected geometry + + + COMPERR_EXCEPTION + Unknown exception + + + COMPERR_MEMORY_PB + Memory allocation problem + + + COMPERR_OCC_EXCEPTION + OCC exception + + + COMPERR_OK + No errors + + + COMPERR_SLM_EXCEPTION + SALOME exception + + + COMPERR_STD_EXCEPTION + std::exception + + + SMESH_GEOM + Geometry + + + DIRECT_GEOM_SELECTION + Direct geometry selection + + + ELEMENT_ID + Element ID + + + FREE_BORDERS + Free Borders + + + GEOMETRY_NAME + Geometry name + + + GEOM_BY_MESH_ELEM_SELECTION + Find geometry by mesh element selection + + + GLOBAL_ALGO + Global + + + INF_SELECT_OBJECT + Select an object + + + LENGTH2D_EDGES + Length 2D + + + LENGTH_EDGES + Length + + + LOCAL_ALGO + Local + + + MAX_ELEMENT_LENGTH_2D + Element Diameter 2D + + + MAX_ELEMENT_LENGTH_3D + Element Diameter 3D + + + MEN_ADD + Add + + + MEN_ADV_INFO + Mesh Information + + + MEN_ALL + All + + + MEN_AREA + Area + + + MEN_ASPECT + Aspect Ratio + + + MEN_ASPECT_3D + Aspect Ratio 3D + + + MEN_AUTO_COLOR + Auto Color + + + MEN_AUTO_UPD + Automatic Update + + + MEN_BUILD_COMPOUND + Build Compound + + + MEN_CLIP + Clipping + + + MEN_COLORS + Colors / Size + + + MEN_COMPUTE + Compute + + + MEN_PRECOMPUTE + Preview + + + MEN_EVALUATE + Evaluate + + + MEN_CONNECTION + Borders at Multi-Connection + + + MEN_CONNECTION_2D + Borders at Multi-Connection 2D + + + MEN_CONSTRUCT_GROUP + Construct Group + + + MEN_CONV_TO_QUAD + Convert to/from quadratic + + + MEN_2D_FROM_3D + Create boundary elements + + + MEN_MESH_ORDER + Change submesh priority + + + MEN_CREATE_GROUP + Create Group + + + MEN_CREATE_GEO_GROUP + Create Groups from Geometry + + + MEN_CREATE_MESH + Create Mesh + + + MEN_CREATE_SUBMESH + Create Sub-mesh + + + MEN_CTRL + Controls + + + MEN_NODE_CTRL + Node Controls + + + MEN_EDGE_CTRL + Edge Controls + + + MEN_FACE_CTRL + Face Controls + + + MEN_VOLUME_CTRL + Volume Controls + + + MEN_CUT + Cutting of Quadrangles + + + MEN_CUT_GROUP + Cut Groups + + + MEN_DAT + DAT File + + + MEN_DELETE + Delete + + + MEN_DEL_GROUP + Delete Groups + + + MEN_FACE_ORIENTATION + Orientation of Faces + + + MEN_DISABLE_AUTO_COLOR + Disable Auto Color + + + MEN_DISPLAY_ONLY + Show Only + + + MEN_DISPMODE + Display Mode + + + MEN_DISP_ENT + Display Entity + + + MEN_ELEM0D + 0D Element + + + MEN_ELEMS0D + 0D Elements + + + MEN_EDGE + Edge + + + MEN_EDGES + Edges + + + MEN_EDIT + Edit + + + MEN_EDIT_GROUP + Edit Group + + + MEN_EDIT_GEOMGROUP_AS_GROUP + Edit Group as Standalone + + + MEN_EDIT_HYPO + Edit Hypothesis + + + MEN_EDIT_MESHSUBMESH + Edit Mesh/Sub-mesh + + + MEN_EXPORT + Export + + + MEN_EXPORT_DAT + Export to DAT File + + + MEN_EXPORT_MED + Export to MED File + + + MEN_EXPORT_SAUV + Export to SAUV (ASCII) file + + + MEN_EXPORT_STL + Export to STL File + + + MEN_EXPORT_UNV + Export to UNV File + + + MEN_EXTRUSION + Extrusion + + + MEN_EXTRUSION_ALONG + Extrusion Along a Path + + + MEN_FACES + Faces + + + MEN_FILE + File + + + MEN_FIND_ELEM + Find Element by Point + + + TOP_FIND_ELEM + Find Element by Point + + + STB_FIND_ELEM + Find Element by Point + + + MEN_FREE_BORDER + Free Borders + + + MEN_FREE_EDGE + Free Edges + + + MEN_FREE_NODE + Free Nodes + + + MEN_FREE_FACES + Free Faces + + + MEN_GLOBAL_HYPO + Global Hypothesis + + + MEN_HEXA + Hexahedron + + + MEN_HIDE + Hide + + + MEN_HYPO + Hypotheses + + + MEN_IMPORT + Import + + + MEN_INT_GROUP + Intersect Groups + + + MEN_INV + Diagonal Inversion + + + MEN_LENGTH + Length + + + MEN_LENGTH_2D + Length 2D + + + MEN_MAP + Pattern Mapping + + + MEN_MAX_ELEMENT_LENGTH_2D + Element Diameter 2D + + + MEN_MAX_ELEMENT_LENGTH_3D + Element Diameter 3D + + + MEN_MED + MED file + + + MEN_SAUV + SAUV (ASCII) file + + + MEN_MERGE + Merge Nodes + + + MEN_MERGE_ELEMENTS + Merge Elements + + + MEN_MESH + Mesh + + + MEN_MESH_THROU_POINT + Move Node + + + MEN_MIN_ANG + Minimum Angle + + + MEN_MODIFY + Modification + + + MEN_MEASURE + Measurements + + + MEN_MEASURE_MIN_DIST + Minimum Distance + + + STB_MEASURE_MIN_DIST + Calculate minimum distance between two objects + + + TOP_MEASURE_MIN_DIST + Minimum distance + + + MEN_MEASURE_BND_BOX + Bounding Box + + + STB_MEASURE_BND_BOX + Calculate bounding box for the selected object(s) + + + TOP_MEASURE_BND_BOX + Bounding box + + + MEN_MOVE + Move Node + + + MEN_NODE + Node + + + MEN_NODES + Nodes + + + MEN_NUM + Numbering + + + MEN_NUM_ELEMENTS + Display Elements # + + + MEN_NUM_NODES + Display Nodes # + + + MEN_ORIENT + Orientation + + + MEN_POLYGON + Polygon + + + MEN_POLYHEDRON + Polyhedron + + + MEN_PRECISION + Precision + + + MEN_PREF + Preferences + + + MEN_QUAD + Quadrangle + + + MEN_QUADRATIC_EDGE + Quadratic Edge + + + MEN_QUADRATIC_HEXAHEDRON + Quadratic Hexahedron + + + MEN_QUADRATIC_PENTAHEDRON + Quadratic Pentahedron + + + MEN_QUADRATIC_PYRAMID + Quadratic Pyramid + + + MEN_QUADRATIC_QUADRANGLE + Quadratic Quadrangle + + + MEN_QUADRATIC_TETRAHEDRON + Quadratic Tetrahedron + + + MEN_QUADRATIC_TRIANGLE + Quadratic Triangle + + + MEN_QUALITY + Quality Controls + + + MEN_REMOVE + Remove + + + MEN_REMOVE_ELEMENTS + Elements + + + MEN_REMOVE_NODES + Nodes + + + MEN_REMOVE_ORPHAN_NODES + Orphan Nodes + + + MEN_RENAME + Rename + + + MEN_RENUM + Renumbering + + + MEN_RENUM_ELEMENTS + Elements + + + MEN_RENUM_NODES + Nodes + + + MEN_RESET + Reset + + + MEN_SAVE_DISTRIBUTION + Export Distribution... + + + MEN_SHOW_DISTRIBUTION + Show Distribution + + + MEN_REVOLUTION + Revolution + + + MEN_ROT + Rotation + + + MEN_SCALAR_BAR + Scalar Bar + + + MEN_SCALAR_BAR_PROP + Scalar Bar Properties + + + MEN_SELECTION + Selection + + + MEN_SEL_FILTER_LIB + Selection Filters Library + + + MEN_SEW + Sewing + + + MEN_SHADE + Shading + + + MEN_QUADRATIC_REPRESENT + 2D Quadratic + + + MEN_LINE_REPRESENTATION + Lines + + + MEN_ARC_REPRESENTATION + Arcs + + + MEN_SHOW + Show + + + MEN_SHRINK + Shrink + + + MEN_SKEW + Skew + + + MEN_SMOOTH + Smoothing + + + MEN_STD_INFO + Standard Mesh Infos + + + MEN_STL + STL File + + + MEN_SYM + Symmetry + + + MEN_TAPER + Taper + + + MEN_TETRA + Tetrahedron + + + MEN_TOOLS + Tools + + + MEN_TRANS + Translation + + + MEN_SCALE + Scale Transform + + + MEN_DUPLICATE_NODES + Duplicate Nodes + + + MEN_TRANSF + Transformation + + + MEN_TRANSP + Transparency + + + MEN_TRIANGLE + Triangle + + + MEN_UNASSIGN + Unassign + + + MEN_UNION + Union of Triangles + + + MEN_UNION2 + Union of Two Triangles + + + MEN_UNV + UNV File + + + MEN_UN_GROUP + Union Groups + + + MEN_UNDERLYING_ELEMS + Group of underlying entities + + + MEN_UPDATE + Update + + + MEN_VIEW + View + + + MEN_VOLUMES + Volumes + + + MEN_VOLUME_3D + Volume + + + MEN_WARP + Warping Angle + + + MEN_WHAT_IS + Mesh Element Information + + + MEN_WIRE + Wireframe + + + MEN_SPLIT_TO_TETRA + Split into Tetrahedra + + + TOP_SPLIT_TO_TETRA + Split into Tetrahedra + + + STB_SPLIT_TO_TETRA + Split into Tetrahedra + + + MESHERS_FILE_CANT_OPEN + Can not open resource file + + + MESHERS_FILE_CHECK_VARIABLE + Check environment variable SMESH_MeshersList + + + MESHERS_FILE_NO_VARIABLE + Environment variable SMESH_MeshersList is not defined + + + MESH_IS_NOT_SELECTED + There is no selected mesh +Please, select a mesh and try again + + + MESH_NODE + Node + + + MESH_NODE_TITLE + Add Node + + + MINIMUMANGLE_ELEMENTS + Minimum Angle + + + MULTI2D_BORDERS + Borders at Multi-Connections 2D + + + MULTI_BORDERS + Borders at Multi-Connections + + + GROUP_NAME_IS_EMPTY + Name of group is not specified. +Please enter a name of new group to be created or choose an existing one. + + + MESH_STANDALONE_GRP_CHOSEN + Group on geometry is chosen: %1. +Do you want to convert it to the standalone group? + + + NODE_ID + Node ID + + + NON_SMESH_OBJECTS_SELECTED + There are objects selected which do not belong to %1 component. + + + PREVIEW + Preview + + + SKEW_ELEMENTS + Skew + + + SMESHGUI_INVALID_PARAMETERS + Parameters are not correctly specified +Please enter correct values and try again + + + SMESH_ADD_ALGORITHM + Algorithms + + + SMESH_ADD_ALGORITHM_TITLE + Algorithms Assignation + + + SMESH_ADD_ELEM0D + Add 0D Element + + + SMESH_ADD_ELEM0D_TITLE + Add 0D Element + + + SMESH_ADD_EDGE + Add Edge + + + SMESH_ADD_EDGE_TITLE + Add Edge + + + SMESH_ADD_HEXAS + Add Hexahedron + + + SMESH_ADD_HEXAS_TITLE + Add Hexahedron + + + SMESH_ADD_HYPOTHESIS + Hypothesis + + + SMESH_ADD_HYPOTHESIS_TITLE + Hypothesis Assignation + + + SMESH_ADD_HYP_WRN + "%1" assigned but: + + + + SMESH_ADD_POLYGON + Add polygon + + + SMESH_ADD_POLYGON_TITLE + Add polygon + + + SMESH_ADD_QUADRANGLE + Add Quadrangle + + + SMESH_ADD_QUADRANGLE_TITLE + Add Quadrangle + + + SMESH_ADD_QUADRATIC_EDGE_TITLE + Add Quadratic Edge + + + SMESH_ADD_QUADRATIC_HEXAHEDRON_TITLE + Add Quadratic Hexahedron + + + SMESH_ADD_QUADRATIC_PENTAHEDRON_TITLE + Add Quadratic Pentahedron + + + SMESH_ADD_QUADRATIC_PYRAMID_TITLE + Add Quadratic Pyramid + + + SMESH_ADD_QUADRATIC_QUADRANGLE_TITLE + Add Quadratic Quadrangle + + + SMESH_ADD_QUADRATIC_TETRAHEDRON_TITLE + Add Quadratic Tetrahedron + + + SMESH_ADD_QUADRATIC_TRIANGLE_TITLE + Add Quadratic Triangle + + + SMESH_ADD_SUBMESH + SubMesh Construction + + + SMESH_ADD_TETRAS + Add Tetrahedron + + + SMESH_ADD_TETRAS_TITLE + Add Tetrahedron + + + SMESH_ADD_TO_GROUP + Add to group + + + SMESH_ADD_TRIANGLE + Add Triangle + + + SMESH_ADD_TRIANGLE_TITLE + Add Triangle + + + SMESH_ANGLE + Angle + + + SMESH_ARGUMENTS + Arguments + + + SMESH_AUTO_GROUPS + Automatically create groups + + + SMESH_AVAILABLE + Available + + + SMESH_AVAILABLE_ALGORITHMS + Available algorithms + + + SMESH_AVAILABLE_HYPOTHESES + Available hypotheses + + + SMESH_AXIS + Axis + + + SMESH_BAD_SELECTION + No valid selection + + + SMESH_BAD_MESH_SELECTION + No valid mesh selection + + + SMESH_BOUNDARYEDGES + Boundary Edges + + + SMESH_BUILD_COMPOUND_TITLE + Create a Compound + + + SMESH_BUT_ADD + A&dd + + + SMESH_BUT_APPLY + &Apply + + + SMESH_BUT_CANCEL + &Cancel + + + SMESH_BUT_CLOSE + &Close + + + SMESH_BUT_CREATE + Create + + + SMESH_BUT_DELETE + Delete + + + SMESH_BUT_FILTER + Set &Filters + + + SMESH_BUT_HELP + &Help + + + SMESH_BUT_NEW + New + + + SMESH_BUT_NO + &No + + + SMESH_BUT_OK + &Ok + + + SMESH_BUT_OVERWRITE + Over&write + + + SMESH_BUT_APPLY_AND_CLOSE + A&pply and Close + + + SMESH_BUT_REMOVE + &Remove + + + SMESH_BUT_SORT + &Sort List + + + SMESH_BUT_YES + &Yes + + + SMESH_CANT_ADD_HYP + Can not assign "%1": + + + + SMESH_CANT_RM_HYP + Can not unassign "%1": + + + + SMESH_CHECK_COLOR + Color + + + SMESH_CLIPPING_FROM + From <--- + + + SMESH_CLIPPING_INTO + ---> Into + + + SMESH_CLIPPING_TITLE + Change Clipping + + + SMESH_COMPUTE_SUCCEED + Mesh computation succeed + + + SMESH_EVALUATE_SUCCEED + Mesh evaluation succeed + + + SMESH_CONTENT + Content + + + SMESH_CONTINUE_MESH_VISUALIZATION + It seems that there is not enough memory to show the mesh +so that the application may crash. Do you wish to continue visualization? + + + SMESH_COORDINATES + Coordinates + + + SMESH_COPY_ELEMENTS + Copy Elements + + + SMESH_COPY_GROUPS + Copy groups + + + SMESH_CREATE_ALGORITHMS + Create algorithms + + + SMESH_CREATE_COPY + Create a copy + + + SMESH_CREATE_GROUP_TITLE + Create Group + + + SMESH_CREATE_GEO_GROUP + Create Groups from Geometry + + + SMESH_CREATE_HYPOTHESES + Create hypotheses + + + SMESH_CREATE_MESH + Create a new mesh + + + SMESH_CREATE_POLYHEDRAL_VOLUME_TITLE + Create polyhedral volume + + + SMESH_DIAGONAL + Diagonal Inversion + + + SMESH_DIAGONAL_INVERSION_TITLE + Diagonal Inversion + + + SMESH_DISTANCE + Distance + + + SMESH_DRS_1 + MED file contains no mesh with the given name + + + SMESH_DRS_2 + MED file has overlapped ranges of element numbers, the numbers from the file are ignored + + + SMESH_DRS_3 + Some elements were skipped due to incorrect file data + + + SMESH_DRS_4 + The file is incorrect, some data is missed + + + SMESH_DRS_EMPTY + The file is empty, there is nothing to be published + + + SMESH_DX + dX + + + SMESH_DY + dY + + + SMESH_DZ + dZ + + + SMESH_ELEM0D + 0D Element + + + SMESH_EDGE + Edge + + + SMESH_EDGES_CONNECTIVITY_TITLE + Edges Connectivity + + + SMESH_EDIT_GROUP_TITLE + Edit Group + + + SMESH_EDIT_GEOMGROUP_AS_GROUP_TITLE + Edit Group as Standalone + + + SMESH_EDIT_HYPOTHESES + Hypotheses Assignation + + + SMESH_EDIT_USED + Used + + + SMESH_ELEMENTS + Elements + + + SMESH_ELEMENTS_COLOR + Mesh Element Color + + + SMESH_ELEMENTS_TYPE + Elements Type + + + SMESH_ELEMENT_TYPE + Element Type + + + SMESH_ERROR + Error + + + SMESH_ERR_SCALARBAR_PARAMS + Warning! The parameters is incorrect + + + SMESH_EXPORT_FAILED + Mesh export failed. +Probably, there is not enough space on disk. + + + SMESH_EXPORT_MED_DUPLICATED_GRP + There are duplicated group names in mesh "%1". +You can cancel exporting and rename them, +otherwise some group names in the resulting MED file +will not match ones in the study. +Do you want to continue ? + + + SMESH_EXPORT_MED_DUPLICATED_MESH_NAMES + There are some meshes with the same names in the selection. +The result file may be incorrect. +Do you want to continue ? + + + SMESH_EXPORT_MED_V2_1 + During export mesh with name - "%1" to MED 2.1 +polygons and polyhedrons elements will be missed +For correct export use MED 2.2 +Are you sure want to export to MED 2.1 ? + + + SMESH_EXPORT_MED_VERSION_COLLISION + MED version of the file "%1" +is unknown or doesn't match the selected version. +Overwrite the file? + + + SMESH_EXPORT_MED_MESH_NAMES_COLLISION + The selected file already contains +meshes with the following names: %1 +The result file may be incorrect. +Overwrite the file? + + + SMESH_EXPORT_STL1 + Mesh - "%1" does not contain triangles + + + SMESH_EXPORT_STL2 + Mesh - "%1" contains another than triangles elements, they are ignored during writing to STL + + + SMESH_EXPORT_UNV + During export mesh with name - "%1" to UNV + pyramid's elements will be missed + + + SMESH_EXTRUSION + Extrusion + + + SMESH_EXTRUSION_TO_DISTANCE + Extrusion To Distance + + + SMESH_EXTRUSION_ALONG_VECTOR + Extrusion Along Vector + + + SMESH_FACE + Face + + + SMESH_FEATUREANGLE + Feature Angle + + + SMESH_FEATUREEDGES + Feature Edges + + + SMESH_FILE_EXISTS + The file "%1" already exists. +Do you want to overwrite it or +add the exported data to its contents? + + + SMESH_FONT_ARIAL + Arial + + + SMESH_FONT_BOLD + Bold + + + SMESH_FONT_COURIER + Courier + + + SMESH_FONT_ITALIC + Italic + + + SMESH_FONT_SCALARBAR + Font + + + SMESH_FONT_SHADOW + Shadow + + + SMESH_FONT_TIMES + Times + + + SMESH_GEOM_GROUP + Geometry group + + + SMESH_GROUP + Group + + + SMESH_GROUP_GEOMETRY + Group on geometry + + + SMESH_GROUP_SELECTED + %1 Groups + + + SMESH_GROUP_STANDALONE + Standalone group + + + SMESH_GROUP_TYPE + Group type + + + SMESH_HEIGHT + Height: + + + SMESH_HEXAS + Hexahedron + + + SMESH_HILIGHT_COLOR + Highlight Color + + + SMESH_HORIZONTAL + Horizontal + + + SMESH_HYPOTHESES + Hypotheses + + + SMESH_HYP_1 + Algorithm misses a hypothesis + + + SMESH_HYP_10 + Hypothesis and submesh dimensions mismatch + + + SMESH_HYP_11 + Shape is neither the main one, nor its subshape, nor a valid group + + + SMESH_HYP_12 + Geometry mismatches algorithm's expectation\nCheck algorithm documentation for supported geometry + + + SMESH_HYP_13 + Algorithm can't work without shape + + + SMESH_HYP_2 + There are concurrent hypotheses on a shape + + + SMESH_HYP_3 + Hypothesis has a bad parameter value + + + SMESH_HYP_4 + Submesh is ignored as there is another algorithm of upper dimension generating %1D elements + + + SMESH_HYP_5 + Algorithm hides algorithm(s) of lower dimension by generating all-dimensions elements + + + SMESH_HYP_6 + Unknown fatal error at hypothesis definition + + + SMESH_HYP_7 + Hypothesis is not suitable in the current context + + + SMESH_HYP_8 + Non-conform mesh is produced using applied hypotheses + + + SMESH_HYP_9 + Such dimention hypothesis is already assigned to the shape + + + SMESH_ID_DIAGONAL + Id Edges + + + SMESH_ID_ELEMENTS + Id Elements + + + SMESH_ID_FACES + Id Faces + + + SMESH_ID_NODES + Id Nodes + + + SMESH_INCORRECT_INPUT + Incorrect input data! + + + SMESH_INFORMATION + Information + + + SMESH_INIT + Mesh + + + SMESH_INIT_MESH + Mesh Construction + + + SMESH_INSUFFICIENT_DATA + Insufficient input value + + + SMESH_LABELS + Labels: + + + SMESH_LABELS_COLORS_SCALARBAR + Colors && Labels + + + SMESH_LENGTH + Length + + + SMESH_MAKE_GROUPS + Generate groups + + + SMESH_MANIFOLDEDGES + Manifold Edges + + + SMESH_MAX + Max + + + SMESH_MEN_ALGORITHMS + Algorithms + + + SMESH_MEN_APPLIED_ALGORIHTMS + Applied Algorithms + + + SMESH_MEN_APPLIED_HYPOTHESIS + Applied Hypotheses + + + SMESH_MEN_COMPONENT + SMESH + + + SMESH_MEN_HYPOTHESIS + Hypotheses + + + SMESH_MEN_SubMeshesOnCompound + SubMeshes On Compound + + + SMESH_MEN_SubMeshesOnEdge + SubMeshes On Edge + + + SMESH_MEN_SubMeshesOnFace + SubMeshes On Face + + + SMESH_MEN_SubMeshesOnSolid + SubMeshes On Solid + + + SMESH_MEN_SubMeshesOnVertex + SubMeshes On Vertex + + + SMESH_AUTOMATIC + Automatic + + + SMESH_MANUAL + Manual + + + SMESH_MERGE_ELEMENTS + Merge elements + + + SMESH_MODE + Mode + + + SMESH_MERGED_ELEMENTS + %1 elements successfully merged. + + + SMESH_MERGED_NODES + %1 nodes successfully merged. + + + SMESH_NO_ELEMENTS_DETECTED + There are no elements to merge. + + + SMESH_NO_NODES_DETECTED + There are no nodes to merge. + + + SMESH_MERGE_NODES + Merge nodes + + + SMESH_MESH + Mesh + + + SMESH_MESHINFO_0DELEMS + 0D Elements + + + SMESH_MESHINFO_ALL_TYPES + Heterogenous + + + SMESH_MESHINFO_EDGES + Edges + + + SMESH_MESHINFO_ELEMENTS + Elements + + + SMESH_MESHINFO_ENTITIES + Entities + + + SMESH_MESHINFO_FACES + Faces + + + SMESH_MESHINFO_HEXAS + Hexahedrons + + + SMESH_MESHINFO_NAME + Name + + + SMESH_MESHINFO_NODES + Nodes + + + SMESH_MESHINFO_ORDER0 + Total + + + SMESH_MESHINFO_ORDER1 + Linear + + + SMESH_MESHINFO_ORDER2 + Quadratic + + + SMESH_MESHINFO_POLYEDRES + Polyhedrons + + + SMESH_MESHINFO_POLYGONES + Polygons + + + SMESH_MESHINFO_PRISMS + Prisms + + + SMESH_MESHINFO_PYRAS + Pyramids + + + SMESH_MESHINFO_QUADRANGLES + Quadrangles + + + SMESH_MESHINFO_TETRAS + Tetrahedrons + + + SMESH_MESHINFO_TITLE + Mesh Infos + + + SMESH_MESHINFO_TOTAL + Total + + + SMESH_MESHINFO_TRIANGLES + Triangles + + + SMESH_MESHINFO_TYPE + Type + + + SMESH_MESHINFO_VOLUMES + Volumes + + + SMESH_MIN + Min + + + SMESH_MOVE + Move + + + SMESH_MOVE_ELEMENTS + Move Elements + + + SMESH_MOVE_NODES_TITLE + Move Node + + + SMESH_NAME + Name + + + SMESH_NODES + Nodes + + + SMESH_NONMANIFOLDEDGES + Non Manifold Edges + + + SMESH_NORMAL + Normal + + + SMESH_NO_MESH_VISUALIZATION + There is not enough memory to show the mesh + + + SMESH_NUMBEROFCOLORS + Nb of colors: + + + SMESH_NUMBEROFLABELS + Nb of labels: + + + SMESH_NUMBEROFSTEPS + Number of steps: + + + SMESH_OBJECTS_SELECTED + %1_objects + + + SMESH_OBJECT_ALGORITHM + Algorithm + + + SMESH_OBJECT_GEOM + Geometrical Object + + + SMESH_OBJECT_HYPOTHESIS + Hypothesis + + + SMESH_OBJECT_MESH + Mesh + + + SMESH_OBJECT_MESHorSUBMESH + Mesh or SubMesh + + + SMESH_OPERATION_FAILED + Operation failed + + + SMESH_ORIENTATION + Orientation + + + SMESH_ORIENTATION_ELEMENTS_TITLE + Change Orientation + + + SMESH_OUTLINE_COLOR + Mesh Object Color + + + SMESH_PARAMETERS + Parameters + + + SMESH_PLANE + Plane + + + SMESH_POINT + Point + + + SMESH_POINT_1 + Point 1 + + + SMESH_POINT_2 + Point 2 + + + SMESH_BASE_POINT + Base Point + + + SMESH_POLYEDRE_CREATE_ERROR + Polyedron creation error + + + SMESH_POLYEDRON + Polyhedron + + + SMESH_POLYGON + Polygon + + + SMESH_POSITION_SIZE_SCALARBAR + Origin && Size + + + SMESH_DISTRIBUTION_SCALARBAR + Distribution + + + SMESH_SHOW_DISTRIBUTION_SCALARBAR + Show Distribution + + + SMESH_PRECISION + Precision + + + SMESH_PREFERENCES_SCALARBAR + Scalar Bar Preferences + + + SMESH_PREF_SELECTION + Preferences - Selection + + + SMESH_PRESELECTION + Preselection + + + SMESH_PRISM + Prism + + + SMESH_PROPERTIES_SCALARBAR + Scalar Bar Properties + + + SMESH_PYRAMID + Pyramid + + + SMESH_QUADRANGLE + Quadrangle + + + SMESH_QUADRATIC_EDGE + Quadratic Edge + + + SMESH_QUADRATIC_HEXAHEDRON + Quadratic Hexahedron + + + SMESH_QUADRATIC_PENTAHEDRON + Quadratic Pentahedron + + + SMESH_QUADRATIC_PYRAMID + Quadratic Pyramid + + + SMESH_QUADRATIC_QUADRANGLE + Quadratic Quadrangle + + + SMESH_QUADRATIC_TETRAHEDRON + Quadratic Tetrahedron + + + SMESH_QUADRATIC_TRIANGLE + Quadratic Triangle + + + SMESH_RANGE_MAX + Max value: + + + SMESH_RANGE_MIN + Min value: + + + SMESH_RANGE_SCALARBAR + Scalar Range + + + SMESH_REALLY_DELETE + Do you really want to delete this %1 object(s)? : %2 + + + SMESH_REMOVE + Remove + + + SMESH_REMOVE_ELEMENTS_TITLE + Remove Elements + + + SMESH_REMOVE_NODES_TITLE + Remove Nodes + + + SMESH_RENUMBERING + Renumbering + + + SMESH_RENUMBERING_ELEMENTS_TITLE + Renumbering elements + + + SMESH_RENUMBERING_NODES_TITLE + Renumbering nodes + + + SMESH_REVERSE + Reverse + + + SMESH_REVOLUTION + Revolution + + + SMESH_RM_HYP_WRN + "%1" unassigned but: + + + + SMESH_ROTATION + Rotation + + + SMESH_ROTATION_TITLE + Rotation about an axis + + + SMESH_SCALARBAR + Scalar Bar + + + SMESH_SEGMENTS + Segments + + + SMESH_SELECTION + Selection + + + SMESH_SELECT_FROM + Select From + + + SMESH_SELECT_WHOLE_MESH + Select whole mesh, submesh or group + + + SMESH_SET_COLOR + Color group + + + SMESH_SEWING + Sewing + + + SMESH_SMOOTHING + Smoothing + + + SMESH_STANDARD_MESHINFO_TITLE + Standard Mesh Infos + + + SMESH_SUBMESH + SubMesh + + + SMESH_SUBMESH_SELECTED + %1 SubMeshes + + + SMESH_SYMMETRY + Symmetry + + + SMESH_TETRAS + Tetrahedron + + + SMESH_TITLE + Title: + + + SMESH_TOLERANCE + Tolerance + + + SMESH_TRANSLATION + Translation + + + SMESH_SCALE_TITLE + Scale Transform + + + SMESH_DUPLICATE_TITLE + Duplicate Nodes + + + SMESH_SCALE + Scale + + + SMESH_SCALE_FACTOR + Scale Factor : + + + SMESH_SCALE_FACTOR_X + Scale Factor X : + + + SMESH_SCALE_FACTOR_Y + Scale Factor Y : + + + SMESH_SCALE_FACTOR_Z + Scale Factor Z : + + + SMESH_TRANSPARENCY_OPAQUE + ---> Opaque + + + SMESH_TRANSPARENCY_TITLE + Change Transparency + + + SMESH_TRANSPARENCY_TRANSPARENT + Transparent <--- + + + SMESH_TRIANGLE + Triangle + + + SMESH_UPDATEVIEW + Update View + + + SMESH_VALUE + Value + + + SMESH_VECTOR + Vector + + + SMESH_VERTICAL + Vertical + + + SMESH_DISTRIBUTION_COLORING_TYPE + Coloring Type + + + SMESH_MONOCOLOR + Monocolor + + + SMESH_DISTRIBUTION_COLOR + Distribution color: + + + SMESH_MULTICOLOR + Multicolor + + + SMESH_VISU_PROBLEM + Mesh visualization failed, probably due to lack of memory + + + SMESH_VISU_PROBLEM_CLEAR + Mesh visualization failed, no memory even to show a message, +so all visual data have been removed to let the application live. +Consider saving your work before application crash + + + SMESH_VOLUME + Volume + + + SMESH_WARNING + Warning + + + SMESH_WHAT_IS_TITLE + Mesh Element Info + + + SMESH_WIDTH + Width: + + + SMESH_WRN_ALGORITHM_ALREADYEXIST + Algorithm already exists + + + SMESH_WRN_COMPUTE_FAILED + Mesh computation failed + + + SMESH_WRN_EVALUATE_FAILED + Mesh evaluation failed + + + SMESH_WRN_EMPTY_NAME + Empty name is not valid + + + SMESH_WRN_HYPOTHESIS_ALREADYEXIST + Hypothesis already exists + + + SMESH_WRN_HYPOTHESIS_NOTEXIST + Hypothesis or Algorithm not exists + + + SMESH_WRN_MISSING_PARAMETERS + Missing parameters + + + SMESH_WRN_NO_AVAILABLE_DATA + No available data in selection + + + SMESH_WRN_SELECTIONMODE_DIAGONAL + Activate Link Selection Mode + + + SMESH_WRN_SELECTIONMODE_ELEMENTS + Activate Elements Selection Mode + + + SMESH_WRN_SELECTIONMODE_NODES + Activate Nodes Selection Mode + + + SMESH_WRN_VIEWER_VTK + Study frame with VTK Viewer must be activated + + + SMESH_WRN_SIZE_LIMIT_EXCEEDED + No automatic update of the presentation has been done: new mesh size (%1 elements) exceeds current size limit (%2 elements). +Please check preferences of Mesh module. + + + + SMESH_WRN_WARNING + Warning + + + SMESH_X + X + + + SMESH_X_SCALARBAR + X: + + + SMESH_Y + Y + + + SMESH_Y_SCALARBAR + Y: + + + SMESH_Z + Z + + + STATE_ALGO_MISSING + %3 %2D algorithm is missing + + + STATE_HYP_BAD_GEOMETRY + %3 %2D algorithm "%1" is assigned to geometry mismatching its expectation + + + STATE_HYP_BAD_PARAMETER + Hypothesis of %3 %2D algorithm "%1" has a bad parameter value + + + STATE_HYP_MISSING + %3 %2D algorithm "%1" misses %4D hypothesis + + + STATE_HYP_NOTCONFORM + %3 %2D algorithm "%1" would produce not conform mesh: global "Not Conform Mesh Allowed" hypotesis is missing + + + STB_ADV_INFO + Show base information about the mesh object + + + STB_ALL + All + + + STB_AREA + Area + + + STB_ASPECT + Aspect Ratio + + + STB_ASPECT_3D + Aspect Ratio 3D + + + STB_AUTO_COLOR + Auto color + + + STB_AUTO_UPD + Automatic update + + + STB_BUILD_COMPOUND + Build Compound Mesh + + + STB_CLIP + Clipping + + + STB_COLORS + Colors / Size + + + STB_COMPUTE + Compute + + + STB_PRECOMPUTE + Preview + + + STB_EVALUATE + Evaluate + + + STB_CONNECTION + Borders at Multi-Connection + + + STB_CONNECTION_2D + Borders at Multi-Connection 2D + + + STB_CONSTRUCT_GROUP + Construct Group + + + STB_CONV_TO_QUAD + Convert to/from quadratic + + + STB_2D_FROM_3D + Create boundary elements + + + STB_MESH_ORDER + Change submesh priority + + + STB_CREATE_GROUP + Create Group + + + STB_CREATE_GEO_GROUP + Create Groups from Geometry + + + STB_CREATE_MESH + Create Mesh + + + STB_CREATE_SUBMESH + Create Sub-mesh + + + STB_CUT + Cutting of quadrangles + + + STB_CUT_GROUP + Cut Groups + + + STB_DAT + Import DAT file + + + STB_DELETE + Delete + + + STB_DEL_GROUP + Delete Groups + + + STB_FACE_ORIENTATION + Orientation of faces + + + STB_DISABLE_AUTO_COLOR + Disable auto color + + + STB_DISPLAY_ONLY + Show only + + + STB_DISP_ENT + Display entity + + + STB_ELEM0D + 0D Element + + + STB_ELEMS0D + 0D Elements + + + STB_EDGE + Edge + + + STB_EDGES + Edges + + + STB_EDIT_GROUP + Edit Group + + + STB_EDIT_GEOMGROUP_AS_GROUP + Edit Group as Standalone + + + STB_EDIT_HYPO + Edit Hypothesis + + + STB_EDIT_MESHSUBMESH + Edit Mesh/Sub-mesh + + + STB_EXPORT_DAT + Export to DAT file + + + STB_EXPORT_MED + Export to MED file + + + STB_EXPORT_SAUV + Export to SAUV (ASCII) file + + + STB_EXPORT_STL + Export to STL file + + + STB_EXPORT_UNV + Export to UNV file + + + STB_EXTRUSION + Extrusion + + + STB_EXTRUSION_ALONG + Extrusion along a path + + + STB_FACES + Faces + + + STB_FREE_BORDER + Free Borders + + + STB_FREE_EDGE + Free Edges + + + STB_FREE_NODE + Free Nodes + + + STB_FREE_FACES + Free Faces + + + STB_GLOBAL_HYPO + Global Hypothesis + + + STB_HEXA + Hexahedron + + + STB_HIDE + Hide + + + STB_INT_GROUP + Intersect Groups + + + STB_INV + Diagonal Inversion + + + STB_LENGTH + Length + + + STB_LENGTH_2D + Length 2D + + + STB_MAP + Pattern mapping + + + STB_MAX_ELEMENT_LENGTH_2D + Element Diameter 2D + + + STB_MAX_ELEMENT_LENGTH_3D + Element Diameter 3D + + + STB_MED + Import MED file + + + STB_SAUV + Import SAUV (ASCII) file + + + STB_MERGE + Merge nodes + + + STB_MERGE_ELEMENTS + Merge elements + + + STB_MESH_THROU_POINT + Move Node + + + STB_MIN_ANG + Minimum Angle + + + STB_MOVE + Move Node + + + STB_NODE + Node + + + STB_NODES + Nodes + + + STB_NUM_ELEMENTS + Display Elements + + + STB_NUM_NODES + Display Nodes + + + STB_ORIENT + Orientation + + + STB_POLYGON + Polygon + + + STB_POLYHEDRON + Polyhedron + + + STB_PRECISION + Precision + + + STB_QUAD + Quadrangle + + + STB_QUADRATIC_EDGE + Quadratic Edge + + + STB_QUADRATIC_HEXAHEDRON + Quadratic Hexahedron + + + STB_QUADRATIC_PENTAHEDRON + Quadratic Pentahedron + + + STB_QUADRATIC_PYRAMID + Quadratic Pyramid + + + STB_QUADRATIC_QUADRANGLE + Quadratic Quadrangle + + + STB_QUADRATIC_TETRAHEDRON + Quadratic Tetrahedron + + + STB_QUADRATIC_TRIANGLE + Quadratic Triangle + + + STB_REMOVE_ELEMENTS + Remove elements + + + STB_REMOVE_NODES + Remove nodes + + + STB_REMOVE_ORPHAN_NODES + Remove orphan nodes + + + STB_RENAME + Rename + + + STB_RENUM_ELEMENTS + Renumbering elements + + + STB_RENUM_NODES + Renumbering nodes + + + STB_RESET + Reset + + + STB_SAVE_DISTRIBUTION + Save distribution to the file + - FULL_RECOMPUTE_QUESTION - + STB_SHOW_DISTRIBUTION + Show Distribution + + + STB_REVOLUTION + Revolution + + + STB_ROT + Rotation + + + STB_SCALAR_BAR + Scalar bar + + + STB_SCALAR_BAR_PROP + Scalar bar Properties + + + STB_SELECTION + Selection + + + STB_SEL_FILTER_LIB + Selection filters library + + + STB_SEW + Sewing + + + STB_SHADE + Shading + + + STB_SHOW + Show + + + STB_SHRINK + Shrink + + + STB_SKEW + Skew + + + STB_SMOOTH + Smoothing + + + STB_STD_INFO + Standard Mesh Infos + + + STB_SYM + Symmetry + + + STB_TAPER + Taper + + + STB_TETRA + Tetrahedron + + + STB_TRANS + Translation + + + STB_SCALE + Scale Transform + + + STB_DUPLICATE_NODES + Duplicate Nodes + + + STB_TRANSP + Transparency + + + STB_TRIANGLE + Triangle + + + STB_UNASSIGN + Unassign + + + STB_UNION + Union of triangles + + + STB_UNION2 + Union of two triangles + + + STB_UNV + Import UNV file + + + STB_UN_GROUP + Union Groups + + + STB_UNDERLYING_ELEMS + Create groups of entities from existing groups of superior dimensions + + + STB_UPDATE + Update + + + STB_VOLUMES + Volumes + + + STB_VOLUME_3D + Volume + + + STB_WARP + Warping angle + + + STB_WHAT_IS + Show information about the mesh node or element + + + STB_WIRE + Wireframe + + + TAPER_ELEMENTS + Taper + + + TB_ADD_REMOVE + Add/Remove Toolbar + + + TB_CTRL + Controls Toolbar + + + TB_DISP_MODE + Display Mode Toolbar + + + TB_HYPO + Hypotheses Toolbar + + + TB_MESH + Mesh Toolbar + + + TB_MODIFY + Modification Toolbar + + + TOP_ADV_INFO + Mesh Information + + + TOP_ALL + All + + + TOP_AREA + Area + + + TOP_ASPECT + Aspect Ratio + + + TOP_ASPECT_3D + Aspect Ratio 3D + + + TOP_AUTO_COLOR + Auto color + + + TOP_AUTO_UPD + Automatic update + + + TOP_BUILD_COMPOUND + Build Compound Mesh + + + TOP_CLIP + Clipping + + + TOP_COLORS + Colors / Size + + + TOP_COMPUTE + Compute + + + TOP_PRECOMPUTE + Preview + + + TOP_EVALUATE + Evaluate + + + TOP_CONNECTION + Borders at Multi-Connection + + + TOP_CONNECTION_2D + Borders at Multi-Connection 2D + + + TOP_CONSTRUCT_GROUP + Construct Group + + + TOP_CONV_TO_QUAD + Convert to/from quadratic + + + TOP_2D_FROM_3D + Create boundary elements + + + TOP_MESH_ORDER + Change submesh priority + + + TOP_CREATE_GROUP + Create Group + + + TOP_CREATE_GEO_GROUP + Create Groups from Geometry + + + TOP_CREATE_MESH + Create Mesh + + + TOP_CREATE_SUBMESH + Create Sub-mesh + + + TOP_CUT + Cutting of quadrangles + + + TOP_CUT_GROUP + Cut Groups + + + TOP_DAT + Import DAT file + + + TOP_DELETE + Delete + + + TOP_DEL_GROUP + Delete Groups + + + TOP_FACE_ORIENTATION + Orientation of faces + + + TOP_DISABLE_AUTO_COLOR + Disable auto color + + + TOP_DISPLAY_ONLY + Show only + + + TOP_DISP_ENT + Display entity + + + TOP_ELEM0D + 0D Element + + + TOP_ELEMS0D + 0D Elements + + + TOP_EDGE + Edge + + + TOP_EDGES + Edges + + + TOP_EDIT_GROUP + Edit Group + + + TOP_EDIT_GEOMGROUP_AS_GROUP + Edit Group as Standalone + + + TOP_EDIT_HYPO + Edit Hypothesis + + + TOP_EDIT_MESHSUBMESH + Edit Mesh/Sub-mesh + + + TOP_EXPORT_DAT + Export to DAT file + + + TOP_EXPORT_MED + Export to MED file + + + TOP_EXPORT_SAUV + Export to SAUV (ASCII) file + + + TOP_EXPORT_STL + Export to STL file + + + TOP_EXPORT_UNV + Export to UNV file + + + TOP_EXTRUSION + Extrusion + + + TOP_EXTRUSION_ALONG + Extrusion along a path + + + TOP_FACES + Faces + + + TOP_FREE_BORDER + Free Borders + + + TOP_FREE_EDGE + Free Edges + + + TOP_FREE_NODE + Free Nodes + + + TOP_FREE_FACES + Free Faces + + + TOP_GLOBAL_HYPO + Global Hypothesis + + + TOP_HEXA + Hexahedron + + + TOP_HIDE + Hide + + + TOP_INT_GROUP + Intersect Groups + + + TOP_INV + Diagonal Inversion + + + TOP_LENGTH + Length + + + TOP_LENGTH_2D + Length 2D + + + TOP_MAP + Pattern mapping + + + TOP_MAX_ELEMENT_LENGTH_2D + Element Diameter 2D + + + TOP_MAX_ELEMENT_LENGTH_3D + Element Diameter 3D + + + TOP_MED + Import MED file + + + TOP_SAUV + Import SAUV (ASCII) file + + + TOP_MERGE + Merge nodes + + + TOP_MERGE_ELEMENTS + Merge elements + + + TOP_MESH_THROU_POINT + Move Node + + + TOP_MIN_ANG + Minimum Angle + + + TOP_MOVE + Move Node + + + TOP_NODE + Node + + + TOP_NODES + Nodes + + + TOP_NUM_ELEMENTS + Display Elements + + + TOP_NUM_NODES + Display Nodes + + + TOP_ORIENT + Orientation + + + TOP_POLYGON + Polygon + + + TOP_POLYHEDRON + Polyhedron + + + TOP_PRECISION + Precision + + + TOP_QUAD + Quadrangle + + + TOP_QUADRATIC_EDGE + Quadratic Edge + + + TOP_QUADRATIC_HEXAHEDRON + Quadratic Hexahedron + + + TOP_QUADRATIC_PENTAHEDRON + Quadratic Pentahedron + + + TOP_QUADRATIC_PYRAMID + Quadratic Pyramid + + + TOP_QUADRATIC_QUADRANGLE + Quadratic Quadrangle + + + TOP_QUADRATIC_TETRAHEDRON + Quadratic Tetrahedron + + + TOP_QUADRATIC_TRIANGLE + Quadratic Triangle + + + TOP_REMOVE_ELEMENTS + Remove elements + + + TOP_REMOVE_NODES + Remove nodes + + + TOP_REMOVE_ORPHAN_NODES + Remove orphan nodes + + + TOP_RENAME + Rename + + + TOP_RENUM_ELEMENTS + Renumbering elements + + + TOP_RENUM_NODES + Renumbering nodes + + + TOP_RESET + Reset + + + TOP_SAVE_DISTRIBUTION + Export distribution + + + TOP_SHOW_DISTRIBUTION + Show Distribution + + + TOP_REVOLUTION + Revolution + + + TOP_ROT + Rotation + + + TOP_SCALAR_BAR + Scalar bar + + + TOP_SCALAR_BAR_PROP + Scalar bar Properties + + + TOP_SELECTION + Selection + + + TOP_SEL_FILTER_LIB + Selection filters library + + + TOP_SEW + Sewing + + + TOP_SHADE + Shading + + + TOP_SHOW + Show + + + TOP_SHRINK + Shrink + + + TOP_SKEW + Skew + + + TOP_SMOOTH + Smoothing + + + TOP_STD_INFO + Standard Mesh Infos + + + TOP_SYM + Symmetry + + + TOP_TAPER + Taper + + + TOP_TETRA + Tetrahedron + + + TOP_TRANS + Translation + + + TOP_SCALE + Scale Transform + + + TOP_DUPLICATE_NODES + Duplicate Nodes + + + TOP_TRANSP + Transparency + + + TOP_TRIANGLE + Triangle + + + TOP_UNASSIGN + Unassign + + + TOP_UNION + Union of triangles + + + TOP_UNION2 + Union of two triangles + + + TOP_UNV + Import UNV file + + + TOP_UN_GROUP + Union Groups + + + TOP_UNDERLYING_ELEMS + Create groups of entities from existing groups of superior dimensions + + + TOP_UPDATE + Update + + + TOP_VOLUMES + Volumes + + + TOP_VOLUME_3D + Volume + + + TOP_WARP + Warping angle + + + TOP_WHAT_IS + Mesh Element Information + + + TOP_WIRE + Wireframe + + + UNKNOWN_CONTROL + Unknown + + + VOLUME_3D_ELEMENTS + Volume + + + WARP_ELEMENTS + Warping + + + MEN_FILE_INFO + MED File Information + + + SMESH_WRN_NO_APPROPRIATE_SELECTION + No appropriate objects selected + + + MEN_CLEAR_MESH + Clear Mesh Data + + + TOP_CLEAR_MESH + Clear Mesh Data + + + STB_CLEAR_MESH + Clear Mesh Data + + + SMESH_IMPORT_MESH + Import mesh data from files + + + SMESH_ERR_NOT_SUPPORTED_FORMAT + Unsupported file format + + + SMESH_ERR_UNKNOWN_IMPORT_ERROR + Unknown error + + + SMESH_IMPORT_ERRORS + Import operation has finished with errors: + + + SMESH_DRS_SOME_EMPTY + One or more mesh files were empty, data has not been published + + + NO_MESH_SELECTED + No mesh selected + + + SMESH_PREF_def_precision + Default precision + + + SMESH_PREF_length_precision + Length precision + + + SMESH_PREF_angle_precision + Angular precision + + + SMESH_PREF_len_tol_precision + Length tolerance precision + + + SMESH_PREF_parametric_precision + Parametric precision + + + SMESH_PREF_area_precision + Area precision + + + FULL_RECOMPUTE_QUESTION + The mesh has been edited since a last total re-compute that may prevent successful computation. Do you wish to re-compute the mesh totally to discard the modifications? - - - - SMESH_PREF_vol_precision - Volume precision - - - SMESH_PRECISION_HINT - + + + + SMESH_PREF_vol_precision + Volume precision + + + SMESH_PRECISION_HINT + Input value precision can be adjusted using -'%1' parameter in Mesh module preferences. - - - - SMESHGUI - - NOT_A_VTK_VIEWER - This command is available in VTK viewer only +'%1' parameter in Mesh module preferences. + + + REMOVE_ORPHAN_NODES_QUESTION + Do you really want to remove all orphan nodes? + + + NB_NODES_REMOVED + Removed %1 node(s). + + + SMESH_SAVE_DISTRIBUTION + Export Distribution + + + SMESH_PLUGINS_OTHER + SMESH plugins + + + + SMESHGUI + + NOT_A_VTK_VIEWER + This command is available in VTK viewer only Please, create VTK viewer and try again - - - PREF_AUTO_GROUPS - Automatically create groups for MED export - - - PREF_GROUP_SEGMENT_LENGTH - Automatic parameters - - - PREF_SEGMENT_LENGTH - Ratio Bounding Box Diagonal / Max Size - - - PREF_NB_SEGMENTS - Default Number of Segments - - - PREF_AUTO_UPDATE - Automatic update - - - PREF_BACKFACE - Back face - - - PREF_COLOR - Color - - - PREF_ORIENTATION_COLOR - Color - - - PREF_ORIENTATION_3D_VECTORS - 3D vectors - - - PREF_ORIENTATION_SCALE - Scale - - - PREF_DISPLAY_ENTITY - Display entity - - - QUADRATIC_REPRESENT_MODE - Representation of the 2D quadratic elements - - - MAX_ARC_ANGLE - Maximum angle - - - PREF_DISPLAY_MODE - Display mode - - - PREF_ELEMENTS - Elements - - - PREF_ELEMENT_COLOR - Element color - - - PREF_FILL - Fill - - - PREF_NOTIFY_MODE - Show a computation result notification - - - SMESH_PREF_GROUP_PRECISION - Input fields precision - - - PREF_GROUP_ELEMENTS - Elements - - - PREF_GROUP_EXPORT - Mesh export - - - PREF_GROUP_FACES_ORIENTATION - Orientation of faces - - - PREF_GROUP_COMPUTE - Mesh computation - - - PREF_GROUP_NODES - Nodes - - - PREF_GROUP_PRECISION - Precision - - - PREF_GROUP_PRESELECTION - Preselection - - - PREF_GROUP_QUALITY - Quality controls - - - PREF_GROUP_SELECTION - Selection - - - PREF_GROUP_UPDATE - Update - - - PREF_HIGHLIGHT_COLOR - Highlight color - - - PREF_LABELS_COLOR - Labels color - - - PREF_MARKER_SCALE - Scale of marker - - - PREF_NODES - Nodes - - - PREF_OBJECTS - Objects - - - PREF_OBJECT_COLOR - Object color - - - PREF_OUTLINE - Outline - - - PREF_PRECISION_USE - Use precision - - - PREF_PRECISION_VALUE - Number of digits after point - - - PREF_RENUMBER - Automatic renumbering - - - PREF_SHRINK_COEFF - Shrink coef. - - - PREF_TAB_GENERAL - General - - - PREF_TAB_MESH - Mesh - - - PREF_TAB_SELECTION - Selection - - - PREF_TITLE_COLOR - Title color - - - PREF_TYPE_OF_MARKER - Type of marker - - - PREF_COLOR_0D - 0D elements - - - PREF_SIZE_0D - Size of 0D elements - - - PREF_WIDTH - Width - - - - SMESHGUI_AddQuadraticElementDlg - - SMESH_ADD_QUADRATIC_EDGE - Add Quadratic Edge - - - SMESH_ADD_QUADRATIC_HEXAHEDRON - Add Quadratic Hexahedron - - - SMESH_ADD_QUADRATIC_PENTAHEDRON - Add Quadratic Pentahedron - - - SMESH_ADD_QUADRATIC_PYRAMID - Add Quadratic Pyramid - - - SMESH_ADD_QUADRATIC_QUADRANGLE - Add Quadratic Quadrangle - - - SMESH_ADD_QUADRATIC_TETRAHEDRON - Add Quadratic Tetrahedron - - - SMESH_ADD_QUADRATIC_TRIANGLE - Add Quadratic Triangle - - - SMESH_CORNER_NODES - Corner Nodes: - - - SMESH_FIRST - First - - - SMESH_LAST - Last - - - SMESH_MIDDLE - Middle - - - - SMESHGUI_BuildCompoundDlg - - COMPOUND - Compound - - - COMPOUND_MESH - Compound_Mesh - - - CREATE_COMMON_GROUPS - Create common groups for initial meshes - - - MERGE_NODES_AND_ELEMENTS - Merge coincident nodes and elements - - - MESHES - Meshes - - - PROCESSING_IDENTICAL_GROUPS - Processing identical groups - - - RENAME - Rename - - - RESULT_NAME - Result name - - - UNITE - Unite - - - - SMESHGUI_ChangeOrientationDlg - - CAPTION - Modification of orientation - - - - SMESHGUI_ComputeDlg - - CAPTION - Compute mesh failed - - - CONSTRUCTOR - Compute mesh - - - EVAL_DLG - Evaluate mesh - - - ERRORS - Errors - - - MEMORY_LACK - Memory allocation problem - - - PUBLISH_SHAPE - Publish SubShape - - - SHOW_SHAPE - Show SubShape - - - SHOW_BAD_MESH - Show bad Mesh - - - - SMESHGUI_PrecomputeDlg - - CAPTION - Preview and Compute mesh - - - PREVIEW - Preview - - - PREVIEW_1 - 1D Mesh - - - PREVIEW_2 - 2D Mesh - - - COMPUTE - Compute - - - - SMESHGUI_PrecomputeOp - - CLEAR_SUBMESH_QUESTION - A temporary submeshes on the selected geometry - created during preview operation. - Do you want to remove all this submeshes? - - - SMESH_WRN_NOTHING_PREVIEW - No mesh preview is available - - - SMESH_REJECT_MESH_ORDER - The submesh priority changed during preview operation. + + + PREF_AUTO_GROUPS + Automatically create groups for MED export + + + PREF_GROUP_SEGMENT_LENGTH + Automatic parameters + + + PREF_SEGMENT_LENGTH + Ratio Bounding Box Diagonal / Max Size + + + PREF_NB_SEGMENTS + Default Number of Segments + + + PREF_AUTO_UPDATE + Automatic update + + + PREF_UPDATE_LIMIT + Size limit (elements) + + + PREF_UPDATE_LIMIT_NOLIMIT + No limit + + + PREF_BACKFACE + Back face + + + PREF_COLOR + Color + + + PREF_ORIENTATION_COLOR + Color + + + PREF_ORIENTATION_3D_VECTORS + 3D vectors + + + PREF_ORIENTATION_SCALE + Scale + + + PREF_DISPLAY_ENTITY + Display entity + + + QUADRATIC_REPRESENT_MODE + Representation of the 2D quadratic elements + + + MAX_ARC_ANGLE + Maximum angle + + + PREF_DISPLAY_MODE + Display mode + + + PREF_ELEMENTS + Elements + + + PREF_ELEMENT_COLOR + Element color + + + PREF_FILL + Fill + + + PREF_NOTIFY_MODE + Show a computation result notification + + + PREF_NOTIFY_NEVER + Never + + + PREF_NOTIFY_ERROR + Errors only + + + PREF_NOTIFY_ALWAYS + Always + + + PREF_ELEM_INFO + Mesh element information + + + PREF_ELEM_INFO_SIMPLE + Simple + + + PREF_ELEM_INFO_TREE + Tree + + + SMESH_PREF_GROUP_PRECISION + Input fields precision + + + PREF_GROUP_ELEMENTS + Elements + + + PREF_GROUP_EXPORT + Mesh export + + + PREF_GROUP_FACES_ORIENTATION + Orientation of faces + + + PREF_GROUP_COMPUTE + Mesh computation + + + PREF_GROUP_NODES + Nodes + + + PREF_GROUP_GROUPS + Groups + + + PREF_GRP_NAMES + Names color + + + PREF_GROUP_PRECISION + Precision + + + PREF_GROUP_PRESELECTION + Preselection + + + PREF_GROUP_QUALITY + Quality controls + + + PREF_GROUP_SELECTION + Selection + + + PREF_GROUP_INFO + Mesh information + + + PREF_HIGHLIGHT_COLOR + Highlight color + + + PREF_LABELS_COLOR + Labels color + + + PREF_MARKER_SCALE + Scale of marker + + + PREF_NODES + Nodes + + + PREF_OBJECTS + Objects + + + PREF_OBJECT_COLOR + Object color + + + PREF_OUTLINE + Outline + + + PREF_PRECISION_USE + Use precision + + + PREF_PRECISION_VALUE + Number of digits after point + + + PREF_RENUMBER + Automatic renumbering + + + PREF_SHRINK_COEFF + Shrink coef. + + + PREF_TAB_GENERAL + General + + + PREF_TAB_MESH + Mesh + + + PREF_TAB_SELECTION + Selection + + + PREF_TITLE_COLOR + Title color + + + PREF_TYPE_OF_MARKER + Type of marker + + + PREF_COLOR_0D + 0D elements + + + PREF_SIZE_0D + Size of 0D elements + + + PREF_WIDTH + Width + + + + SMESHGUI_AddQuadraticElementDlg + + SMESH_ADD_QUADRATIC_EDGE + Add Quadratic Edge + + + SMESH_ADD_QUADRATIC_HEXAHEDRON + Add Quadratic Hexahedron + + + SMESH_ADD_QUADRATIC_PENTAHEDRON + Add Quadratic Pentahedron + + + SMESH_ADD_QUADRATIC_PYRAMID + Add Quadratic Pyramid + + + SMESH_ADD_QUADRATIC_QUADRANGLE + Add Quadratic Quadrangle + + + SMESH_ADD_QUADRATIC_TETRAHEDRON + Add Quadratic Tetrahedron + + + SMESH_ADD_QUADRATIC_TRIANGLE + Add Quadratic Triangle + + + SMESH_CORNER_NODES + Corner Nodes: + + + SMESH_FIRST + First + + + SMESH_LAST + Last + + + SMESH_MIDDLE + Middle + + + + SMESHGUI_BuildCompoundDlg + + COMPOUND + Compound + + + COMPOUND_MESH + Compound_Mesh + + + CREATE_COMMON_GROUPS + Create common groups for initial meshes + + + MERGE_NODES_AND_ELEMENTS + Merge coincident nodes and elements + + + MESHES + Meshes + + + PROCESSING_IDENTICAL_GROUPS + Processing identical groups + + + RENAME + Rename + + + RESULT_NAME + Result name + + + UNITE + Unite + + + + SMESHGUI_ChangeOrientationDlg + + CAPTION + Modification of orientation + + + + SMESHGUI_ComputeDlg + + CAPTION + Compute mesh failed + + + CONSTRUCTOR + Compute mesh + + + EVAL_DLG + Evaluate mesh + + + ERRORS + Errors + + + MEMORY_LACK + Memory allocation problem + + + PUBLISH_SHAPE + Publish SubShape + + + SHOW_SHAPE + Show SubShape + + + SHOW_BAD_MESH + Show bad Mesh + + + + SMESHGUI_PrecomputeDlg + + CAPTION + Preview and Compute mesh + + + PREVIEW + Preview + + + PREVIEW_1 + 1D Mesh + + + PREVIEW_2 + 2D Mesh + + + COMPUTE + Compute + + + + SMESHGUI_PrecomputeOp + + CLEAR_SUBMESH_QUESTION + Temporary submeshes on the selected geometry +were created during preview operation. +Do you want to remove all these submeshes? + + + SMESH_WRN_NOTHING_PREVIEW + No mesh preview is available + + + SMESH_REJECT_MESH_ORDER + The submesh priority changed during preview operation. Do you want to restore original submesh priority? - - - - SMESHGUI_ConvToQuadDlg - - CAPTION - Convert to/from quadratic - - - MEDIUMNDS - Medium nodes on geometry - - - MESH - Mesh - - - RADIOBTN_1 - Convert to quadratic - - - RADIOBTN_2 - Convert from quadratic - - - - SMESHGUI_ConvToQuadOp - - MESH_IS_NOT_SELECTED - Mesh is not selected + + + + SMESHGUI_ConvToQuadDlg + + CAPTION + Convert to/from quadratic + + + MEDIUMNDS + Medium nodes on geometry + + + MESH + Mesh + + + RADIOBTN_1 + Convert to quadratic + + + RADIOBTN_2 + Convert from quadratic + + + + SMESHGUI_ConvToQuadOp + + MESH_IS_NOT_SELECTED + Mesh is not selected Please specify it and try again - - - REF_IS_NULL - No valid mesh object selected - - - - SMESHGUI_Make2DFrom3DDlg - - CAPTION - Create 2D mesh from 3D - - - - SMESHGUI_CreatePatternDlg - - CAPTION - Pattern Creation - - - DEFAULT_2D - Pattern_2d - - - DEFAULT_3D - Pattern_3d - - - ERROR_OF_CREATION - Internal error occurs during pattern creation -Please verify validity of entered information - - - ERROR_OF_SAVING - Internal error occurs during pattern saving. Please verify -\free disk space and your write permission to this file - - - ERR_LOADF_CANT_PROJECT - Impossible to perform projection of nodes to the face - - - ERR_LOADF_CLOSED_FACE - It is impossible to create pattern from face having seam edge - - - ERR_LOADF_NARROW_FACE - It is impossible to create pattern from narrow face - - - ERR_LOADV_BAD_SHAPE - Pattern can be created from closed shell or solid with 6 faces only - - - ERR_LOADV_COMPUTE_PARAMS - It is impossible to compute point parameters - - - ERR_LOAD_EMPTY_SUBMESH - There are no elements to create pattern - - - MESH_OR_SUBMESH - Mesh or SubMesh - - - PATTERN - Pattern - - - PATTERN_FILT - Pattern files(*.smp) - - - PATTERN_NAME - Pattern name - - - PATTERN_TYPE - Pattern type - - - PROJECT - Project nodes on the face - - - SAVE - Save... - - - SAVE_PATTERN - Save Pattern - - - - SMESHGUI_CreatePolyhedralVolumeDlg - - FACES_BY_NODES - Faces by nodes - - - SMESH_POLYEDRE_CREATE_ERROR - Polyhedron creation error. - - - SMESH_POLYEDRE_PREVIEW - Polyhedron preview - - - - SMESHGUI_CuttingOfQuadsDlg - - CAPTION - Cutting of quadrangles - - - - SMESHGUI_DeleteGroupDlg - - CAPTION - Delete groups with contents - - - NO_SELECTED_GROUPS - There are no selected groups -Please select a groups and try again - - - SELECTED_GROUPS - Selected groups - - - - SMESHGUI_EditMeshDlg - - COINCIDENT_ELEMENTS - Coincident elements - - - COINCIDENT_NODES - Coincident nodes - - - DETECT - Detect - - - EDIT_SELECTED_GROUP - Edit selected group - - - SELECT_ALL - Select all - - - - SMESHGUI_ExtrusionAlongPathDlg - - BAD_SHAPE_TYPE - The shape selected for the path is not edge - - - CANT_GET_TANGENT - Can't get tangent for one of the path nodes - - - EXTRUSION_1D - Extrusion of 1D elements - - - EXTRUSION_2D - Extrusion of 2D elements - - - EXTRUSION_ALONG_PATH - Extrusion along a path - - - EXTR_BAD_STARTING_NODE - Wrong path starting node - - - LINEAR_ANGLES - Linear variation of the angles - - - NO_ELEMENTS_SELECTED - No mesh elements are selected for extrusion - - - SELECTED_PATH_IS_NOT_EDGE - Path mesh should be of edge type - - - SMESH_ANGLES - Rotation Angles - - - SMESH_BASE_POINT - Base Point - - - SMESH_PATH - Path - - - SMESH_PATH_MESH - Mesh or submesh - - - SMESH_PATH_SHAPE - Shape (edge) - - - SMESH_PATH_START - Start node - - - SMESH_USE_ANGLES - Use Angles - - - SMESH_USE_BASE_POINT - Use Base Point - - - WRONG_ANGLES_NUMBER - The number of angles should correspond to the number of path nodes - - - - SMESHGUI_ExtrusionDlg - - EXTRUSION_1D - Extrusion of 1D elements - - - EXTRUSION_2D - Extrusion of 2D elements - - - EXTRUSION_ALONG_LINE - Extrusion along a line - - - - SMESHGUI_FilterDlg - - BAD_SHAPE_NAME - There is no "%1" geometrical object in the current study + + + REF_IS_NULL + No valid mesh object selected + + + + SMESHGUI_CreatePatternDlg + + CAPTION + Pattern Creation + + + DEFAULT_2D + Pattern_2d + + + DEFAULT_3D + Pattern_3d + + + ERROR_OF_CREATION + Internal error occurs during pattern creation +Please verify validity of entered information + + + ERROR_OF_SAVING + Internal error occurs during pattern saving. Please verify +\free disk space and your write permission to this file + + + ERR_LOADF_CANT_PROJECT + Impossible to perform projection of nodes to the face + + + ERR_LOADF_CLOSED_FACE + It is impossible to create pattern from face having seam edge + + + ERR_LOADF_NARROW_FACE + It is impossible to create pattern from narrow face + + + ERR_LOADV_BAD_SHAPE + Pattern can be created from closed shell or solid with 6 faces only + + + ERR_LOADV_COMPUTE_PARAMS + It is impossible to compute point parameters + + + ERR_LOAD_EMPTY_SUBMESH + There are no elements to create pattern + + + MESH_OR_SUBMESH + Mesh or SubMesh + + + PATTERN + Pattern + + + PATTERN_FILT + Pattern files(*.smp) + + + PATTERN_NAME + Pattern name + + + PATTERN_TYPE + Pattern type + + + PROJECT + Project nodes on the face + + + SAVE + Save... + + + SAVE_PATTERN + Save Pattern + + + + SMESHGUI_CreatePolyhedralVolumeDlg + + FACES_BY_NODES + Faces by nodes + + + SMESH_POLYEDRE_CREATE_ERROR + Polyhedron creation error. + + + SMESH_POLYEDRE_PREVIEW + Polyhedron preview + + + + SMESHGUI_CuttingOfQuadsDlg + + CAPTION + Cutting of quadrangles + + + + SMESHGUI_DeleteGroupDlg + + CAPTION + Delete groups with contents + + + NO_SELECTED_GROUPS + There are no selected groups +Please select a group and try again + + + SELECTED_GROUPS + Selected groups + + + + SMESHGUI_MergeDlg + + COINCIDENT_ELEMENTS + Coincident elements + + + COINCIDENT_NODES + Coincident nodes + + + DETECT + Detect + + + EDIT_SELECTED_GROUP + Edit selected group + + + SELECT_ALL + Select all + + + EXCLUDE_GROUPS + Exclude Groups + + + + SMESHGUI_ExtrusionAlongPathDlg + + BAD_SHAPE_TYPE + The shape selected for the path is not edge + + + CANT_GET_TANGENT + Can't get tangent for one of the path nodes + + + EXTRUSION_1D + Extrusion of 1D elements + + + EXTRUSION_2D + Extrusion of 2D elements + + + EXTRUSION_ALONG_PATH + Extrusion along a path + + + EXTR_BAD_STARTING_NODE + Wrong path starting node + + + LINEAR_ANGLES + Linear variation of the angles + + + NO_ELEMENTS_SELECTED + No mesh elements are selected for extrusion + + + SELECTED_PATH_IS_NOT_EDGE + Path mesh should be of edge type + + + SMESH_ANGLES + Rotation Angles + + + SMESH_BASE_POINT + Base Point + + + SMESH_PATH + Path + + + SMESH_PATH_MESH + Mesh or submesh + + + SMESH_PATH_SHAPE + Shape (edge) + + + SMESH_PATH_START + Start node + + + SMESH_USE_ANGLES + Use Angles + + + SMESH_USE_BASE_POINT + Use Base Point + + + WRONG_ANGLES_NUMBER + The number of angles should correspond to the number of path nodes + + + + SMESHGUI_ExtrusionDlg + + EXTRUSION_1D + Extrusion of 1D elements + + + EXTRUSION_2D + Extrusion of 2D elements + + + EXTRUSION_ALONG_LINE + Extrusion along a line + + + + SMESHGUI_FilterDlg + + BAD_SHAPE_NAME + There is no "%1" geometrical object in the current study Please select valid object and try again - - - CURRENT_DIALOG - Current Dialog - - - EDGES_TLT - Filter for Edges - - - FACES_TLT - Filter for Faces - - - MESH - Mesh - - - NODES_TLT - Filter for Nodes - - - SELECTION - Initial Selection - - - SET_IN_VIEWER - Insert filter in viewer - - - SHAPE_IS_NOT_A_CYLINDER - "%1" is not a cylinderical face + + + CURRENT_DIALOG + Current Group + + + EDGES_TLT + Filter for Edges + + + FACES_TLT + Filter for Faces + + + MESH + Mesh + + + NODES_TLT + Filter for Nodes + + + SELECTION + Initial Selection + + + SET_IN_VIEWER + Insert filter in viewer + + + SHAPE_IS_NOT_A_CYLINDER + "%1" is not a cylinderical face Please select a cylindrical face and try again - - - SHAPE_IS_NOT_A_FACE - "%1" is not a face + + + SHAPE_IS_NOT_A_FACE + "%1" is not a face Please select a face and try again - - - SHAPE_IS_NOT_A_PLANE - "%1" is not a plane + + + SHAPE_IS_NOT_A_PLANE + "%1" is not a plane Please select a plane and try again - - - SOURCE - Source - - - TLT - Selection filter - - - VOLUMES_TLT - Filter for Volumes - - - - SMESHGUI_FilterLibraryDlg - - ADD - Add - - - ADD_TO_TLT - Add selection filter to library - - - ALL_FILES_FILTER - All Files (*.*) - - - ASSIGN_NEW_NAME - Library already contains filter with name "%1" -New name "%2" is assigned to added filter - - - COPY_FROM_TLT - Copy selection filter from library - - - DELETE - Delete - - - EDGE - Edge - - - EDIT_LIB_TLT - Selection filter library - - - ELEMENT - Element - - - EMPTY_FILTER_NAME - Name of the filter is empty + + + FACE_ID_NOT_SELECTED + Mesh face is not selected +Please specify it and try again + + + NOT_FACE_ID + "%1" is not an ID of a mesh face. +Please select a face and try again + + + SOURCE + Source + + + TLT + Selection filter + + + VOLUMES_TLT + Filter for Volumes + + + + SMESHGUI_FilterLibraryDlg + + ADD + Add + + + ADD_TO_TLT + Add selection filter to library + + + ALL_FILES_FILTER + All Files (*.*) + + + ASSIGN_NEW_NAME + Library already contains filter with name "%1" +New name "%2" is assigned to added filter + + + COPY_FROM_TLT + Copy selection filter from library + + + DELETE + Delete + + + EDGE + Edge + + + EDIT_LIB_TLT + Selection filter library + + + ELEMENT + Element + + + EMPTY_FILTER_NAME + Name of the filter is empty Please enter a non-empty name - - - ERROR_FILTER_NAME - Name of the filter is not unique + + + ERROR_FILTER_NAME + Name of the filter is not unique Please enter other name - - - ERROR_LOAD - It is impossible to load library + + + ERROR_LOAD + It is impossible to load library Please check library file name and attributes - - - ERROR_OF_ADDING - Internal error occurs during adiing new filter in library. + + + ERROR_OF_ADDING + Internal error occurs during adiing new filter in library. Please verify validity of entered information - - - ERROR_OF_COPYING - Internal error occurs during copying filter from library. + + + ERROR_OF_COPYING + Internal error occurs during copying filter from library. Please verify validity of entered information - - - ERROR_OF_DELETING - Internal error occurs during deleting filter from library. + + + ERROR_OF_DELETING + Internal error occurs during deleting filter from library. Please verify validity of entered information - - - ERROR_OF_EDITING - Internal error occurs during editing filter library. + + + ERROR_OF_EDITING + Internal error occurs during editing filter library. Please verify validity of entered information - - - ERROR_OF_SAVING - Internal error occurs during saving filter library + + + ERROR_OF_SAVING + Internal error occurs during saving filter library Please check input data and try again - - - FACE - Face - - - FILTER - Filter - - - FILTER_NAME - Filter name - - - FILTER_NAMES - Names of filters - - - LIBRARY_FILE - Library file name - - - LIBRARY_IS_NOT_LOADED - Library is not loaded. Please load library and try again - - - LIB_NAME - FilterLib.xml - - - NODE - Node - - - NO_PERMISSION - You do not have write permission to this file - - - OPEN_LIBRARY - Open library - - - SELECTION - Selection - - - VOLUME - Volume - - - XML_FILT - XML files(*.xml) - - - - SMESHGUI_FilterTable - - ADD - Add - - - ADDITIONAL_PARAMETERS - Additional parameters - - - ADD_TO - Add to... - - - AND - And - - - AREA - Area - - - ASPECT_RATIO - Aspect ratio - - - ASPECT_RATIO_3D - Aspect ratio 3D - - - BAD_ORIENTED_VOLUME - Bad oriented volume - - - BELONG_TO_CYLINDER - Belong to Cylinder - - - BELONG_TO_GENSURFACE - Belong to Surface - - - BELONG_TO_GEOM - Belong to Geom - - - BELONG_TO_PLANE - Belong to Plane - - - BINARY - Binary - - - CLEAR - Clear - - - COMPARE - Compare - - - COPY_FROM - Copy from... - - - CRITERION - Criterion - - - EDGES - Edges - - - ENTITY_TYPE - Entity type - - - EQUAL_TO - Equal to - - - ERROR - Threshold value is not correctly specified + + + FACE + Face + + + FILTER + Filter + + + FILTER_NAME + Filter name + + + FILTER_NAMES + Names of filters + + + LIBRARY_FILE + Library file name + + + LIBRARY_IS_NOT_LOADED + Library is not loaded. Please load library and try again + + + LIB_NAME + FilterLib.xml + + + NODE + Node + + + NO_PERMISSION + You do not have write permission to this file + + + OPEN_LIBRARY + Open library + + + SELECTION + Selection + + + VOLUME + Volume + + + XML_FILT + XML files(*.xml) + + + + SMESHGUI_FilterTable + + ADD + Add + + + ADDITIONAL_PARAMETERS + Additional parameters + + + ADD_TO + Add to... + + + AND + And + + + AREA + Area + + + ASPECT_RATIO + Aspect ratio + + + ASPECT_RATIO_3D + Aspect ratio 3D + + + BAD_ORIENTED_VOLUME + Bad oriented volume + + + BELONG_TO_CYLINDER + Belong to Cylinder + + + BELONG_TO_GENSURFACE + Belong to Surface + + + BELONG_TO_GEOM + Belong to Geom + + + BELONG_TO_PLANE + Belong to Plane + + + BINARY + Binary + + + CLEAR + Clear + + + COMPARE + Compare + + + COPLANAR_FACES + Coplanar faces + + + COPY_FROM + Copy from... + + + CRITERION + Criterion + + + EDGES + Edges + + + ENTITY_TYPE + Entity type + + + EQUAL_TO + Equal to + + + ERROR + Threshold value is not correctly specified Please enter correct value and try again - - - FACES - Faces - - - FILTER - Filter - - - FREE_BORDERS - Free borders - - - FREE_EDGES - Free edges - - - FREE_NODES - Free nodes - - - - - FREE_FACES - Free faces - - - ID - ID - - - INSERT - Insert - - - LENGTH - Length - - - LENGTH2D - Length 2D - - - LESS_THAN - Less than - - - LYING_ON_GEOM - Lying on Geom - - - MINIMUM_ANGLE - Minimum angle - - - MORE_THAN - More than - - - MULTIEDGES_ERROR - Threshold value of borders at multi-connections can not be equal 1 + + + FACES + Faces + + + FILTER + Filter + + + FREE_BORDERS + Free borders + + + FREE_EDGES + Free edges + + + FREE_NODES + Free nodes + + + FREE_FACES + Free faces + + + ID + ID + + + INSERT + Insert + + + LENGTH + Length + + + LENGTH2D + Length 2D + + + LESS_THAN + Less than + + + LYING_ON_GEOM + Lying on Geom + + + MAX_ELEMENT_LENGTH_2D + Element Diameter 2D + + + MAX_ELEMENT_LENGTH_3D + Element Diameter 3D + + + MINIMUM_ANGLE + Minimum angle + + + MORE_THAN + More than + + + MULTIEDGES_ERROR + Threshold value of borders at multi-connections can not be equal 1 Please enter correct value and try again - - - GROUPCOLOR_ERROR - Color of group can not be undefied + + + GROUPCOLOR_ERROR + Color of group can not be undefied Please enter correct value and try again - - - MULTI_BORDERS - Borders at multi-connections - - - NODES - Nodes - - - NOT - Not - - - OR - Or - - - RANGE_OF_IDS - Range of IDs - - - REMOVE - Remove - - - SKEW - Skew - - - TAPER - Taper - - - THRESHOLD_VALUE - Threshold value - - - UNARY - Unary - - - VOLUMES - Volumes - - - VOLUME_3D - Volume - - - WARPING - Warping - - - LINEAR - Linear - - - GROUP_COLOR - Color of Group - - - ELEMENTS - Elements - - - GEOM_TYPE - Geometry type - - - GEOM_TYPE_0 - Point - - - GEOM_TYPE_1 - Edge - - - GEOM_TYPE_2 - Triangle - - - GEOM_TYPE_3 - Quadrangle - - - GEOM_TYPE_4 - Polygon - - - GEOM_TYPE_5 - Tetrahedron - - - GEOM_TYPE_6 - Pyramid - - - GEOM_TYPE_7 - Hexahedron - - - GEOM_TYPE_8 - Pentahedron - - - GEOM_TYPE_9 - Polyhedra - - - - SMESHGUI_GroupOpDlg - - ARGUMENTS - Arguments - - - DIFF_MESHES - Arguments of operation are not correctly specified + + + MULTI_BORDERS + Borders at multi-connections + + + NODES + Nodes + + + NOT + Not + + + OR + Or + + + RANGE_OF_IDS + Range of IDs + + + REMOVE + Remove + + + SKEW + Skew + + + TAPER + Taper + + + THRESHOLD_VALUE + Threshold value + + + UNARY + Unary + + + VOLUMES + Volumes + + + VOLUME_3D + Volume + + + WARPING + Warping + + + LINEAR + Linear + + + GROUP_COLOR + Color of Group + + + ELEMENTS + Elements + + + GEOM_TYPE + Geometry type + + + GEOM_TYPE_0 + Point + + + GEOM_TYPE_1 + Edge + + + GEOM_TYPE_2 + Triangle + + + GEOM_TYPE_3 + Quadrangle + + + GEOM_TYPE_4 + Polygon + + + GEOM_TYPE_5 + Tetrahedron + + + GEOM_TYPE_6 + Pyramid + + + GEOM_TYPE_7 + Hexahedron + + + GEOM_TYPE_8 + Pentahedron + + + GEOM_TYPE_9 + Polyhedra + + + + SMESHGUI_GroupOpDlg + + ARGUMENTS + Arguments + + + DIFF_MESHES + Arguments of operation are not correctly specified Groups correspond to a different meshes Please specify valid arguments and try again - - - DIFF_TYPES - Arguments of operation are not correctly specified + + + DIFF_TYPES + Arguments of operation are not correctly specified Groups contain elements of different types Please specify valid arguments and try again - - - EMPTY_NAME - Name of group to be created is not valid + + + EMPTY_NAME + Name of group to be created is not valid Please specify non-empty name and try again - - - INCORRECT_ARGUMENTS - Arguments of operation are not specified + + + INCORRECT_ARGUMENTS + Arguments of operation are not specified Please specify them and try again - - - NAME - Name - - - OBJECT_1 - Object 1 - - - OBJECT_2 - Object 2 - - - RESULT_NAME - Result name - - - TOOL_OBJECT - Tool object - - - UNION_OF_TWO_GROUPS - Union of two groups - - - - SMESHGUI_UnionGroupsDlg - - UNION_OF_GROUPS - Union of groups - - - - SMESHGUI_DimGroupDlg - - CREATE_GROUP_OF_UNDERLYING_ELEMS - Create group of underlying entities - + + + NAME + Name + + + OBJECT_1 + Object 1 + + + OBJECT_2 + Object 2 + + + RESULT_NAME + Result name + + + TOOL_OBJECT + Tool object + + + UNION_OF_TWO_GROUPS + Union of two groups + + + + SMESHGUI_GroupDlg + + SELECT_ALL + Select All + + + + SMESHGUI_UnionGroupsDlg + + UNION_OF_GROUPS + Union of groups + + + + SMESHGUI_DimGroupDlg + + CREATE_GROUP_OF_UNDERLYING_ELEMS + Create group of underlying entities + + + ELEMENTS_TYPE + Elements type + + + NODE + Node + + + EDGE + Edge + + + FACE + Face + + + VOLUME + Volume + + + + SMESHGUI_IntersectGroupsDlg + + INTERSECTION_OF_GROUPS + Intersection of groups + + + + SMESHGUI_CutGroupsDlg + + CUT_OF_GROUPS + Cut of groups + + + MAIN_OBJECT + Main object + + + TOOL_OBJECT + Tool object + + + + SMESHGUI_MakeNodeAtPointDlg + + AUTO_SEARCH + Find closest to destination + + + CAPTION + Move node + + + DESTINATION + Destination + + + MOVE_NODE + Move node + + + METHOD + Method + + + NODE_2MOVE + Node to move + + + NODE_2MOVE_ID + ID + + + + SMESHGUI_MakeNodeAtPointOp + + INVALID_ID + Node ID is invalid + + + INVALID_MESH + Mesh to modify not selected + + + + SMESHGUI_FindElemByPointDlg + + CAPTION + Find Element by Point + + + CREATE_NEW_METHOD + Create a node + + + MESH_PASS_THROUGH_POINT + Make a node at point + + + METHOD + Method + + + MOVE_EXISTING_METHOD + Move a node + + + NODE_2MOVE + Node to move + + + NODE_2MOVE_ID + ID + + + + SMESHGUI_MeshDlg + + CREATE_MESH + Create mesh + + + CREATE_SUBMESH + Create sub-mesh + + + DIM_0D + 0D + + + DIM_1D + 1D + + + DIM_2D + 2D + + + DIM_3D + 3D + + + EDIT_MESH_SUBMESH + Edit mesh/sub-mesh + + + GEOMETRY + Geometry + + + HYPOTHESES_SETS + Assign a set of hypotheses + + + MESH + Mesh + + + NAME + Name + + + + SMESHGUI_MeshOp + + ALGORITHM_WITHOUT_HYPOTHESIS + Algorithm is defined for %1 dimension but hypothesis is not defined + + + EDIT_SUBMESH_QUESTION + A submesh on the selected geometry already exists. + Do you want to edit this submesh? + + + SUBMESH_NOT_ALLOWED + No sense in creating a submesh ignored by global algorithm "%1" + + + GEOMETRY_OBJECT_IS_NOT_DEFINED + Geometry object is not defined +Please specify it and try again + + + GEOMETRY_OBJECT_IS_NULL + Geometry object is null + + + HYPOTHESES_AND_ALGORITHMS_ARE_NOT_DEFINED + Hypotheses and algorithms are not defined + + + HYPOTHESIS_WITHOUT_ALGORITHM + Hypothesis is defined for %1 dimension but algorithm is not defined + + + IMPORTED_MESH + Mesh is not built on geometry + + + INVALID_SUBSHAPE + Geometry object is not a subshape of the shape to mesh + + + MESH_IS_NOT_DEFINED + Mesh is not defined +Please specify it and try again + + + MESH_IS_NULL + Mesh is null + + + NAME_OF_MESH_IS_EMPTY + Name of mesh is empty +Please enter valid name and try again + + + NAME_OF_SUBMESH_IS_EMPTY + Name of submesh is empty +Please enter valid name and try again + + + THERE_IS_NO_OBJECT_FOR_EDITING + There is no object for editing. Please +select mesh or sub-mesh and try again + + + + SMESHGUI_MeshPatternDlg + + 3D_BLOCK + 3D block + + + CAPTION + Pattern Mapping + + + CREATE_POLYEDRS_NEAR_BOUNDARY + Create polyhedrons near boundary + + + CREATE_POLYGONS_NEAR_BOUNDARY + Create polygons near boundary + + + ERROR_OF_LOADING + Loading of pattern from file failed. Probably file +is corrupted or contains pattern of the other type + + + ERROR_OF_OPENING + It is impossible to open file. Please verify whether +file exists and your permission to this file + + + ERROR_OF_READING + It is impossible to load pattern +Please verify file's contents + + + ERR_READ_3D_COORD + It is impossible to load pattern +Coordinates of 3D points out of [0,1] range + + + ERR_READ_BAD_INDEX + It is impossible to load pattern +Invalid index of point detected + + + ERR_READ_BAD_KEY_POINT + It is impossible to load pattern +Key-point not on a boundary + + + ERR_READ_ELEM_POINTS + It is impossible to load pattern +invalid number of points in element + + + ERR_READ_NB_POINTS + It is impossible to load pattern +It is impossible to read number of points from file + + + ERR_READ_NO_ELEMS + It is impossible to load pattern +There are no elements in it + + + ERR_READ_NO_KEYPOINT + It is impossible to load pattern +There are no key-points in 2D one + + + ERR_READ_POINT_COORDS + It is impossible to load pattern +It is impossible to read point coordinates from file + + + ERR_READ_TOO_FEW_POINTS + It is impossible to load pattern. There are + too few points in the file for pattern loading + + + FACE + Face + + + LOAD_PATTERN + Load pattern + + + MESH_FACES + Mesh faces + + + MESH_VOLUMES + Mesh volumes + + + NEW + New... + + + NODE_1 + Node 1 + + + NODE_2 + Node 2 + + + PATTERN + Pattern + + + PATTERN_FILT + Pattern files(*.smp) + + + PATTERN_TYPE + Pattern type + + + PREVIEW + Preview + + + REFINE + Refine selected mesh elements + + + REVERSE + Reverse order of key-points + + + VERTEX + Vertex + + + VERTEX1 + Vertex 1 + + + VERTEX2 + Vertex 2 + + + + SMESHGUI_MeshTab + + ADD_HYPOTHESIS + Add. Hypothesis + + + ALGORITHM + Algorithm + + + HYPOTHESIS + Hypothesis + + + NONE + <None> + + + + SMESHGUI_MultiEditDlg + + ADD + Add + + + FILTER + Filter + + + REMOVE + Remove + + + SELECT_FROM + Select from + + + SORT_LIST + Sort list + + + SPLIT_JOIN_CRITERION + Criterion + + + TO_ALL + Apply to all + + + USE_DIAGONAL_1_3 + Use diagonal 1-3 + + + USE_DIAGONAL_2_4 + Use diagonal 2-4 + + + USE_NUMERIC_FUNC + Use numeric functor + + + + SMESHGUI_CuttingIntoTetraDlg + + CAPTION + Splitting volumes into tetrahedra + + + SPLIT_METHOD + Split hexahedron + + + SPLIT_HEX_TO_5_TETRA + Into 5 tetrahedra + + + SPLIT_HEX_TO_6_TETRA + Into 6 tetrahedra + + + SPLIT_HEX_TO_24_TETRA + Into 24 tetrahedra + + + + SMESHGUI_PrecisionDlg + + CAPTION + Precision for mesh quality controls + + + NOT_USE + Do not use + + + PRECISION + Number of digits after point + + + + SMESHGUI_RevolutionDlg + + ANGLE_BY_STEP + Angle by Step + + + PREVIEW + Preview + + + REVOLUTION_1D + Revolution of 1D elements + + + REVOLUTION_2D + Revolution of 2D elements + + + REVOLUTION_AROUND_AXIS + Revolution around an axis + + + TOTAL_ANGLE + Total Angle + + + MEN_POINT_SELECT + From Origin to selected Point + + + MEN_FACE_SELECT + Normal to selected Face + + + + SMESHGUI_SewingDlg + + BORDER + Border + + + BORDER_1 + Border 1 + + + BORDER_2 + Border 2 + + + CREATE_POLYEDRS_NEAR_BOUNDARY + Replace affected volumes by polyedres + + + CREATE_POLYGONS_INSTEAD_SPLITTING + Create polygons instead of splitting + + + ERROR_1 + Free Border1 not found by the selected nodes + + + ERROR_2 + Free Border2 not found by the selected nodes + + + ERROR_3 + Free Border1 and Border2 not found by the selected nodes + + + ERROR_4 + No path from the first side node to the last side node have been found + + + ERROR_5 + Not allowed to splite volumes on the side! + + + ERROR_6 + Different number of elements selected on the sides + + + ERROR_7 + Element sets are topologically different or given nodes are inconvenient + + + ERROR_8 + Nodes on the side 1 are either not linked or not laying on the element set boundary + + + ERROR_9 + Nodes on the side 2 are either not linked or not laying on the element set boundary + + + FIRST_NODE_ID + First Node ID + + + LAST_NODE_ID + Last Node ID + + + MERGE_EQUAL_ELEMENTS + Merge equal elements + + + NODE1_TO_MERGE + Node 1 To Merge + + + NODE2_TO_MERGE + Node 2 To Merge + + + SECOND_NODE_ID + Second Node ID + + + SEW_BORDER_TO_SIDE + Sew Border To Side + + + SEW_CONFORM_FREE_BORDERS + Sew Conform Free Borders + + + SEW_FREE_BORDERS + Sew Free Borders + + + SEW_SIDE_ELEMENTS + Sew Side Elements + + + SIDE + Side + + + SIDE_1 + Side 1 + + + SIDE_2 + Side 2 + + + + SMESHGUI_ShapeByMeshDlg + + CAPTION + Find geometry by mesh element + + + + SMESHGUI_SingleEditDlg + + EDGE_BETWEEN + Edge between neighboring triangles + + + + SMESHGUI_SmoothingDlg + + CENTROIDAL + Centroidal + + + FIXED_NODES_IDS + Fixed nodes ids + + + IS_PARAMETRIC + in parametric space + + + ITERATION_LIMIT + Iteration limit + + + LAPLACIAN + Laplacian + + + MAX_ASPECT_RATIO + Max. aspect ratio + + + METHOD + Method + + + + SMESHGUI_TrianglesInversionDlg + + CAPTION + Diagonal inversion + + + + SMESHGUI_UnionOfTrianglesDlg + + CAPTION + Union of triangles + + + MAXIMUM_ANGLE + Maximum bending angle + + + + SMESHGUI_UnionOfTwoTrianglesDlg + + CAPTION + Union of two triangles + + + + SMESHGUI_WhatIsDlg + + ENTITY_TYPE + Element type + + + GRAVITY_CENTER + Gravity center + + + CONNECTED_ELEMENTS + Connected With Elements + + + + SMESHGUI_FileInfoDlg + + CAPTION + File information + + + FILE_NAME + File name + + + FILE_SIZE + File size (bytes) + + + MED_VERSION + MED version + + + + SMESHGUI_GroupOnShapeDlg + + SMESH_CREATE_GROUP_FROM_GEOM + Create Groups from Geometry + + + + SMESHGUI_MeshOrderDlg + + SMESH_MESHORDER_TITLE + Order of submesh in meshing process + + + + SMESHGUI_MeshOrderOp + + SMESH_NO_CONCURENT_MESH + No concurent submeshes detected + + + + SMESHGUI_ClippingDlg + + CLIP_PLANES + Clipping planes + + + MESHES_SUBMESHES_GROUPS + Meshes, sub-meshes and groups + + + SELECT_ALL + Select all + + + ROTATION_AROUND_X_Y2Z + Rotation around X (Y to Z): + + + ROTATION_AROUND_Y_X2Z + Rotation around Y (X to Z): + + + ROTATION_AROUND_Z_Y2X + Rotation around Z (Y to X): + + + ROTATION_AROUND_X_Z2Y + Rotation around X (Z to Y): + + + ROTATION_AROUND_Y_Z2X + Rotation around Y (Z to X): + + + ROTATION_AROUND_Z_X2Y + Rotation around Z (X to Y): + + + SHOW_PREVIEW + Show preview + + + AUTO_APPLY + Auto Apply + + + ALONG_XY + || X-Y + + + ALONG_YZ + || Y-Z + + + ALONG_ZX + || Z-X + + + PLANE_NUM + Plane# %1 + + + NO_PLANES + No planes + + + + SMESHGUI_DuplicateNodesDlg + + DUPLICATION_MODE + Duplication mode + + + DUPLICATION_WITHOUT_ELEMS + Without duplication of border elements + + + GROUP_NODES_TO_DUPLICATE + Group of nodes to duplicate + + + GROUP_NODES_TO_REPLACE + Group of elements to replace nodes with new ones + + + DUPLICATION_WITH_ELEMS + With duplication of border elements + + + GROUP_ELEMS_TO_DUPLICATE + Group of elements to duplicate + + + GROUP_NODES_NOT_DUPLICATE + Group of nodes not to duplicate + + + GROUP_ELEMS_TO_REPLACE + Group of elements to replace nodes with new ones + + + CONSTRUCT_NEW_GROUP_NODES + Construct group with newly created nodes + + + CONSTRUCT_NEW_GROUP_ELEMENTS + Construct group with newly created elements + + + + SMESHGUI_Make2DFrom3DDlg + + CAPTION + Create boundary elements + + + MESH + Mesh, submesh or group + + + MODE + Mode + + + 2D_FROM_3D + 2D from 3D + + + 1D_FROM_3D + 1D from 3D + + + 1D_FROM_2D + 1D from 2D + + + TARGET + Target + + + THIS_MESH + This mesh + + + NEW_MESH + New mesh + + + COPY_SRC + Copy source mesh + + + MISSING_ONLY + Copy missing elements only + + + CREATE_GROUP + Create group + + + + SMESHGUI_Make2DFrom3DOp + + SMESH_ERR_NO_INPUT_MESH + Source mesh, sub-mesh or group is not specified + + + SMESH_ERR_NO_3D_ELEMENTS + The source object does not contain 3D elements + + + SMESH_ERR_NO_2D_ELEMENTS + The source object does not contain 2D elements + + + SMESH_ERR_MESH_NAME_NOT_SPECIFIED + New mesh name is not specified + + + SMESH_ERR_GRP_NAME_NOT_SPECIFIED + Group name is not specified + + + + SMESHGUI_MeshInfo + + NAME_LAB + Name: + + + OBJECT_LAB + Object: + + + NODES_LAB + Nodes: + + + ELEMENTS_LAB + Elements: + + + TOTAL_LAB + Total + + + LINEAR_LAB + Linear + + + QUADRATIC_LAB + Quadratic + + + 0D_LAB + 0D: + + + 1D_LAB + 1D (edges): + + + 2D_LAB + 2D (faces): + + + TRIANGLES_LAB + Triangles: + + + QUADRANGLES_LAB + Quadrandgles: + + + POLYGONS_LAB + Polygons: + + + 3D_LAB + 3D (volumes): + + + TETRAHEDRONS_LAB + Tetrahedrons: + + + HEXAHEDONRS_LAB + Hexahedrons: + + + PYRAMIDS_LAB + Pyramids: + + + PRISMS_LAB + Prisms: + + + POLYHEDRONS_LAB + Polyhedrons: + + + OBJECT_MESH + Mesh + + + OBJECT_SUBMESH + Sub-mesh + + + OBJECT_GROUP + Group + + + OBJECT_GROUP_NODES + Group of nodes + + + OBJECT_GROUP_EDGES + Group of edges + + + OBJECT_GROUP_FACES + Group of faces + + + OBJECT_GROUP_VOLUMES + Group of volumes + + + OBJECT_GROUP_0DELEMS + Group of 0D elements + + + + SMESHGUI_MeshInfoDlg + + MESH_INFO + Mesh Information + + + BASE_INFO + Base Info + + + ELEM_INFO + Element Info + + + NODE_MODE + Node + + + ELEM_MODE + Element + + + + SMESHGUI_ElemInfo + + COORDINATES + COORDINATES + + + CONNECTIVITY + CONNECTIVITY + + + GRAVITY_CENTER + GRAVITY CENTER + + + NODE + NODE + + + 0D_ELEMENT + 0D ELEMENT + + + 0D_ELEMENTS + 0D ELEMENTS + + + EDGE + EDGE + + + EDGES + EDGES + + + FACE + FACE + + + FACES + FACES + + + VOLUME + VOLUME + + + VOLUMES + VOLUMES + + + FREE_NODE + Free node (no connectivity) + + + TYPE + TYPE + + + TRIANGLE + Triangle + - ELEMENTS_TYPE - Elements type - + QUADRANGLE + Quadrangle + + + POLYGON + Polygon + + + TETRAHEDRON + Tetrahedron + + + HEXAHEDRON + Hexahedron + + + PYRAMID + Pyramid + + + PRISM + Prism + + + POLYHEDRON + Polyhedron + + + QUADRATIC + QUADRATIC + + + YES + Yes + + + NO + No + + + GRAVITY_CENTER + GRAVITY CENTER + + + PROPERTY + Property + + + VALUE + Value + + + + SMESHGUI_MinDistance + + FIRST_TARGET + First target + + + SECOND_TARGET + Second target + NODE Node - + - EDGE - Edge + ELEMENT + Element - FACE - Face + OBJECT + Object - VOLUME - Volume + ORIGIN + Origin - - - SMESHGUI_IntersectGroupsDlg - - INTERSECTION_OF_GROUPS - Intersection of groups - - - - SMESHGUI_CutGroupsDlg - - CUT_OF_GROUPS - Cut of groups - - - MAIN_OBJECT - Main object - - - TOOL_OBJECT - Tool object - - - - SMESHGUI_MakeNodeAtPointDlg - - AUTO_SEARCH - Automatic search - - - CAPTION - Mesh to pass through a point - - - CREATE_NEW_METHOD - Create a node - - - MESH_PASS_THROUGH_POINT - Make a node at point - - - METHOD - Method - - - MOVE_EXISTING_METHOD - Move a node - - - NODE_2MOVE - Node to move - - - NODE_2MOVE_ID - ID - - - - SMESHGUI_MakeNodeAtPointOp - - INVALID_ID - Node ID is invalid - - - INVALID_MESH - Mesh to modify not selected - - - - SMESHGUI_FindElemByPointDlg - - CAPTION - Find Element by Point - - - CREATE_NEW_METHOD - Create a node - - - MESH_PASS_THROUGH_POINT - Make a node at point - - - METHOD - Method - - - MOVE_EXISTING_METHOD - Move a node - - - NODE_2MOVE - Node to move - - - NODE_2MOVE_ID - ID - - - - SMESHGUI_MeshDlg - - CREATE_MESH - Create mesh - - - CREATE_SUBMESH - Create sub-mesh - - - DIM_0D - 0D - - - DIM_1D - 1D - - - DIM_2D - 2D - - - DIM_3D - 3D - - - EDIT_MESH_SUBMESH - Edit mesh/sub-mesh - - - GEOMETRY - Geometry - - - HYPOTHESES_SETS - Assign a set of hypotheses - - - MESH - Mesh - - - NAME - Name - - - - SMESHGUI_MeshOp - - ALGORITHM_WITHOUT_HYPOTHESIS - Algorithm is defined for %1 dimension but hypothesis is not defined - - - EDIT_SUBMESH_QUESTION - A submesh on the selected geometry already exists. - Do you want to edit this submesh? - - - SUBMESH_NOT_ALLOWED - No sense in creating a submesh ignored by global algorithm "%1" - - - GEOMETRY_OBJECT_IS_NOT_DEFINED - Geometry object is not defined -Please specify it and try again - - - GEOMETRY_OBJECT_IS_NULL - Geometry object is null - - - HYPOTHESES_AND_ALGORITHMS_ARE_NOT_DEFINED - Hypotheses and algorithms are not defined - - - HYPOTHESIS_WITHOUT_ALGORITHM - Hypothesis is defined for %1 dimension but algorithm is not defined - - - IMPORTED_MESH - Mesh is not built on geometry - - - INVALID_SUBSHAPE - Geometry object is not a subshape of the shape to mesh - - - MESH_IS_NOT_DEFINED - Mesh is not defined -Please specify it and try again - - - MESH_IS_NULL - Mesh is null - - - NAME_OF_MESH_IS_EMPTY - Name of mesh is empty -Please enter valid name and try again - - - NAME_OF_SUBMESH_IS_EMPTY - Name of submesh is empty -Please enter valid name and try again - - - THERE_IS_NO_OBJECT_FOR_EDITING - There is no object for editing. Please -select mesh or sub-mesh and try again - - - - SMESHGUI_MeshPatternDlg - - 3D_BLOCK - 3D block - - - CAPTION - Pattern Mapping - - - CREATE_POLYEDRS_NEAR_BOUNDARY - Create polyhedrons near boundary - - - CREATE_POLYGONS_NEAR_BOUNDARY - Create polygons near boundary - - - ERROR_OF_LOADING - Loading of pattern from file failed. Probably file -is corrupted or contains pattern of the other type - - - ERROR_OF_OPENING - It is impossible to open file. Please verify whether -file exists and your permission to this file - - - ERROR_OF_READING - It is impossible to load pattern -Please verify file's contents - - - ERR_READ_3D_COORD - It is impossible to load pattern -Coordinates of 3D points out of [0,1] range - - - ERR_READ_BAD_INDEX - It is impossible to load pattern -Invalid index of point detected - - - ERR_READ_BAD_KEY_POINT - It is impossible to load pattern -Key-point not on a boundary - - - ERR_READ_ELEM_POINTS - It is impossible to load pattern -invalid number of points in element - - - ERR_READ_NB_POINTS - It is impossible to load pattern -It is impossible to read number of points from file - - - ERR_READ_NO_ELEMS - It is impossible to load pattern -There are no elements in it - - - ERR_READ_NO_KEYPOINT - It is impossible to load pattern -There are no key-points in 2D one - - - ERR_READ_POINT_COORDS - It is impossible to load pattern -It is impossible to read point coordinates from file - - - ERR_READ_TOO_FEW_POINTS - It is impossible to load pattern. There are - too few points in the file for pattern loading - - - FACE - Face - - - LOAD_PATTERN - Load pattern - - - MESH_FACES - Mesh faces - - - MESH_VOLUMES - Mesh volumes - - - NEW - New... - - - NODE_1 - Node 1 - - - NODE_2 - Node 2 - - - PATTERN - Pattern - - - PATTERN_FILT - Pattern files(*.smp) - - - PATTERN_TYPE - Pattern type - - - PREVIEW - Preview - - - REFINE - Refine selected mesh elements - - - REVERSE - Reverse order of key-points - - - VERTEX - Vertex - - - VERTEX1 - Vertex 1 - - - VERTEX2 - Vertex 2 - - - - SMESHGUI_MeshTab - - ADD_HYPOTHESIS - Add. Hypothesis - - - ALGORITHM - Algorithm - - - HYPOTHESIS - Hypothesis - - - NONE - <None> - - - - SMESHGUI_MoveNodesDlg - - CAPTION - Move node - - - NODE_ID_IS_NOT_DEFINED - Node ID is not defined - - - - SMESHGUI_MultiEditDlg - - ADD - Add - - - FILTER - Filter - - - REMOVE - Remove - - - SELECT_FROM - Select from - - - SORT_LIST - Sort list - - - SPLIT_JOIN_CRITERION - Criterion - - - TO_ALL - Apply to all - - - USE_DIAGONAL_1_3 - Use diagonal 1-3 - - - USE_DIAGONAL_2_4 - Use diagonal 2-4 - - - USE_NUMERIC_FUNC - Use numeric functor - - - - SMESHGUI_CuttingIntoTetraDlg - - CAPTION - Splitting volumes into tetrahedra - - - SPLIT_METHOD - Split hexahedron - - - SPLIT_HEX_TO_5_TETRA - Into 5 tetrahedra - - - SPLIT_HEX_TO_6_TETRA - Into 6 tetrahedra - - - - SMESHGUI_PrecisionDlg - - CAPTION - Precision for mesh quality controls - - - NOT_USE - Do not use - - - PRECISION - Number of digits after point - - - - SMESHGUI_RevolutionDlg - - ANGLE_BY_STEP - Angle by Step - - - PREVIEW - Preview - - - REVOLUTION_1D - Revolution of 1D elements - - - REVOLUTION_2D - Revolution of 2D elements - - - REVOLUTION_AROUND_AXIS - Revolution around an axis - - - TOTAL_ANGLE - Total Angle - - - MEN_POINT_SELECT - From Origin to selected Point - - - MEN_FACE_SELECT - Normal to selected Face - - - - SMESHGUI_SewingDlg - - BORDER - Border - - - BORDER_1 - Border 1 - - - BORDER_2 - Border 2 - - - CREATE_POLYEDRS_NEAR_BOUNDARY - Replace affected volumes by polyedres - - - CREATE_POLYGONS_INSTEAD_SPLITTING - Create polygons instead of splitting - - - ERROR_1 - Free Border1 not found by the selected nodes - - - ERROR_2 - Free Border2 not found by the selected nodes - - - ERROR_3 - Free Border1 and Border2 not found by the selected nodes - - - ERROR_4 - No path from the first side node to the last side node have been found - - - ERROR_5 - Not allowed to splite volumes on the side! - - - ERROR_6 - Different number of elements selected on the sides - - - ERROR_7 - Element sets are topologically different or given nodes are inconvenient - - - ERROR_8 - Nodes on the side 1 are either not linked or not laying on the element set boundary - - - ERROR_9 - Nodes on the side 2 are either not linked or not laying on the element set boundary - - - FIRST_NODE_ID - First Node ID - - - LAST_NODE_ID - Last Node ID - - - MERGE_EQUAL_ELEMENTS - Merge equal elements - - - - NODE1_TO_MERGE - Node 1 To Merge - - - NODE2_TO_MERGE - Node 2 To Merge - - - SECOND_NODE_ID - Second Node ID - - - SEW_BORDER_TO_SIDE - Sew Border To Side - - - SEW_CONFORM_FREE_BORDERS - Sew Conform Free Borders - - - SEW_FREE_BORDERS - Sew Free Borders - - - SEW_SIDE_ELEMENTS - Sew Side Elements - - - SIDE - Side - - - SIDE_1 - Side 1 - - - SIDE_2 - Side 2 - - - - SMESHGUI_ShapeByMeshDlg - - CAPTION - Find geometry by mesh element - - - - SMESHGUI_SingleEditDlg - - EDGE_BETWEEN - Edge between neighboring triangles - - - - SMESHGUI_SmoothingDlg - - CENTROIDAL - Centroidal - - - FIXED_NODES_IDS - Fixed nodes ids - - - IS_PARAMETRIC - in parametric space - - - ITERATION_LIMIT - Iteration limit - - - LAPLACIAN - Laplacian - - - MAX_ASPECT_RATIO - Max. aspect ratio - - - METHOD - Method - - - - SMESHGUI_TrianglesInversionDlg - - CAPTION - Diagonal inversion - - - - SMESHGUI_UnionOfTrianglesDlg - - CAPTION - Union of triangles - - - MAXIMUM_ANGLE - Maximum bending angle - - - - SMESHGUI_UnionOfTwoTrianglesDlg - - CAPTION - Union of two triangles - - - - SMESHGUI_WhatIsDlg - - ENTITY_TYPE - Element type - - - GRAVITY_CENTER - Gravity center - - - CONNECTED_ELEMENTS - Connected With Elements - - - - SMESHGUI_FileInfoDlg - - CAPTION - File information - - - FILE_NAME - File name - - - FILE_SIZE - File size (bytes) - - - MED_VERSION - MED version - - - - SMESHGUI_GroupOnShapeDlg - - SMESH_CREATE_GROUP_FROM_GEOM - Create Groups from Geometry - - - - SMESHGUI_MeshOrderDlg - - SMESH_MESHORDER_TITLE - Order of submesh in meshing process - - - - SMESHGUI_MeshOrderOp - - SMESH_NO_CONCURENT_MESH - No concurent submeshes detected - - - - SMESHGUI_ClippingDlg - - CLIP_PLANES - Clipping planes - - - ROTATION_AROUND_X_Y2Z - Rotation around X (Y to Z): - - - ROTATION_AROUND_Y_X2Z - Rotation around Y (X to Z): - - - ROTATION_AROUND_Z_Y2X - Rotation around Z (Y to X): - - - ROTATION_AROUND_X_Z2Y - Rotation around X (Z to Y): - - - ROTATION_AROUND_Y_Z2X - Rotation around Y (Z to X): - - - ROTATION_AROUND_Z_X2Y - Rotation around Z (X to Y): - - - SHOW_PREVIEW - Show preview - - - AUTO_APPLY - Auto Apply - - - ALONG_XY - || X-Y - - - ALONG_YZ - || Y-Z - - - ALONG_ZX - || Z-X - - - PLANE_NUM - Plane# %1 - - - NO_PLANES - No planes - - + + COMPUTE + Compute + + + RESULT + Distance between targets + + + DISTANCE + Distance + + + + SMESHGUI_MeasureDlg + + MEASUREMENTS + Measurements + + + MIN_DIST + Minimum Distance + + + BND_BOX + Bounding Box + + + + SMESHGUI_BoundingBox + + SOURCE + Source + + + OBJECTS + Objects + + + NODES + Nodes + + + ELEMENTS + Elements + + + COMPUTE + Compute + + + RESULT + Bounding Box + + + SELECTED_NB_OBJ + %1 %2 selected + + + NB_NODES + nodes + + + NB_ELEMENTS + elements + + diff --git a/src/SMESHGUI/SMESH_msg_fr.ts b/src/SMESHGUI/SMESH_msg_fr.ts new file mode 100755 index 000000000..955e9396b --- /dev/null +++ b/src/SMESHGUI/SMESH_msg_fr.ts @@ -0,0 +1,5346 @@ + + + + + @default + + AREA_ELEMENTS + Aire + + + ASPECTRATIO_3D_ELEMENTS + Rapport de forme 3D + + + ASPECTRATIO_ELEMENTS + Rapport de forme + + + COL_ALGO_HEADER + Algorithme + + + COL_ERROR_HEADER + Erreur + + + COL_SHAPE_HEADER + SousObjet + + + COMPERR_ALGO_FAILED + L'algorithme n'a pas abouti + + + COMPERR_BAD_INPUT_MESH + Le maillage d'entrée est invalide + + + COMPERR_BAD_SHAPE + Géométrie inattendue + + + COMPERR_EXCEPTION + Exception inconnue + + + COMPERR_MEMORY_PB + Problème d'affectation de la mémoire + + + COMPERR_OCC_EXCEPTION + Exception OCC + + + COMPERR_OK + Pas d'erreur + + + COMPERR_SLM_EXCEPTION + Exception SALOME + + + COMPERR_STD_EXCEPTION + std::exception + + + SMESH_GEOM + Géométrie + + + DIRECT_GEOM_SELECTION + Sélection directe de la géométrie + + + ELEMENT_ID + ID de l'élément + + + FREE_BORDERS + Frontières libres + + + GEOMETRY_NAME + Nom de la géométrie + + + GEOM_BY_MESH_ELEM_SELECTION + Trouver la géométrie en choisissant l'élément de maillage + + + GLOBAL_ALGO + Global + + + INF_SELECT_OBJECT + Choisir un objet + + + LENGTH2D_EDGES + Longueur 2D + + + LENGTH_EDGES + Longueur + + + LOCAL_ALGO + Local + + + MEN_ADD + Ajouter + + + MEN_ADV_INFO + Informations avancées du maillage + + + MEN_ALL + Tous + + + MEN_AREA + Aire + + + MEN_ASPECT + Rapport de forme + + + MEN_ASPECT_3D + Rapport de forme 3D + + + MEN_AUTO_COLOR + Couleur automatique + + + MEN_AUTO_UPD + Mise à jour automatique + + + MEN_BUILD_COMPOUND + Construire un assemblage + + + MEN_CLIP + Plan de coupe + + + MEN_COLORS + Couleurs / Taille + + + MEN_COMPUTE + Calculer + + + MEN_PRECOMPUTE + Prévisualiser + + + MEN_EVALUATE + Evaluer + + + MEN_CONNECTION + Frontières sur connections multiples + + + MEN_CONNECTION_2D + Frontières sur connections multiples 2D + + + MEN_CONSTRUCT_GROUP + Construire un groupe + + + MEN_CONV_TO_QUAD + Convertir vers/de quadratique + + + MEN_2D_FROM_3D + Créer les éléments de frontière + + + MEN_MESH_ORDER + Changer la priorité des sous-maillages + + + MEN_CREATE_GROUP + Créer un groupe + + + MEN_CREATE_GEO_GROUP + Créer les groupes à partir de la géométrie + + + MEN_CREATE_MESH + Créer un maillage + + + MEN_CREATE_SUBMESH + Créer un sous-maillage + + + MEN_CTRL + Contrôles + + + MEN_CUT + Découpe des quadrangles + + + MEN_CUT_GROUP + Découpe des groupes + + + MEN_DAT + Fichier DAT + + + MEN_DELETE + Supprimer + + + MEN_DEL_GROUP + Supprimer les groupes + + + MEN_FACE_ORIENTATION + Orientation des faces + + + MEN_DISABLE_AUTO_COLOR + Désactiver la couleur automatique + + + MEN_DISPLAY_ONLY + Afficher uniquement + + + MEN_DISPMODE + Mode de visualisation + + + MEN_DISP_ENT + Montrer l'entité + + + MEN_ELEM0D + Elément 0D + + + MEN_ELEMS0D + Eléments 0D + + + MEN_EDGE + Arête + + + MEN_EDGES + Arêtes + + + MEN_EDIT + Edition + + + MEN_EDIT_GROUP + Editer un groupe + + + MEN_EDIT_GEOMGROUP_AS_GROUP + Editer un groupe en tant qu'autonome + + + MEN_EDIT_HYPO + Editer une hypothèse + + + MEN_EDIT_MESHSUBMESH + Editer un maillage/sous-maillage + + + MEN_EXPORT + Exporter + + + MEN_EXPORT_DAT + Exporter au format DAT + + + MEN_EXPORT_MED + Exporter au format MED + + + MEN_EXPORT_SAUV + Exporter au format SAUV (ASCII) + + + MEN_EXPORT_STL + Exporter au format STL + + + MEN_EXPORT_UNV + Exporter au format UNV + + + MEN_EXTRUSION + Extrusion + + + MEN_EXTRUSION_ALONG + Extrusion suivant un chemin + + + MEN_FACES + Faces + + + MEN_FILE + Fichier + + + MEN_FIND_ELEM + Trouver un élément par un point + + + TOP_FIND_ELEM + Trouver un élément par un point + + + STB_FIND_ELEM + Trouver un élément par un point + + + MEN_FREE_BORDER + Frontières libres + + + MEN_FREE_EDGE + Arêtes libres + + + MEN_FREE_NODE + Nœuds libres + + + MEN_FREE_FACES + Faces libres + + + MEN_GLOBAL_HYPO + Hypothèse globale + + + MEN_HEXA + Hexaèdre + + + MEN_HIDE + Cacher + + + MEN_HYPO + Hypothèses + + + MEN_IMPORT + Importer + + + MEN_INT_GROUP + Intersection des groupes + + + MEN_INV + Inversion de diagonale + + + MEN_LENGTH + Longueur + + + MEN_LENGTH_2D + Longueur 2D + + + MEN_MAP + Projection de motif + + + MEN_MED + Fichier MED + + + MEN_SAUV + Fichier SAUV (ASCII) + + + MEN_MERGE + Fusionner les nœuds + + + MEN_MERGE_ELEMENTS + Fusionner les éléments + + + MEN_MESH + Maillage + + + MEN_MESH_THROU_POINT + Déplacer un nœud + + + MEN_MIN_ANG + Angle minimal + + + MEN_MODIFY + Modification + + + MEN_MOVE + Déplacer un nœud + + + MEN_NODE + Nœud + + + MEN_NODES + Nœuds + + + MEN_NUM + Numérotation + + + MEN_NUM_ELEMENTS + Montrer les n° des éléments + + + MEN_NUM_NODES + Montrer les n° des nœuds + + + MEN_ORIENT + Orientation + + + MEN_POLYGON + Polygone + + + MEN_POLYHEDRON + Polyèdre + + + MEN_PRECISION + Précision + + + MEN_PREF + Préférences + + + MEN_QUAD + Quadrangle + + + MEN_QUADRATIC_EDGE + Arête quadratique + + + MEN_QUADRATIC_HEXAHEDRON + Hexaèdre quadratique + + + MEN_QUADRATIC_PENTAHEDRON + Pentaèdre quadratique + + + MEN_QUADRATIC_PYRAMID + Pyramide quadratique + + + MEN_QUADRATIC_QUADRANGLE + Quadrangle quadratique + + + MEN_QUADRATIC_TETRAHEDRON + Tetraèdre quadratique + + + MEN_QUADRATIC_TRIANGLE + Triangle quadratique + + + MEN_QUALITY + Contrôles de qualité + + + MEN_REMOVE + Supprimer + + + MEN_REMOVE_ELEMENTS + Eléments + + + MEN_REMOVE_NODES + Nœuds + + + MEN_REMOVE_ORPHAN_NODES + Nœuds orphelins + + + MEN_RENAME + Renommer + + + MEN_RENUM + Renuméroter + + + MEN_RENUM_ELEMENTS + Eléments + + + MEN_RENUM_NODES + Nœuds + + + MEN_RESET + Restaurer + + + MEN_REVOLUTION + Révolution + + + MEN_ROT + Rotation + + + MEN_SCALAR_BAR + Barre scalaire + + + MEN_SCALAR_BAR_PROP + Propriétés de la barre scalaire + + + MEN_SELECTION + Sélection + + + MEN_SEL_FILTER_LIB + Librairie des filtres de sélection + + + MEN_SEW + Couture + + + MEN_SHADE + Ombrage + + + MEN_QUADRATIC_REPRESENT + Quadratique 2D + + + MEN_LINE_REPRESENTATION + Lignes + + + MEN_ARC_REPRESENTATION + Arcs + + + MEN_SHOW + Visualiser + + + MEN_SHRINK + Contraction + + + MEN_SKEW + Inclinaison d'angle + + + MEN_SMOOTH + Lissage + + + MEN_STD_INFO + Informations du maillage + + + MEN_STL + Fichier STL + + + MEN_SYM + Symétrie + + + MEN_TAPER + Cône + + + MEN_TETRA + Tétraèdre + + + MEN_TOOLS + Outils + + + MEN_TRANS + Translation + + + MEN_SCALE + Transformation d'échelle + + + MEN_DUPLICATE_NODES + Dupliquer les nœuds + + + MEN_TRANSF + Transformation + + + MEN_TRANSP + Transparence + + + MEN_TRIANGLE + Triangle + + + MEN_UNASSIGN + Désassocier + + + MEN_UNION + Union des triangles + + + MEN_UNION2 + Union de deux triangles + + + MEN_UNV + Fichier UNV + + + MEN_UN_GROUP + Union des groupes + + + MEN_UNDERLYING_ELEMS + Groupe des entités sous-jacentes + + + MEN_UPDATE + Mettre à jour + + + MEN_VIEW + Affichage + + + MEN_VOLUMES + Volumes + + + MEN_VOLUME_3D + Volume + + + MEN_WARP + Angle de déformation + + + MEN_WHAT_IS + Information sur un élément de maillage + + + MEN_WIRE + Contours + + + MEN_SPLIT_TO_TETRA + Explosion en tétraèdres + + + TOP_SPLIT_TO_TETRA + Eclater en tétraèdres + + + STB_SPLIT_TO_TETRA + Eclater en tétraèdres + + + MESHERS_FILE_CANT_OPEN + Impossible d'ouvrir le fichier de ressource + + + MESHERS_FILE_CHECK_VARIABLE + Vérifier la variable d'environnement SMESH_MeshersList + + + MESHERS_FILE_NO_VARIABLE + La variable d'environnement SMESH_MeshersList n'est pas définie + + + MESH_IS_NOT_SELECTED + Il n'y a pas de maillage sélectionné. +Choisissez un maillage et essayez de nouveau + + + MESH_NODE + Nœud + + + MESH_NODE_TITLE + Ajouter un nœud + + + MINIMUMANGLE_ELEMENTS + Angle minimal + + + MULTI2D_BORDERS + Frontières sur multi-connections 2D + + + MULTI_BORDERS + Frontières sur multi-connections + + + GROUP_NAME_IS_EMPTY + Le nom du groupe n'est pas indiqué. +Indiquez le nom d'un nouveau groupe à créer ou choisissez un groupe existant. + + + MESH_STANDALONE_GRP_CHOSEN + Un groupe lié à la géométrie est choisi: %1. +Voulez-vous le convertir en un groupe autonome ? + + + NODE_ID + ID du nœud + + + NON_SMESH_OBJECTS_SELECTED + Certains objets sélectionnés n'appartiennent pas au composant %1. + + + PREVIEW + Prévisualiser + + + SKEW_ELEMENTS + Inclinaison d'angle + + + SMESHGUI_INVALID_PARAMETERS + Les paramètres spécifiés ne sont pas corrects. +Merci de les corriger, puis essayez de nouveau + + + SMESH_ADD_ALGORITHM + Algorithmes + + + SMESH_ADD_ALGORITHM_TITLE + Attribution des algorithmes + + + SMESH_ADD_ELEM0D + Ajouter un élément 0D + + + SMESH_ADD_ELEM0D_TITLE + Ajouter un élément 0D + + + SMESH_ADD_EDGE + Ajouter une arête + + + SMESH_ADD_EDGE_TITLE + Ajouter une arête + + + SMESH_ADD_HEXAS + Ajouter un hexaèdre + + + SMESH_ADD_HEXAS_TITLE + Ajouter un hexahèdre + + + SMESH_ADD_HYPOTHESIS + Hypothèse + + + SMESH_ADD_HYPOTHESIS_TITLE + Attrbution d'une hypothèse + + + SMESH_ADD_HYP_WRN + "%1" est attribué, mais: + + + + SMESH_ADD_POLYGON + Ajouter un polygone + + + SMESH_ADD_POLYGON_TITLE + Ajouter un polygone + + + SMESH_ADD_QUADRANGLE + Ajouter un quadrangle + + + SMESH_ADD_QUADRANGLE_TITLE + Ajouter un quadrangle + + + SMESH_ADD_QUADRATIC_EDGE_TITLE + Ajouter une arête quadratique + + + SMESH_ADD_QUADRATIC_HEXAHEDRON_TITLE + Ajouter un hexaèdre quadratique + + + SMESH_ADD_QUADRATIC_PENTAHEDRON_TITLE + Ajouter un pentaèdre quadratique + + + SMESH_ADD_QUADRATIC_PYRAMID_TITLE + Ajouter une pyramide quadratique + + + SMESH_ADD_QUADRATIC_QUADRANGLE_TITLE + Ajouter un quadrangle quadratique + + + SMESH_ADD_QUADRATIC_TETRAHEDRON_TITLE + Ajouter un tétraèdre quadratique + + + SMESH_ADD_QUADRATIC_TRIANGLE_TITLE + Ajouter un triangle quadratique + + + SMESH_ADD_SUBMESH + Construction d'un sous-maillage + + + SMESH_ADD_TETRAS + Ajouter un tétraèdre + + + SMESH_ADD_TETRAS_TITLE + Ajouter un tétraèdre + + + SMESH_ADD_TO_GROUP + Ajouter à un groupe + + + SMESH_ADD_TRIANGLE + Ajouter un triangle + + + SMESH_ADD_TRIANGLE_TITLE + Ajouter un triangle + + + SMESH_ANGLE + Angle + + + SMESH_ARGUMENTS + Arguments + + + SMESH_AUTO_GROUPS + Créer les groupes automatiquement + + + SMESH_AVAILABLE + Disponible + + + SMESH_AVAILABLE_ALGORITHMS + Algorithmes disponibles + + + SMESH_AVAILABLE_HYPOTHESES + Hypothèses disponibles + + + SMESH_AXIS + Axe + + + SMESH_BAD_SELECTION + Pas de sélection valide + + + SMESH_BAD_MESH_SELECTION + La sélection du maillage n'est pas valide + + + SMESH_BOUNDARYEDGES + Arêtes frontières + + + SMESH_BUILD_COMPOUND_TITLE + Créer un assemblage + + + SMESH_BUT_ADD + A&jouter + + + SMESH_BUT_APPLY + A&ppliquer + + + SMESH_BUT_CANCEL + A&nnuler + + + SMESH_BUT_CLOSE + &Fermer + + + SMESH_BUT_CREATE + &Créer + + + SMESH_BUT_DELETE + Eff&acer + + + SMESH_BUT_FILTER + Définir les fil&tres + + + SMESH_BUT_HELP + Ai&de + + + SMESH_BUT_NEW + Nou&veau + + + SMESH_BUT_NO + &Non + + + SMESH_BUT_OK + &Ok + + + SMESH_BUT_OVERWRITE + Réécr&ire + + + SMESH_BUT_APPLY_AND_CLOSE + App&liquer et fermer + + + SMESH_BUT_REMOVE + S&upprimer + + + SMESH_BUT_SORT + &Trier la liste + + + SMESH_BUT_YES + &Oui + + + SMESH_CANT_ADD_HYP + Impossible d'attribuer "%1": + + + + SMESH_CANT_RM_HYP + Impossible de désassigner "%1": + + + + SMESH_CHECK_COLOR + Couleur + + + SMESH_CLIPPING_FROM + De <--- + + + SMESH_CLIPPING_INTO + ---> En + + + SMESH_CLIPPING_TITLE + Changer le plan de coupe + + + SMESH_COMPUTE_SUCCEED + Le calcul du maillage a réussi + + + SMESH_EVALUATE_SUCCEED + L'évaluation du maillage a réussi + + + SMESH_CONTENT + Contenu + + + SMESH_CONTINUE_MESH_VISUALIZATION + La système semble manquer de mémoire pour visualiser le maillage, +ce qui peut faire planter l'application. Voulez-vous continuer la visualisation ? + + + SMESH_COORDINATES + Coordonnées + + + SMESH_COPY_ELEMENTS + Copier les éléments + + + SMESH_COPY_GROUPS + Copier les groupes + + + SMESH_CREATE_ALGORITHMS + Créer les algorithmes + + + SMESH_CREATE_COPY + Créer une copie + + + SMESH_CREATE_GROUP_TITLE + Créer un groupe + + + SMESH_CREATE_GEO_GROUP + Créer les groupes liés à la géométrie + + + SMESH_CREATE_HYPOTHESES + Créer une hypothèse + + + SMESH_CREATE_MESH + Créer un nouveau maillage + + + SMESH_CREATE_POLYHEDRAL_VOLUME_TITLE + Créer un volume polyèdrique + + + SMESH_DIAGONAL + Inversion de diagonale + + + SMESH_DIAGONAL_INVERSION_TITLE + Inversion de diagonale + + + SMESH_DISTANCE + Distance + + + SMESH_DRS_1 + Le fichier MED contient pas de maillage avec ce nom + + + SMESH_DRS_2 + Le fichier MED contient des rangées de nombre d'éléments superposées, donc les nombres de ce fichier ne sont pas pris en compte + + + SMESH_DRS_3 + Quelques éléments ont été omis à cause du fichier de données incorrect + + + SMESH_DRS_4 + Le fichier n'est pas correct, des données sont manquantes + + + SMESH_DRS_EMPTY + Le fichier est vide, il n'y a rien à publier + + + SMESH_DX + dX + + + SMESH_DY + dY + + + SMESH_DZ + dZ + + + SMESH_ELEM0D + Elément 0D + + + SMESH_EDGE + Arête + + + SMESH_EDGES_CONNECTIVITY_TITLE + Connectivité des arêtes + + + SMESH_EDIT_GROUP_TITLE + Editer un groupe + + + SMESH_EDIT_GEOMGROUP_AS_GROUP_TITLE + Editer un groupe en tant qu'autonome + + + SMESH_EDIT_HYPOTHESES + Attribuer les hypothèses + + + SMESH_EDIT_USED + Utilisé + + + SMESH_ELEMENTS + Eléments + + + SMESH_ELEMENTS_COLOR + Couleur des éléments du maillage + + + SMESH_ELEMENTS_TYPE + Type des éléments + + + SMESH_ELEMENT_TYPE + Type de l'élément + + + SMESH_ERROR + Erreur + + + SMESH_ERR_SCALARBAR_PARAMS + Avertissement! Les paramètres ne sont pas corrects + + + SMESH_EXPORT_FAILED + Impossible d'exporter le maillage. +Vérifiez l'espace disponible sur le disque. + + + SMESH_EXPORT_MED_DUPLICATED_GRP + Il y a des noms de groupes dupliqués dans le maillage "%1". +Vous pouvez annuler l'exportation et les renommer, +si non des noms de groupes au fichier MED résultant +ne correspondront pas aux noms de l'étude. +Voulez-vous continuer ? + + + SMESH_EXPORT_MED_DUPLICATED_MESH_NAMES + Il y a des maillages avec les mêmes noms dans la sélection. +Il est possible que le fichier résultant soit incorrect. +Voulez-vous continuer ? + + + SMESH_EXPORT_MED_V2_1 + Les éléments polygonaux et polyèdriques seront omis dans le cas d'exportation du maillage "%1" à MED 2.1 +Utilisez MED 2.2 pour l'exportation correcte. +Voulez-vous effectuer l'exportation à MED 2.1 ? + + + SMESH_EXPORT_MED_VERSION_COLLISION + La version MED du fichier "%1" n'est pas connue ou ne correspond pas à la version choisie. +Réécrire le fichier ? + + + SMESH_EXPORT_MED_MESH_NAMES_COLLISION + Le fichier choisi contient déjà +les maillages avec les noms suivants: %1 +Il est possible que le fichier résultant ne soit pas correct. +Réécrire le fichier ? + + + SMESH_EXPORT_STL1 + Le maillage - "%1" ne contient pas de triangles + + + SMESH_EXPORT_STL2 + Le maillage - "%1" contient d'autres éléments que les triangles, ils ne seront donc pas enregistrés dans le fichier STL + + + SMESH_EXPORT_UNV + Les éléments pyramides seront omis au cours de l'exportation du maillage "%1" dans le fichier UNV + + + SMESH_EXTRUSION + Extrusion + + + SMESH_EXTRUSION_TO_DISTANCE + Distance de l'extrusion + + + SMESH_EXTRUSION_ALONG_VECTOR + Extrusion le long du vecteur + + + SMESH_FACE + Face + + + SMESH_FEATUREANGLE + Montrer l'angle + + + SMESH_FEATUREEDGES + Montrer les arêtes + + + SMESH_FILE_EXISTS + Le fichier "%1" existe déjà. +Voulez-vous le réécrire ou y ajouter les données exportées ? + + + SMESH_FONT_ARIAL + Arial + + + SMESH_FONT_BOLD + Gras + + + SMESH_FONT_COURIER + Courrier + + + SMESH_FONT_ITALIC + Italique + + + SMESH_FONT_SCALARBAR + Police + + + SMESH_FONT_SHADOW + Ombrage + + + SMESH_FONT_TIMES + Times + + + SMESH_GEOM_GROUP + Groupe géométrique + + + SMESH_GROUP + Groupe + + + SMESH_GROUP_GEOMETRY + Groupe lié à la géométrie + + + SMESH_GROUP_SELECTED + %1 groupes + + + SMESH_GROUP_STANDALONE + Groupe autonome + + + SMESH_GROUP_TYPE + Type du groupe + + + SMESH_HEIGHT + Hauteur : + + + SMESH_HEXAS + Hexaèdre + + + SMESH_HILIGHT_COLOR + Couleur de sélection + + + SMESH_HORIZONTAL + Horizontale + + + SMESH_HYPOTHESES + Hypothèses + + + SMESH_HYP_1 + Il manque une hypothèse à l'algorithme + + + SMESH_HYP_10 + L'hypothèse ne correspond pas aux dimensions du sous-maillage + + + SMESH_HYP_11 + La géométrie n'est ni la géométrie principale, ni un de ses sous-objets, ni un groupe valide + + + SMESH_HYP_12 + La géométrie ne correspond pas à l'algorithme +Référez-vous à la documentation sur l'algorithme et la géométrie supportée + + + SMESH_HYP_13 + L'algorithme ne peut pas opérer sans géométrie + + + SMESH_HYP_2 + Il y a des hypothèses concurrentes sur la géométrie + + + SMESH_HYP_3 + L'hypothèse contient une valeur de paramètre incorrecte + + + SMESH_HYP_4 + Le sous-maillage n'est pas pris en compte parce qu'il y a un algorithme de dimension supérieure pour générer les éléments %1D + + + SMESH_HYP_5 + L'algorithme l'emporte sur les algorithme(s) de dimensions inférieures en générant les éléments de toutes les dimensions + + + SMESH_HYP_6 + Erreur critique inconnue lors de la définition de l'hypothèse + + + SMESH_HYP_7 + L'hypothèse ne correspond pas à la situation actuelle + + + SMESH_HYP_8 + Un maillage non-conforme a été produit avec les hypothèses appliquées + + + SMESH_HYP_9 + L'hypothèse d'une telle dimension est déjà attribuée à la géométrie + + + SMESH_ID_DIAGONAL + IDs des arêtes + + + SMESH_ID_ELEMENTS + IDs des éléments + + + SMESH_ID_FACES + IDs des faces + + + SMESH_ID_NODES + IDs des nœuds + + + SMESH_INCORRECT_INPUT + Les données d'entrée ne sont pas correctes + + + SMESH_INFORMATION + Information + + + SMESH_INIT + Maillage + + + SMESH_INIT_MESH + Construction du maillage + + + SMESH_INSUFFICIENT_DATA + La valeur d'entrée n'est pas suffisante + + + SMESH_LABELS + Etiquettes : + + + SMESH_LABELS_COLORS_SCALARBAR + Couleurs && étiquettes + + + SMESH_LENGTH + Longueur + + + SMESH_MAKE_GROUPS + Générer les groupes + + + SMESH_MANIFOLDEDGES + Arêtes partagées + + + SMESH_MAX + Max + + + SMESH_MEN_ALGORITHMS + Algorithmes + + + SMESH_MEN_APPLIED_ALGORIHTMS + Algorithmes appliqués + + + SMESH_MEN_APPLIED_HYPOTHESIS + Hypothèses appliquées + + + SMESH_MEN_COMPONENT + SMESH + + + SMESH_MEN_HYPOTHESIS + Hypothèses + + + SMESH_MEN_SubMeshesOnCompound + Sous-maillages sur un assemblage + + + SMESH_MEN_SubMeshesOnEdge + Sous-maillages sur une arête + + + SMESH_MEN_SubMeshesOnFace + Sous-maillages sur une face + + + SMESH_MEN_SubMeshesOnSolid + Sous-maillages sur un solide + + + SMESH_MEN_SubMeshesOnVertex + Sous-maillages sur un point + + + SMESH_AUTOMATIC + Automatique + + + SMESH_MANUAL + Manuel + + + SMESH_MERGE_ELEMENTS + Fusionner les éléments + + + SMESH_MODE + Mode + + + SMESH_MERGED_ELEMENTS + %1 éléments fusionnés avec succès + + + SMESH_MERGED_NODES + %1 nœuds fusionnés avec succès + + + SMESH_NO_ELEMENTS_DETECTED + Il n'y a aucun élément à fusionner. + + + SMESH_NO_NODES_DETECTED + Il n'y a aucun nœud à fusionner + + + SMESH_MERGE_NODES + Fusionner les nœuds + + + SMESH_MESH + Maillage + + + SMESH_MESHINFO_0DELEMS + Eléments 0D + + + SMESH_MESHINFO_ALL_TYPES + Hétérogène + + + SMESH_MESHINFO_EDGES + Arêtes + + + SMESH_MESHINFO_ELEMENTS + Eléments + + + SMESH_MESHINFO_ENTITIES + Entités + + + SMESH_MESHINFO_FACES + Faces + + + SMESH_MESHINFO_HEXAS + Hexaèdres + + + SMESH_MESHINFO_NAME + Nom + + + SMESH_MESHINFO_NODES + Nœuds + + + SMESH_MESHINFO_ORDER0 + Total + + + SMESH_MESHINFO_ORDER1 + Linéaire + + + SMESH_MESHINFO_ORDER2 + Quadratique + + + SMESH_MESHINFO_POLYEDRES + Polyèdres + + + SMESH_MESHINFO_POLYGONES + Polygones + + + SMESH_MESHINFO_PRISMS + Prismes + + + SMESH_MESHINFO_PYRAS + Pyramides + + + SMESH_MESHINFO_QUADRANGLES + Quadrangles + + + SMESH_MESHINFO_TETRAS + Tetraèdres + + + SMESH_MESHINFO_TITLE + Informations sur le maillage + + + SMESH_MESHINFO_TOTAL + Total + + + SMESH_MESHINFO_TRIANGLES + Triangles + + + SMESH_MESHINFO_TYPE + Type + + + SMESH_MESHINFO_VOLUMES + Volumes + + + SMESH_MIN + Min + + + SMESH_MOVE + Déplacer + + + SMESH_MOVE_ELEMENTS + Déplacer les éléments + + + SMESH_MOVE_NODES_TITLE + Déplacer un nœud + + + SMESH_NAME + Nom + + + SMESH_NODES + Nœuds + + + SMESH_NONMANIFOLDEDGES + Arêtes non-partagées + + + SMESH_NORMAL + Normal + + + SMESH_NO_MESH_VISUALIZATION + Il n'y a pas assez de mémoire pour visualiser le maillage + + + SMESH_NUMBEROFCOLORS + Nombre de couleurs : + + + SMESH_NUMBEROFLABELS + Nombre d'étiquettes : + + + SMESH_NUMBEROFSTEPS + Nombre de pas : + + + SMESH_OBJECTS_SELECTED + %1_objets + + + SMESH_OBJECT_ALGORITHM + Algorithme + + + SMESH_OBJECT_GEOM + Objet géométrique + + + SMESH_OBJECT_HYPOTHESIS + Hypothèse + + + SMESH_OBJECT_MESH + Maillage + + + SMESH_OBJECT_MESHorSUBMESH + Maillage ou sous-maillage + + + SMESH_OPERATION_FAILED + L'opération n'a pas abouti + + + SMESH_ORIENTATION + Orientation + + + SMESH_ORIENTATION_ELEMENTS_TITLE + Changer l'orientation + + + SMESH_OUTLINE_COLOR + Couleur de l'objet maillage + + + SMESH_PARAMETERS + Paramètres + + + SMESH_PLANE + Plan + + + SMESH_POINT + Point + + + SMESH_POINT_1 + Point 1 + + + SMESH_POINT_2 + Point 2 + + + SMESH_BASE_POINT + Point de base + + + SMESH_POLYEDRE_CREATE_ERROR + Erreur de création du polyèdre + + + SMESH_POLYEDRON + Polyèdre + + + SMESH_POLYGON + Polygone + + + SMESH_POSITION_SIZE_SCALARBAR + Origine && Taille + + + SMESH_PRECISION + Précision + + + SMESH_PREFERENCES_SCALARBAR + Préférences de la barre d'échelle + + + SMESH_PREF_SELECTION + Préférences - Sélection + + + SMESH_PRESELECTION + Présélection + + + SMESH_PRISM + Prisme + + + SMESH_PROPERTIES_SCALARBAR + Proprétés de la barre d'échelle + + + SMESH_PYRAMID + Pyramide + + + SMESH_QUADRANGLE + Quadrangle + + + SMESH_QUADRATIC_EDGE + Arête quadratique + + + SMESH_QUADRATIC_HEXAHEDRON + Hexaèdre quadratique + + + SMESH_QUADRATIC_PENTAHEDRON + Pentaèdre quadratique + + + SMESH_QUADRATIC_PYRAMID + Pyramide quadratique + + + SMESH_QUADRATIC_QUADRANGLE + Quadrangle quadratique + + + SMESH_QUADRATIC_TETRAHEDRON + Tetraèdre quadratique + + + SMESH_QUADRATIC_TRIANGLE + Triangle quadratique + + + SMESH_RANGE_MAX + Valeur maximale : + + + SMESH_RANGE_MIN + Valeur minimale : + + + SMESH_RANGE_SCALARBAR + Echelle de valeurs + + + SMESH_REALLY_DELETE + Voulez-vous vraiment supprimer ces %1 objets? : %2 + + + SMESH_REMOVE + Supprimer + + + SMESH_REMOVE_ELEMENTS_TITLE + Supprimer les éléments + + + SMESH_REMOVE_NODES_TITLE + Supprimer les nœuds + + + SMESH_RENUMBERING + Renuméroter + + + SMESH_RENUMBERING_ELEMENTS_TITLE + Renuméroter les éléments + + + SMESH_RENUMBERING_NODES_TITLE + Renuméroter les nœuds + + + SMESH_REVERSE + Inverser + + + SMESH_REVOLUTION + Révolution + + + SMESH_RM_HYP_WRN + "%1" n'est pas attribué, mais: + + + + SMESH_ROTATION + Rotation + + + SMESH_ROTATION_TITLE + Rotation autour d'un axe + + + SMESH_SCALARBAR + Barre d'échelle + + + SMESH_SEGMENTS + Segments + + + SMESH_SELECTION + Sélection + + + SMESH_SELECT_FROM + Sélectionner à partir de + + + SMESH_SELECT_WHOLE_MESH + Choisir un maillage entier, un sous-maillage ou un groupe + + + SMESH_SET_COLOR + Groupe de couleur + + + SMESH_SEWING + Couture + + + SMESH_SMOOTHING + Lissage + + + SMESH_STANDARD_MESHINFO_TITLE + Information de maillage + + + SMESH_SUBMESH + Sous-maillage + + + SMESH_SUBMESH_SELECTED + %1 sous-maillages + + + SMESH_SYMMETRY + Symétrie + + + SMESH_TETRAS + Tétraèdre + + + SMESH_TITLE + Titre : + + + SMESH_TOLERANCE + Tolérance + + + SMESH_TRANSLATION + Translation + + + SMESH_SCALE_TITLE + Transformation d'échelle + + + SMESH_DUPLICATE_TITLE + Dupliquer les nœuds + + + SMESH_SCALE + Echelle + + + SMESH_SCALE_FACTOR + Facteur d'échelle : + + + SMESH_SCALE_FACTOR_X + Facteur d'échelle X : + + + SMESH_SCALE_FACTOR_Y + Facteur d'échelle Y : + + + SMESH_SCALE_FACTOR_Z + Facteur d'échelle Z : + + + SMESH_TRANSPARENCY_OPAQUE + → Opaque + + + SMESH_TRANSPARENCY_TITLE + Changer la transparence + + + SMESH_TRANSPARENCY_TRANSPARENT + Transparent ← + + + SMESH_TRIANGLE + Triangle + + + SMESH_UPDATEVIEW + Mettre à jour la vue + + + SMESH_VALUE + Valeur + + + SMESH_VECTOR + Vecteur + + + SMESH_VERTICAL + Verticale + + + SMESH_VISU_PROBLEM + Impossible de visualiser le maillage, probablement à cause d'un manque de mémoire + + + SMESH_VISU_PROBLEM_CLEAR + Impossible de visualiser le maillage, pas assez de la mémoire pour montrer le message, +donc toutes les données visuelles ont été supprimées pour ne pas planter l'application. +Enregistrez votre travail avant que l'application se plante + + + SMESH_VOLUME + Volume + + + SMESH_WARNING + Avertissement + + + SMESH_WHAT_IS_TITLE + Information sur un élément de maillage + + + SMESH_WIDTH + Largeur : + + + SMESH_WRN_ALGORITHM_ALREADYEXIST + L'algorithme existe déjà + + + SMESH_WRN_COMPUTE_FAILED + Impossible de calculer le maillage + + + SMESH_WRN_EVALUATE_FAILED + Impossible d'évaluer le maillage + + + SMESH_WRN_EMPTY_NAME + Un nom vide n'est pas valide + + + SMESH_WRN_HYPOTHESIS_ALREADYEXIST + L'hypothèse existe déjà + + + SMESH_WRN_HYPOTHESIS_NOTEXIST + L'hypothèse ou l'algorithme n'existent pas + + + SMESH_WRN_MISSING_PARAMETERS + Paramètres manquants + + + SMESH_WRN_NO_AVAILABLE_DATA + Pas de données disponibles dans la sélection + + + SMESH_WRN_SELECTIONMODE_DIAGONAL + Activer le mode de sélection des références + + + SMESH_WRN_SELECTIONMODE_ELEMENTS + Activer le mode de sélection des éléments + + + SMESH_WRN_SELECTIONMODE_NODES + Activer le mode de sélection des nœuds + + + SMESH_WRN_VIEWER_VTK + Il faut ouvrir la scène dans le visualisateur VTK + + + SMESH_WRN_SIZE_LIMIT_EXCEEDED + La présentation n'a pas été mise à jour automatiquement: la nouvelle taille du maillage (%1 éléments) dépasse la limite de taille actuelle (%2 éléments). +Vérifiez la limite dans les préférences du module Mesh. + + + + SMESH_WRN_WARNING + Avertissement + + + SMESH_X + X + + + SMESH_X_SCALARBAR + X : + + + SMESH_Y + Y + + + SMESH_Y_SCALARBAR + Y : + + + SMESH_Z + Z + + + STATE_ALGO_MISSING + Il manque l'algorithme %3 %2D + + + STATE_HYP_BAD_GEOMETRY + L'algorithme %3 %2D "%1" est attribué à une géométrie qui ne convient pas + + + STATE_HYP_BAD_PARAMETER + Il y a un paramètre incorrect dans l'hypothèse %3 %2D de l'algorithme "%1" + + + STATE_HYP_MISSING + L'hypothèse %4D manque à l'algorithme %3 %2D "%1" + + + STATE_HYP_NOTCONFORM + L'algorithme %3 %2D "%1" produit un maillage non-conforme: l'hypothèse globale "Maillage non conforme autorisé" doit être cochée + + + STB_ADV_INFO + Information avancée sur le maillage + + + STB_ALL + Tous + + + STB_AREA + Aire + + + STB_ASPECT + Rapport de forme + + + STB_ASPECT_3D + Rapport de forme 3D + + + STB_AUTO_COLOR + Couleur automatique + + + STB_AUTO_UPD + Mise à jour automatique + + + STB_BUILD_COMPOUND + Construire un maillage assemblé + + + STB_CLIP + Pan de coupe + + + STB_COLORS + Couleurs / Taille + + + STB_COMPUTE + Calculer + + + STB_PRECOMPUTE + Prévisualiser + + + STB_EVALUATE + Evaluer + + + STB_CONNECTION + Frontières sur connection multiples + + + STB_CONNECTION_2D + Frontières sur connection multiples 2D + + + STB_CONSTRUCT_GROUP + Construire un groupe + + + STB_CONV_TO_QUAD + Convertir vers/de quadratique + + + STB_2D_FROM_3D + Créer les éléments de frontière + + + STB_MESH_ORDER + Changer la priorité des sous-maillages + + + STB_CREATE_GROUP + Créer un groupe + + + STB_CREATE_GEO_GROUP + Créer les groupes à partir de la géométrie + + + STB_CREATE_MESH + Créer un maillage + + + STB_CREATE_SUBMESH + Créer un sous-maillage + + + STB_CUT + Découpe des quadrangles + + + STB_CUT_GROUP + Découper les groupes + + + STB_DAT + Importer un fichier DAT + + + STB_DELETE + Supprimer + + + STB_DEL_GROUP + Supprimer les groupes + + + STB_FACE_ORIENTATION + Orientation des faces + + + STB_DISABLE_AUTO_COLOR + Désactiver la couleur automatique + + + STB_DISPLAY_ONLY + Afficher uniquement + + + STB_DISP_ENT + Visualiser une entité + + + STB_ELEM0D + Elément 0D + + + STB_ELEMS0D + Eléments 0D + + + STB_EDGE + Arête + + + STB_EDGES + Arêtes + + + STB_EDIT_GROUP + Editer un groupe + + + STB_EDIT_GEOMGROUP_AS_GROUP + Editer un groupe en tant qu'autonome + + + STB_EDIT_HYPO + Editer une hypothèse + + + STB_EDIT_MESHSUBMESH + Editer un maillage/sous-maillage + + + STB_EXPORT_DAT + Exporter au format DAT + + + STB_EXPORT_MED + Exporter au format MED + + + STB_EXPORT_SAUV + Exporter au format SAUV (ASCII) + + + STB_EXPORT_STL + Exporter au format STL + + + STB_EXPORT_UNV + Exporter au format UNV + + + STB_EXTRUSION + Extrusion + + + STB_EXTRUSION_ALONG + Extrusion suivant un chemin + + + STB_FACES + Faces + + + STB_FREE_BORDER + Frontières libres + + + STB_FREE_EDGE + Arêtes libres + + + STB_FREE_NODE + Nœuds libres + + + STB_FREE_FACES + Faces libres + + + STB_GLOBAL_HYPO + Hypothèse globale + + + STB_HEXA + Hexaèdre + + + STB_HIDE + Cacher + + + STB_INT_GROUP + Intersection des groupes + + + STB_INV + Inversion de diagonale + + + STB_LENGTH + Longueur + + + STB_LENGTH_2D + Longueur 2D + + + STB_MAP + Projection de motif + + + STB_MED + Importer un fichier MED + + + STB_SAUV + Importer un fichier SAUV (ASCII) + + + STB_MERGE + Fusionner les nœuds + + + STB_MERGE_ELEMENTS + Fusionner les éléments + + + STB_MESH_THROU_POINT + Déplacer un nœud + + + STB_MIN_ANG + Angle minimal + + + STB_MOVE + Déplacer un nœud + + + STB_NODE + Nœud + + + STB_NODES + Nœuds + + + STB_NUM_ELEMENTS + Visualiser les éléments + + + STB_NUM_NODES + Visualiser les nœuds + + + STB_ORIENT + Orientation + + + STB_POLYGON + Polygone + + + STB_POLYHEDRON + Polyèdre + + + STB_PRECISION + Précision + + + STB_QUAD + Quadrangle + + + STB_QUADRATIC_EDGE + Arête quadratique + + + STB_QUADRATIC_HEXAHEDRON + Hexaèdre quadratique + + + STB_QUADRATIC_PENTAHEDRON + Pentaèdre quadratique + + + STB_QUADRATIC_PYRAMID + Pyramide quadratique + + + STB_QUADRATIC_QUADRANGLE + Quadrangle quadratique + + + STB_QUADRATIC_TETRAHEDRON + Tétraèdre quadratique + + + STB_QUADRATIC_TRIANGLE + Triangle quadratique + + + STB_REMOVE_ELEMENTS + Supprimer les éléments + + + STB_REMOVE_NODES + Supprimer les nœuds + + + STB_REMOVE_ORPHAN_NODES + Supprimer les nœuds orphelins + + + STB_RENAME + Renommer + + + STB_RENUM_ELEMENTS + Renuméroter les éléments + + + STB_RENUM_NODES + Renuméroter les nœuds + + + STB_RESET + Restaurer + + + STB_REVOLUTION + Révolution + + + STB_ROT + Rotation + + + STB_SCALAR_BAR + Barre d'échelle + + + STB_SCALAR_BAR_PROP + Propriétés de la barre d'échelle + + + STB_SELECTION + Sélection + + + STB_SEL_FILTER_LIB + Librairie des filtres de sélection + + + STB_SEW + Couture + + + STB_SHADE + Ombrage + + + STB_SHOW + Visualiser + + + STB_SHRINK + Contraction + + + STB_SKEW + Inclinaison d'angle + + + STB_SMOOTH + Lissage + + + STB_STD_INFO + Informations du maillage + + + STB_SYM + Symétrie + + + STB_TAPER + Cône + + + STB_TETRA + Tétraèdre + + + STB_TRANS + Translation + + + STB_SCALE + Mise à l'échelle + + + STB_DUPLICATE_NODES + Dupliquer les nœuds + + + STB_TRANSP + Transparence + + + STB_TRIANGLE + Triangle + + + STB_UNASSIGN + Désassocier + + + STB_UNION + Union des triangles + + + STB_UNION2 + Union de deux triangles + + + STB_UNV + Importer un fichier UNV + + + STB_UN_GROUP + Union des groupes + + + STB_UNDERLYING_ELEMS + Créer les groupes d'entités à partir des groupes existants de dimensions supérieures + + + STB_UPDATE + Mettre à jour + + + STB_VOLUMES + Volumes + + + STB_VOLUME_3D + Volume + + + STB_WARP + Angle de déformation + + + STB_WHAT_IS + Information sur l'élément de maillage + + + STB_WIRE + Contour + + + TAPER_ELEMENTS + Cône + + + TB_ADD_REMOVE + Ajouter/supprimer la barre d'outils + + + TB_CTRL + Barre d'outils des contrôles + + + TB_DISP_MODE + Barre du mode de visualisation + + + TB_HYPO + Barre d'hypothèses + + + TB_MESH + Barre de maillage + + + TB_MODIFY + Barre des modifications + + + TOP_ADV_INFO + Informations avancées du maillage + + + TOP_ALL + Tous + + + TOP_AREA + Aire + + + TOP_ASPECT + Rapport de forme + + + TOP_ASPECT_3D + Rapport de forme 3D + + + TOP_AUTO_COLOR + Couleur automatique + + + TOP_AUTO_UPD + Mise à jour automatique + + + TOP_BUILD_COMPOUND + Construire un maillage assemblé + + + TOP_CLIP + Plan de coupe + + + TOP_COLORS + Couleurs / Taille + + + TOP_COMPUTE + Calculer + + + TOP_PRECOMPUTE + Prévisualiser + + + TOP_EVALUATE + Evaluer + + + TOP_CONNECTION + Frontières sur connections multiples + + + TOP_CONNECTION_2D + Frontières sur connections multiples 2D + + + TOP_CONSTRUCT_GROUP + Construire un groupe + + + TOP_CONV_TO_QUAD + Convertir vers/de quadratique + + + TOP_2D_FROM_3D + Créer les éléments de frontière + + + TOP_MESH_ORDER + Changer la priorité des sous-maillages + + + TOP_CREATE_GROUP + Créer un groupe + + + TOP_CREATE_GEO_GROUP + Créer les groupes liés à la géométrie + + + TOP_CREATE_MESH + Créer un maillage + + + TOP_CREATE_SUBMESH + Créer un sous-maillage + + + TOP_CUT + Découpe des quadrangles + + + TOP_CUT_GROUP + Découper les groupes + + + TOP_DAT + Importer un fichier DAT + + + TOP_DELETE + Supprimer + + + TOP_DEL_GROUP + Supprimer les groupes + + + TOP_FACE_ORIENTATION + Orientation des faces + + + TOP_DISABLE_AUTO_COLOR + Désactiver la couleur automatique + + + TOP_DISPLAY_ONLY + Afficher uniquement + + + TOP_DISP_ENT + Visualiser une entité + + + TOP_ELEM0D + Elément 0D + + + TOP_ELEMS0D + Eléments 0D + + + TOP_EDGE + Arête + + + TOP_EDGES + Arêtes + + + TOP_EDIT_GROUP + Editer un groupe + + + TOP_EDIT_GEOMGROUP_AS_GROUP + Editer un groupe en tant qu'autonome + + + TOP_EDIT_HYPO + Editer l'hypothèse + + + TOP_EDIT_MESHSUBMESH + Editer un maillage/sous-maillage + + + TOP_EXPORT_DAT + Exporter au format DAT + + + TOP_EXPORT_MED + Exporter au format MED + + + TOP_EXPORT_SAUV + Exporter au format SAUV (ASCII) + + + TOP_EXPORT_STL + Exporter au format STL + + + TOP_EXPORT_UNV + Exporter au format UNV + + + TOP_EXTRUSION + Extrusion + + + TOP_EXTRUSION_ALONG + Extrusion suivant un chemin + + + TOP_FACES + Faces + + + TOP_FREE_BORDER + Frontières libres + + + TOP_FREE_EDGE + Arêtes libres + + + TOP_FREE_NODE + Nœuds libres + + + TOP_FREE_FACES + Faces libres + + + TOP_GLOBAL_HYPO + Hypothèse globale + + + TOP_HEXA + Hexaèdre + + + TOP_HIDE + Cacher + + + TOP_INT_GROUP + Intersection de groupes + + + TOP_INV + Inversion de diagonale + + + TOP_LENGTH + Longueur + + + TOP_LENGTH_2D + Longueur 2D + + + TOP_MAP + Projection de motif + + + TOP_MED + Importer un fichier MED + + + TOP_SAUV + Importer un fichier SAUV (ASCII) + + + TOP_MERGE + Fusionner les nœuds + + + TOP_MERGE_ELEMENTS + Fusionner les éléments + + + TOP_MESH_THROU_POINT + Déplacer un nœud + + + TOP_MIN_ANG + Angle minimal + + + TOP_MOVE + Déplacer un nœud + + + TOP_NODE + Nœud + + + TOP_NODES + Nœuds + + + TOP_NUM_ELEMENTS + Visualiser les éléments + + + TOP_NUM_NODES + Visualiser les nœuds + + + TOP_ORIENT + Orientation + + + TOP_POLYGON + Polygone + + + TOP_POLYHEDRON + Polyèdre + + + TOP_PRECISION + Précision + + + TOP_QUAD + Quadrangle + + + TOP_QUADRATIC_EDGE + Arête quadratique + + + TOP_QUADRATIC_HEXAHEDRON + Hexaèdre quadratique + + + TOP_QUADRATIC_PENTAHEDRON + Pentaèdre quadratique + + + TOP_QUADRATIC_PYRAMID + Pyramide quadratique + + + TOP_QUADRATIC_QUADRANGLE + Quadrangle quadratique + + + TOP_QUADRATIC_TETRAHEDRON + Tétraèdre quadratique + + + TOP_QUADRATIC_TRIANGLE + Triangle quadratique + + + TOP_REMOVE_ELEMENTS + Supprimer les éléments + + + TOP_REMOVE_NODES + Supprimer les nœuds + + + TOP_REMOVE_ORPHAN_NODES + Supprimer les nœuds ophelins + + + TOP_RENAME + Renommer + + + TOP_RENUM_ELEMENTS + Renuméroter les éléments + + + TOP_RENUM_NODES + Renuméroter les nœuds + + + TOP_RESET + Restaurer + + + TOP_REVOLUTION + Révolution + + + TOP_ROT + Rotation + + + TOP_SCALAR_BAR + Barre d'échelle + + + TOP_SCALAR_BAR_PROP + Propriétés de la barre d'échelle + + + TOP_SELECTION + Sélection + + + TOP_SEL_FILTER_LIB + Librairie des filtres de sélection + + + TOP_SEW + Couture + + + TOP_SHADE + Ombrage + + + TOP_SHOW + Visualiser + + + TOP_SHRINK + Contraction + + + TOP_SKEW + Inclinaison d'angle + + + TOP_SMOOTH + Lissage + + + TOP_STD_INFO + Informations du maillage + + + TOP_SYM + Symétrie + + + TOP_TAPER + Cône + + + TOP_TETRA + Tétraèdre + + + TOP_TRANS + Translation + + + TOP_SCALE + Mise à l'échelle + + + TOP_DUPLICATE_NODES + Dupliquer les nœuds + + + TOP_TRANSP + Transparence + + + TOP_TRIANGLE + Triangle + + + TOP_UNASSIGN + Désassocier + + + TOP_UNION + Union des triangles + + + TOP_UNION2 + Union de deux triangles + + + TOP_UNV + Importer un fichier UNV + + + TOP_UN_GROUP + Union des groupes + + + TOP_UNDERLYING_ELEMS + Créer les groupes d'entités à partir des groupes existants de dimensions supérieures + + + TOP_UPDATE + Mettre à jour + + + TOP_VOLUMES + Volumes + + + TOP_VOLUME_3D + Volume + + + TOP_WARP + Angle de déformation + + + TOP_WHAT_IS + Information sur l'élément de maillage + + + TOP_WIRE + Contours + + + VOLUME_3D_ELEMENTS + Aire + + + WARP_ELEMENTS + Déformation + + + MEN_FILE_INFO + Information du fichier MED + + + SMESH_WRN_NO_APPROPRIATE_SELECTION + Aucun objet sélectionné ne convient + + + MEN_CLEAR_MESH + Effacer les données du maillage + + + TOP_CLEAR_MESH + Effacer les données du maillage + + + STB_CLEAR_MESH + Effacer les données du maillage + + + SMESH_IMPORT_MESH + Importer les donnés du maillage à partir des fichiers + + + SMESH_ERR_NOT_SUPPORTED_FORMAT + Le format de fichier n'est pas supporté + + + SMESH_ERR_UNKNOWN_IMPORT_ERROR + Erreur inconnue + + + SMESH_IMPORT_ERRORS + L'importation s'est terminée avec des erreurs + + + SMESH_DRS_SOME_EMPTY + Un ou plusieurs fichiers de maillage sont vides, les données n'ont pas été publiées + + + NO_MESH_SELECTED + Aucun maillage sélectionné + + + SMESH_PREF_def_precision + Précision par défaut + + + SMESH_PREF_length_precision + Précision de la longueur + + + SMESH_PREF_angle_precision + Précision angulaire + + + SMESH_PREF_len_tol_precision + Précision de tolérance de la longueur + + + SMESH_PREF_parametric_precision + Précision paramétrique + + + SMESH_PREF_area_precision + Précision de l'aire + + + FULL_RECOMPUTE_QUESTION + +Le maillage a été édité après le dernier calcul complet, +ceci peut empêcher un calcul correct. +Voulez-vous recalculer le maillage entier pour rejeter les modifications ? + + + + SMESH_PREF_vol_precision + Précision du volume + + + SMESH_PRECISION_HINT + +Il est possible de modifier la précision de la valeur d'entrée +avec le paramètre '%1' des préférences du module Mesh. + + + REMOVE_ORPHAN_NODES_QUESTION + Voulez-vous supprimer tous les nœuds orphelins ? + + + NB_NODES_REMOVED + %1 nœud(s) supprimés. + + + SMESH_PLUGINS_OTHER + Extensions SMESH + + + + SMESHGUI + + NOT_A_VTK_VIEWER + Cette commande n'est disponible qu'à partir d'une fenêtre VTK. +Ouvrez une fenêtre VTK et essayez de nouveau + + + PREF_AUTO_GROUPS + Créer les groupes automatiquement pour l'export MED + + + PREF_GROUP_SEGMENT_LENGTH + Paramètres automatiques + + + PREF_SEGMENT_LENGTH + Ratio de la diagonale de la boîte englobante / taille maximale + + + PREF_NB_SEGMENTS + Nombre de segments par défaut + + + PREF_AUTO_UPDATE + Mettre à jour automatiquement + + + PREF_UPDATE_LIMIT + Limite de taille (nombre d'éléments) + + + PREF_UPDATE_LIMIT_NOLIMIT + Sans limite + + + PREF_BACKFACE + Face arrière + + + PREF_COLOR + Couleur + + + PREF_ORIENTATION_COLOR + Couleur + + + PREF_ORIENTATION_3D_VECTORS + Vecteurs 3D + + + PREF_ORIENTATION_SCALE + Echelle + + + PREF_DISPLAY_ENTITY + Eléments à visualiser + + + QUADRATIC_REPRESENT_MODE + Représentation des éléments quadratiques 2D + + + MAX_ARC_ANGLE + Angle maximal + + + PREF_DISPLAY_MODE + Mode de visualisation + + + PREF_ELEMENTS + Eléments + + + PREF_ELEMENT_COLOR + Couleur d'élément + + + PREF_FILL + Remplir + + + PREF_NOTIFY_MODE + Montrer la notification sur le résultat de calcul + + + SMESH_PREF_GROUP_PRECISION + Précision des champs d'entrée + + + PREF_GROUP_ELEMENTS + Eléments + + + PREF_GROUP_EXPORT + Exporter un maillage + + + PREF_GROUP_FACES_ORIENTATION + Orientation des faces + + + PREF_GROUP_COMPUTE + Calculer le maillage + + + PREF_GROUP_NODES + Nœuds + + + PREF_GROUP_GROUPS + Groupes + + + PREF_GRP_NAMES + Couleur des noms + + + PREF_GROUP_PRECISION + Précision + + + PREF_GROUP_PRESELECTION + Présélection + + + PREF_GROUP_QUALITY + Contrôles de qualité + + + PREF_GROUP_SELECTION + Sélection + + + PREF_HIGHLIGHT_COLOR + Couleur de sélection + + + PREF_LABELS_COLOR + Couleur des étiquettes + + + PREF_MARKER_SCALE + Echelle du marqueur + + + PREF_NODES + Nœuds + + + PREF_OBJECTS + Objets + + + PREF_OBJECT_COLOR + Couleur d'objet + + + PREF_OUTLINE + Silhouette + + + PREF_PRECISION_USE + Utiliser la précision + + + PREF_PRECISION_VALUE + Nombre de chiffres après la virgule + + + PREF_RENUMBER + Renuméroter automatiquement + + + PREF_SHRINK_COEFF + Coefficient de contraction + + + PREF_TAB_GENERAL + Général + + + PREF_TAB_MESH + Maillage + + + PREF_TAB_SELECTION + Sélection + + + PREF_TITLE_COLOR + Couleur du titre + + + PREF_TYPE_OF_MARKER + Type de marqueur + + + PREF_COLOR_0D + Eléments 0D + + + PREF_SIZE_0D + Taille des éléments 0D + + + PREF_WIDTH + Epaisseur + + + + SMESHGUI_AddQuadraticElementDlg + + SMESH_ADD_QUADRATIC_EDGE + Ajouter une arête quadratique + + + SMESH_ADD_QUADRATIC_HEXAHEDRON + Ajouter un hexaèdre quadratique + + + SMESH_ADD_QUADRATIC_PENTAHEDRON + Ajouter un pentaèdre quadratique + + + SMESH_ADD_QUADRATIC_PYRAMID + Ajouter une pyramide quadratique + + + SMESH_ADD_QUADRATIC_QUADRANGLE + Ajouter un quadrangle quadratique + + + SMESH_ADD_QUADRATIC_TETRAHEDRON + Ajouter un tétraèdre quadratique + + + SMESH_ADD_QUADRATIC_TRIANGLE + Ajouter un triangle quadratique + + + SMESH_CORNER_NODES + Nœuds angulaires: + + + SMESH_FIRST + Premier + + + SMESH_LAST + Dernier + + + SMESH_MIDDLE + Milieu + + + + SMESHGUI_BuildCompoundDlg + + COMPOUND + Assemblage + + + COMPOUND_MESH + Maillage d'assemblage + + + CREATE_COMMON_GROUPS + Créer des groupes communs pour les maillages initiaux + + + MERGE_NODES_AND_ELEMENTS + Fusionner les nœuds et les éléments coïncidents + + + MESHES + Maillages + + + PROCESSING_IDENTICAL_GROUPS + Traitement des groupes identiques + + + RENAME + Renommer + + + RESULT_NAME + Nom du résultat + + + UNITE + Réunir + + + + SMESHGUI_ChangeOrientationDlg + + CAPTION + Modifier l'orientation + + + + SMESHGUI_ComputeDlg + + CAPTION + Le calcul du maillage a échoué + + + CONSTRUCTOR + Calculer le maillage + + + EVAL_DLG + Evaluer le maillage + + + ERRORS + Erreurs + + + MEMORY_LACK + Problème d'allocation de mémoire + + + PUBLISH_SHAPE + Publier un sous-objet + + + SHOW_SHAPE + Montrer un sous-objet + + + SHOW_BAD_MESH + Montrer le maillage incorrect + + + + SMESHGUI_PrecomputeDlg + + CAPTION + Prévisualiser et calculer le maillage + + + PREVIEW + Prévisualiser + + + PREVIEW_1 + Maillage 1D + + + PREVIEW_2 + Maillage 2D + + + COMPUTE + Calculer + + + + SMESHGUI_PrecomputeOp + + CLEAR_SUBMESH_QUESTION + Des sous-maillages temporaires ont été créés sur la géométrie sélectionnée +au cours de l'opération de prévisualisation. +Voulez-vous supprimer toutes ces sous-maillages ? + + + SMESH_WRN_NOTHING_PREVIEW + La prévisualisation du maillage n'est pas disponible + + + SMESH_REJECT_MESH_ORDER + La priorité des sous-maillages a été changée au cours de la prévisualisation. +Voulez-vous restaurer la priorité initiale ? + + + + SMESHGUI_ConvToQuadDlg + + CAPTION + Convertir vers/de quadratique + + + MEDIUMNDS + Nœuds milieux sur la géométrie + + + MESH + Maillage + + + RADIOBTN_1 + Convertir en éléments quadratiques + + + RADIOBTN_2 + Convertir à partir d'éléments quadratiques + + + + SMESHGUI_ConvToQuadOp + + MESH_IS_NOT_SELECTED + Le maillage n'est pas sélectionné +Indiquez-le et essayez de nouveau + + + REF_IS_NULL + Aucun maillage valide n'est sélecionné + + + + SMESHGUI_CreatePatternDlg + + CAPTION + Projection de motif + + + DEFAULT_2D + Motif_2d + + + DEFAULT_3D + Motif_3d + + + ERROR_OF_CREATION + Une erreur interne s'est produite au cours de la création du motif +Vérifiez la validité des informations données + + + ERROR_OF_SAVING + Une erreur interne s'est produite au cours de l'enregistrement du motif. +Vérifiez l'espace de disque disponible et vos droits d'écriture dans ce fichier + + + ERR_LOADF_CANT_PROJECT + Impossible d'appliquer la projection des nœuds vers la face + + + ERR_LOADF_CLOSED_FACE + Impossible de créer un motif à partir d'une face avec une arête de couture + + + ERR_LOADF_NARROW_FACE + Impossible de créer un motif à partir d'une face étroite + + + ERR_LOADV_BAD_SHAPE + Il n'est possible de créer un motif que d'une coque fermée ou d'un solide avec 6 faces + + + ERR_LOADV_COMPUTE_PARAMS + Il est impossible de calculer les paramètres du point + + + ERR_LOAD_EMPTY_SUBMESH + Il n'y a pas d'éléments pour créer de motif + + + MESH_OR_SUBMESH + Maillage ou sous-maillage + + + PATTERN + Motif + + + PATTERN_FILT + Fichiers de motif (*.smp) + + + PATTERN_NAME + Nom du motif + + + PATTERN_TYPE + Type du motif + + + PROJECT + Projeter les nœuds sur la face + + + SAVE + Sauvegarder... + + + SAVE_PATTERN + Sauvegarder le motif + + + + SMESHGUI_CreatePolyhedralVolumeDlg + + FACES_BY_NODES + Faces par nœuds + + + SMESH_POLYEDRE_CREATE_ERROR + Erreur de création du polyèdre. + + + SMESH_POLYEDRE_PREVIEW + Prévisualiser le polyèdre + + + + SMESHGUI_CuttingOfQuadsDlg + + CAPTION + Découpe des quadrangles + + + + SMESHGUI_DeleteGroupDlg + + CAPTION + Supprimer les groupes et leur contenu + + + NO_SELECTED_GROUPS + Il n'y a aucun groupe sélectionné +Choisissez un groupe et essayez de nouveau + + + SELECTED_GROUPS + Groupes sélectionnés + + + + SMESHGUI_MergeDlg + + COINCIDENT_ELEMENTS + Eléments coïncidents + + + COINCIDENT_NODES + Nœuds coïncidents + + + DETECT + Détecter + + + EDIT_SELECTED_GROUP + Editer le groupe sélectionné + + + SELECT_ALL + Tout sélectionner + + + EXCLUDE_GROUPS + Exclure les groupes + + + + SMESHGUI_ExtrusionAlongPathDlg + + BAD_SHAPE_TYPE + La géométrie choisie en tant que chemin n'est pas une arête + + + CANT_GET_TANGENT + Impossible d'obtenir la tangente pour un des nœuds du chemin + + + EXTRUSION_1D + Extrusion des éléments 1D + + + EXTRUSION_2D + Extrusion des éléments 2D + + + EXTRUSION_ALONG_PATH + Extrusion suivant un chemin + + + EXTR_BAD_STARTING_NODE + Nœud de départ du chemin incorrect + + + LINEAR_ANGLES + Variation linéaire des angles + + + NO_ELEMENTS_SELECTED + Aucun élément de maillage n'est sélectionné pour l'extrusion + + + SELECTED_PATH_IS_NOT_EDGE + Le maillage du chemin doît être du type arête + + + SMESH_ANGLES + Angles de rotation + + + SMESH_BASE_POINT + Point de base + + + SMESH_PATH + Chemin + + + SMESH_PATH_MESH + Maillage ou sous-maillage + + + SMESH_PATH_SHAPE + Géométrie (arête) + + + SMESH_PATH_START + Nœud de début + + + SMESH_USE_ANGLES + Utiliser les angles + + + SMESH_USE_BASE_POINT + Utiliser le point de base + + + WRONG_ANGLES_NUMBER + Le nombre d'angles doit correspondre au nombre des nœuds du chemin + + + + SMESHGUI_ExtrusionDlg + + EXTRUSION_1D + Extrusion des éléments 1D + + + EXTRUSION_2D + Extrusion des éléments 2D + + + EXTRUSION_ALONG_LINE + Extrusion suivant une ligne + + + + SMESHGUI_FilterDlg + + BAD_SHAPE_NAME + Il n'y a pas d'objet géométrique "%1" dans l'étude actuelle +Sélectionnez un objet valide et essayez de nouveau + + + CURRENT_DIALOG + Groupe actuel + + + EDGES_TLT + Filtre d'arêtes + + + FACES_TLT + Filtre de faces + + + MESH + Maillage + + + NODES_TLT + Filtre de nœuds + + + SELECTION + Sélection initiale + + + SET_IN_VIEWER + Insérer le filtre dans la fenêtre 3D + + + SHAPE_IS_NOT_A_CYLINDER + "%1" n'est pas une face cylindrique +Sélectionnez une face cylindrique et essayez de nouveau + + + SHAPE_IS_NOT_A_FACE + "%1" n'est pas une face +Sélectionnez une face et essayez de nouveau + + + SHAPE_IS_NOT_A_PLANE + "%1" n'est pas un plan +Sélectionnez un plan et essayez de nouveau + + + FACE_ID_NOT_SELECTED + Aucune face de maillage n'est sélectionnée. +Indiquez-la et essayez de nouveau + + + NOT_FACE_ID + "%1" ne correspond à aucun ID valide d'une face du maillage. +Sélectionnez une face et essayez de nouveau + + + SOURCE + Source + + + TLT + Filtre de sélection + + + VOLUMES_TLT + Filtre de volumes + + + + SMESHGUI_FilterLibraryDlg + + ADD + Ajouter + + + ADD_TO_TLT + Ajouter le filtre de sélection à la librairie + + + ALL_FILES_FILTER + Tous les fichiers (*.*) + + + ASSIGN_NEW_NAME + La librairie déjà contient un filtre avec le nom "%1" +Le nouveau nom "%2" est attribué au filtre ajouté + + + COPY_FROM_TLT + Copier le filtre de la sélection de la librairie + + + DELETE + Supprimer + + + EDGE + Arête + + + EDIT_LIB_TLT + Librairie des filtres de sélection + + + ELEMENT + Elément + + + EMPTY_FILTER_NAME + Le nom du filtre est vide +Indiquez un nom non-vide + + + ERROR_FILTER_NAME + Le nom du filtre n'est pas unique +Indiquez un autre nom + + + ERROR_LOAD + Il est impossible de charger la librairie +Vérifiez le nom du fichier de la librairie et ses propriétés + + + ERROR_OF_ADDING + Une erreur interne s'est produite à l'addition d'un nouveau filtre dans la librairie. +Vérifiez la validité des informations données + + + ERROR_OF_COPYING + Une erreur interne s'est produite à la copie d'un filtre depuis la librairie. +Vérifiez la validité des informations données + + + ERROR_OF_DELETING + Une erreur interne s'est produite lors de la suppression d'un filtre depuis la librairie. +Vérifiez la validité des informations données + + + ERROR_OF_EDITING + Une erreur interne s'est produite à l'édition d'un filtre dans la librairie. +Vérifiez la validité des informations données + + + ERROR_OF_SAVING + Une erreur s'est produite à la sauvegarde de la librairie des filtres. +Vérifiez la validité des informations données + + + FACE + Face + + + FILTER + Filtre + + + FILTER_NAME + Nom du filtre + + + FILTER_NAMES + Noms des filtres + + + LIBRARY_FILE + Nom du fichier de librairie + + + LIBRARY_IS_NOT_LOADED + La librairie n'est pas ouverte. Ouvrez la librairie et essayez de nouveau + + + LIB_NAME + FilterLib.xml + + + NODE + Noeud + + + NO_PERMISSION + Vous n'avez pas la permission d'écrire dans ce fichier + + + OPEN_LIBRARY + Ouvrir la librairie + + + SELECTION + Sélection + + + VOLUME + Volume + + + XML_FILT + Fichiers XML (*.xml) + + + + SMESHGUI_FilterTable + + ADD + Ajouter + + + ADDITIONAL_PARAMETERS + Paramètres supplémentaires + + + ADD_TO + Ajouter à... + + + AND + Et + + + AREA + Aire + + + ASPECT_RATIO + Rapport de forme + + + ASPECT_RATIO_3D + Rapport de forme 3D + + + BAD_ORIENTED_VOLUME + Volume mal orienté + + + BELONG_TO_CYLINDER + Appartient au cylindre + + + BELONG_TO_GENSURFACE + Appartient à la surface + + + BELONG_TO_GEOM + Appartient à la géométrie + + + BELONG_TO_PLANE + Appartient au plan + + + BINARY + Opérateur logique + + + CLEAR + Effacer + + + COMPARE + Comparer + + + COPLANAR_FACES + Faces coplanaires + + + COPY_FROM + Copier de... + + + CRITERION + Critère + + + EDGES + Arêtes + + + ENTITY_TYPE + Type de l'entité + + + EQUAL_TO + Egal à + + + ERROR + La valeur du seuil n'est pas valide. Entrez une valeur correcte et essayez de nouveau + + + FACES + Faces + + + FILTER + Filtre + + + FREE_BORDERS + Bords libres + + + FREE_EDGES + Arêtes libres + + + FREE_NODES + Nœuds isolés + + + FREE_FACES + Faces libres + + + ID + ID + + + INSERT + Insérer + + + LENGTH + Longueur + + + LENGTH2D + Longueur 2D + + + LESS_THAN + Inférieur à ... + + + LYING_ON_GEOM + Repose sur la géométrie + + + MINIMUM_ANGLE + Angle minimal + + + MORE_THAN + Supérieur à ... + + + MULTIEDGES_ERROR + La valeur de seuil des bords multi-connectés ne peut pas être égal à 1 +Entrez une valeur correcte et essayez de nouveau + + + GROUPCOLOR_ERROR + Impossible d'identifier la couleur du groupe +Entrez une valeur correcte et essayez de nouveau + + + MULTI_BORDERS + Bords multi-connectés + + + NODES + Nœuds + + + NOT + Non + + + OR + Ou + + + RANGE_OF_IDS + Liste d'IDs + + + REMOVE + Supprimer + + + SKEW + Inclinaison + + + TAPER + Cône + + + THRESHOLD_VALUE + Valeur du seuil + + + UNARY + Négation + + + VOLUMES + Volumes + + + VOLUME_3D + Volume + + + WARPING + Déformation + + + LINEAR + Linéaire + + + GROUP_COLOR + Couleur du groupe + + + ELEMENTS + Eléments + + + GEOM_TYPE + Type de géométrie + + + GEOM_TYPE_0 + Point + + + GEOM_TYPE_1 + Arête + + + GEOM_TYPE_2 + Triangle + + + GEOM_TYPE_3 + Quadrangle + + + GEOM_TYPE_4 + Polygone + + + GEOM_TYPE_5 + Tétraèdre + + + GEOM_TYPE_6 + Pyramide + + + GEOM_TYPE_7 + Hexaèdre + + + GEOM_TYPE_8 + Pentaèdre + + + GEOM_TYPE_9 + Polyèdres + + + + SMESHGUI_GroupOpDlg + + ARGUMENTS + Arguments + + + DIFF_MESHES + Les arguments de l'opération ne sont pas indiqués correctement +Les groupes correspondent à des maillages différents +Donnez des arguments valides et essayez de nouveau + + + DIFF_TYPES + Les arguments de l'opération ne sont pas indiqués correctement +Les groupes contiennent des éléments de types différents +Donnez des arguments valides et essayez de nouveau + + + EMPTY_NAME + Le nom du groupe est invalide +Indiquez un nom non-vide et essayez de nouveau + + + INCORRECT_ARGUMENTS + Les arguments de l'opération ne sont pas indiqués +Indiquez-les et essayez de nouveau + + + NAME + Nom + + + OBJECT_1 + Objet 1 + + + OBJECT_2 + Objet 2 + + + RESULT_NAME + Nom du résultat + + + TOOL_OBJECT + Outil + + + UNION_OF_TWO_GROUPS + Union de deux groupes + + + + SMESHGUI_GroupDlg + + SELECT_ALL + Sélectionner tout + + + + SMESHGUI_UnionGroupsDlg + + UNION_OF_GROUPS + Union de groupes + + + + SMESHGUI_DimGroupDlg + + CREATE_GROUP_OF_UNDERLYING_ELEMS + Créer un groupe d'entités sous-jacentes + + + ELEMENTS_TYPE + Type d'éléments + + + NODE + Noeud + + + EDGE + Arête + + + FACE + Face + + + VOLUME + Volume + + + + SMESHGUI_IntersectGroupsDlg + + INTERSECTION_OF_GROUPS + Intersection de groupes + + + + SMESHGUI_CutGroupsDlg + + CUT_OF_GROUPS + Différence de groupes + + + MAIN_OBJECT + Objet principal + + + TOOL_OBJECT + Objet outil + + + + SMESHGUI_MakeNodeAtPointDlg + + AUTO_SEARCH + Trouver le noeud le plus proche de la destination + + + CAPTION + Déplacer un noeud + + + DESTINATION + Destination + + + MOVE_NODE + Déplacer un noeud + + + METHOD + Méthode + + + NODE_2MOVE + Noeud à déplacer + + + NODE_2MOVE_ID + ID + + + + SMESHGUI_MakeNodeAtPointOp + + INVALID_ID + L'ID du noeud est invalide + + + INVALID_MESH + Le maillage à modifier n'est pas sélectionné + + + + SMESHGUI_FindElemByPointDlg + + CAPTION + Trouver un élément par un point + + + CREATE_NEW_METHOD + Créer un noeud + + + MESH_PASS_THROUGH_POINT + Créer un noeud au point + + + METHOD + Méthode + + + MOVE_EXISTING_METHOD + Déplacer un noeud + + + NODE_2MOVE + Noeud à déplacer + + + NODE_2MOVE_ID + ID + + + + SMESHGUI_MeshDlg + + CREATE_MESH + Créer un maillage + + + CREATE_SUBMESH + Créer un sous-maillage + + + DIM_0D + 0D + + + DIM_1D + 1D + + + DIM_2D + 2D + + + DIM_3D + 3D + + + EDIT_MESH_SUBMESH + Editer un maillage/sous-maillage + + + GEOMETRY + Géométrie + + + HYPOTHESES_SETS + Attribuer un jeu d'hypothèses + + + MESH + Maillage + + + NAME + Nom + + + + SMESHGUI_MeshOp + + ALGORITHM_WITHOUT_HYPOTHESIS + L'algorithm pour la dimension %1 est défini mais l'hypothèse ne l'est pas + + + EDIT_SUBMESH_QUESTION + Un sous-maillage existe déjà sur la géométrie choisie +Voulez-vous éditer ce sous-maillage? + + + SUBMESH_NOT_ALLOWED + Créer un sous-maillage ignoré par l'algorithme global n'a pas de sens "%1" + + + GEOMETRY_OBJECT_IS_NOT_DEFINED + L'objet géométrique n'est pas défini +Indiquez-le et essayez de nouveau + + + GEOMETRY_OBJECT_IS_NULL + L'objet géométrique est nul + + + HYPOTHESES_AND_ALGORITHMS_ARE_NOT_DEFINED + Les hypothèses et les algorithmes ne sont pas définis + + + HYPOTHESIS_WITHOUT_ALGORITHM + L'hypothèse est définie pour la dimension %1 mais l'algorithme n'est pas défini + + + IMPORTED_MESH + Le maillage n'est pas construit sur une géométrie + + + INVALID_SUBSHAPE + L'objet géométrique n'est pas un sous-objet de l'objet maillé + + + MESH_IS_NOT_DEFINED + Le maillage n'est pas défini +Spécifiez-le et essayez de nouveau + + + MESH_IS_NULL + Le maillage est nul + + + NAME_OF_MESH_IS_EMPTY + Le nom du maillage est vide +Indiquez un nom valide et essayez de nouveau + + + NAME_OF_SUBMESH_IS_EMPTY + Le nom du sous-maillage est vide +Indiquez un nom valide et essayez de nouveau + + + THERE_IS_NO_OBJECT_FOR_EDITING + Il n'y a pas d'objet à éditer. +Sélectionnez un maillage ou un sous-maillage et essayez de nouveau + + + + SMESHGUI_MeshPatternDlg + + 3D_BLOCK + Bloc 3D + + + CAPTION + Projection de motif + + + CREATE_POLYEDRS_NEAR_BOUNDARY + Créer des polyèdres près de la frontière + + + CREATE_POLYGONS_NEAR_BOUNDARY + Créer des polygones près de la frontière + + + ERROR_OF_LOADING + Impossible de charger le motif. +Il est probable que le fichier est corrompu ou contient un autre type de motif + + + ERROR_OF_OPENING + Il est impossible d'ouvrir le fichier. +Vérifiez s'il existe et si vous avez l'autorisation + + + ERROR_OF_READING + Il est impossible de charger le motif +Vérifiez le contenu du fichier + + + ERR_READ_3D_COORD + Il est impossible de charger le motif +Les coordonnées des points 3D sont en dehors de l'intervalle [0,1] + + + ERR_READ_BAD_INDEX + Il est impossible de charger le motif +Un index de point invalide a été detecté + + + ERR_READ_BAD_KEY_POINT + Il est impossible de charger le motif +Le point-clef n'est pas situé sur la frontière + + + ERR_READ_ELEM_POINTS + Il est impossible de charger le motif +Le nombre de points de l'élément est invalide + + + ERR_READ_NB_POINTS + Il est impossible de charger le motif +Il est impossible de lire le nombre de points dans le fichier + + + ERR_READ_NO_ELEMS + Il est impossible de charger le motif +Il ne contient pas d'éléments + + + ERR_READ_NO_KEYPOINT + Il est impossible de charger le motif +Le motif 2D n'a pas de point-clef + + + ERR_READ_POINT_COORDS + Il est impossible de charger le motif +Il est impossible de lire les coordonnées des points dans le fichier + + + ERR_READ_TOO_FEW_POINTS + Il est impossible de charger le motif. +Il y a trop peu de points dans le fichier + + + FACE + Face + + + LOAD_PATTERN + Charger un motif + + + MESH_FACES + Faces du maillage + + + MESH_VOLUMES + Volumes du maillage + + + NEW + Nouveau... + + + NODE_1 + Noeud 1 + + + NODE_2 + Noeud 2 + + + PATTERN + Motif + + + PATTERN_FILT + Fichiers de motif (*.smp) + + + PATTERN_TYPE + Type de motif + + + PREVIEW + Prévisualiser + + + REFINE + Raffiner les éléments de maillage sélectionnés + + + REVERSE + Inverser l'ordre des points-clefs + + + VERTEX + Sommet... + + + VERTEX1 + Sommet 1 + + + VERTEX2 + Sommet 2 + + + + SMESHGUI_MeshTab + + ADD_HYPOTHESIS + Ajouter l'hypothèse + + + ALGORITHM + Algorithme + + + HYPOTHESIS + Hypothèse + + + NONE + <None> + + + + SMESHGUI_MultiEditDlg + + ADD + Ajouter + + + FILTER + Filtre + + + REMOVE + Supprimer + + + SELECT_FROM + Sélectionner à partir de + + + SORT_LIST + Trier la liste + + + SPLIT_JOIN_CRITERION + Critère + + + TO_ALL + Appliquer à tous + + + USE_DIAGONAL_1_3 + Utiliser la diagonale 1-3 + + + USE_DIAGONAL_2_4 + Utiliser la diagonale 2-4 + + + USE_NUMERIC_FUNC + Utiliser le facteur numérique + + + + SMESHGUI_CuttingIntoTetraDlg + + CAPTION + Diviser les volumes en tétraèdres + + + SPLIT_METHOD + Diviser l'héxaèdre + + + SPLIT_HEX_TO_5_TETRA + En 5 tétraèdres + + + SPLIT_HEX_TO_6_TETRA + En 6 tétraèdres + + + SPLIT_HEX_TO_24_TETRA + En 24 tétraèdres + + + + SMESHGUI_PrecisionDlg + + CAPTION + Précision pour les contrôles de qualité du maillage + + + NOT_USE + Ne pas utiliser! + + + PRECISION + Nombre de chiffres après la virgule + + + + SMESHGUI_RevolutionDlg + + ANGLE_BY_STEP + Angle par pas + + + PREVIEW + Prévisualiser + + + REVOLUTION_1D + Révolution des éléments 1D + + + REVOLUTION_2D + Révolution des éléments 2D + + + REVOLUTION_AROUND_AXIS + Révolution autour d'un axe + + + TOTAL_ANGLE + Angle total + + + MEN_POINT_SELECT + De l'origine au point sélectionner + + + MEN_FACE_SELECT + Normale de la face sélectionnée + + + + SMESHGUI_SewingDlg + + BORDER + Frontière + + + BORDER_1 + Frontière 1 + + + BORDER_2 + Frontière 2 + + + CREATE_POLYEDRS_NEAR_BOUNDARY + Remplacer les volumes concernés par des polyèdres + + + CREATE_POLYGONS_INSTEAD_SPLITTING + Créer des polygones au lieu de redécouper + + + ERROR_1 + La frontière Libre1 n'est pas trouvée avec les nœuds sélectionnés + + + ERROR_2 + La frontière Libre2 n'est pas trouvée avec les nœuds sélectionnés + + + ERROR_3 + Les frontières Libres 1 et 2 n'ont pas été trouvées avec les nœuds sélectionnés + + + ERROR_4 + Aucun chemin du premier au dernier noeud de la frontière n'est trouvé + + + ERROR_5 + Il n'est pas permis de découper les volumes de bord! + + + ERROR_6 + Le nombre d'éléments sélectionnés est différent de chaque côté + + + ERROR_7 + Les jeux d'éléments sont topologiquement différents ou les nœuds ne conviennent pas + + + ERROR_8 + Les nœuds du côté 1 soit ne sont pas connectés soit ne sont pas situés à la frontière du jeu d'éléments + + + ERROR_9 + Les nœuds du côté 2 soit ne sont pas connectés soit ne sont pas situés à la frontière de l'élément + + + FIRST_NODE_ID + ID du premier noeud + + + LAST_NODE_ID + ID du dernier noeud + + + MERGE_EQUAL_ELEMENTS + Fusionner les éléments égaux + + + NODE1_TO_MERGE + Noeud 1 à fusionner + + + NODE2_TO_MERGE + Noeud 2 à fusionner + + + SECOND_NODE_ID + ID du deuxième noeud + + + SEW_BORDER_TO_SIDE + Coudre la frontière au côté + + + SEW_CONFORM_FREE_BORDERS + Coudre les frontières libres conformes + + + SEW_FREE_BORDERS + Coudre les frontières libres + + + SEW_SIDE_ELEMENTS + Coudre les éléments de bord + + + SIDE + Bord + + + SIDE_1 + Bord 1 + + + SIDE_2 + Bord 2 + + + + SMESHGUI_ShapeByMeshDlg + + CAPTION + Trouver la géométrie par le maillage + + + + SMESHGUI_SingleEditDlg + + EDGE_BETWEEN + Arête entre des triangles voisins + + + + SMESHGUI_SmoothingDlg + + CENTROIDAL + Centroïdal + + + FIXED_NODES_IDS + IDs des nœuds fixes + + + IS_PARAMETRIC + dans l'espace paramétrique + + + ITERATION_LIMIT + Limite d'Itération + + + LAPLACIAN + Laplacien + + + MAX_ASPECT_RATIO + Rapport de forme maximal + + + METHOD + Méthode + + + + SMESHGUI_TrianglesInversionDlg + + CAPTION + Inversion de diagonale + + + + SMESHGUI_UnionOfTrianglesDlg + + CAPTION + Union des triangles + + + MAXIMUM_ANGLE + Angle maximal de pliage + + + + SMESHGUI_UnionOfTwoTrianglesDlg + + CAPTION + Union de deux triangles + + + + SMESHGUI_WhatIsDlg + + ENTITY_TYPE + Type d'élément + + + GRAVITY_CENTER + Centre de Gravité + + + CONNECTED_ELEMENTS + Connecté avec d'Eléments + + + + SMESHGUI_FileInfoDlg + + CAPTION + Informations sur le fichier + + + FILE_NAME + Nom du fichier + + + FILE_SIZE + Taille du fichier (bytes) + + + MED_VERSION + Version MED + + + + SMESHGUI_GroupOnShapeDlg + + SMESH_CREATE_GROUP_FROM_GEOM + Créer des groupes à partir de la géométrie + + + + SMESHGUI_MeshOrderDlg + + SMESH_MESHORDER_TITLE + Ordre des sous-maillages dans la procédure de maillage + + + + SMESHGUI_MeshOrderOp + + SMESH_NO_CONCURENT_MESH + Pas de sous-maillages concurrents détectés + + + + SMESHGUI_ClippingDlg + + CLIP_PLANES + Plans de découpe + + + ROTATION_AROUND_X_Y2Z + Rotation autour de X (Y à Z): + + + ROTATION_AROUND_Y_X2Z + Rotation autour de Y (X à Z): + + + ROTATION_AROUND_Z_Y2X + Rotation autour de Z (Y à X): + + + ROTATION_AROUND_X_Z2Y + Rotation autour de X (Z à Y): + + + ROTATION_AROUND_Y_Z2X + Rotation autour de Y (Z à X): + + + ROTATION_AROUND_Z_X2Y + Rotation autour de Z (X à Y): + + + SHOW_PREVIEW + Prévisualiser + + + AUTO_APPLY + Appliquer automatiquement + + + ALONG_XY + || X-Y + + + ALONG_YZ + || Y-Z + + + ALONG_ZX + || Z-X + + + PLANE_NUM + Plan# %1 + + + NO_PLANES + Pas de plans + + + + SMESHGUI_DuplicateNodesDlg + + DUPLICATION_MODE + Mode de duplication + + + DUPLICATION_WITHOUT_ELEMS + Sans duplication des éléments de frontière + + + GROUP_NODES_TO_DUPLICATE + Groupe des nœuds à dupliquer + + + GROUP_NODES_TO_REPLACE + Groupe des éléments dont les nœuds sont à remplacer + + + DUPLICATION_WITH_ELEMS + Avec duplication des éléments de frontière + + + GROUP_ELEMS_TO_DUPLICATE + Groupe des éléments à dupliquer + + + GROUP_NODES_NOT_DUPLICATE + Groupe des nœuds à ne pas dupliquer + + + GROUP_ELEMS_TO_REPLACE + Groupe des éléments dont les nœuds sont à remplacer + + + CONSTRUCT_NEW_GROUP_NODES + Construire un groupe avec les nœuds nouvellement créés + + + CONSTRUCT_NEW_GROUP_ELEMENTS + Construire un groupe avec les éléments nouvellement créés + + + + SMESHGUI_Make2DFrom3DDlg + + CAPTION + Créer les éléments de frontière + + + MESH + Maillage, sous-maillage ou groupe + + + MODE + Mode + + + 2D_FROM_3D + 2D à partir de 3D + + + 1D_FROM_3D + 1D à partir de 3D + + + 1D_FROM_2D + 1D à partir de 2D + + + TARGET + Cible + + + THIS_MESH + Ce maillage + + + NEW_MESH + Nouveau maillage + + + COPY_SRC + Copier le maillage source + + + MISSING_ONLY + Copier seulement les éléments manquants + + + CREATE_GROUP + Créer un groupe + + + + SMESHGUI_Make2DFrom3DOp + + SMESH_ERR_NO_INPUT_MESH + Aucun maillage, sous-maillage ou groupe source n'est indiqué + + + SMESH_ERR_NO_3D_ELEMENTS + L'objet source ne contient pas d'éléments 3D + + + SMESH_ERR_NO_2D_ELEMENTS + L'objet source ne contient pas d'éléments 2D + + + SMESH_ERR_MESH_NAME_NOT_SPECIFIED + Le nom du nouveau maillage n'est pas indiqué + + + SMESH_ERR_GRP_NAME_NOT_SPECIFIED + Le nom du groupe n'est pas indiqué + + + diff --git a/src/SMESH_I/Makefile.am b/src/SMESH_I/Makefile.am index 9a2a3c6a4..53f285528 100644 --- a/src/SMESH_I/Makefile.am +++ b/src/SMESH_I/Makefile.am @@ -46,6 +46,7 @@ salomeinclude_HEADERS = \ SMESH_Pattern_i.hxx \ SMESH_2smeshpy.hxx \ SMESH_NoteBook.hxx \ + SMESH_Measurements_i.hxx \ SMESH.hxx # Scripts to be installed. @@ -76,7 +77,8 @@ dist_libSMESHEngine_la_SOURCES = \ SMESH_Group_i.cxx \ SMESH_Pattern_i.cxx \ SMESH_2smeshpy.cxx \ - SMESH_NoteBook.cxx + SMESH_NoteBook.cxx \ + SMESH_Measurements_i.cxx # Executables targets bin_PROGRAMS = SMESHEngine diff --git a/src/SMESH_I/SMESH_2smeshpy.cxx b/src/SMESH_I/SMESH_2smeshpy.cxx index 640f51191..dfb378f24 100644 --- a/src/SMESH_I/SMESH_2smeshpy.cxx +++ b/src/SMESH_I/SMESH_2smeshpy.cxx @@ -342,6 +342,7 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand ) // Concatenate( [mesh1, ...], ... ) // CreateHypothesis( theHypType, theLibName ) // Compute( mesh, geom ) + // Evaluate( mesh, geom ) // mesh creation TCollection_AsciiString method = theCommand->GetMethod(); @@ -395,6 +396,20 @@ void _pyGen::Process( const Handle(_pyCommand)& theCommand ) } } + // smeshgen.Evaluate( mesh, geom ) --> mesh.Evaluate(geom) + if ( method == "Evaluate" ) + { + const _pyID& meshID = theCommand->GetArg( 1 ); + map< _pyID, Handle(_pyMesh) >::iterator id_mesh = myMeshes.find( meshID ); + if ( id_mesh != myMeshes.end() ) { + theCommand->SetObject( meshID ); + _pyID geom = theCommand->GetArg( 2 ); + theCommand->RemoveArgs(); + theCommand->SetArg( 1, geom ); + return; + } + } + // objects erasing creation command if no more it's commands invoked: // SMESH_Pattern, FilterManager if ( method == "GetPattern" || method == "CreateFilterManager" ) { @@ -1091,12 +1106,12 @@ _pyMeshEditor::_pyMeshEditor(const Handle(_pyCommand)& theCreationCmd): void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand) { - // names of SMESH_MeshEditor methods fully equal to methods of class Mesh, so + // names of SMESH_MeshEditor methods fully equal to methods of python class Mesh, so // commands calling this methods are converted to calls of methods of Mesh static TStringSet sameMethods; if ( sameMethods.empty() ) { const char * names[] = { - "RemoveElements","RemoveNodes","AddNode","Add0DElement","AddEdge","AddFace","AddPolygonalFace", + "RemoveElements","RemoveNodes","RemoveOrphanNodes","AddNode","Add0DElement","AddEdge","AddFace","AddPolygonalFace", "AddVolume","AddPolyhedralVolume","AddPolyhedralVolumeByFaces","MoveNode", "MoveClosestNodeToPoint", "InverseDiag","DeleteDiag","Reorient","ReorientObject","TriToQuad","SplitQuad","SplitQuadObject", "BestSplit","Smooth","SmoothObject","SmoothParametric","SmoothParametricObject", @@ -1105,7 +1120,7 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand) "ExtrusionSweep","AdvancedExtrusion","ExtrusionSweepObject","ExtrusionSweepObject1D","ExtrusionSweepObject2D", "ExtrusionAlongPath","ExtrusionAlongPathObject","ExtrusionAlongPathObject1D","ExtrusionAlongPathObject2D", "Mirror","MirrorObject","Translate","TranslateObject","Rotate","RotateObject", - "FindCoincidentNodes","FindCoincidentNodesOnPart","MergeNodes","FindEqualElements", + "FindCoincidentNodes",/*"FindCoincidentNodesOnPart",*/"MergeNodes","FindEqualElements", "MergeElements","MergeEqualElements","SewFreeBorders","SewConformFreeBorders", "SewBorderToSide","SewSideElements","ChangeElemNodes","GetLastCreatedNodes", "GetLastCreatedElems", @@ -1116,9 +1131,9 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand) } // names of SMESH_MeshEditor methods which differ from methods of class Mesh - // only last two arguments + // only by last two arguments static TStringSet diffLastTwoArgsMethods; - if (diffLastTwoArgsMethods.empty() ){ + if (diffLastTwoArgsMethods.empty() ) { const char * names[] = { "MirrorMakeGroups","MirrorObjectMakeGroups", "TranslateMakeGroups","TranslateObjectMakeGroups", @@ -1127,41 +1142,59 @@ void _pyMeshEditor::Process( const Handle(_pyCommand)& theCommand) diffLastTwoArgsMethods.Insert( names ); } - if ( sameMethods.Contains( theCommand->GetMethod() )) { - theCommand->SetObject( myMesh ); - - // meshes made by *MakeMesh() methods are not wrapped by _pyMesh, - // so let _pyMesh care of it (TMP?) -// if ( theCommand->GetMethod().Search("MakeMesh") != -1 ) -// _pyMesh( new _pyCommand( theCommand->GetString(), 0 )); // for theGen->SetAccessorMethod() - } - else { - + const TCollection_AsciiString & method = theCommand->GetMethod(); + bool isPyMeshMethod = sameMethods.Contains( method ); + if ( !isPyMeshMethod ) + { //Replace SMESH_MeshEditor "MakeGroups" functions on the Mesh //functions with the flag "theMakeGroups = True" like: //SMESH_MeshEditor.CmdMakeGroups => Mesh.Cmd(...,True) - int pos = theCommand->GetMethod().Search("MakeGroups"); - if( pos != -1) { + int pos = method.Search("MakeGroups"); + if( pos != -1) + { + isPyMeshMethod = true; + // 1. Remove "MakeGroups" from the Command TCollection_AsciiString aMethod = theCommand->GetMethod(); int nbArgsToAdd = diffLastTwoArgsMethods.Contains(aMethod) ? 2 : 1; aMethod.Trunc(pos-1); theCommand->SetMethod(aMethod); - // 2. Set Mesh object instead of SMESH_MeshEditor - theCommand->SetObject( myMesh ); - - // 3. And add last "True" argument + // 2. And add last "True" argument(s) while(nbArgsToAdd--) - theCommand->SetArg(theCommand->GetNbArgs()+1,"True "); + theCommand->SetArg(theCommand->GetNbArgs()+1,"True"); } - else { - // editor creation command is needed only if any editor function is called - theGen->AddMeshAccessorMethod( theCommand ); // for *Object() - if ( !myCreationCmdStr.IsEmpty() ) { - GetCreationCmd()->GetString() = myCreationCmdStr; - myCreationCmdStr.Clear(); - } + } + + // set "FindCoincidentNodesOnPart()" instead of "FindCoincidentNodesOnPartBut()" + if ( !isPyMeshMethod && method == "FindCoincidentNodesOnPartBut") + { + isPyMeshMethod=true; + theCommand->SetMethod("FindCoincidentNodesOnPart"); + } + // DoubleNodeElemGroupNew() -> DoubleNodeElemGroup() + if ( !isPyMeshMethod && ( method == "DoubleNodeElemGroupNew" || method == "DoubleNodeGroupNew")) + { + isPyMeshMethod=true; + theCommand->SetMethod( method.SubString( 1, method.Length()-3)); + theCommand->SetArg(theCommand->GetNbArgs()+1,"True"); + } + + // meshes made by *MakeMesh() methods are not wrapped by _pyMesh, + // so let _pyMesh care of it (TMP?) + // if ( theCommand->GetMethod().Search("MakeMesh") != -1 ) + // _pyMesh( new _pyCommand( theCommand->GetString(), 0 )); // for theGen->SetAccessorMethod() + if ( isPyMeshMethod ) + { + theCommand->SetObject( myMesh ); + } + else + { + // editor creation command is needed only if any editor function is called + theGen->AddMeshAccessorMethod( theCommand ); // for *Object() + if ( !myCreationCmdStr.IsEmpty() ) { + GetCreationCmd()->GetString() = myCreationCmdStr; + myCreationCmdStr.Clear(); } } } diff --git a/src/SMESH_I/SMESH_DumpPython.cxx b/src/SMESH_I/SMESH_DumpPython.cxx index 5be4f5de4..3fd8ff22f 100644 --- a/src/SMESH_I/SMESH_DumpPython.cxx +++ b/src/SMESH_I/SMESH_DumpPython.cxx @@ -152,7 +152,7 @@ namespace SMESH } template - void DumpArray(const TArray& theArray, std::ostringstream & theStream) + void DumpArray(const TArray& theArray, TPythonDump & theStream) { theStream << "[ "; for (int i = 1; i <= theArray.length(); i++) { @@ -166,14 +166,14 @@ namespace SMESH TPythonDump& TPythonDump::operator<<(const SMESH::long_array& theArg) { - DumpArray( theArg, myStream ); + DumpArray( theArg, *this ); return *this; } TPythonDump& TPythonDump::operator<<(const SMESH::double_array& theArg) { - DumpArray( theArg, myStream ); + DumpArray( theArg, *this ); return *this; } @@ -274,6 +274,8 @@ namespace SMESH 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; @@ -287,6 +289,7 @@ namespace SMESH 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; @@ -306,6 +309,15 @@ namespace SMESH return *this; } + TPythonDump& + TPythonDump:: + operator<<(SMESH::Measurements_i* theArg) + { + myStream<<"aMeasurements"; + return *this; + } + + TPythonDump& TPythonDump:: operator<<(SMESH_Gen_i* theArg) { myStream << SMESHGenName(); return *this; @@ -354,21 +366,14 @@ namespace SMESH return *this; } - TPythonDump& TPythonDump::operator<<(const SMESH::ListOfGroups * theList){ - if(theList && theList->length() > 0 ) { - SMESH_Gen_i* aSMESHGen = SMESH_Gen_i::GetSMESHGen(); - SALOMEDS::Study_ptr aStudy = aSMESHGen->GetCurrentStudy(); - myStream << "["; - int aListLen = theList->length(); - for(int i = 0 ; i < aListLen; i++){ - SALOMEDS::SObject_var aSObject = SMESH_Gen_i::ObjectToSObject(aStudy,(*theList)[i]); - if(!aSObject->_is_nil()) { - myStream << aSObject->GetID(); - i < (aListLen - 1) ? myStream<<", " : myStream<<"]"; - } - - } - } + TPythonDump& TPythonDump::operator<<(const SMESH::ListOfGroups& theList) + { + DumpArray( theList, *this ); + return *this; + } + TPythonDump& TPythonDump::operator<<(const SMESH::ListOfIDSources& theList) + { + DumpArray( theList, *this ); return *this; } @@ -377,10 +382,10 @@ namespace SMESH //================================================================================ /*! - * \brief Return marker of long string literal beginning - * \param type - a name of functionality producing the string literal - * \retval TCollection_AsciiString - the marker string to be written into - * a raw python script + * \brief Return marker of long string literal beginning + * \param type - a name of functionality producing the string literal + * \retval TCollection_AsciiString - the marker string to be written into + * a raw python script */ //================================================================================ @@ -690,6 +695,7 @@ TCollection_AsciiString SMESH_Gen_i::DumpPython_impl TCollection_AsciiString aScript; aScript = "def RebuildData(theStudy):\n\t"; aScript += helper + "aFilterManager = " + aSMESHGen + ".CreateFilterManager()\n\t"; + aScript += helper + "aMeasurements = " + aSMESHGen + ".CreateMeasurements()\n\t"; if ( isPublished ) aScript += aSMESHGen + ".SetCurrentStudy(theStudy)"; else diff --git a/src/SMESH_I/SMESH_Filter_i.cxx b/src/SMESH_I/SMESH_Filter_i.cxx index 969ffb613..d2a7ae648 100644 --- a/src/SMESH_I/SMESH_Filter_i.cxx +++ b/src/SMESH_I/SMESH_Filter_i.cxx @@ -596,6 +596,28 @@ CORBA::Double NumericalFunctor_i::GetValue( CORBA::Long theId ) return myNumericalFunctorPtr->GetValue( theId ); } +SMESH::Histogram* NumericalFunctor_i::GetHistogram(CORBA::Short nbIntervals) +{ + std::vector nbEvents; + std::vector funValues; + myNumericalFunctorPtr->GetHistogram(nbIntervals,nbEvents,funValues); + + nbIntervals = CORBA::Short( std::min( nbEvents.size(), funValues.size() - 1)); + SMESH::Histogram_var histogram = new SMESH::Histogram; + if ( nbIntervals > 0 ) + { + histogram->length( nbIntervals ); + for ( int i = 0; i < nbIntervals; ++i ) + { + HistogramRectangle& rect = histogram[i]; + rect.nbEvents = nbEvents[i]; + rect.min = funValues[i]; + rect.max = funValues[i+1]; + } + } + return histogram._retn(); +} + void NumericalFunctor_i::SetPrecision( CORBA::Long thePrecision ) { myNumericalFunctorPtr->SetPrecision( thePrecision ); @@ -738,6 +760,36 @@ FunctorType Volume3D_i::GetFunctorType() return SMESH::FT_Volume3D; } +/* + Class : MaxElementLength2D_i + Description : Functor for calculating maximum length of 2D element +*/ +MaxElementLength2D_i::MaxElementLength2D_i() +{ + myNumericalFunctorPtr.reset( new Controls::MaxElementLength2D() ); + myFunctorPtr = myNumericalFunctorPtr; +} + +FunctorType MaxElementLength2D_i::GetFunctorType() +{ + return SMESH::FT_MaxElementLength2D; +} + +/* + Class : MaxElementLength3D_i + Description : Functor for calculating maximum length of 3D element +*/ +MaxElementLength3D_i::MaxElementLength3D_i() +{ + myNumericalFunctorPtr.reset( new Controls::MaxElementLength3D() ); + myFunctorPtr = myNumericalFunctorPtr; +} + +FunctorType MaxElementLength3D_i::GetFunctorType() +{ + return SMESH::FT_MaxElementLength3D; +} + /* Class : Length_i Description : Functor for calculating length off edge @@ -772,11 +824,12 @@ SMESH::Length2D::Values* Length2D_i::GetValues() { INFOS("Length2D_i::GetValues"); SMESH::Controls::Length2D::TValues aValues; - myLength2DPtr->GetValues( aValues ); + (dynamic_cast(myFunctorPtr.get()))->GetValues( aValues ); long i = 0, iEnd = aValues.size(); SMESH::Length2D::Values_var aResult = new SMESH::Length2D::Values(iEnd); + aResult->length(iEnd); SMESH::Controls::Length2D::TValues::const_iterator anIter; for ( anIter = aValues.begin() ; anIter != aValues.end(); anIter++, i++ ) @@ -827,11 +880,12 @@ SMESH::MultiConnection2D::Values* MultiConnection2D_i::GetValues() { INFOS("MultiConnection2D_i::GetValues"); SMESH::Controls::MultiConnection2D::MValues aValues; - myMulticonnection2DPtr->GetValues( aValues ); - + (dynamic_cast(myFunctorPtr.get()))->GetValues( aValues ); + long i = 0, iEnd = aValues.size(); SMESH::MultiConnection2D::Values_var aResult = new SMESH::MultiConnection2D::Values(iEnd); + aResult->length(iEnd); SMESH::Controls::MultiConnection2D::MValues::const_iterator anIter; for ( anIter = aValues.begin() ; anIter != aValues.end(); anIter++, i++ ) @@ -1441,7 +1495,7 @@ void ElemGeomType_i::SetGeometryType(GeometryType theType) GeometryType ElemGeomType_i::GetGeometryType() const { - return (GeometryType)myElemGeomTypePtr->GetGeomType();; + return (GeometryType)myElemGeomTypePtr->GetGeomType(); } FunctorType ElemGeomType_i::GetFunctorType() @@ -1449,6 +1503,49 @@ FunctorType ElemGeomType_i::GetFunctorType() return SMESH::FT_ElemGeomType; } +/* + Class : CoplanarFaces_i + Description : Returns true if a mesh face is a coplanar neighbour to a given one +*/ +CoplanarFaces_i::CoplanarFaces_i() +{ + myCoplanarFacesPtr.reset(new Controls::CoplanarFaces()); + myFunctorPtr = myPredicatePtr = myCoplanarFacesPtr; +} + +void CoplanarFaces_i::SetFace ( CORBA::Long theFaceID ) +{ + myCoplanarFacesPtr->SetFace(theFaceID); + TPythonDump()<SetTolerance(theToler); + TPythonDump()<GetFace(); +} + +char* CoplanarFaces_i::GetFaceAsString () const +{ + TCollection_AsciiString str(Standard_Integer(myCoplanarFacesPtr->GetFace())); + return CORBA::string_dup( str.ToCString() ); +} + +CORBA::Double CoplanarFaces_i::GetTolerance() const +{ + return myCoplanarFacesPtr->GetTolerance(); +} + +FunctorType CoplanarFaces_i::GetFunctorType() +{ + return SMESH::FT_CoplanarFaces; +} + /* Class : Comparator_i Description : Base class for comparators @@ -1793,6 +1890,24 @@ Volume3D_ptr FilterManager_i::CreateVolume3D() } +MaxElementLength2D_ptr FilterManager_i::CreateMaxElementLength2D() +{ + SMESH::MaxElementLength2D_i* aServant = new SMESH::MaxElementLength2D_i(); + SMESH::MaxElementLength2D_var anObj = aServant->_this(); + TPythonDump()<_this(); + TPythonDump()<_this(); + TPythonDump()<length( 1 ); + types[0] = GetElementType(); + return types._retn(); +} + +//======================================================================= +//function : GetMesh +//purpose : Returns mesh +//======================================================================= + +SMESH::SMESH_Mesh_ptr Filter_i::GetMesh() +{ + return SMESH_Mesh::_duplicate( myMesh ); +} + //======================================================================= // name : getCriteria // Purpose : Retrieve criterions from predicate @@ -2283,6 +2431,22 @@ static inline bool getCriteria( Predicate_i* thePred, theCriteria[ i ].TypeOfElement = aPred->GetElementType(); theCriteria[ i ].Tolerance = aPred->GetTolerance(); + return true; + } + case FT_CoplanarFaces: + { + CoplanarFaces_i* aPred = dynamic_cast( thePred ); + + CORBA::ULong i = theCriteria->length(); + theCriteria->length( i + 1 ); + + theCriteria[ i ] = createCriterion(); + CORBA::String_var faceId = aPred->GetFaceAsString(); + + theCriteria[ i ].Type = FT_CoplanarFaces; + theCriteria[ i ].ThresholdID = faceId; + theCriteria[ i ].Tolerance = aPred->GetTolerance(); + return true; } case FT_RangeOfIds: @@ -2489,6 +2653,12 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria case SMESH::FT_Volume3D: aFunctor = aFilterMgr->CreateVolume3D(); break; + case SMESH::FT_MaxElementLength2D: + aFunctor = aFilterMgr->CreateMaxElementLength2D(); + break; + case SMESH::FT_MaxElementLength3D: + aFunctor = aFilterMgr->CreateMaxElementLength3D(); + break; // Predicates @@ -2576,6 +2746,14 @@ CORBA::Boolean Filter_i::SetCriteria( const SMESH::Filter::Criteria& theCriteria aPredicate = tmpPred; break; } + case SMESH::FT_CoplanarFaces: + { + SMESH::CoplanarFaces_ptr tmpPred = aFilterMgr->CreateCoplanarFaces(); + tmpPred->SetFace( atol (aThresholdID )); + tmpPred->SetTolerance( aTolerance ); + aPredicate = tmpPred; + break; + } default: continue; @@ -2778,6 +2956,8 @@ static inline LDOMString toString( CORBA::Long theType ) case FT_Skew : return "Skew"; case FT_Area : return "Area"; case FT_Volume3D : return "Volume3D"; + case FT_MaxElementLength2D: return "Max element length 2D"; + case FT_MaxElementLength3D: return "Max element length 3D"; case FT_BelongToGeom : return "Belong to Geom"; case FT_BelongToPlane : return "Belong to Plane"; case FT_BelongToCylinder: return "Belong to Cylinder"; @@ -2820,6 +3000,8 @@ static inline SMESH::FunctorType toFunctorType( const LDOMString& theStr ) else if ( theStr.equals( "Skew" ) ) return FT_Skew; else if ( theStr.equals( "Area" ) ) return FT_Area; else if ( theStr.equals( "Volume3D" ) ) return FT_Volume3D; + else if ( theStr.equals( "Max element length 2D" ) ) return FT_MaxElementLength2D; + else if ( theStr.equals( "Max element length 3D" ) ) return FT_MaxElementLength3D; else if ( theStr.equals( "Belong to Geom" ) ) return FT_BelongToGeom; else if ( theStr.equals( "Belong to Plane" ) ) return FT_BelongToPlane; else if ( theStr.equals( "Belong to Cylinder" ) ) return FT_BelongToCylinder; diff --git a/src/SMESH_I/SMESH_Filter_i.hxx b/src/SMESH_I/SMESH_Filter_i.hxx index 057c7693b..bef8c2252 100644 --- a/src/SMESH_I/SMESH_Filter_i.hxx +++ b/src/SMESH_I/SMESH_Filter_i.hxx @@ -157,6 +157,7 @@ namespace SMESH { public: CORBA::Double GetValue( CORBA::Long theElementId ); + SMESH::Histogram* GetHistogram(CORBA::Short nbIntervals); void SetPrecision( CORBA::Long thePrecision ); CORBA::Long GetPrecision(); Controls::NumericalFunctorPtr GetNumericalFunctor(); @@ -270,6 +271,32 @@ namespace SMESH }; + /* + Class : MaxElementLength2D_i + Description : Functor for calculating maximum length of 2D element + */ + class SMESH_I_EXPORT MaxElementLength2D_i: public virtual POA_SMESH::MaxElementLength2D, + public virtual NumericalFunctor_i + { + public: + MaxElementLength2D_i(); + FunctorType GetFunctorType(); + }; + + + /* + Class : MaxElementLength3D_i + Description : Functor for calculating maximum length of 3D element + */ + class SMESH_I_EXPORT MaxElementLength3D_i: public virtual POA_SMESH::MaxElementLength3D, + public virtual NumericalFunctor_i + { + public: + MaxElementLength3D_i(); + FunctorType GetFunctorType(); + }; + + /* Class : Length_i Description : Functor for calculating length of edge @@ -622,6 +649,26 @@ namespace SMESH Controls::ElemGeomTypePtr myElemGeomTypePtr; }; + /* + Class : CoplanarFaces_i + Description : Returns true if a mesh face is a coplanar neighbour to a given one + */ + class SMESH_I_EXPORT CoplanarFaces_i: public virtual POA_SMESH::CoplanarFaces, + public virtual Predicate_i + { + public: + CoplanarFaces_i(); + FunctorType GetFunctorType(); + + void SetFace ( CORBA::Long theFaceID ); + void SetTolerance( CORBA::Double theToler ); + char* GetFaceAsString () const; + CORBA::Long GetFace () const; + CORBA::Double GetTolerance () const; + private: + Controls::CoplanarFacesPtr myCoplanarFacesPtr; + }; + /* Class : Comparator_i Description : Base class for comparators @@ -782,14 +829,6 @@ namespace SMESH void SetMesh( SMESH_Mesh_ptr ); - virtual - SMESH::long_array* - GetIDs(); - - virtual - SMESH::long_array* - GetMeshInfo(); - static void GetElementsId( Predicate_i*, @@ -823,6 +862,14 @@ namespace SMESH Predicate_i* GetPredicate_i(); + // ========================= + // SMESH_IDSource interface + // ========================= + virtual SMESH::long_array* GetIDs(); + virtual SMESH::long_array* GetMeshInfo(); + virtual SMESH::array_of_ElementType* GetTypes(); + virtual SMESH::SMESH_Mesh_ptr GetMesh(); + private: Controls::Filter myFilter; Predicate_i* myPredicate; @@ -886,6 +933,8 @@ namespace SMESH Skew_ptr CreateSkew(); Area_ptr CreateArea(); Volume3D_ptr CreateVolume3D(); + MaxElementLength2D_ptr CreateMaxElementLength2D(); + MaxElementLength3D_ptr CreateMaxElementLength3D(); Length_ptr CreateLength(); Length2D_ptr CreateLength2D(); MultiConnection_ptr CreateMultiConnection(); @@ -904,13 +953,11 @@ namespace SMESH FreeFaces_ptr CreateFreeFaces(); RangeOfIds_ptr CreateRangeOfIds(); - BadOrientedVolume_ptr CreateBadOrientedVolume(); LinearOrQuadratic_ptr CreateLinearOrQuadratic(); - GroupColor_ptr CreateGroupColor(); - ElemGeomType_ptr CreateElemGeomType(); + CoplanarFaces_ptr CreateCoplanarFaces(); LessThan_ptr CreateLessThan(); MoreThan_ptr CreateMoreThan(); diff --git a/src/SMESH_I/SMESH_Gen_i.cxx b/src/SMESH_I/SMESH_Gen_i.cxx index 49ec45fad..a0ce885aa 100644 --- a/src/SMESH_I/SMESH_Gen_i.cxx +++ b/src/SMESH_I/SMESH_Gen_i.cxx @@ -889,7 +889,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromUNV( const char* theFileName aStudyBuilder->CommitCommand(); if ( !aSO->_is_nil() ) { // Update Python script - TPythonDump() << aSO << " = smeshgen.CreateMeshesFromUNV('" << theFileName << "')"; + TPythonDump() << aSO << " = smeshgen.CreateMeshesFromUNV(r'" << theFileName << "')"; } } @@ -932,7 +932,6 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName, // Python Dump TPythonDump aPythonDump; aPythonDump << "(["; - //TCollection_AsciiString aStr ("(["); if (theStatus == SMESH::DRS_OK) { SALOMEDS::StudyBuilder_var aStudyBuilder = myCurrentStudy->NewBuilder(); @@ -943,7 +942,6 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName, // Iterate through all meshes and create mesh objects for ( list::iterator it = aNames.begin(); it != aNames.end(); it++ ) { // Python Dump - //if (i > 0) aStr += ", "; if (i > 0) aPythonDump << ", "; // create mesh @@ -956,12 +954,9 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName, if ( !aSO->_is_nil() ) { // Python Dump aPythonDump << aSO; - //aStr += aSO->GetID(); } else { // Python Dump aPythonDump << "mesh_" << i; -// aStr += "mesh_"; -// aStr += TCollection_AsciiString(i); } // Read mesh data (groups are published automatically by ImportMEDFile()) @@ -978,7 +973,7 @@ SMESH::mesh_array* SMESH_Gen_i::CreateMeshesFromMED( const char* theFileName, } // Update Python script - aPythonDump << "], status) = " << this << ".CreateMeshesFromMED('" << theFileName << "')"; + aPythonDump << "], status) = " << this << ".CreateMeshesFromMED(r'" << theFileName << "')"; } // Dump creation of groups for ( int i = 0; i < aResult->length(); ++i ) @@ -1012,7 +1007,7 @@ SMESH::SMESH_Mesh_ptr SMESH_Gen_i::CreateMeshesFromSTL( const char* theFileName aStudyBuilder->CommitCommand(); if ( !aSO->_is_nil() ) { // Update Python script - TPythonDump() << aSO << " = " << this << ".CreateMeshesFromSTL('" << theFileName << "')"; + TPythonDump() << aSO << " = " << this << ".CreateMeshesFromSTL(r'" << theFileName << "')"; } } @@ -1431,7 +1426,9 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, myLocShape = SMESH_Mesh::PseudoShape(); // call implementation compute ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); - return myGen.Compute( myLocMesh, myLocShape); + bool ok = myGen.Compute( myLocMesh, myLocShape); + meshServant->CreateGroupServants(); // algos can create groups (issue 0020918) + return ok; } } catch ( std::bad_alloc ) { @@ -2157,7 +2154,7 @@ SMESH_Gen_i::ConcatenateCommon(const SMESH::mesh_array& theMeshesArray, if (theMergeNodesAndElements) { // merge nodes - set aMeshNodes; // no input nodes + TIDSortedNodeSet aMeshNodes; // no input nodes SMESH_MeshEditor::TListOfListOfNodes aGroupsOfNodes; aNewEditor.FindCoincidentNodes( aMeshNodes, theMergeTolerance, aGroupsOfNodes ); aNewEditor.MergeNodes( aGroupsOfNodes ); @@ -2323,6 +2320,38 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, DriverMED_W_SMESHDS_Mesh myWriter; myWriter.SetFile( meshfile.ToCString() ); + // IMP issue 20918 + // SetStoreName() to groups before storing hypotheses to let them refer to + // groups using "store name", which is "Group " + { + SALOMEDS::ChildIterator_var itBig = myCurrentStudy->NewChildIterator( theComponent ); + for ( ; itBig->More(); itBig->Next() ) { + SALOMEDS::SObject_var gotBranch = itBig->Value(); + if ( gotBranch->Tag() > GetAlgorithmsRootTag() ) { + CORBA::Object_var anObject = SObjectToObject( gotBranch ); + if ( !CORBA::is_nil( anObject ) ) { + SMESH::SMESH_Mesh_var myMesh = SMESH::SMESH_Mesh::_narrow( anObject ) ; + if ( !myMesh->_is_nil() ) { + SMESH::ListOfGroups_var groups = myMesh->GetGroups(); + for ( int i = 0; i < groups->length(); ++i ) + { + SMESH_GroupBase_i* grImpl = SMESH::DownCast( groups[i]); + if ( grImpl ) + { + CORBA::String_var objStr = GetORB()->object_to_string( grImpl->_this() ); + int anId = myStudyContext->findId( string( objStr.in() ) ); + char grpName[ 30 ]; + sprintf( grpName, "Group %d", anId ); + SMESHDS_GroupBase* aGrpBaseDS = grImpl->GetGroupDS(); + aGrpBaseDS->SetStoreName( grpName ); + } + } + } + } + } + } + } + // Write data // ---> create HDF file aFile = new HDFfile( (char*) filename.ToCString() ); @@ -2519,13 +2548,21 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aDataset->CloseOnDisk(); // issue 0020693. Store _isModified flag - int isModified = myImpl->GetImpl().GetIsModified(); + int isModified = myLocMesh.GetIsModified(); aSize[ 0 ] = 1; aDataset = new HDFdataset( "_isModified", aTopGroup, HDF_INT32, aSize, 1 ); aDataset->CreateOnDisk(); aDataset->WriteOnDisk( &isModified ); aDataset->CloseOnDisk(); + // issue 20918. Store Persistent Id of SMESHDS_Mesh + int meshPersistentId = mySMESHDSMesh->GetPersistentId(); + aSize[ 0 ] = 1; + aDataset = new HDFdataset( "meshPersistentId", aTopGroup, HDF_INT32, aSize, 1 ); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( &meshPersistentId ); + aDataset->CloseOnDisk(); + // write reference on a shape if exists SALOMEDS::SObject_var myRef; bool shapeRefFound = false; @@ -2869,17 +2906,19 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, dynamic_cast( GetServant( aSubObject ).in() ); if ( !myGroupImpl ) continue; + SMESHDS_GroupBase* aGrpBaseDS = myGroupImpl->GetGroupDS(); + if ( !aGrpBaseDS ) + continue; CORBA::String_var objStr = GetORB()->object_to_string( aSubObject ); int anId = myStudyContext->findId( string( objStr.in() ) ); - + // For each group, create a dataset named "Group " // and store the group's user name into it - char grpName[ 30 ]; - sprintf( grpName, "Group %d", anId ); + const char* grpName = aGrpBaseDS->GetStoreName(); char* aUserName = myGroupImpl->GetName(); aSize[ 0 ] = strlen( aUserName ) + 1; - + aDataset = new HDFdataset( grpName, aGroup, HDF_STRING, aSize, 1 ); aDataset->CreateOnDisk(); aDataset->WriteOnDisk( aUserName ); @@ -2901,46 +2940,36 @@ SALOMEDS::TMPFile* SMESH_Gen_i::Save( SALOMEDS::SComponent_ptr theComponent, aDataset->WriteOnDisk( anRGB ); aDataset->CloseOnDisk(); - // Store the group contents into MED file - if ( myLocMesh.GetGroup( myGroupImpl->GetLocalID() ) ) { - - if(MYDEBUG) MESSAGE( "VSR - SMESH_Gen_i::Save(): saving group with StoreName = " - << grpName << " to MED file" ); - SMESHDS_GroupBase* aGrpBaseDS = - myLocMesh.GetGroup( myGroupImpl->GetLocalID() )->GetGroupDS(); - aGrpBaseDS->SetStoreName( grpName ); - - // Pass SMESHDS_Group to MED writer - SMESHDS_Group* aGrpDS = dynamic_cast( aGrpBaseDS ); - if ( aGrpDS ) - myWriter.AddGroup( aGrpDS ); - - // write reference on a shape if exists - SMESHDS_GroupOnGeom* aGeomGrp = - dynamic_cast( aGrpBaseDS ); - if ( aGeomGrp ) { - SALOMEDS::SObject_var mySubRef, myShape; - if (mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef ) && - mySubRef->ReferencedObject( myShape ) && - !CORBA::is_nil( myShape->GetObject() )) - { - string myRefOnObject = myShape->GetID(); - if ( myRefOnObject.length() > 0 ) { - char aRefName[ 30 ]; - sprintf( aRefName, "Ref on shape %d", anId); - aSize[ 0 ] = myRefOnObject.length() + 1; - aDataset = new HDFdataset(aRefName, aGroup, HDF_STRING, aSize, 1); - aDataset->CreateOnDisk(); - aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) ); - aDataset->CloseOnDisk(); - } - } - else // shape ref is invalid: - { - // save a group on geometry as ordinary group - myWriter.AddGroup( aGeomGrp ); + // Pass SMESHDS_Group to MED writer + SMESHDS_Group* aGrpDS = dynamic_cast( aGrpBaseDS ); + if ( aGrpDS ) + myWriter.AddGroup( aGrpDS ); + + // write reference on a shape if exists + SMESHDS_GroupOnGeom* aGeomGrp = + dynamic_cast( aGrpBaseDS ); + if ( aGeomGrp ) { + SALOMEDS::SObject_var mySubRef, myShape; + if (mySObject->FindSubObject( GetRefOnShapeTag(), mySubRef ) && + mySubRef->ReferencedObject( myShape ) && + !CORBA::is_nil( myShape->GetObject() )) + { + string myRefOnObject = myShape->GetID(); + if ( myRefOnObject.length() > 0 ) { + char aRefName[ 30 ]; + sprintf( aRefName, "Ref on shape %d", anId); + aSize[ 0 ] = myRefOnObject.length() + 1; + aDataset = new HDFdataset(aRefName, aGroup, HDF_STRING, aSize, 1); + aDataset->CreateOnDisk(); + aDataset->WriteOnDisk( ( char* )( myRefOnObject.c_str() ) ); + aDataset->CloseOnDisk(); } } + else // shape ref is invalid: + { + // save a group on geometry as ordinary group + myWriter.AddGroup( aGeomGrp ); + } } } } @@ -3247,13 +3276,15 @@ public: } PositionCreator() { myFuncTable.resize( (size_t) TopAbs_SHAPE, & PositionCreator::defaultPosition ); - myFuncTable[ TopAbs_FACE ] = & PositionCreator::facePosition; - myFuncTable[ TopAbs_EDGE ] = & PositionCreator::edgePosition; + myFuncTable[ TopAbs_SOLID ] = & PositionCreator::volumePosition; + myFuncTable[ TopAbs_FACE ] = & PositionCreator::facePosition; + myFuncTable[ TopAbs_EDGE ] = & PositionCreator::edgePosition; myFuncTable[ TopAbs_VERTEX ] = & PositionCreator::vertexPosition; } private: SMDS_PositionPtr edgePosition() const { return SMDS_PositionPtr( new SMDS_EdgePosition ); } SMDS_PositionPtr facePosition() const { return SMDS_PositionPtr( new SMDS_FacePosition ); } + SMDS_PositionPtr volumePosition() const { return SMDS_PositionPtr( new SMDS_SpacePosition ); } SMDS_PositionPtr vertexPosition() const { return SMDS_PositionPtr( new SMDS_VertexPosition); } SMDS_PositionPtr defaultPosition() const { return SMDS_SpacePosition::originSpacePosition(); } typedef SMDS_PositionPtr (PositionCreator:: * FmakePos)() const; @@ -3628,6 +3659,18 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aDataset->CloseOnDisk(); myNewMeshImpl->GetImpl().SetIsModified( bool(*isModified)); } + + // issue 20918. Restore Persistent Id of SMESHDS_Mesh + if( aTopGroup->ExistInternalObject( "meshPersistentId" ) ) + { + aDataset = new HDFdataset( "meshPersistentId", aTopGroup ); + aDataset->OpenOnDisk(); + size = aDataset->GetSize(); + int* meshPersistentId = new int[ size ]; + aDataset->ReadFromDisk( meshPersistentId ); + aDataset->CloseOnDisk(); + myNewMeshImpl->GetImpl().GetMeshDS()->SetPersistentId( *meshPersistentId ); + } } } } @@ -3942,7 +3985,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aGroup = new HDFgroup( "Submeshes", aTopGroup ); aGroup->OpenOnDisk(); - int maxID = mySMESHDSMesh->MaxShapeIndex(); + int maxID = Max( mySMESHDSMesh->MaxSubMeshIndex(), mySMESHDSMesh->MaxShapeIndex() ); vector< SMESHDS_SubMesh * > subMeshes( maxID + 1, (SMESHDS_SubMesh*) 0 ); vector< TopAbs_ShapeEnum > smType ( maxID + 1, TopAbs_SHAPE ); @@ -4130,20 +4173,6 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, } // if ( aTopGroup->ExistInternalObject( "Node Positions" ) ) } // if ( hasData ) - // Recompute State (as computed sub-meshes are restored from MED) - if ( !aShapeObject->_is_nil() || !myNewMeshImpl->HasShapeToMesh()) { - MESSAGE("Compute State Engine ..."); - TopoDS_Shape myLocShape; - if(myNewMeshImpl->HasShapeToMesh()) - myLocShape = GeomObjectToShape( aShapeObject ); - else - myLocShape = SMESH_Mesh::PseudoShape(); - - myNewMeshImpl->GetImpl().GetSubMesh(myLocShape)->ComputeStateEngine - (SMESH_subMesh::SUBMESH_RESTORED); - MESSAGE("Compute State Engine finished"); - } - // try to get groups for ( int ii = GetNodeGroupsTag(); ii <= GetVolumeGroupsTag(); ii++ ) { char name_group[ 30 ]; @@ -4250,6 +4279,7 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, aGroup->CloseOnDisk(); } } + // read submeh order if any if( aTopGroup->ExistInternalObject( "Mesh Order" ) ) { aDataset = new HDFdataset( "Mesh Order", aTopGroup ); @@ -4268,7 +4298,30 @@ bool SMESH_Gen_i::Load( SALOMEDS::SComponent_ptr theComponent, myNewMeshImpl->GetImpl().SetMeshOrder( anOrderIds ); } + } // loop on meshes + + // notify algos on completed restoration + for ( meshi_group = meshGroupList.begin(); meshi_group != meshGroupList.end(); ++meshi_group ) + { + SMESH_Mesh_i* myNewMeshImpl = meshi_group->first; + ::SMESH_Mesh& myLocMesh = myNewMeshImpl->GetImpl(); + + TopoDS_Shape myLocShape; + if(myLocMesh.HasShapeToMesh()) + myLocShape = myLocMesh.GetShapeToMesh(); + else + myLocShape = SMESH_Mesh::PseudoShape(); + + myLocMesh.GetSubMesh(myLocShape)-> + ComputeStateEngine (SMESH_subMesh::SUBMESH_RESTORED); } + + for ( hyp_data = hypDataList.begin(); hyp_data != hypDataList.end(); ++hyp_data ) + { + SMESH_Hypothesis_i* hyp = hyp_data->first; + hyp->UpdateAsMeshesRestored(); // for hyps needing full mesh data restored (issue 20918) + } + // close mesh group if(aTopGroup) aTopGroup->CloseOnDisk(); diff --git a/src/SMESH_I/SMESH_Gen_i.hxx b/src/SMESH_I/SMESH_Gen_i.hxx index 89cf79ca7..b2c90805c 100644 --- a/src/SMESH_I/SMESH_Gen_i.hxx +++ b/src/SMESH_I/SMESH_Gen_i.hxx @@ -223,7 +223,7 @@ public: SMESH::SMESH_Mesh_ptr CreateEmptyMesh() throw ( SALOME::SALOME_Exception ); - // Create mesh(es) and import data from UNV file + // Create mesh(es) and import data from UNV fileter SMESH::SMESH_Mesh_ptr CreateMeshesFromUNV( const char* theFileName ) throw ( SALOME::SALOME_Exception ); @@ -357,6 +357,9 @@ public: // Return a pattern mesher SMESH::SMESH_Pattern_ptr GetPattern(); + // Create measurement instance + SMESH::Measurements_ptr CreateMeasurements(); + // Clears study-connected data when it is closed void Close( SALOMEDS::SComponent_ptr theComponent ); diff --git a/src/SMESH_I/SMESH_Gen_i_1.cxx b/src/SMESH_I/SMESH_Gen_i_1.cxx index d5161e29f..5a82382d6 100644 --- a/src/SMESH_I/SMESH_Gen_i_1.cxx +++ b/src/SMESH_I/SMESH_Gen_i_1.cxx @@ -19,14 +19,14 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // - // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses -// File : SMESH_Gen_i_1.cxx -// Created : Thu Oct 21 17:24:06 2004 -// Author : Edward AGAPOV (eap) -// Module : SMESH -// $Header: // +// File : SMESH_Gen_i_1.cxx +// Created : Thu Oct 21 17:24:06 2004 +// Author : Edward AGAPOV (eap) +// Module : SMESH +// $Header : $ + #include "SMESH_Gen_i.hxx" #include "SMESH_Mesh_i.hxx" @@ -923,7 +923,30 @@ void SMESH_Gen_i::UpdateParameters(CORBA::Object_ptr theObject, const char* theP if(!hasAttr) aNewParams = anInputParams; else - aNewParams = aOldParameters+"|"+anInputParams; + { + int pos = aOldParameters.SearchFromEnd("|"); + if(pos==-1) pos = 0; + TCollection_AsciiString previousParamFull(aOldParameters.Split(pos)); + TCollection_AsciiString previousParam(previousParamFull); + TCollection_AsciiString theRepet("1"); + pos = previousParam.SearchFromEnd(";*="); + if(pos >= 0) + { + theRepet = previousParam.Split(pos+2); + pos = pos-1; + if(pos==-1) pos = 0; + previousParam.Split(pos); + } + if(previousParam == anInputParams) + { + theRepet = theRepet.IntegerValue()+1; + aNewParams = aOldParameters + previousParam + ";*=" + theRepet; + } + else + { + aNewParams = aOldParameters + previousParamFull + "|" + anInputParams; + } + } if(VARIABLE_DEBUG) { diff --git a/src/SMESH_I/SMESH_Group_i.cxx b/src/SMESH_I/SMESH_Group_i.cxx index c69024ed2..592d172ba 100644 --- a/src/SMESH_I/SMESH_Group_i.cxx +++ b/src/SMESH_I/SMESH_Group_i.cxx @@ -36,6 +36,8 @@ #include "SMESH_Filter_i.hxx" #include "SMESH_PythonDump.hxx" +#include CORBA_SERVER_HEADER(SMESH_Filter) + #include "utilities.h" using namespace SMESH; @@ -347,6 +349,37 @@ RemoveByPredicate( SMESH::Predicate_ptr thePredicate ) return 0; } +CORBA::Long SMESH_Group_i::AddFrom( SMESH::SMESH_IDSource_ptr theSource ) +{ + long nbAdd = 0; + SMESHDS_Group* aGroupDS = dynamic_cast( GetGroupDS() ); + if (aGroupDS) { + SMESH::long_array_var anIds; + SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theSource); + SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow(theSource); + SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow(theSource); + SMESH::Filter_var filter = SMESH::Filter::_narrow(theSource); + if ( !group->_is_nil()) + anIds = group->GetType()==GetType() ? theSource->GetIDs() : new SMESH::long_array(); + else if ( !mesh->_is_nil() ) + anIds = mesh->GetElementsByType( GetType() ); + else if ( !submesh->_is_nil()) + anIds = submesh->GetElementsByType( GetType() ); + else if ( !filter->_is_nil() ) + anIds = filter->GetElementType()==GetType() ? theSource->GetIDs() : new SMESH::long_array(); + else + anIds = theSource->GetIDs(); + for ( int i = 0, total = anIds->length(); i < total; i++ ) { + if ( aGroupDS->Add((int)anIds[i]) ) nbAdd++; + } + } + + // Update Python script + TPythonDump() << "nbAdd = " << _this() << ".AddFrom( " << theSource << " )"; + + return nbAdd; +} + //============================================================================= /*! * @@ -396,17 +429,6 @@ SMESH::SMESH_Mesh_ptr SMESH_GroupBase_i::GetMesh() return aMesh._retn(); } -//============================================================================= -/*! - * - */ -//============================================================================= -SMESH::long_array* SMESH_GroupBase_i::GetIDs() -{ - SMESH::long_array_var aResult = GetListOfID(); - return aResult._retn(); -} - //======================================================================= //function : GetShape //purpose : @@ -513,3 +535,28 @@ SMESH::long_array* SMESH_GroupBase_i::GetMeshInfo() SMESH_Mesh_i::CollectMeshInfo( aGrpDS->GetElements(), aRes); return aRes._retn(); } + +//======================================================================= +//function : GetIDs +//purpose : Returns ids of members +//======================================================================= + +SMESH::long_array* SMESH_GroupBase_i::GetIDs() +{ + SMESH::long_array_var aResult = GetListOfID(); + return aResult._retn(); +} + +//======================================================================= +//function : GetTypes +//purpose : Returns types of elements it contains +//======================================================================= + +SMESH::array_of_ElementType* SMESH_GroupBase_i::GetTypes() +{ + SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType; + types->length( 1 ); + types[0] = GetType(); + return types._retn(); +} + diff --git a/src/SMESH_I/SMESH_Group_i.hxx b/src/SMESH_I/SMESH_Group_i.hxx index 30ea828c0..3b1b08eaa 100644 --- a/src/SMESH_I/SMESH_Group_i.hxx +++ b/src/SMESH_I/SMESH_Group_i.hxx @@ -75,6 +75,12 @@ class SMESH_I_EXPORT SMESH_GroupBase_i: // Inherited from SMESH_IDSource interface virtual SMESH::long_array* GetIDs(); + /*! + * Returns types of elements it contains + * Inherited from SMESH_IDSource interface + */ + virtual SMESH::array_of_ElementType* GetTypes(); + // Internal C++ interface int GetLocalID() const { return myLocalID; } SMESH_Mesh_i* GetMeshServant() const { return myMeshServant; } @@ -92,7 +98,7 @@ private: int myLocalID; void changeLocalId(int localId) { myLocalID = localId; } - friend void SMESH_Mesh_i::CheckGeomGroupModif(); + friend class SMESH_Mesh_i; }; // ====== @@ -113,6 +119,8 @@ class SMESH_I_EXPORT SMESH_Group_i: CORBA::Long AddByPredicate( SMESH::Predicate_ptr thePredicate ); CORBA::Long RemoveByPredicate( SMESH::Predicate_ptr thePredicate ); + + CORBA::Long AddFrom( SMESH::SMESH_IDSource_ptr theSource ); }; // ========================= diff --git a/src/SMESH_I/SMESH_Hypothesis_i.cxx b/src/SMESH_I/SMESH_Hypothesis_i.cxx index 19d436ff6..8875e4d1f 100644 --- a/src/SMESH_I/SMESH_Hypothesis_i.cxx +++ b/src/SMESH_I/SMESH_Hypothesis_i.cxx @@ -279,4 +279,17 @@ void SMESH_Hypothesis_i::LoadFrom( const char* theStream ) MESSAGE( "SMESH_Hypothesis_i::LoadFrom" ); std::istringstream is( theStream ); myBaseImpl->LoadFrom( is ); + // let listeners know about loading (issue 0020918) + myBaseImpl->NotifySubMeshesHypothesisModification(); +} + +//================================================================================ +/*! + * \brief This mesthod is called after completion of loading a study + */ +//================================================================================ + +void SMESH_Hypothesis_i::UpdateAsMeshesRestored() +{ + // for hyps needing full data restored } diff --git a/src/SMESH_I/SMESH_Hypothesis_i.hxx b/src/SMESH_I/SMESH_Hypothesis_i.hxx index 24c01d46a..99eba89ca 100644 --- a/src/SMESH_I/SMESH_Hypothesis_i.hxx +++ b/src/SMESH_I/SMESH_Hypothesis_i.hxx @@ -91,7 +91,8 @@ public: // Persistence virtual char* SaveTo(); virtual void LoadFrom( const char* theStream ); - + virtual void UpdateAsMeshesRestored(); // for hyps needing full data restored + protected: ::SMESH_Hypothesis* myBaseImpl; // base hypothesis implementation }; diff --git a/src/SMESH_I/SMESH_MEDFamily_i.cxx b/src/SMESH_I/SMESH_MEDFamily_i.cxx index 66d26cc0d..8dbd37d19 100644 --- a/src/SMESH_I/SMESH_MEDFamily_i.cxx +++ b/src/SMESH_I/SMESH_MEDFamily_i.cxx @@ -126,7 +126,7 @@ throw (SALOME::SALOME_Exception) * CORBA: Accessor for attributes identifiers */ //============================================================================= -SALOME_MED::long_array* SMESH_MEDFamily_i::getAttributesIdentifiers() +SALOME_TYPES::ListOfLong* SMESH_MEDFamily_i::getAttributesIdentifiers() throw (SALOME::SALOME_Exception) { if (_subMeshDS==NULL) @@ -139,7 +139,7 @@ throw (SALOME::SALOME_Exception) ,SALOME::BAD_PARAM); }; - SALOME_MED::long_array_var myseq= new SALOME_MED::long_array; + SALOME_TYPES::ListOfLong_var myseq= new SALOME_TYPES::ListOfLong; myseq->length(_numberOfAttribute); for (int i=0;i<_numberOfAttribute;i++) { @@ -176,7 +176,7 @@ CORBA::Long SMESH_MEDFamily_i::getAttributeIdentifier(CORBA::Long i) * CORBA: Accessor for attributes values */ //============================================================================= -SALOME_MED::long_array* SMESH_MEDFamily_i::getAttributesValues() +SALOME_TYPES::ListOfLong* SMESH_MEDFamily_i::getAttributesValues() throw (SALOME::SALOME_Exception) { if (_subMeshDS==NULL) @@ -190,7 +190,7 @@ SALOME_MED::long_array* SMESH_MEDFamily_i::getAttributesValues() ,SALOME::BAD_PARAM); }; - SALOME_MED::long_array_var myseq= new SALOME_MED::long_array; + SALOME_TYPES::ListOfLong_var myseq= new SALOME_TYPES::ListOfLong; myseq->length(_numberOfAttribute); for (int i=0;i<_numberOfAttribute;i++) { @@ -224,7 +224,7 @@ CORBA::Long SMESH_MEDFamily_i::getAttributeValue(CORBA::Long i) * CORBA: Accessor for attributes desriptions */ //============================================================================= -SALOME_MED::string_array * SMESH_MEDFamily_i::getAttributesDescriptions() +SALOME_TYPES::ListOfString * SMESH_MEDFamily_i::getAttributesDescriptions() throw (SALOME::SALOME_Exception) { if (_subMeshDS==NULL) @@ -236,7 +236,7 @@ SALOME_MED::string_array * SMESH_MEDFamily_i::getAttributesDescriptions() THROW_SALOME_CORBA_EXCEPTION("No attributes"\ ,SALOME::BAD_PARAM); } - SALOME_MED::string_array_var myseq = new SALOME_MED::string_array; + SALOME_TYPES::ListOfString_var myseq = new SALOME_TYPES::ListOfString; for (int i=0;i<_numberOfAttribute;i++) { myseq[i]=CORBA::string_dup(_attributeDescription[i].c_str()); @@ -292,7 +292,7 @@ char * SMESH_MEDFamily_i::getGroupName( CORBA::Long i) * CORBA: Accessor for all the groups name */ //============================================================================= -SALOME_MED::string_array* SMESH_MEDFamily_i::getGroupsNames() +SALOME_TYPES::ListOfString* SMESH_MEDFamily_i::getGroupsNames() throw (SALOME::SALOME_Exception) { MESSAGE("!!! NOT YET IMPLEMENTED !!!!"); diff --git a/src/SMESH_I/SMESH_MEDFamily_i.hxx b/src/SMESH_I/SMESH_MEDFamily_i.hxx index 06a13600d..27f4d80b5 100644 --- a/src/SMESH_I/SMESH_MEDFamily_i.hxx +++ b/src/SMESH_I/SMESH_MEDFamily_i.hxx @@ -70,15 +70,15 @@ public : throw (SALOME::SALOME_Exception); CORBA::Long getNumberOfAttributes() throw (SALOME::SALOME_Exception); - SALOME_MED::long_array* getAttributesIdentifiers() + SALOME_TYPES::ListOfLong* getAttributesIdentifiers() throw (SALOME::SALOME_Exception); CORBA::Long getAttributeIdentifier(CORBA::Long i) throw (SALOME::SALOME_Exception); - SALOME_MED::long_array* getAttributesValues() + SALOME_TYPES::ListOfLong* getAttributesValues() throw (SALOME::SALOME_Exception); CORBA::Long getAttributeValue(CORBA::Long i) throw (SALOME::SALOME_Exception); - SALOME_MED::string_array* getAttributesDescriptions() + SALOME_TYPES::ListOfString* getAttributesDescriptions() throw (SALOME::SALOME_Exception); char* getAttributeDescription( CORBA::Long i) throw (SALOME::SALOME_Exception); @@ -86,7 +86,7 @@ public : throw (SALOME::SALOME_Exception); char * getGroupName( CORBA::Long i) throw (SALOME::SALOME_Exception); - SALOME_MED::string_array* getGroupsNames() + SALOME_TYPES::ListOfString* getGroupsNames() throw (SALOME::SALOME_Exception); }; #endif /* MED_FAMILY_I_HXX_ */ diff --git a/src/SMESH_I/SMESH_MEDMesh_i.cxx b/src/SMESH_I/SMESH_MEDMesh_i.cxx index b1b093770..e69b00e45 100644 --- a/src/SMESH_I/SMESH_MEDMesh_i.cxx +++ b/src/SMESH_I/SMESH_MEDMesh_i.cxx @@ -248,13 +248,13 @@ char *SMESH_MEDMesh_i::getCoordinatesSystem() throw(SALOME::SALOME_Exception) * CORBA: Accessor for Coordinates */ //============================================================================= -SALOME_MED::double_array * SMESH_MEDMesh_i::getCoordinates +SALOME_TYPES::ListOfDouble * SMESH_MEDMesh_i::getCoordinates (SALOME_MED::medModeSwitch typeSwitch) throw(SALOME::SALOME_Exception) { if (_mesh_i == 0) THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", SALOME::INTERNAL_ERROR); - SALOME_MED::double_array_var myseq = new SALOME_MED::double_array; + SALOME_TYPES::ListOfDouble_var myseq = new SALOME_TYPES::ListOfDouble; try { // PN : En dur @@ -305,13 +305,13 @@ SALOME_MED::double_array * SMESH_MEDMesh_i::getCoordinates * CORBA: Accessor for Coordinates Names */ //============================================================================= -SALOME_MED::string_array * +SALOME_TYPES::ListOfString * SMESH_MEDMesh_i::getCoordinatesNames()throw(SALOME::SALOME_Exception) { if (_mesh_i == 0) THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", SALOME::INTERNAL_ERROR); - SALOME_MED::string_array_var myseq = new SALOME_MED::string_array; + SALOME_TYPES::ListOfString_var myseq = new SALOME_TYPES::ListOfString; try { // PN : en dur @@ -336,13 +336,13 @@ SMESH_MEDMesh_i::getCoordinatesNames()throw(SALOME::SALOME_Exception) * CORBA: Accessor for Coordinates Units */ //============================================================================= -SALOME_MED::string_array * +SALOME_TYPES::ListOfString * SMESH_MEDMesh_i::getCoordinatesUnits()throw(SALOME::SALOME_Exception) { if (_mesh_i == 0) THROW_SALOME_CORBA_EXCEPTION("No associated Mesh", SALOME::INTERNAL_ERROR); - SALOME_MED::string_array_var myseq = new SALOME_MED::string_array; + SALOME_TYPES::ListOfString_var myseq = new SALOME_TYPES::ListOfString; try { // PN : en dur @@ -509,7 +509,7 @@ CORBA::Long SMESH_MEDMesh_i::getNumberOfElements(SALOME_MED:: * CORBA: Accessor for connectivities */ //============================================================================= -SALOME_MED::long_array * +SALOME_TYPES::ListOfLong * SMESH_MEDMesh_i::getConnectivity(SALOME_MED::medModeSwitch typeSwitch, SALOME_MED::medConnectivity mode, SALOME_MED::medEntityMesh entity, @@ -541,7 +541,7 @@ SMESH_MEDMesh_i::getConnectivity(SALOME_MED::medModeSwitch typeSwitch, * CORBA: Accessor for connectivities */ //============================================================================= -SALOME_MED::long_array * +SALOME_TYPES::ListOfLong * SMESH_MEDMesh_i::getConnectivityIndex(SALOME_MED::medConnectivity mode, SALOME_MED::medEntityMesh entity) throw(SALOME::SALOME_Exception) @@ -560,7 +560,7 @@ CORBA::Long SMESH_MEDMesh_i::getElementNumber(SALOME_MED::medConnectivity mode, SALOME_MED::medEntityMesh entity, SALOME_MED::medGeometryElement type, - const SALOME_MED::long_array & connectivity) + const SALOME_TYPES::ListOfLong & connectivity) throw(SALOME::SALOME_Exception) { const char *LOC = "getElementNumber "; @@ -575,7 +575,7 @@ SMESH_MEDMesh_i::getElementNumber(SALOME_MED::medConnectivity mode, * not implemented for MED_ALL_ENTITIES and MED_MAILLE */ //============================================================================= -SALOME_MED::long_array * +SALOME_TYPES::ListOfLong * SMESH_MEDMesh_i::getReverseConnectivity(SALOME_MED:: medConnectivity mode) throw(SALOME::SALOME_Exception) { @@ -589,7 +589,7 @@ SMESH_MEDMesh_i::getReverseConnectivity(SALOME_MED:: * CORBA: Accessor for connectivities */ //============================================================================= -SALOME_MED::long_array * +SALOME_TYPES::ListOfLong * SMESH_MEDMesh_i::getReverseConnectivityIndex(SALOME_MED:: medConnectivity mode) throw(SALOME::SALOME_Exception) { @@ -708,7 +708,7 @@ SALOME_MED::GROUP_ptr SMESH_MEDMesh_i::getGroup(SALOME_MED:: * CORBA: Returns references for the global numbering index */ //============================================================================= -SALOME_MED::long_array* +SALOME_TYPES::ListOfLong* SMESH_MEDMesh_i::getGlobalNumberingIndex(SALOME_MED::medEntityMesh entity) throw (SALOME::SALOME_Exception) { diff --git a/src/SMESH_I/SMESH_MEDMesh_i.hxx b/src/SMESH_I/SMESH_MEDMesh_i.hxx index 68fcc96c3..fa49725f5 100644 --- a/src/SMESH_I/SMESH_MEDMesh_i.hxx +++ b/src/SMESH_I/SMESH_MEDMesh_i.hxx @@ -63,7 +63,7 @@ protected: int _famIdent; std::map < SALOME_MED::medGeometryElement, int >_mapIndToSeqElts; - SALOME_MED::long_array_var _seq_elemId[MED_NBR_GEOMETRIE_MAILLE]; + SALOME_TYPES::ListOfLong_var _seq_elemId[MED_NBR_GEOMETRIE_MAILLE]; std::map < SALOME_MED::medEntityMesh, int >_mapNbTypes; std::map < SALOME_MED::medEntityMesh, int >_mapIndToVectTypes; @@ -112,13 +112,13 @@ public: CORBA::Double getCoordinate(CORBA::Long Number, CORBA::Long Axis) throw (SALOME::SALOME_Exception); - SALOME_MED::double_array * getCoordinates(SALOME_MED::medModeSwitch typeSwitch) + SALOME_TYPES::ListOfDouble * getCoordinates(SALOME_MED::medModeSwitch typeSwitch) throw(SALOME::SALOME_Exception); - SALOME_MED::string_array * getCoordinatesNames() + SALOME_TYPES::ListOfString * getCoordinatesNames() throw(SALOME::SALOME_Exception); - SALOME_MED::string_array * getCoordinatesUnits() + SALOME_TYPES::ListOfString * getCoordinatesUnits() throw(SALOME::SALOME_Exception); CORBA::Long getNumberOfNodes() throw(SALOME::SALOME_Exception); @@ -139,33 +139,33 @@ public: SALOME_MED::medGeometryElement geomElement) throw(SALOME::SALOME_Exception); - SALOME_MED::long_array * + SALOME_TYPES::ListOfLong * getConnectivity(SALOME_MED::medModeSwitch typeSwitch, SALOME_MED::medConnectivity mode, SALOME_MED::medEntityMesh entity, SALOME_MED::medGeometryElement geomElement) throw(SALOME::SALOME_Exception); - SALOME_MED::long_array * + SALOME_TYPES::ListOfLong * getConnectivityIndex(SALOME_MED::medConnectivity mode, SALOME_MED::medEntityMesh entity) throw(SALOME::SALOME_Exception); - SALOME_MED::long_array* + SALOME_TYPES::ListOfLong* getGlobalNumberingIndex(SALOME_MED::medEntityMesh entity) throw (SALOME::SALOME_Exception); CORBA::Long getElementNumber(SALOME_MED::medConnectivity mode, SALOME_MED::medEntityMesh entity, SALOME_MED::medGeometryElement type, - const SALOME_MED::long_array & connectivity) + const SALOME_TYPES::ListOfLong & connectivity) throw(SALOME::SALOME_Exception); - SALOME_MED::long_array * + SALOME_TYPES::ListOfLong * getReverseConnectivity(SALOME_MED::medConnectivity mode) throw(SALOME::SALOME_Exception); - SALOME_MED::long_array * + SALOME_TYPES::ListOfLong * getReverseConnectivityIndex(SALOME_MED::medConnectivity mode) throw(SALOME::SALOME_Exception); diff --git a/src/SMESH_I/SMESH_MEDSupport_i.cxx b/src/SMESH_I/SMESH_MEDSupport_i.cxx index c1a8fe548..adc941cbf 100644 --- a/src/SMESH_I/SMESH_MEDSupport_i.cxx +++ b/src/SMESH_I/SMESH_MEDSupport_i.cxx @@ -296,7 +296,7 @@ CORBA::Long SMESH_MEDSupport_i::getNumberOfElements(SALOME_MED:: */ //============================================================================= -SALOME_MED::long_array * SMESH_MEDSupport_i::getNumber( +SALOME_TYPES::ListOfLong * SMESH_MEDSupport_i::getNumber( SALOME_MED::medGeometryElement geomElement) throw(SALOME::SALOME_Exception) { Unexpect aCatch(SALOME_SalomeException); @@ -308,7 +308,7 @@ SALOME_MED::long_array * SMESH_MEDSupport_i::getNumber( if (geomElement != SALOME_MED::MED_NONE) THROW_SALOME_CORBA_EXCEPTION("Not implemented", SALOME::BAD_PARAM); - SALOME_MED::long_array_var myseq = new SALOME_MED::long_array; + SALOME_TYPES::ListOfLong_var myseq = new SALOME_TYPES::ListOfLong; int i = 0; myseq->length(_subMeshDS->NbNodes()); @@ -332,7 +332,7 @@ SALOME_MED::long_array * SMESH_MEDSupport_i::getNumber( */ //============================================================================= -SALOME_MED::long_array * SMESH_MEDSupport_i::getNumberFromFile( +SALOME_TYPES::ListOfLong * SMESH_MEDSupport_i::getNumberFromFile( SALOME_MED::medGeometryElement geomElement) throw(SALOME::SALOME_Exception) { return getNumber(geomElement); @@ -345,7 +345,7 @@ SALOME_MED::long_array * SMESH_MEDSupport_i::getNumberFromFile( */ //============================================================================= -SALOME_MED::long_array * +SALOME_TYPES::ListOfLong * SMESH_MEDSupport_i::getNumberIndex()throw(SALOME::SALOME_Exception) { MESSAGE("Not implemented for SMESH_i"); @@ -382,7 +382,7 @@ CORBA::Long SMESH_MEDSupport_i::getNumberOfTypes() * included in the support */ //============================================================================= -SALOME_MED::long_array* SMESH_MEDSupport_i::getNumbersOfGaussPoint() +SALOME_TYPES::ListOfLong* SMESH_MEDSupport_i::getNumbersOfGaussPoint() throw (SALOME::SALOME_Exception) { MESSAGE("!!! NOT YET IMPLEMENTED !!!!"); diff --git a/src/SMESH_I/SMESH_MEDSupport_i.hxx b/src/SMESH_I/SMESH_MEDSupport_i.hxx index b30528dad..5e8c821af 100644 --- a/src/SMESH_I/SMESH_MEDSupport_i.hxx +++ b/src/SMESH_I/SMESH_MEDSupport_i.hxx @@ -64,25 +64,25 @@ class SMESH_I_EXPORT SMESH_MEDSupport_i: CORBA::Long getNumberOfTypes() throw (SALOME::SALOME_Exception); - SALOME_MED::long_array * + SALOME_TYPES::ListOfLong * getNumber(SALOME_MED::medGeometryElement geomElement) throw(SALOME::SALOME_Exception); /*! * Same function as getNumber. */ - SALOME_MED::long_array * + SALOME_TYPES::ListOfLong * getNumberFromFile(SALOME_MED::medGeometryElement geomElement) throw(SALOME::SALOME_Exception); - SALOME_MED::long_array * getNumberIndex() + SALOME_TYPES::ListOfLong * getNumberIndex() throw(SALOME::SALOME_Exception); CORBA::Long getNumberOfGaussPoint(SALOME_MED::medGeometryElement geomElement) throw(SALOME::SALOME_Exception); - SALOME_MED::long_array* getNumbersOfGaussPoint() + SALOME_TYPES::ListOfLong* getNumbersOfGaussPoint() throw (SALOME::SALOME_Exception); SALOME_MED::medGeometryElement_array *getTypes() diff --git a/src/SMESH_I/SMESH_Measurements_i.cxx b/src/SMESH_I/SMESH_Measurements_i.cxx new file mode 100644 index 000000000..1397a4c39 --- /dev/null +++ b/src/SMESH_I/SMESH_Measurements_i.cxx @@ -0,0 +1,259 @@ +// 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 +// +// File : SMESH_Measurements_i.cxx +// Author : Pavel TELKOV, Open CASCADE S.A.S. (pavel.telkov@opencascade.com) + +#include "SMESH_Measurements_i.hxx" + +#include "SMESH_Gen_i.hxx" +#include "SMESH_PythonDump.hxx" + +#include "SMDS_Mesh.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMDS_MeshElement.hxx" +#include "SMDS_ElemIterator.hxx" + +#include "SMESHDS_Mesh.hxx" + + +using namespace SMESH; + +/** + * this local function to avoid uninitialized fields + */ +static void initMeasure( SMESH::Measure& theMeasure) +{ + + theMeasure.minX = theMeasure.minY = theMeasure.minZ = 0.; + theMeasure.maxX = theMeasure.maxY = theMeasure.maxZ = 0.; + theMeasure.node1 = theMeasure.node2 = -1; + theMeasure.elem1 = theMeasure.elem2 = -1; + theMeasure.value = 0.; +} + +//============================================================================= +/*! + * SMESH_Gen_i::CreateMeasurements + * + * Create measurement instance + */ +//============================================================================= + +SMESH::Measurements_ptr SMESH_Gen_i::CreateMeasurements() +{ + SMESH::Measurements_i* aMeasure = new SMESH::Measurements_i(); + SMESH::Measurements_var anObj = aMeasure->_this(); + return anObj._retn(); +} + + +/* + Class : Measurements + Description : make measure of mesh qunatities +*/ + +//======================================================================= +// name : Measurements_i +// Purpose : Constructor +//======================================================================= +Measurements_i::Measurements_i() +: SALOME::GenericObj_i( SMESH_Gen_i::GetPOA() ) +{ + //Base class Salome_GenericObject do it inmplicitly by overriding PortableServer::POA_ptr _default_POA() method + //PortableServer::ObjectId_var anObjectId = + // SMESH_Gen_i::GetPOA()->activate_object( this ); +} + +//======================================================================= +// name : ~Measurements_i +// Purpose : Destructor +//======================================================================= +Measurements_i::~Measurements_i() +{ + //TPythonDump()<X(); if (theNode2) dd -= theNode2->X(); theMeasure.minX = dd; dd *= dd; dist += dd; + dd = theNode1->Y(); if (theNode2) dd -= theNode2->Y(); theMeasure.minY = dd; dd *= dd; dist += dd; + dd = theNode1->Z(); if (theNode2) dd -= theNode2->Z(); theMeasure.minZ = dd; dd *= dd; dist += dd; + + if (dist < 0) + return false; + + theMeasure.value = sqrt(dist); + theMeasure.node1 = theNode1->GetID(); + theMeasure.node2 = theNode2 ? theNode2->GetID() : 0; + + return true; +} + +static SMESHDS_Mesh* getMesh(SMESH::SMESH_IDSource_ptr theSource) +{ + if (!CORBA::is_nil( theSource )) + { + SMESH_Mesh_i* anImplPtr = DownCast(theSource->GetMesh()); + if (anImplPtr) + return anImplPtr->GetImpl().GetMeshDS(); + } + return 0; +} + +static bool isNodeType (SMESH::array_of_ElementType_var theTypes) +{ + return theTypes->length() > 0 && theTypes[0] == SMESH::NODE; +} + +//======================================================================= +// name : MinDistance +// Purpose : minimal distance between two given entities +//======================================================================= +SMESH::Measure Measurements_i::MinDistance + (SMESH::SMESH_IDSource_ptr theSource1, + SMESH::SMESH_IDSource_ptr theSource2) +{ + SMESH::Measure aMeasure; + initMeasure(aMeasure); + + if (CORBA::is_nil( theSource1 )) + return aMeasure; + + // if second source is null, min distance from theSource1 to the origin is calculated + bool isOrigin = CORBA::is_nil( theSource2 ); + + // calculate minimal distance between two mesh entities + SMESH::array_of_ElementType_var types1 = theSource1->GetTypes(); + SMESH::array_of_ElementType_var types2; + if ( !isOrigin ) types2 = theSource2->GetTypes(); + + // here we assume that type of all IDs defined by first type in array + bool isNode1 = isNodeType(types1); + bool isNode2 = isOrigin || isNodeType(types2); + + SMESH::long_array_var aElementsId1 = theSource1->GetIDs(); + SMESH::long_array_var aElementsId2; + if ( !isOrigin ) aElementsId2 = theSource2->GetIDs(); + + // compute distance between two entities + /* NOTE: currently only node-to-node case is implemented + * all other cases will be implemented later + * below IF should be replaced by complete switch + * on mesh entities types + */ + if (isNode1 && isNode2) + { + // node - node + const SMESHDS_Mesh* aMesh1 = getMesh( theSource1 ); + const SMESHDS_Mesh* aMesh2 = isOrigin ? 0 : getMesh( theSource2 ); + const SMDS_MeshNode* theNode1 = aMesh1 ? aMesh1->FindNode( aElementsId1[0] ) : 0; + const SMDS_MeshNode* theNode2 = aMesh2 ? aMesh2->FindNode( aElementsId2[0] ) : 0; + getNodeNodeDistance( aMeasure, theNode1, theNode2 ); + } + else + { + // NOT_IMPLEMENTED + } + + return aMeasure; +} + +//======================================================================= +// name : enlargeBoundingBox +// Purpose : +//======================================================================= +static void enlargeBoundingBox(const SMDS_MeshNode* theNode, + SMESH::Measure& theMeasure) +{ + if (!theNode) + return; + if ( theMeasure.node1 == -1 ) { + // we use this attribute as a flag that it is the first node added to the bnd box + theMeasure.minX = theMeasure.maxX = theNode->X(); + theMeasure.minY = theMeasure.maxY = theNode->Y(); + theMeasure.minZ = theMeasure.maxZ = theNode->Z(); + theMeasure.node1 = theNode->GetID(); + } + else { + theMeasure.minX = min( theMeasure.minX, theNode->X() ); + theMeasure.maxX = max( theMeasure.maxX, theNode->X() ); + theMeasure.minY = min( theMeasure.minY, theNode->Y() ); + theMeasure.maxY = max( theMeasure.maxY, theNode->Y() ); + theMeasure.minZ = min( theMeasure.minZ, theNode->Z() ); + theMeasure.maxZ = max( theMeasure.maxZ, theNode->Z() ); + } +} + +//======================================================================= +// name : enlargeBoundingBox +// Purpose : +//======================================================================= +static void enlargeBoundingBox(const SMESH::SMESH_IDSource_ptr theObject, + SMESH::Measure& theMeasure) +{ + if ( CORBA::is_nil( theObject ) ) + return; + const SMESHDS_Mesh* aMesh = getMesh( theObject ); + if ( !aMesh ) + return; + SMESH::array_of_ElementType_var types = theObject->GetTypes(); + SMESH::long_array_var aElementsId = theObject->GetIDs(); + // here we assume that type of all IDs defined by first type in array + const bool isNode = isNodeType( types ); + for(int i = 0, n = aElementsId->length(); i < n; i++) + { + if (isNode) + enlargeBoundingBox( aMesh->FindNode( aElementsId[i] ), theMeasure); + else + { + const SMDS_MeshElement* elem = aMesh->FindElement( aElementsId[i] ); + if (!elem) + continue; + SMDS_ElemIteratorPtr aNodeIter = elem->nodesIterator(); + while( aNodeIter->more() ) + enlargeBoundingBox( dynamic_cast( aNodeIter->next() ), theMeasure); + } + } +} + +//======================================================================= +// name : BoundingBox +// Purpose : compute common bounding box of entities +//======================================================================= +SMESH::Measure Measurements_i::BoundingBox (const SMESH::ListOfIDSources& theSources) +{ + SMESH::Measure aMeasure; + initMeasure(aMeasure); + + // calculate bounding box on sources + for ( int i = 0, n = theSources.length(); i < n ; ++i ) + enlargeBoundingBox( theSources[i], aMeasure ); + + return aMeasure; +} diff --git a/src/SMESH_I/SMESH_Measurements_i.hxx b/src/SMESH_I/SMESH_Measurements_i.hxx new file mode 100644 index 000000000..0e1d77dcf --- /dev/null +++ b/src/SMESH_I/SMESH_Measurements_i.hxx @@ -0,0 +1,63 @@ +// 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 +// +// File : SMESH_Measurements_i.hxx +// Author : Pavel TELKOV, Open CASCADE S.A.S. (pavel.telkov@opencascade.com) + +#ifndef _SMESH_MEASUREMENTS_I_HXX_ +#define _SMESH_MEASUREMENTS_I_HXX_ + +#include "SMESH.hxx" + +#include +#include CORBA_SERVER_HEADER(SMESH_Measurements) + +#include "SALOME_GenericObj_i.hh" + +class SMESHDS_Mesh; + +namespace SMESH +{ + + /* + Measurements + */ + class SMESH_I_EXPORT Measurements_i: public virtual POA_SMESH::Measurements, + public virtual SALOME::GenericObj_i + { + public: + Measurements_i(); + ~Measurements_i(); + + /*! + * minimal distance between two given entities + */ + SMESH::Measure MinDistance(SMESH::SMESH_IDSource_ptr theSource1, + SMESH::SMESH_IDSource_ptr theSource2); + + /*! + * common bounding box of entities + */ + SMESH::Measure BoundingBox(const SMESH::ListOfIDSources& theSources); + }; +} + +#endif diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index 6887ed0a1..d442601d5 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -25,6 +25,10 @@ // Author : Nicolas REJNERI // Module : SMESH // +#ifdef WNT +#define NOMINMAX +#endif + #include "SMESH_MeshEditor_i.hxx" #include "SMDS_Mesh0DElement.hxx" @@ -32,13 +36,13 @@ #include "SMDS_MeshFace.hxx" #include "SMDS_MeshVolume.hxx" #include "SMDS_PolyhedralVolumeOfNodes.hxx" -#include "SMESH_MeshEditor.hxx" #include "SMESH_subMeshEventListener.hxx" #include "SMESH_Gen_i.hxx" #include "SMESH_Filter_i.hxx" #include "SMESH_subMesh_i.hxx" #include "SMESH_Group_i.hxx" #include "SMESH_PythonDump.hxx" +#include "SMESH_ControlsDef.hxx" #include "utilities.h" #include "Utils_ExceptHandlers.hxx" @@ -65,6 +69,7 @@ #endif #include +#include #define cast2Node(elem) static_cast( elem ) @@ -228,6 +233,91 @@ namespace { } return typeStr; } + //================================================================================ + /*! + * \brief function for conversion long_array to TIDSortedElemSet + * \param IDs - array of IDs + * \param aMesh - mesh + * \param aMap - collection to fill + * \param aType - element type + */ + //================================================================================ + + void arrayToSet(const SMESH::long_array & IDs, + const SMESHDS_Mesh* aMesh, + TIDSortedElemSet& aMap, + const SMDSAbs_ElementType aType = SMDSAbs_All ) + { + for (int i=0; iFindNode(ind) : aMesh->FindElement(ind)); + if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType )) + aMap.insert( elem ); + } + } + //================================================================================ + /*! + * \brief Retrieve elements of given type from SMESH_IDSource + */ + //================================================================================ + + bool idSourceToSet(SMESH::SMESH_IDSource_ptr theIDSource, + const SMESHDS_Mesh* theMeshDS, + TIDSortedElemSet& theElemSet, + const SMDSAbs_ElementType theType, + const bool emptyIfIsMesh=false) + + { + if ( CORBA::is_nil( theIDSource ) ) + return false; + if ( emptyIfIsMesh && SMESH::DownCast( theIDSource )) + return true; + + SMESH::long_array_var anIDs = theIDSource->GetIDs(); + if ( anIDs->length() == 0 ) + return false; + SMESH::array_of_ElementType_var types = theIDSource->GetTypes(); + if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes + { + if ( theType == SMDSAbs_All || theType == SMDSAbs_Node ) + arrayToSet( anIDs, theMeshDS, theElemSet, SMDSAbs_Node ); + else + return false; + } + else + { + arrayToSet( anIDs, theMeshDS, theElemSet, theType); + } + return true; + } + //================================================================================ + /*! + * \brief Retrieve nodes from SMESH_IDSource + */ + //================================================================================ + + void idSourceToNodeSet(SMESH::SMESH_IDSource_ptr theObject, + const SMESHDS_Mesh* theMeshDS, + TIDSortedNodeSet& theNodeSet) + + { + if ( CORBA::is_nil( theObject ) ) + return; + SMESH::array_of_ElementType_var types = theObject->GetTypes(); + SMESH::long_array_var aElementsId = theObject->GetIDs(); + if ( types->length() == 1 && types[0] == SMESH::NODE) + { + for(int i = 0; i < aElementsId->length(); i++) + if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] )) + theNodeSet.insert( theNodeSet.end(), n); + } + else { + for(int i = 0; i < aElementsId->length(); i++) + if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] )) + theNodeSet.insert( elem->begin_nodes(), elem->end_nodes()); + } + } } //============================================================================= @@ -279,17 +369,30 @@ void SMESH_MeshEditor_i::initData(bool deleteSearchers) struct _IDSource : public POA_SMESH::SMESH_IDSource { - SMESH::long_array _ids; + SMESH::long_array _ids; + SMESH::ElementType _type; + SMESH::SMESH_Mesh_ptr _mesh; SMESH::long_array* GetIDs() { return new SMESH::long_array( _ids ); } SMESH::long_array* GetMeshInfo() { return 0; } + SMESH::SMESH_Mesh_ptr GetMesh() { return SMESH::SMESH_Mesh::_duplicate( _mesh ); } + SMESH::array_of_ElementType* GetTypes() + { + SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType; + types->length( 1 ); + types[0] = _type; + return types._retn(); + } }; -SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids) +SMESH::SMESH_IDSource_ptr SMESH_MeshEditor_i::MakeIDSource(const SMESH::long_array& ids, + SMESH::ElementType type) { _IDSource* anIDSource = new _IDSource; anIDSource->_ids = ids; + anIDSource->_type = type; + anIDSource->_mesh = myMesh_i->_this(); SMESH::SMESH_IDSource_var anIDSourceVar = anIDSource->_this(); - + return anIDSourceVar._retn(); } @@ -350,6 +453,37 @@ CORBA::Boolean SMESH_MeshEditor_i::RemoveNodes(const SMESH::long_array & IDsOfNo */ //============================================================================= +CORBA::Long SMESH_MeshEditor_i::RemoveOrphanNodes() +{ + initData(); + + ::SMESH_MeshEditor anEditor( myMesh ); + + // Update Python script + TPythonDump() << "nbRemoved = " << this << ".RemoveOrphanNodes()"; + + // Create filter to find all orphan nodes + SMESH::Controls::Filter::TIdSequence seq; + SMESH::Controls::PredicatePtr predicate( new SMESH::Controls::FreeNodes() ); + SMESH::Controls::Filter::GetElementsId( GetMeshDS(), predicate, seq ); + + // remove orphan nodes (if there are any) + list< int > IdList; + for ( int i = 0; i < seq.size(); i++ ) + IdList.push_back( seq[i] ); + + if ( IdList.size() ) + myMesh->SetIsModified( true ); + + return anEditor.Remove( IdList, true ); +} + +//============================================================================= +/*! + * + */ +//============================================================================= + CORBA::Long SMESH_MeshEditor_i::AddNode(CORBA::Double x, CORBA::Double y, CORBA::Double z) { @@ -900,34 +1034,6 @@ CORBA::Boolean SMESH_MeshEditor_i::ReorientObject(SMESH::SMESH_IDSource_ptr theO return isDone; } -namespace -{ - //================================================================================ - /*! - * \brief function for conversion long_array to TIDSortedElemSet - * \param IDs - array of IDs - * \param aMesh - mesh - * \param aMap - collection to fill - * \param aType - element type - */ - //================================================================================ - - void arrayToSet(const SMESH::long_array & IDs, - const SMESHDS_Mesh* aMesh, - TIDSortedElemSet& aMap, - const SMDSAbs_ElementType aType = SMDSAbs_All ) - { - for (int i=0; iFindNode(ind) - : aMesh->FindElement(ind)); - if ( elem && ( aType == SMDSAbs_All || elem->GetType() == aType )) - aMap.insert( elem ); - } - } -} - //============================================================================= /*! * @@ -1116,6 +1222,8 @@ CORBA::Boolean SMESH_MeshEditor_i::SplitQuadObject (SMESH::SMESH_IDSource_ptr th CORBA::Long SMESH_MeshEditor_i::BestSplit (CORBA::Long IDOfQuad, SMESH::NumericalFunctor_ptr Criterion) { + initData(); + const SMDS_MeshElement* quad = GetMeshDS()->FindElement(IDOfQuad); if (quad && quad->GetType() == SMDSAbs_Face && quad->NbNodes() == 4) { @@ -1145,6 +1253,8 @@ void SMESH_MeshEditor_i::SplitVolumesIntoTetra (SMESH::SMESH_IDSource_ptr elems, { Unexpect aCatch(SALOME_SalomeException); + initData(); + SMESH::long_array_var anElementsId = elems->GetIDs(); TIDSortedElemSet elemSet; arrayToSet( anElementsId, GetMeshDS(), elemSet, SMDSAbs_Volume ); @@ -2726,7 +2836,7 @@ SMESH_MeshEditor_i::LinearAnglesVariation(SMESH::SMESH_Mesh_ptr thePathMes //======================================================================= SMESH::ListOfGroups* -SMESH_MeshEditor_i::mirror(const SMESH::long_array & theIDsOfElements, +SMESH_MeshEditor_i::mirror(TIDSortedElemSet & theElements, const SMESH::AxisStruct & theAxis, SMESH::SMESH_MeshEditor::MirrorType theMirrorType, CORBA::Boolean theCopy, @@ -2735,9 +2845,6 @@ SMESH_MeshEditor_i::mirror(const SMESH::long_array & theIDsOfElements, { initData(); - TIDSortedElemSet elements; - arrayToSet(theIDsOfElements, GetMeshDS(), elements); - gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z ); gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz ); @@ -2755,7 +2862,7 @@ SMESH_MeshEditor_i::mirror(const SMESH::long_array & theIDsOfElements, ::SMESH_MeshEditor anEditor( myMesh ); ::SMESH_MeshEditor::PGroupIDs groupIds = - anEditor.Transform (elements, aTrsf, theCopy, theMakeGroups, theTargetMesh); + anEditor.Transform (theElements, aTrsf, theCopy, theMakeGroups, theTargetMesh); if(theCopy) storeResult(anEditor); @@ -2782,7 +2889,12 @@ void SMESH_MeshEditor_i::Mirror(const SMESH::long_array & theIDsOfElem << mirrorTypeName(theMirrorType) << ", " << theCopy << " )"; } - mirror(theIDsOfElements, theAxis, theMirrorType, theCopy, false); + if ( theIDsOfElements.length() > 0 ) + { + TIDSortedElemSet elements; + arrayToSet(theIDsOfElements, GetMeshDS(), elements); + mirror(elements, theAxis, theMirrorType, theCopy, false); + } } @@ -2803,8 +2915,9 @@ void SMESH_MeshEditor_i::MirrorObject(SMESH::SMESH_IDSource_ptr theObj << mirrorTypeName(theMirrorType) << ", " << theCopy << " )"; } - SMESH::long_array_var anElementsId = theObject->GetIDs(); - mirror(anElementsId, theAxis, theMirrorType, theCopy, false); + TIDSortedElemSet elements; + if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) + mirror(elements, theAxis, theMirrorType, theCopy, false); } //======================================================================= @@ -2817,7 +2930,13 @@ SMESH_MeshEditor_i::MirrorMakeGroups(const SMESH::long_array& theIDsO const SMESH::AxisStruct& theMirror, SMESH::SMESH_MeshEditor::MirrorType theMirrorType) { - SMESH::ListOfGroups * aGroups = mirror(theIDsOfElements, theMirror, theMirrorType, true, true); + SMESH::ListOfGroups * aGroups = 0; + if ( theIDsOfElements.length() > 0 ) + { + TIDSortedElemSet elements; + arrayToSet(theIDsOfElements, GetMeshDS(), elements); + aGroups = mirror(elements, theMirror, theMirrorType, true, true); + } if ( !myPreviewMode ) { TPythonDump aPythonDump; DumpGroupsList(aPythonDump,aGroups); @@ -2839,9 +2958,13 @@ SMESH_MeshEditor_i::MirrorObjectMakeGroups(SMESH::SMESH_IDSource_ptr t const SMESH::AxisStruct& theMirror, SMESH::SMESH_MeshEditor::MirrorType theMirrorType) { - SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups * aGroups = mirror(anElementsId, theMirror, theMirrorType, true, true); - if ( !myPreviewMode ) { + SMESH::ListOfGroups * aGroups = 0; + TIDSortedElemSet elements; + if ( idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) + aGroups = mirror(elements, theMirror, theMirrorType, true, true); + + if ( !myPreviewMode ) + { TPythonDump aPythonDump; DumpGroupsList(aPythonDump,aGroups); aPythonDump << this << ".MirrorObjectMakeGroups( " @@ -2873,8 +2996,11 @@ SMESH_MeshEditor_i::MirrorMakeMesh(const SMESH::long_array& theIDsOfE mesh = makeMesh( theMeshName ); mesh_i = SMESH::DownCast( mesh ); - if (mesh_i) { - mirror(theIDsOfElements, theMirror, theMirrorType, + if (mesh_i && theIDsOfElements.length() > 0 ) + { + TIDSortedElemSet elements; + arrayToSet(theIDsOfElements, GetMeshDS(), elements); + mirror(elements, theMirror, theMirrorType, false, theCopyGroups, & mesh_i->GetImpl()); mesh_i->CreateGroupServants(); } @@ -2917,13 +3043,14 @@ SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr the mesh = makeMesh( theMeshName ); mesh_i = SMESH::DownCast( mesh ); - if ( mesh_i ) { - SMESH::long_array_var anElementsId = theObject->GetIDs(); - mirror(anElementsId, theMirror, theMirrorType, + TIDSortedElemSet elements; + if ( mesh_i && + idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) + { + mirror(elements, theMirror, theMirrorType, false, theCopyGroups, & mesh_i->GetImpl()); mesh_i->CreateGroupServants(); } - if ( !myPreviewMode ) { pydump << mesh << " = " << this << ".MirrorObjectMakeMesh( " << theObject << ", " @@ -2932,7 +3059,7 @@ SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr the << theCopyGroups << ", '" << theMeshName << "' )"; } - } + } //dump "GetGroups" if(!myPreviewMode && mesh_i) @@ -2947,7 +3074,7 @@ SMESH_MeshEditor_i::MirrorObjectMakeMesh(SMESH::SMESH_IDSource_ptr the //======================================================================= SMESH::ListOfGroups* -SMESH_MeshEditor_i::translate(const SMESH::long_array & theIDsOfElements, +SMESH_MeshEditor_i::translate(TIDSortedElemSet & theElements, const SMESH::DirStruct & theVector, CORBA::Boolean theCopy, const bool theMakeGroups, @@ -2955,16 +3082,13 @@ SMESH_MeshEditor_i::translate(const SMESH::long_array & theIDsOfElements, { initData(); - TIDSortedElemSet elements; - arrayToSet(theIDsOfElements, GetMeshDS(), elements); - gp_Trsf aTrsf; const SMESH::PointStruct * P = &theVector.PS; aTrsf.SetTranslation( gp_Vec( P->x, P->y, P->z )); ::SMESH_MeshEditor anEditor( myMesh ); ::SMESH_MeshEditor::PGroupIDs groupIds = - anEditor.Transform (elements, aTrsf, theCopy, theMakeGroups, theTargetMesh); + anEditor.Transform (theElements, aTrsf, theCopy, theMakeGroups, theTargetMesh); if(theCopy) storeResult(anEditor); @@ -2989,10 +3113,12 @@ void SMESH_MeshEditor_i::Translate(const SMESH::long_array & theIDsOfElements, << theVector << ", " << theCopy << " )"; } - translate(theIDsOfElements, - theVector, - theCopy, - false); + if ( theIDsOfElements.length() ) + { + TIDSortedElemSet elements; + arrayToSet(theIDsOfElements, GetMeshDS(), elements); + translate(elements,theVector,theCopy,false); + } } //======================================================================= @@ -3010,11 +3136,9 @@ void SMESH_MeshEditor_i::TranslateObject(SMESH::SMESH_IDSource_ptr theObject, << theVector << ", " << theCopy << " )"; } - SMESH::long_array_var anElementsId = theObject->GetIDs(); - translate(anElementsId, - theVector, - theCopy, - false); + TIDSortedElemSet elements; + if ( idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) + translate( elements, theVector, theCopy, false); } //======================================================================= @@ -3026,7 +3150,13 @@ SMESH::ListOfGroups* SMESH_MeshEditor_i::TranslateMakeGroups(const SMESH::long_array& theIDsOfElements, const SMESH::DirStruct& theVector) { - SMESH::ListOfGroups * aGroups = translate(theIDsOfElements,theVector,true,true); + SMESH::ListOfGroups * aGroups = 0; + if ( theIDsOfElements.length() ) + { + TIDSortedElemSet elements; + arrayToSet(theIDsOfElements, GetMeshDS(), elements); + aGroups = translate(elements,theVector,true,true); + } if ( !myPreviewMode ) { TPythonDump aPythonDump; DumpGroupsList(aPythonDump,aGroups); @@ -3046,8 +3176,10 @@ SMESH::ListOfGroups* SMESH_MeshEditor_i::TranslateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject, const SMESH::DirStruct& theVector) { - SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups * aGroups = translate(anElementsId, theVector, true, true); + SMESH::ListOfGroups * aGroups = 0; + TIDSortedElemSet elements; + if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) + aGroups = translate(elements, theVector, true, true); if ( !myPreviewMode ) { @@ -3082,9 +3214,11 @@ SMESH_MeshEditor_i::TranslateMakeMesh(const SMESH::long_array& theIDsOfElements, mesh = makeMesh( theMeshName ); mesh_i = SMESH::DownCast( mesh ); - if ( mesh_i ) { - translate(theIDsOfElements, theVector, - false, theCopyGroups, & mesh_i->GetImpl()); + if ( mesh_i && theIDsOfElements.length() ) + { + TIDSortedElemSet elements; + arrayToSet(theIDsOfElements, GetMeshDS(), elements); + translate(elements, theVector, false, theCopyGroups, & mesh_i->GetImpl()); mesh_i->CreateGroupServants(); } @@ -3124,10 +3258,11 @@ SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject, mesh = makeMesh( theMeshName ); mesh_i = SMESH::DownCast( mesh ); - if ( mesh_i ) { - SMESH::long_array_var anElementsId = theObject->GetIDs(); - translate(anElementsId, theVector, - false, theCopyGroups, & mesh_i->GetImpl()); + TIDSortedElemSet elements; + if ( mesh_i && + idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) + { + translate(elements, theVector,false, theCopyGroups, & mesh_i->GetImpl()); mesh_i->CreateGroupServants(); } if ( !myPreviewMode ) { @@ -3152,7 +3287,7 @@ SMESH_MeshEditor_i::TranslateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject, //======================================================================= SMESH::ListOfGroups* -SMESH_MeshEditor_i::rotate(const SMESH::long_array & theIDsOfElements, +SMESH_MeshEditor_i::rotate(TIDSortedElemSet & theElements, const SMESH::AxisStruct & theAxis, CORBA::Double theAngle, CORBA::Boolean theCopy, @@ -3161,9 +3296,6 @@ SMESH_MeshEditor_i::rotate(const SMESH::long_array & theIDsOfElements, { initData(); - TIDSortedElemSet elements; - arrayToSet(theIDsOfElements, GetMeshDS(), elements); - gp_Pnt P ( theAxis.x, theAxis.y, theAxis.z ); gp_Vec V ( theAxis.vx, theAxis.vy, theAxis.vz ); @@ -3172,7 +3304,7 @@ SMESH_MeshEditor_i::rotate(const SMESH::long_array & theIDsOfElements, ::SMESH_MeshEditor anEditor( myMesh ); ::SMESH_MeshEditor::PGroupIDs groupIds = - anEditor.Transform (elements, aTrsf, theCopy, theMakeGroups, theTargetMesh); + anEditor.Transform (theElements, aTrsf, theCopy, theMakeGroups, theTargetMesh); if(theCopy) storeResult(anEditor); @@ -3199,11 +3331,12 @@ void SMESH_MeshEditor_i::Rotate(const SMESH::long_array & theIDsOfElements, << theAngle << ", " << theCopy << " )"; } - rotate(theIDsOfElements, - theAxis, - theAngle, - theCopy, - false); + if ( theIDsOfElements.length() > 0 ) + { + TIDSortedElemSet elements; + arrayToSet(theIDsOfElements, GetMeshDS(), elements); + rotate(elements,theAxis,theAngle,theCopy,false); + } } //======================================================================= @@ -3223,12 +3356,9 @@ void SMESH_MeshEditor_i::RotateObject(SMESH::SMESH_IDSource_ptr theObject, << theAngle << ", " << theCopy << " )"; } - SMESH::long_array_var anElementsId = theObject->GetIDs(); - rotate(anElementsId, - theAxis, - theAngle, - theCopy, - false); + TIDSortedElemSet elements; + if (idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) + rotate(elements,theAxis,theAngle,theCopy,false); } //======================================================================= @@ -3241,7 +3371,13 @@ SMESH_MeshEditor_i::RotateMakeGroups(const SMESH::long_array& theIDsOfElements, const SMESH::AxisStruct& theAxis, CORBA::Double theAngle) { - SMESH::ListOfGroups * aGroups = rotate(theIDsOfElements,theAxis,theAngle,true,true); + SMESH::ListOfGroups * aGroups = 0; + if ( theIDsOfElements.length() > 0 ) + { + TIDSortedElemSet elements; + arrayToSet(theIDsOfElements, GetMeshDS(), elements); + aGroups = rotate(elements,theAxis,theAngle,true,true); + } if ( !myPreviewMode ) { TPythonDump aPythonDump; DumpGroupsList(aPythonDump,aGroups); @@ -3263,8 +3399,10 @@ SMESH_MeshEditor_i::RotateObjectMakeGroups(SMESH::SMESH_IDSource_ptr theObject, const SMESH::AxisStruct& theAxis, CORBA::Double theAngle) { - SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups * aGroups = rotate(anElementsId,theAxis,theAngle,true,true); + SMESH::ListOfGroups * aGroups = 0; + TIDSortedElemSet elements; + if ( idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) + aGroups = rotate(elements,theAxis,theAngle,true,true); if ( !myPreviewMode ) { TPythonDump aPythonDump; @@ -3300,8 +3438,11 @@ SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements, mesh = makeMesh( theMeshName ); mesh_i = SMESH::DownCast( mesh ); - if ( mesh_i ) { - rotate(theIDsOfElements, theAxis, theAngleInRadians, + if ( mesh_i && theIDsOfElements.length() > 0 ) + { + TIDSortedElemSet elements; + arrayToSet(theIDsOfElements, GetMeshDS(), elements); + rotate(elements, theAxis, theAngleInRadians, false, theCopyGroups, & mesh_i->GetImpl()); mesh_i->CreateGroupServants(); } @@ -3316,7 +3457,7 @@ SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements, } //dump "GetGroups" - if(!myPreviewMode && mesh_i) + if(!myPreviewMode && mesh_i && theIDsOfElements.length() > 0 ) mesh_i->GetGroups(); return mesh._retn(); @@ -3327,7 +3468,7 @@ SMESH_MeshEditor_i::RotateMakeMesh(const SMESH::long_array& theIDsOfElements, //purpose : //======================================================================= -SMESH::SMESH_Mesh_ptr +SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject, const SMESH::AxisStruct& theAxis, CORBA::Double theAngleInRadians, @@ -3344,9 +3485,11 @@ SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject, mesh = makeMesh( theMeshName ); mesh_i = SMESH::DownCast( mesh ); - if (mesh_i ) { - SMESH::long_array_var anElementsId = theObject->GetIDs(); - rotate(anElementsId, theAxis, theAngleInRadians, + TIDSortedElemSet elements; + if (mesh_i && + idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1)) + { + rotate(elements, theAxis, theAngleInRadians, false, theCopyGroups, & mesh_i->GetImpl()); mesh_i->CreateGroupServants(); } @@ -3367,14 +3510,13 @@ SMESH_MeshEditor_i::RotateObjectMakeMesh(SMESH::SMESH_IDSource_ptr theObject, return mesh._retn(); } - //======================================================================= //function : scale //purpose : //======================================================================= SMESH::ListOfGroups* -SMESH_MeshEditor_i::scale(const SMESH::long_array & theIDsOfElements, +SMESH_MeshEditor_i::scale(SMESH::SMESH_IDSource_ptr theObject, const SMESH::PointStruct& thePoint, const SMESH::double_array& theScaleFact, CORBA::Boolean theCopy, @@ -3382,20 +3524,28 @@ SMESH_MeshEditor_i::scale(const SMESH::long_array & theIDsOfElements, ::SMESH_Mesh* theTargetMesh) { initData(); + if ( theScaleFact.length() < 1 ) + THROW_SALOME_CORBA_EXCEPTION("Scale factor not given", SALOME::BAD_PARAM); + if ( theScaleFact.length() == 2 ) + THROW_SALOME_CORBA_EXCEPTION("Invalid nb of scale factors : 2", SALOME::BAD_PARAM); TIDSortedElemSet elements; - arrayToSet(theIDsOfElements, GetMeshDS(), elements); + if ( !idSourceToSet(theObject, GetMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/true)) + return 0; - gp_Pnt aPnt( thePoint.x, thePoint.y, thePoint.z ); - list aScaleFact; - for (int i = 0; i < theScaleFact.length(); i++) { - aScaleFact.push_back( theScaleFact[i] ); - } + vector S(3); + S[0] = theScaleFact[0]; + S[1] = (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[1]; + S[2] = (theScaleFact.length() == 1) ? theScaleFact[0] : theScaleFact[2]; + double tol = std::numeric_limits::max(); + gp_Trsf aTrsf; + aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]), + 0, S[1], 0, thePoint.y * (1-S[1]), + 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol); ::SMESH_MeshEditor anEditor( myMesh ); ::SMESH_MeshEditor::PGroupIDs groupIds = - anEditor.Scale (elements, aPnt, aScaleFact, theCopy, - theMakeGroups, theTargetMesh); + anEditor.Transform (elements, aTrsf, theCopy, theMakeGroups, theTargetMesh); if(theCopy) storeResult(anEditor); @@ -3405,7 +3555,6 @@ SMESH_MeshEditor_i::scale(const SMESH::long_array & theIDsOfElements, return theMakeGroups ? getGroups(groupIds.get()) : 0; } - //======================================================================= //function : Scale //purpose : @@ -3424,8 +3573,7 @@ void SMESH_MeshEditor_i::Scale(SMESH::SMESH_IDSource_ptr theObject, << theScaleFact << ", " << theCopy << " )"; } - SMESH::long_array_var anElementsId = theObject->GetIDs(); - scale(anElementsId, thePoint, theScaleFact, theCopy, false); + scale(theObject, thePoint, theScaleFact, theCopy, false); } @@ -3439,10 +3587,7 @@ SMESH_MeshEditor_i::ScaleMakeGroups(SMESH::SMESH_IDSource_ptr theObject, const SMESH::PointStruct& thePoint, const SMESH::double_array& theScaleFact) { - SMESH::long_array_var anElementsId = theObject->GetIDs(); - SMESH::ListOfGroups * aGroups = - scale(anElementsId, thePoint, theScaleFact, true, true); - + SMESH::ListOfGroups * aGroups = scale(theObject, thePoint, theScaleFact, true, true); if ( !myPreviewMode ) { TPythonDump aPythonDump; @@ -3478,13 +3623,12 @@ SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject, mesh = makeMesh( theMeshName ); mesh_i = SMESH::DownCast( mesh ); - if ( mesh_i ) { - SMESH::long_array_var anElementsId = theObject->GetIDs(); - scale(anElementsId, thePoint, theScaleFact, - false, theCopyGroups, & mesh_i->GetImpl()); + if ( mesh_i ) + { + scale(theObject, thePoint, theScaleFact,false, theCopyGroups, & mesh_i->GetImpl()); mesh_i->CreateGroupServants(); } - if ( !myPreviewMode ) { + if ( !myPreviewMode ) pydump << mesh << " = " << this << ".ScaleMakeMesh( " << theObject << ", " << "SMESH.PointStruct( " << thePoint.x << ", " @@ -3492,7 +3636,6 @@ SMESH_MeshEditor_i::ScaleMakeMesh(SMESH::SMESH_IDSource_ptr theObject, << theScaleFact << ", " << theCopyGroups << ", '" << theMeshName << "' )"; - } } //dump "GetGroups" @@ -3515,7 +3658,7 @@ void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tol ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes; ::SMESH_MeshEditor anEditor( myMesh ); - set nodes; // no input nodes + TIDSortedNodeSet nodes; // no input nodes anEditor.FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes ); GroupsOfNodes = new SMESH::array_of_long_array; @@ -3542,33 +3685,9 @@ void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr SMESH::array_of_long_array_out GroupsOfNodes) { initData(); - SMESH::long_array_var aElementsId = theObject->GetIDs(); - - SMESHDS_Mesh* aMesh = GetMeshDS(); - set nodes; - - SMESH::SMESH_GroupBase_var group = SMESH::SMESH_GroupBase::_narrow(theObject); - if ( !group->_is_nil() && group->GetType() == SMESH::NODE) - { - for(int i = 0; i < aElementsId->length(); i++) { - CORBA::Long ind = aElementsId[i]; - const SMDS_MeshNode * elem = aMesh->FindNode(ind); - if(elem) - nodes.insert(elem); - } - } - else { - for(int i = 0; i < aElementsId->length(); i++) { - CORBA::Long ind = aElementsId[i]; - const SMDS_MeshElement * elem = aMesh->FindElement(ind); - if(elem) { - SMDS_ElemIteratorPtr nIt = elem->nodesIterator(); - while ( nIt->more() ) - nodes.insert( nodes.end(),static_cast(nIt->next())); - } - } - } + TIDSortedNodeSet nodes; + idSourceToNodeSet( theObject, GetMeshDS(), nodes ); ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes; ::SMESH_MeshEditor anEditor( myMesh ); @@ -3578,7 +3697,8 @@ void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr GroupsOfNodes = new SMESH::array_of_long_array; GroupsOfNodes->length( aListOfListOfNodes.size() ); ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin(); - for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) { + for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) + { list< const SMDS_MeshNode* >& aListOfNodes = *llIt; list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();; SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ]; @@ -3591,6 +3711,55 @@ void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr << Tolerance << " )"; } +//================================================================================ +/*! + * \brief Finds nodes coinsident with Tolerance within Object excluding nodes within + * ExceptSubMeshOrGroups + */ +//================================================================================ + +void SMESH_MeshEditor_i:: +FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject, + CORBA::Double theTolerance, + SMESH::array_of_long_array_out theGroupsOfNodes, + const SMESH::ListOfIDSources& theExceptSubMeshOrGroups) +{ + initData(); + + TIDSortedNodeSet nodes; + idSourceToNodeSet( theObject, GetMeshDS(), nodes ); + + for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i ) + { + TIDSortedNodeSet exceptNodes; + idSourceToNodeSet( theExceptSubMeshOrGroups[i], GetMeshDS(), exceptNodes ); + TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin(); + for ( ; avoidNode != exceptNodes.end(); ++avoidNode) + nodes.erase( *avoidNode ); + } + ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes; + ::SMESH_MeshEditor anEditor( myMesh ); + if(!nodes.empty()) + anEditor.FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes ); + + theGroupsOfNodes = new SMESH::array_of_long_array; + theGroupsOfNodes->length( aListOfListOfNodes.size() ); + ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin(); + for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) + { + list< const SMDS_MeshNode* >& aListOfNodes = *llIt; + list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();; + SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ]; + aGroup.length( aListOfNodes.size() ); + for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ ) + aGroup[ j ] = (*lIt)->GetID(); + } + TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( " + << theObject<<", " + << theTolerance << ", " + << theExceptSubMeshOrGroups << " )"; +} + //======================================================================= //function : MergeNodes //purpose : @@ -3750,16 +3919,39 @@ CORBA::Boolean SMESH_MeshEditor_i::MoveNode(CORBA::Long NodeID, if ( theNodeSearcher ) theSearchersDeleter.Set( myMesh ); // remove theNodeSearcher if mesh is other - if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly + if ( myPreviewMode ) // make preview data + { + // in a preview mesh, make edges linked to a node + TPreviewMesh tmpMesh; + TIDSortedElemSet linkedNodes; + ::SMESH_MeshEditor::GetLinkedNodes( node, linkedNodes ); + TIDSortedElemSet::iterator nIt = linkedNodes.begin(); + for ( ; nIt != linkedNodes.end(); ++nIt ) + { + SMDS_MeshEdge edge( node, cast2Node( *nIt )); + tmpMesh.Copy( &edge ); + } + // move copied node + node = tmpMesh.GetMeshDS()->FindNode( NodeID ); + if ( node ) + tmpMesh.GetMeshDS()->MoveNode(node, x, y, z); + // fill preview data + ::SMESH_MeshEditor anEditor( & tmpMesh ); + storeResult( anEditor ); + } + else if ( theNodeSearcher ) // move node and update theNodeSearcher data accordingly theNodeSearcher->MoveNode(node, gp_Pnt( x,y,z )); else GetMeshDS()->MoveNode(node, x, y, z); - // Update Python script - TPythonDump() << "isDone = " << this << ".MoveNode( " - << NodeID << ", " << x << ", " << y << ", " << z << " )"; + if ( !myPreviewMode ) + { + // Update Python script + TPythonDump() << "isDone = " << this << ".MoveNode( " + << NodeID << ", " << x << ", " << y << ", " << z << " )"; - myMesh->SetIsModified( true ); + myMesh->SetIsModified( true ); + } return true; } @@ -4414,6 +4606,46 @@ void SMESH_MeshEditor_i::DumpGroupsList(TPythonDump & theDumpPytho } } +//================================================================================ +/*! + \brief Generates the unique group name. + \param thePrefix name prefix + \return unique name +*/ +//================================================================================ +string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix) +{ + SMESH::ListOfGroups_var groups = myMesh_i->GetGroups(); + set groupNames; + + // Get existing group names + for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) { + SMESH::SMESH_GroupBase_var aGroup = groups[i]; + if (CORBA::is_nil(aGroup)) + continue; + + groupNames.insert(aGroup->GetName()); + } + + // Find new name + string name = thePrefix; + int index = 0; + + while (!groupNames.insert(name).second) { + if (index == 0) { + name += "_1"; + } + else { + TCollection_AsciiString nbStr(index+1); + name.resize( name.rfind('_')+1 ); + name += nbStr.ToCString(); + } + ++index; + } + + return name; +} + //================================================================================ /*! \brief Creates a hole in a mesh by doubling the nodes of some particular elements @@ -4447,6 +4679,9 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodes( const SMESH::long_array& theNode if ( aResult ) myMesh->SetIsModified( true ); + // Update Python script + TPythonDump() << this << ".DoubleNodes( " << theNodes << ", "<< theModifiedElems << " )"; + return aResult; } @@ -4467,9 +4702,13 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeI SMESH::long_array_var aNodes = new SMESH::long_array; aNodes->length( 1 ); aNodes[ 0 ] = theNodeId; - bool done = DoubleNodes( aNodes, theModifiedElems ); - if ( done ) - myMesh->SetIsModified( true ); + + TPythonDump pyDump; // suppress dump by the next line + + CORBA::Boolean done = DoubleNodes( aNodes, theModifiedElems ); + + pyDump << this << ".DoubleNode( " << theNodeId << ", " << theModifiedElems << " )"; + return done; } @@ -4484,9 +4723,8 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNode( CORBA::Long theNodeI */ //================================================================================ -CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup( - SMESH::SMESH_GroupBase_ptr theNodes, - SMESH::SMESH_GroupBase_ptr theModifiedElems ) +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup(SMESH::SMESH_GroupBase_ptr theNodes, + SMESH::SMESH_GroupBase_ptr theModifiedElems ) { if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE ) return false; @@ -4501,14 +4739,63 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup( aModifiedElems->length( 0 ); } + TPythonDump pyDump; // suppress dump by the next line + bool done = DoubleNodes( aNodes, aModifiedElems ); - if ( done ) - myMesh->SetIsModified( true ); + pyDump << this << ".DoubleNodeGroup( " << theNodes << ", " << theModifiedElems << " )"; return done; } +/*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements. + * Works as DoubleNodeGroup(), but returns a new group with newly created nodes. + * \param theNodes - group of nodes to be doubled. + * \param theModifiedElems - group of elements to be updated. + * \return a new group with newly created nodes + * \sa DoubleNodeGroup() + */ +SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes, + SMESH::SMESH_GroupBase_ptr theModifiedElems ) +{ + if ( CORBA::is_nil( theNodes ) && theNodes->GetType() != SMESH::NODE ) + return false; + + SMESH::SMESH_Group_var aNewGroup; + + // Duplicate nodes + SMESH::long_array_var aNodes = theNodes->GetListOfID(); + SMESH::long_array_var aModifiedElems; + if ( !CORBA::is_nil( theModifiedElems ) ) + aModifiedElems = theModifiedElems->GetListOfID(); + else { + aModifiedElems = new SMESH::long_array; + aModifiedElems->length( 0 ); + } + + TPythonDump pyDump; // suppress dump by the next line + + bool aResult = DoubleNodes( aNodes, aModifiedElems ); + + if ( aResult ) + { + // Create group with newly created nodes + SMESH::long_array_var anIds = GetLastCreatedNodes(); + if (anIds->length() > 0) { + string anUnindexedName (theNodes->GetName()); + string aNewName = generateGroupName(anUnindexedName + "_double"); + aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str()); + aNewGroup->Add(anIds); + } + } + + pyDump << "createdNodes = " << this << ".DoubleNodeGroupNew( " << theNodes << ", " + << theModifiedElems << " )"; + + return aNewGroup._retn(); +} + //================================================================================ /*! \brief Creates a hole in a mesh by doubling the nodes of some particular elements @@ -4520,9 +4807,8 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroup( */ //================================================================================ -CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups( - const SMESH::ListOfGroups& theNodes, - const SMESH::ListOfGroups& theModifiedElems ) +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups(const SMESH::ListOfGroups& theNodes, + const SMESH::ListOfGroups& theModifiedElems ) { initData(); @@ -4560,6 +4846,9 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeGroups( if ( aResult ) myMesh->SetIsModified( true ); + + TPythonDump() << this << ".DoubleNodeGroups( " << theNodes << ", " << theModifiedElems << " )"; + return aResult; } @@ -4599,8 +4888,8 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theE myMesh->SetIsModified( true ); // Update Python script - TPythonDump() << "isDone = " << this << ".DoubleNodes( " << theElems << ", " - << theNodesNot << ", " << theAffectedElems << " )"; + TPythonDump() << this << ".DoubleNodeElem( " << theElems << ", " + << theNodesNot << ", " << theAffectedElems << " )"; return aResult; } @@ -4618,10 +4907,9 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElem( const SMESH::long_array& theE */ //================================================================================ -CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion -( const SMESH::long_array& theElems, - const SMESH::long_array& theNodesNot, - GEOM::GEOM_Object_ptr theShape ) +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion ( const SMESH::long_array& theElems, + const SMESH::long_array& theNodesNot, + GEOM::GEOM_Object_ptr theShape ) { initData(); @@ -4642,8 +4930,8 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion myMesh->SetIsModified( true ); // Update Python script - TPythonDump() << "isDone = " << this << ".DoubleNodesInRegion( " << theElems << ", " - << theNodesNot << ", " << theShape << " )"; + TPythonDump() << "isDone = " << this << ".DoubleNodeElemInRegion( " << theElems << ", " + << theNodesNot << ", " << theShape << " )"; return aResult; } @@ -4659,18 +4947,6 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemInRegion */ //================================================================================ -static void groupToSet(SMESH::SMESH_GroupBase_ptr theGrp, - SMESHDS_Mesh* theMeshDS, - TIDSortedElemSet& theElemSet, - const SMDSAbs_ElementType theType) - -{ - if ( CORBA::is_nil( theGrp ) ) - return; - SMESH::long_array_var anIDs = theGrp->GetIDs(); - arrayToSet( anIDs, theMeshDS, theElemSet, theType); -} - CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_ptr theElems, SMESH::SMESH_GroupBase_ptr theNodesNot, SMESH::SMESH_GroupBase_ptr theAffectedElems) @@ -4684,9 +4960,9 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_pt SMESHDS_Mesh* aMeshDS = GetMeshDS(); TIDSortedElemSet anElems, aNodes, anAffected; - groupToSet( theElems, aMeshDS, anElems, SMDSAbs_All ); - groupToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node ); - groupToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All ); + idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All ); + idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node ); + idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All ); bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected ); @@ -4696,11 +4972,65 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_pt myMesh->SetIsModified( true ); // Update Python script - TPythonDump() << "isDone = " << this << ".DoubleNodeGroup( " << theElems << ", " - << theNodesNot << ", " << theAffectedElems << " )"; + TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroup( " << theElems << ", " + << theNodesNot << ", " << theAffectedElems << " )"; return aResult; } +/*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements. + * \param theElems - group of of elements (edges or faces) to be replicated + * \param theNodesNot - group of nodes not to replicated + * \param theAffectedElems - group of elements to which the replicated nodes + * should be associated to. + * \return a new group with newly created elements + * \sa DoubleNodeElemGroup() + */ +SMESH::SMESH_Group_ptr SMESH_MeshEditor_i::DoubleNodeElemGroupNew(SMESH::SMESH_GroupBase_ptr theElems, + SMESH::SMESH_GroupBase_ptr theNodesNot, + SMESH::SMESH_GroupBase_ptr theAffectedElems) +{ + if ( CORBA::is_nil( theElems ) && theElems->GetType() == SMESH::NODE ) + return false; + + SMESH::SMESH_Group_var aNewGroup; + + initData(); + + ::SMESH_MeshEditor aMeshEditor( myMesh ); + + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + TIDSortedElemSet anElems, aNodes, anAffected; + idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All ); + idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node ); + idSourceToSet( theAffectedElems, aMeshDS, anAffected, SMDSAbs_All ); + + + bool aResult = aMeshEditor.DoubleNodes( anElems, aNodes, anAffected ); + + storeResult( aMeshEditor) ; + + if ( aResult ) { + myMesh->SetIsModified( true ); + + // Create group with newly created elements + SMESH::long_array_var anIds = GetLastCreatedElems(); + if (anIds->length() > 0) { + SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true); + string anUnindexedName (theElems->GetName()); + string aNewName = generateGroupName(anUnindexedName + "_double"); + aNewGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str()); + aNewGroup->Add(anIds); + } + } + + // Update Python script + TPythonDump() << "createdElems = " << this << ".DoubleNodeElemGroupNew( " << theElems << ", " + << theNodesNot << ", " << theAffectedElems << " )"; + return aNewGroup._retn(); +} + //================================================================================ /*! \brief Creates a hole in a mesh by doubling the nodes of some particular elements @@ -4714,8 +5044,7 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroup(SMESH::SMESH_GroupBase_pt */ //================================================================================ -CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion( - SMESH::SMESH_GroupBase_ptr theElems, +CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion(SMESH::SMESH_GroupBase_ptr theElems, SMESH::SMESH_GroupBase_ptr theNodesNot, GEOM::GEOM_Object_ptr theShape ) @@ -4729,8 +5058,8 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion( SMESHDS_Mesh* aMeshDS = GetMeshDS(); TIDSortedElemSet anElems, aNodes, anAffected; - groupToSet( theElems, aMeshDS, anElems, SMDSAbs_All ); - groupToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node ); + idSourceToSet( theElems, aMeshDS, anElems, SMDSAbs_All ); + idSourceToSet( theNodesNot, aMeshDS, aNodes, SMDSAbs_Node ); TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( theShape ); bool aResult = aMeshEditor.DoubleNodesInRegion( anElems, aNodes, aShape ); @@ -4741,8 +5070,8 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroupInRegion( myMesh->SetIsModified( true ); // Update Python script - TPythonDump() << "isDone = " << this << ".DoubleNodeGroupInRegion( " << theElems << ", " - << theNodesNot << ", " << theShape << " )"; + TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupInRegion( " << theElems << ", " + << theNodesNot << ", " << theShape << " )"; return aResult; } @@ -4799,7 +5128,7 @@ CORBA::Boolean SMESH_MeshEditor_i::DoubleNodeElemGroups(const SMESH::ListOfGroup // Update Python script TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroups( " << &theElems << ", " - << &theNodesNot << ", " << &theAffectedElems << " )"; + << &theNodesNot << ", " << &theAffectedElems << " )"; return aResult; } @@ -4840,8 +5169,8 @@ SMESH_MeshEditor_i::DoubleNodeElemGroupsInRegion(const SMESH::ListOfGroups& theE myMesh->SetIsModified( true ); // Update Python script - TPythonDump() << "isDone = " << this << ".DoubleNodeGroupsInRegion( " << &theElems << ", " - << &theNodesNot << ", " << theShape << " )"; + TPythonDump() << "isDone = " << this << ".DoubleNodeElemGroupsInRegion( " << &theElems << ", " + << &theNodesNot << ", " << theShape << " )"; return aResult; } @@ -4860,7 +5189,98 @@ CORBA::Boolean SMESH_MeshEditor_i::Make2DMeshFrom3D() ::SMESH_MeshEditor aMeshEditor( myMesh ); bool aResult = aMeshEditor.Make2DMeshFrom3D(); storeResult( aMeshEditor) ; - + TPythonDump() << "isDone = " << this << ".Make2DMeshFrom3D()"; return aResult; } + +// issue 20749 =================================================================== +/*! + * \brief Creates missing boundary elements + * \param elements - elements whose boundary is to be checked + * \param dimension - defines type of boundary elements to create + * \param groupName - a name of group to store created boundary elements in, + * "" means not to create the group + * \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 + * boundary elements will be copied into the new mesh + * \param group - returns the create group, if any + * \retval SMESH::SMESH_Mesh - the mesh where elements were added to + */ +// ================================================================================ + +SMESH::SMESH_Mesh_ptr +SMESH_MeshEditor_i::MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr idSource, + SMESH::Bnd_Dimension dim, + const char* groupName, + const char* meshName, + CORBA::Boolean toCopyElements, + CORBA::Boolean toCopyExistingBondary, + SMESH::SMESH_Group_out group) +{ + initData(); + + if ( dim > SMESH::BND_1DFROM2D ) + THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM); + + + SMESHDS_Mesh* aMeshDS = GetMeshDS(); + + SMESH::SMESH_Mesh_var mesh_var; + SMESH::SMESH_Group_var group_var; + + TPythonDump pyDump; + + TIDSortedElemSet elements; + SMDSAbs_ElementType elemType = (dim == SMESH::BND_1DFROM2D) ? SMDSAbs_Face : SMDSAbs_Volume; + if ( idSourceToSet( idSource, aMeshDS, elements, elemType,/*emptyIfIsMesh=*/true )) + { + // mesh to fill in + mesh_var = + strlen(meshName) ? makeMesh(meshName) : SMESH::SMESH_Mesh::_duplicate(myMesh_i->_this()); + SMESH_Mesh_i* mesh_i = SMESH::DownCast( mesh_var ); + // other mesh + SMESH_Mesh* smesh_mesh = (mesh_i==myMesh_i) ? (SMESH_Mesh*)0 : &mesh_i->GetImpl(); + + // group of new boundary elements + SMESH_Group* smesh_group = 0; + if ( strlen(groupName) ) + { + group_var = mesh_i->CreateGroup( SMESH::ElementType(elemType),groupName); + if ( SMESH_GroupBase_i* group_i = SMESH::DownCast( group_var )) + smesh_group = group_i->GetSmeshGroup(); + } + + // do it + ::SMESH_MeshEditor aMeshEditor( myMesh ); + aMeshEditor.MakeBoundaryMesh( elements, + ::SMESH_MeshEditor::Bnd_Dimension(dim), + smesh_group, + smesh_mesh, + toCopyElements, + toCopyExistingBondary); + storeResult( aMeshEditor ); + } + + // result of MakeBoundaryMesh() is a tuple (mesh, group) + if ( mesh_var->_is_nil() ) + pyDump << myMesh_i->_this() << ", "; + else + pyDump << mesh_var << ", "; + if ( group_var->_is_nil() ) + pyDump << "_NoneGroup = "; // assignment to None is forbiden + else + pyDump << group_var << " = "; + pyDump << this << ".MakeBoundaryMesh( " + << idSource << ", " + << dim << ", " + << groupName << ", " + << meshName<< ", " + << toCopyElements << ", " + << toCopyExistingBondary << ")"; + + group = group_var._retn(); + return mesh_var._retn(); +} diff --git a/src/SMESH_I/SMESH_MeshEditor_i.hxx b/src/SMESH_I/SMESH_MeshEditor_i.hxx index 046573b17..3a96b87cd 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.hxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.hxx @@ -35,6 +35,7 @@ #include "SMESH_Mesh.hxx" #include "SMESH_PythonDump.hxx" +#include "SMESH_MeshEditor.hxx" #include class SMESH_MeshEditor; @@ -52,10 +53,11 @@ public: /*! * \brief Wrap a sequence of ids in a SMESH_IDSource */ - SMESH::SMESH_IDSource_ptr MakeIDSource(const SMESH::long_array& IDsOfElements); - + SMESH::SMESH_IDSource_ptr MakeIDSource(const SMESH::long_array& IDsOfElements, + SMESH::ElementType type); CORBA::Boolean RemoveElements(const SMESH::long_array & IDsOfElements); CORBA::Boolean RemoveNodes(const SMESH::long_array & IDsOfNodes); + CORBA::Long RemoveOrphanNodes(); /*! * Methods for creation new elements. @@ -449,6 +451,10 @@ public: void FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr Object, CORBA::Double Tolerance, SMESH::array_of_long_array_out GroupsOfNodes); + void FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr Object, + CORBA::Double Tolerance, + SMESH::array_of_long_array_out GroupsOfNodes, + const SMESH::ListOfIDSources& ExceptSubMeshOrGroups); void MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes); void FindEqualElements(SMESH::SMESH_IDSource_ptr Object, SMESH::array_of_long_array_out GroupsOfElementsID); @@ -542,7 +548,7 @@ public: */ int GetMeshId() const { return myMesh->GetId(); } - CORBA::Boolean DoubleNodes( const SMESH::long_array& theNodes, + CORBA::Boolean DoubleNodes( const SMESH::long_array& theNodes, const SMESH::long_array& theModifiedElems ); CORBA::Boolean DoubleNode( CORBA::Long theNodeId, @@ -551,6 +557,17 @@ public: CORBA::Boolean DoubleNodeGroup( SMESH::SMESH_GroupBase_ptr theNodes, SMESH::SMESH_GroupBase_ptr theModifiedElems ); + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements. + * Works as DoubleNodeGroup(), but returns a new group with newly created nodes. + * \param theNodes - group of nodes to be doubled. + * \param theModifiedElems - group of elements to be updated. + * \return a new group with newly created nodes + * \sa DoubleNodeGroup() + */ + SMESH::SMESH_Group_ptr DoubleNodeGroupNew( SMESH::SMESH_GroupBase_ptr theNodes, + SMESH::SMESH_GroupBase_ptr theModifiedElems ); + CORBA::Boolean DoubleNodeGroups( const SMESH::ListOfGroups& theNodes, const SMESH::ListOfGroups& theModifiedElems); @@ -595,6 +612,20 @@ public: CORBA::Boolean DoubleNodeElemGroup( SMESH::SMESH_GroupBase_ptr theElems, SMESH::SMESH_GroupBase_ptr theNodesNot, SMESH::SMESH_GroupBase_ptr theAffectedElems ); + + /*! + * \brief Creates a hole in a mesh by doubling the nodes of some particular elements + * Works as DoubleNodeElemGroup(), but returns a new group with newly created elements. + * \param theElems - group of of elements (edges or faces) to be replicated + * \param theNodesNot - group of nodes not to replicated + * \param theAffectedElems - group of elements to which the replicated nodes + * should be associated to. + * \return a new group with newly created elements + * \sa DoubleNodeElemGroup() + */ + SMESH::SMESH_Group_ptr DoubleNodeElemGroupNew( SMESH::SMESH_GroupBase_ptr theElems, + SMESH::SMESH_GroupBase_ptr theNodesNot, + SMESH::SMESH_GroupBase_ptr theAffectedElems ); /*! * \brief Creates a hole in a mesh by doubling the nodes of some particular elements @@ -640,14 +671,22 @@ public: const SMESH::ListOfGroups& theNodesNot, GEOM::GEOM_Object_ptr theShape ); - /*! - * \brief Generated skin mesh (containing 2D cells) from 3D mesh - * The created 2D mesh elements based on nodes of free faces of boundary volumes - * \return TRUE if operation has been completed successfully, FALSE otherwise - */ - CORBA::Boolean Make2DMeshFrom3D(); + /*! + * \brief Generated skin mesh (containing 2D cells) from 3D mesh + * The created 2D mesh elements based on nodes of free faces of boundary volumes + * \return TRUE if operation has been completed successfully, FALSE otherwise + */ + CORBA::Boolean Make2DMeshFrom3D(); + + SMESH::SMESH_Mesh_ptr MakeBoundaryMesh(SMESH::SMESH_IDSource_ptr elements, + SMESH::Bnd_Dimension dimension, + const char* groupName, + const char* meshName, + CORBA::Boolean toCopyElements, + CORBA::Boolean toCopyMissingBondary, + SMESH::SMESH_Group_out group); - private: //!< private methods +private: //!< private methods SMESHDS_Mesh * GetMeshDS() { return myMesh->GetMeshDS(); } @@ -706,36 +745,38 @@ public: const bool MakeGroups, const SMDSAbs_ElementType ElementType, SMESH::SMESH_MeshEditor::Extrusion_Error & theError); - SMESH::ListOfGroups* mirror(const SMESH::long_array & IDsOfElements, + SMESH::ListOfGroups* mirror(TIDSortedElemSet & IDsOfElements, const SMESH::AxisStruct & Axis, SMESH::SMESH_MeshEditor::MirrorType MirrorType, CORBA::Boolean Copy, const bool MakeGroups, ::SMESH_Mesh* TargetMesh=0); - SMESH::ListOfGroups* translate(const SMESH::long_array & IDsOfElements, + SMESH::ListOfGroups* translate(TIDSortedElemSet & IDsOfElements, const SMESH::DirStruct & Vector, CORBA::Boolean Copy, const bool MakeGroups, ::SMESH_Mesh* TargetMesh=0); - SMESH::ListOfGroups* rotate(const SMESH::long_array & IDsOfElements, + SMESH::ListOfGroups* rotate(TIDSortedElemSet & IDsOfElements, const SMESH::AxisStruct & Axis, CORBA::Double Angle, CORBA::Boolean Copy, const bool MakeGroups, ::SMESH_Mesh* TargetMesh=0); - SMESH::ListOfGroups* scale(const SMESH::long_array & theIDsOfElements, - const SMESH::PointStruct& thePoint, - const SMESH::double_array& theScaleFact, - CORBA::Boolean theCopy, - const bool theMakeGroups, - ::SMESH_Mesh* theTargetMesh=0); + SMESH::ListOfGroups* scale(SMESH::SMESH_IDSource_ptr theObject, + const SMESH::PointStruct& thePoint, + const SMESH::double_array& theScaleFact, + CORBA::Boolean theCopy, + const bool theMakeGroups, + ::SMESH_Mesh* theTargetMesh=0); SMESH::SMESH_Mesh_ptr makeMesh(const char* theMeshName); void DumpGroupsList(SMESH::TPythonDump & theDumpPython, const SMESH::ListOfGroups * theGroupList); + string generateGroupName(const string& thePrefix); + private: //!< fields SMESH_Mesh_i* myMesh_i; diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index a21535af8..c3be622ae 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -19,12 +19,11 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // - // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_Mesh_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// + #include "SMESH_Mesh_i.hxx" #include "SMESH_Filter_i.hxx" @@ -90,7 +89,9 @@ using SMESH::TPythonDump; int SMESH_Mesh_i::myIdGenerator = 0; - +//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 //============================================================================= /*! @@ -119,17 +120,48 @@ SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA, SMESH_Mesh_i::~SMESH_Mesh_i() { INFOS("~SMESH_Mesh_i"); - map::iterator it; - for ( it = _mapGroups.begin(); it != _mapGroups.end(); it++ ) { - SMESH_GroupBase_i* aGroup = dynamic_cast( SMESH_Gen_i::GetServant( it->second ).in() ); - if ( aGroup ) { - // this method is colled from destructor of group (PAL6331) + +#ifdef WITHGENERICOBJ + // destroy groups + map::iterator itGr; + for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) { + if ( CORBA::is_nil( itGr->second )) + continue; + SMESH_GroupBase_i* aGroup = dynamic_cast(SMESH_Gen_i::GetServant(itGr->second).in()); + if (aGroup) { + // this method is called from destructor of group (PAL6331) //_impl->RemoveGroup( aGroup->GetLocalID() ); - + aGroup->myMeshServant = 0; aGroup->Destroy(); } } _mapGroups.clear(); + + // destroy submeshes + map::iterator itSM; + for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ ) { + if ( CORBA::is_nil( itSM->second )) + continue; + SMESH_subMesh_i* aSubMesh = dynamic_cast(SMESH_Gen_i::GetServant(itSM->second).in()); + if (aSubMesh) { + aSubMesh->Destroy(); + } + } + _mapSubMeshIor.clear(); + + // destroy hypotheses + map::iterator itH; + for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) { + if ( CORBA::is_nil( itH->second )) + continue; + SMESH_Hypothesis_i* aHypo = dynamic_cast(SMESH_Gen_i::GetServant(itH->second).in()); + if (aHypo) { + aHypo->Destroy(); + } + } + _mapHypo.clear(); +#endif + delete _impl; } @@ -474,6 +506,9 @@ SMESH_Hypothesis::Hypothesis_Status status = _impl->AddHypothesis(myLocSubShape, hypId); if ( !SMESH_Hypothesis::IsStatusFatal(status) ) { _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp ); +#ifdef WITHGENERICOBJ + _mapHypo[hypId]->Register(); +#endif // assure there is a corresponding submesh if ( !_impl->IsMainShape( myLocSubShape )) { int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape ); @@ -625,6 +660,9 @@ SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShap //Get or Create the SMESH_subMesh object implementation int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape ); + if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape )) + THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM); + subMesh = getSubMesh( subMeshId ); // create a new subMesh object servant if there is none for the shape @@ -698,6 +736,7 @@ inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType CASE2STRING( EDGE ); CASE2STRING( FACE ); CASE2STRING( VOLUME ); + CASE2STRING( ELEM0D ); default:; } return ""; @@ -819,8 +858,7 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup SMESH::long_array_var anIds = aGroup->GetListOfID(); SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor(); - // Update Python script - TPythonDump() << _this() << ".RemoveGroupWithContents( " << theGroup << " )"; + TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup() // Remove contents if ( aGroup->GetType() == SMESH::NODE ) @@ -831,12 +869,10 @@ void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup // Remove group RemoveGroup( theGroup ); - // Clear python lines, created by RemoveNodes/Elements() and RemoveGroup() - _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId()); - _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId()); + // Update Python script + pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )"; } - //================================================================================ /*! * \brief Get the list of groups existing in the mesh @@ -879,6 +915,7 @@ SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception) return aList._retn(); } + //============================================================================= /*! * Get number of groups existing in the mesh @@ -2071,13 +2108,17 @@ void SMESH_Mesh_i::removeGroup( const int theId ) { if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" ); if ( _mapGroups.find( theId ) != _mapGroups.end() ) { - removeGeomGroupData( _mapGroups[theId] ); + SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId]; _mapGroups.erase( theId ); - _impl->RemoveGroup( theId ); + removeGeomGroupData( group ); + if (! _impl->RemoveGroup( theId )) + { + // it seems to be a call up from _impl caused by hyp modification (issue 0020918) + RemoveGroup( group ); + } } } - //============================================================================= /*! * @@ -2174,6 +2215,19 @@ CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception) return _studyId; } +//============================================================================= +namespace +{ + //!< implementation of struct used to call SMESH_Mesh_i::removeGroup() from + // SMESH_Mesh::RemoveGroup() (issue 0020918) + struct TRmGroupCallUp_i : public SMESH_Mesh::TRmGroupCallUp + { + SMESH_Mesh_i* _mesh; + TRmGroupCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {} + virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); } + }; +} + //============================================================================= /*! * @@ -2184,6 +2238,8 @@ void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl) { if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl"); _impl = impl; + if ( _impl ) + _impl->SetRemoveGroupCallUp( new TRmGroupCallUp_i(this)); } //============================================================================= @@ -2360,7 +2416,7 @@ void SMESH_Mesh_i::ExportToMEDX (const char* file, // check names of groups checkGroupNames(); - TPythonDump() << _this() << ".ExportToMEDX( '" + TPythonDump() << _this() << ".ExportToMEDX( r'" << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )"; _impl->ExportMED( file, aMeshName, auto_groups, theVersion ); @@ -2389,7 +2445,7 @@ void SMESH_Mesh_i::ExportDAT (const char *file) // Update Python script // check names of groups checkGroupNames(); - TPythonDump() << _this() << ".ExportDAT( '" << file << "' )"; + TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )"; // Perform Export PrepareForWriting(file); @@ -2404,7 +2460,7 @@ void SMESH_Mesh_i::ExportUNV (const char *file) // Update Python script // check names of groups checkGroupNames(); - TPythonDump() << _this() << ".ExportUNV( '" << file << "' )"; + TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )"; // Perform Export PrepareForWriting(file); @@ -2419,7 +2475,7 @@ void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii) // Update Python script // check names of groups checkGroupNames(); - TPythonDump() << _this() << ".ExportSTL( '" << file << "', " << isascii << " )"; + TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )"; // Perform Export PrepareForWriting(file); @@ -2749,7 +2805,7 @@ SMESH::long_array* SMESH_Mesh_i::GetNodesId() long nbNodes = NbNodes(); aResult->length( nbNodes ); - SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(); + SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true); for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ ) aResult[i] = anIt->next()->GetID(); @@ -3351,6 +3407,7 @@ void SMESH_Mesh_i::CreateGroupServants() { SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy(); + set addedIDs; ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups(); while ( groupIt->more() ) { @@ -3360,6 +3417,7 @@ void SMESH_Mesh_i::CreateGroupServants() map::iterator it = _mapGroups.find(anId); if ( it != _mapGroups.end() && !CORBA::is_nil( it->second )) continue; + addedIDs.insert( anId ); SMESH_GroupBase_i* aGroupImpl; TopoDS_Shape shape; @@ -3385,12 +3443,23 @@ void SMESH_Mesh_i::CreateGroupServants() int nextId = _gen_i->RegisterObject( groupVar ); if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId); - // publishing of the groups in the study + // publishing the groups in the study if ( !aStudy->_is_nil() ) { GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape ); _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName()); } } + if ( !addedIDs.empty() ) + { + // python dump + set::iterator id = addedIDs.begin(); + for ( ; id != addedIDs.end(); ++id ) + { + map::iterator it = _mapGroups.find(*id); + int i = std::distance( _mapGroups.begin(), it ); + TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]"; + } + } } //============================================================================= @@ -3518,6 +3587,40 @@ SMESH::string_array* SMESH_Mesh_i::GetLastParameters() return aResult._retn(); } +//======================================================================= +//function : GetTypes +//purpose : Returns types of elements it contains +//======================================================================= + +SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes() +{ + SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType; + + types->length( 4 ); + int nbTypes = 0; + if (_impl->NbEdges()) + types[nbTypes++] = SMESH::EDGE; + if (_impl->NbFaces()) + types[nbTypes++] = SMESH::FACE; + if (_impl->NbVolumes()) + types[nbTypes++] = SMESH::VOLUME; + if (_impl->Nb0DElements()) + types[nbTypes++] = SMESH::ELEM0D; + types->length( nbTypes ); + + return types._retn(); +} + +//======================================================================= +//function : GetMesh +//purpose : Returns self +//======================================================================= + +SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh() +{ + return SMESH::SMESH_Mesh::_duplicate( _this() ); +} + //============================================================================= /*! * \brief Returns statistic of mesh elements @@ -3862,10 +3965,9 @@ SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder() */ //============================================================================= -static void findCommonSubMesh - (list& theSubMeshList, - const SMESH_subMesh* theSubMesh, - set& theCommon ) +static void findCommonSubMesh (list& theSubMeshList, + const SMESH_subMesh* theSubMesh, + set& theCommon ) { if ( !theSubMesh ) return; diff --git a/src/SMESH_I/SMESH_Mesh_i.hxx b/src/SMESH_I/SMESH_Mesh_i.hxx index 521633e51..ea33ec9fa 100644 --- a/src/SMESH_I/SMESH_Mesh_i.hxx +++ b/src/SMESH_I/SMESH_Mesh_i.hxx @@ -19,12 +19,11 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // - // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : SMESH_Mesh_i.hxx // Author : Paul RASCLE, EDF // Module : SMESH -// + #ifndef _SMESH_MESH_I_HXX_ #define _SMESH_MESH_I_HXX_ @@ -98,7 +97,7 @@ public: SMESH::SMESH_Group_ptr CreateGroup( SMESH::ElementType theElemType, const char* theName ) throw (SALOME::SALOME_Exception); - + SMESH::SMESH_GroupOnGeom_ptr CreateGroupFromGEOM(SMESH::ElementType theElemType, const char* theName, GEOM::GEOM_Object_ptr theGeomObj ) @@ -106,49 +105,49 @@ public: void RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup ) throw (SALOME::SALOME_Exception); - + void RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup ) throw (SALOME::SALOME_Exception); - + SMESH::ListOfGroups* GetGroups() throw (SALOME::SALOME_Exception); CORBA::Long NbGroups() throw (SALOME::SALOME_Exception); - SMESH::SMESH_Group_ptr UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1, - SMESH::SMESH_GroupBase_ptr theGroup2, + SMESH::SMESH_Group_ptr UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1, + SMESH::SMESH_GroupBase_ptr theGroup2, const char* theName ) throw (SALOME::SALOME_Exception); - SMESH::SMESH_Group_ptr UnionListOfGroups( const SMESH::ListOfGroups& theGroups, + SMESH::SMESH_Group_ptr UnionListOfGroups( const SMESH::ListOfGroups& theGroups, const char* theName) throw (SALOME::SALOME_Exception); - - SMESH::SMESH_Group_ptr IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1, - SMESH::SMESH_GroupBase_ptr theGroup2, + + SMESH::SMESH_Group_ptr IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1, + SMESH::SMESH_GroupBase_ptr theGroup2, const char* theName ) throw (SALOME::SALOME_Exception); - SMESH::SMESH_Group_ptr IntersectListOfGroups( const SMESH::ListOfGroups& theGroups, + SMESH::SMESH_Group_ptr IntersectListOfGroups( const SMESH::ListOfGroups& theGroups, const char* theName ) throw (SALOME::SALOME_Exception); - - SMESH::SMESH_Group_ptr CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1, - SMESH::SMESH_GroupBase_ptr theGroup2, + + SMESH::SMESH_Group_ptr CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1, + SMESH::SMESH_GroupBase_ptr theGroup2, const char* theName ) throw (SALOME::SALOME_Exception); - SMESH::SMESH_Group_ptr CutListOfGroups( const SMESH::ListOfGroups& theMainGroups, - const SMESH::ListOfGroups& theToolGroups, + SMESH::SMESH_Group_ptr CutListOfGroups( const SMESH::ListOfGroups& theMainGroups, + const SMESH::ListOfGroups& theToolGroups, const char* theName ) throw (SALOME::SALOME_Exception); - SMESH::SMESH_Group_ptr CreateDimGroup( const SMESH::ListOfGroups& theGroups, - SMESH::ElementType theElemType, + SMESH::SMESH_Group_ptr CreateDimGroup( const SMESH::ListOfGroups& theGroups, + SMESH::ElementType theElemType, const char* theName ) throw (SALOME::SALOME_Exception); - + SMESH::SMESH_Group_ptr ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGeomGroup ); @@ -303,16 +302,16 @@ public: SMESH::long_array* GetElementsByType( SMESH::ElementType theElemType ) throw (SALOME::SALOME_Exception); - + SMESH::long_array* GetNodesId() throw (SALOME::SALOME_Exception); - + SMESH::ElementType GetElementType( CORBA::Long id, bool iselem ) throw (SALOME::SALOME_Exception); - + SMESH::EntityType GetElementGeomType( CORBA::Long id ) throw (SALOME::SALOME_Exception); - + /*! * Returns ID of elements for given submesh */ @@ -326,15 +325,15 @@ public: */ SMESH::long_array* GetSubMeshNodesId(CORBA::Long ShapeID, CORBA::Boolean all) throw (SALOME::SALOME_Exception); - + /*! * Returns type of elements for given submesh */ SMESH::ElementType GetSubMeshElementType(CORBA::Long ShapeID) throw (SALOME::SALOME_Exception); - + char* Dump(); - + // Internal methods not available through CORBA // They are called by corresponding interface methods SMESH_Hypothesis::Hypothesis_Status addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, @@ -342,7 +341,7 @@ public: SMESH_Hypothesis::Hypothesis_Status removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject, SMESH::SMESH_Hypothesis_ptr anHyp); - + static SMESH::Hypothesis_Status ConvertHypothesisStatus (SMESH_Hypothesis::Hypothesis_Status theStatus); @@ -369,13 +368,11 @@ public: /*! * \brief Update hypotheses assigned to geom groups if the latter change - * + * * NPAL16168: "geometrical group edition from a submesh don't modifiy mesh computation" */ void CheckGeomGroupModif(); - virtual SMESH::long_array* GetIDs(); - CORBA::LongLong GetMeshPtr(); /*! @@ -393,7 +390,7 @@ public: * If there is not node for given ID - returns empty list */ SMESH::double_array* GetNodeXYZ(CORBA::Long id); - + /*! * For given node returns list of IDs of inverse elements * If there is not node for given ID - returns empty list @@ -412,7 +409,7 @@ public: CORBA::Long GetShapeID(CORBA::Long id); /*! - * For given element returns ID of result shape after + * For given element returns ID of result shape after * ::FindShape() from SMESH_MeshEditor * If there is not element for given ID - returns -1 */ @@ -435,25 +432,25 @@ public: * If there is not node for given index - returns -2 */ CORBA::Long GetElemNode(CORBA::Long id, CORBA::Long index); - + /*! * Returns true if given node is medium node * in given quadratic element */ CORBA::Boolean IsMediumNode(CORBA::Long ide, CORBA::Long idn); - + /*! * Returns true if given node is medium node * in one of quadratic elements */ CORBA::Boolean IsMediumNodeOfAnyElem(CORBA::Long idn, SMESH::ElementType theElemType); - + /*! * Returns number of edges for given element */ CORBA::Long ElemNbEdges(CORBA::Long id); - + /*! * Returns number of faces for given element */ @@ -472,12 +469,12 @@ public: * Returns true if given element is polygon */ CORBA::Boolean IsPoly(CORBA::Long id); - + /*! * Returns true if given element is quadratic */ CORBA::Boolean IsQuadratic(CORBA::Long id); - + /*! * Returns bary center for given element */ @@ -492,7 +489,7 @@ public: * Sets list of notebook variables used for Mesh operations separated by ":" symbol */ void SetParameters (const char* theParameters); - + /*! * Returns list of notebook variables used for Mesh operations separated by ":" symbol */ @@ -503,20 +500,11 @@ public: */ SMESH::string_array* GetLastParameters(); - - /*! - * Returns statistic of mesh elements - * Result array of number enityties - * Inherited from SMESH_IDSource - */ - virtual SMESH::long_array* GetMeshInfo(); - /*! * Collect statistic of mesh elements given by iterator */ static void CollectMeshInfo(const SMDS_ElemIteratorPtr theItr, SMESH::long_array& theInfo); - /*! * \brief Return submesh objects list in meshing order @@ -527,7 +515,28 @@ public: */ virtual ::CORBA::Boolean SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray); - + + // ========================= + // SMESH_IDSource interface + // ========================= + + virtual SMESH::long_array* GetIDs(); + /*! + * Returns statistic of mesh elements + * Result array of number enityties + * Inherited from SMESH_IDSource + */ + virtual SMESH::long_array* GetMeshInfo(); + /*! + * Returns types of elements it contains + */ + virtual SMESH::array_of_ElementType* GetTypes(); + /*! + * Returns self + */ + virtual SMESH::SMESH_Mesh_ptr GetMesh(); + + std::map _mapSubMesh_i; //NRI std::map _mapSubMesh; //NRI @@ -581,8 +590,7 @@ private: * \brief Return new group contents if it has been changed and update group data */ TopoDS_Shape newGroupShape( TGeomGroupData & groupData); - + }; #endif - diff --git a/src/SMESH_I/SMESH_Pattern_i.cxx b/src/SMESH_I/SMESH_Pattern_i.cxx index 3d725b8fb..2a799a5b6 100644 --- a/src/SMESH_I/SMESH_Pattern_i.cxx +++ b/src/SMESH_I/SMESH_Pattern_i.cxx @@ -387,7 +387,14 @@ CORBA::Boolean SMESH_Pattern_i::MakeMesh (SMESH::SMESH_Mesh_ptr theMesh, << CreatePolygons << ", " << CreatePolyedrs << " )"; addErrorCode( "MakeMesh" ); - return myPattern.MakeMesh( aMesh, CreatePolygons, CreatePolyedrs ); + int nb = aMesh->NbNodes() + aMesh->NbEdges() + aMesh->NbFaces() + aMesh->NbVolumes(); + + bool res = myPattern.MakeMesh( aMesh, CreatePolygons, CreatePolyedrs ); + + if ( nb > 0 && nb != aMesh->NbNodes() + aMesh->NbEdges() + aMesh->NbFaces() + aMesh->NbVolumes()) + aMesh->SetIsModified(true); + + return res; } //======================================================================= diff --git a/src/SMESH_I/SMESH_PythonDump.hxx b/src/SMESH_I/SMESH_PythonDump.hxx index afcd15ddb..f1ee26581 100644 --- a/src/SMESH_I/SMESH_PythonDump.hxx +++ b/src/SMESH_I/SMESH_PythonDump.hxx @@ -73,6 +73,7 @@ namespace SMESH class FilterManager_i; class Filter_i; class Functor_i; + class Measurements_i; // =========================================================================================== /*! @@ -142,6 +143,9 @@ namespace SMESH TPythonDump& operator<<(SMESH::Functor_i* theArg); + TPythonDump& + operator<<(SMESH::Measurements_i* theArg); + TPythonDump& operator<<(SMESH_Gen_i* theArg); @@ -161,7 +165,10 @@ namespace SMESH operator<<(const TCollection_AsciiString & theArg); TPythonDump& - operator<<(const SMESH::ListOfGroups * theList); + operator<<(const SMESH::ListOfGroups& theList); + + TPythonDump& + operator<<(const SMESH::ListOfIDSources& theList); static const char* SMESHGenName() { return "smeshgen"; } static const char* MeshEditorName() { return "mesh_editor"; } diff --git a/src/SMESH_I/SMESH_subMesh_i.cxx b/src/SMESH_I/SMESH_subMesh_i.cxx index 301f1a972..45d486733 100644 --- a/src/SMESH_I/SMESH_subMesh_i.cxx +++ b/src/SMESH_I/SMESH_subMesh_i.cxx @@ -545,3 +545,46 @@ SMESH::long_array* SMESH_subMesh_i::GetMeshInfo() return aRes._retn(); } + + +//======================================================================= +//function : GetTypes +//purpose : Returns types of elements it contains +//======================================================================= + +SMESH::array_of_ElementType* SMESH_subMesh_i::GetTypes() +{ + SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType; + + ::SMESH_subMesh* aSubMesh = _mesh_i->_mapSubMesh[_localId]; + TopoDS_Shape shape = aSubMesh->GetSubShape(); + while ( !shape.IsNull() && shape.ShapeType() == TopAbs_COMPOUND ) + { + TopoDS_Iterator it( shape ); + shape = it.More() ? it.Value() : TopoDS_Shape(); + } + if ( !shape.IsNull() ) + { + types->length( 1 ); + switch ( ::SMESH_Gen::GetShapeDim( shape )) + { + case 0: types[0] = SMESH::ELEM0D; break; + case 1: types[0] = SMESH::EDGE; break; + case 2: types[0] = SMESH::FACE; break; + case 3: types[0] = SMESH::VOLUME; break; + default: + types->length(0); + } + } + return types._retn(); +} + +//======================================================================= +//function : GetMesh +//purpose : interface SMESH_IDSource +//======================================================================= + +SMESH::SMESH_Mesh_ptr SMESH_subMesh_i::GetMesh() +{ + return GetFather(); +} diff --git a/src/SMESH_I/SMESH_subMesh_i.hxx b/src/SMESH_I/SMESH_subMesh_i.hxx index bd53171ae..f5fd559d4 100644 --- a/src/SMESH_I/SMESH_subMesh_i.hxx +++ b/src/SMESH_I/SMESH_subMesh_i.hxx @@ -85,14 +85,29 @@ public: SALOME_MED::FAMILY_ptr GetFamily() throw (SALOME::SALOME_Exception); - virtual SMESH::long_array* GetIDs(); + // ========================= + // interface SMESH_IDSource + // ========================= + /*! + * Returns a sequence of all element IDs + */ + virtual SMESH::long_array* GetIDs(); /*! * Returns statistic of mesh elements * Result array of number enityties * Inherited from SMESH_IDSource */ virtual SMESH::long_array* GetMeshInfo(); + /*! + * Returns types of elements it contains + */ + virtual SMESH::array_of_ElementType* GetTypes(); + /*! + * Returns the mesh + */ + SMESH::SMESH_Mesh_ptr GetMesh(); + SMESH_Mesh_i* _mesh_i; //NRI diff --git a/src/SMESH_PY/Makefile.am b/src/SMESH_PY/Makefile.am new file mode 100644 index 000000000..254e9ef08 --- /dev/null +++ b/src/SMESH_PY/Makefile.am @@ -0,0 +1,25 @@ +# Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +include $(top_srcdir)/adm_local/unix/make_common_starter.am + +salomepypkgdir = $(salomepythondir)/salome/smesh +salomepypkg_PYTHON = \ + __init__.py \ + smeshstudytools.py diff --git a/src/SMESH_PY/__init__.py b/src/SMESH_PY/__init__.py new file mode 100644 index 000000000..5d3edfa55 --- /dev/null +++ b/src/SMESH_PY/__init__.py @@ -0,0 +1 @@ +# -*- coding: iso-8859-1 -*- diff --git a/src/SMESH_PY/smeshstudytools.py b/src/SMESH_PY/smeshstudytools.py new file mode 100644 index 000000000..0545efae6 --- /dev/null +++ b/src/SMESH_PY/smeshstudytools.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2007-2009 EDF R&D +# +# This file is part of PAL_SRC. +# +# PAL_SRC is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# PAL_SRC 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with PAL_SRC; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# +""" +This module provides a new class :class:`SMeshStudyTools` to facilitate the +use of mesh objects in Salome study. +""" + +import salome +SMESH = None # SMESH module is loaded only when needed + +from salome.kernel.studyedit import getStudyEditor + +class SMeshStudyTools: + """ + This class provides several methods to manipulate mesh objects in Salome + study. The parameter `studyEditor` defines a + :class:`~salome.kernel.studyedit.StudyEditor` object used to access the study. If + :const:`None`, the method returns a :class:`~salome.kernel.studyedit.StudyEditor` + object on the current study. + + .. attribute:: editor + + This instance attribute contains the underlying + :class:`~salome.kernel.studyedit.StudyEditor` object. It can be used to access + the study but the attribute itself should not be modified. + + """ + + def __init__(self, studyEditor = None): + global SMESH + if SMESH is None: + SMESH = __import__("SMESH") + if studyEditor is None: + studyEditor = getStudyEditor() + self.editor = studyEditor + + def getMeshFromGroup(self, meshGroupItem): + """ + Get the mesh item owning the mesh group `meshGroupItem`. + + :type meshGroupItem: SObject + :param meshGroupItem: Mesh group belonging to the searched mesh. + + :return: The SObject corresponding to the mesh, or None if it was not + found. + """ + meshItem = None + obj = self.editor.getOrLoadObject(meshGroupItem) + group = obj._narrow(SMESH.SMESH_GroupBase) + if group is not None: # The type of the object is ok + meshObj = group.GetMesh() + meshItem = salome.ObjectToSObject(meshObj) + return meshItem diff --git a/src/SMESH_SWIG/SMESH_BelongToGeom.py b/src/SMESH_SWIG/SMESH_BelongToGeom.py index 02047a1cf..af6c98420 100644 --- a/src/SMESH_SWIG/SMESH_BelongToGeom.py +++ b/src/SMESH_SWIG/SMESH_BelongToGeom.py @@ -40,6 +40,7 @@ def CheckBelongToGeomFilterOld(theMeshGen, theMesh, theShape, theSubShape, theEl aBelongToGeom.SetElementType(theElemType) aFilter.SetPredicate(aBelongToGeom) + aFilterMgr.Destroy() return aFilter.GetElementsId(theMesh) ## Current style diff --git a/src/SMESH_SWIG/SMESH_GroupLyingOnGeom.py b/src/SMESH_SWIG/SMESH_GroupLyingOnGeom.py index e0cbb6404..c90a3bd89 100644 --- a/src/SMESH_SWIG/SMESH_GroupLyingOnGeom.py +++ b/src/SMESH_SWIG/SMESH_GroupLyingOnGeom.py @@ -36,6 +36,7 @@ def BuildGroupLyingOn(theMesh, theElemType, theName, theShape): aFilter.SetPredicate(aLyingOnGeom) anIds = aFilter.GetElementsId(theMesh) + aFilterMgr.Destroy() aGroup = theMesh.CreateGroup(theElemType, theName) aGroup.Add(anIds) diff --git a/src/SMESH_SWIG/SMESH_Nut.py b/src/SMESH_SWIG/SMESH_Nut.py index 801e554f1..62b6af8b9 100755 --- a/src/SMESH_SWIG/SMESH_Nut.py +++ b/src/SMESH_SWIG/SMESH_Nut.py @@ -87,7 +87,7 @@ geompy.addToStudy(Chamfer_2, "Chamfer_2") #Import of the shape from "slots.brep" print "Import multi-rotation from the DATA_DIR/Shapes/Brep/slots.brep" thePath = os.getenv("DATA_DIR") -theFileName = thePath + "/Shapes/Brep/slots.brep" +theFileName = os.path.join( thePath,"Shapes","Brep","slots.brep") theShapeForCut = geompy.ImportBREP(theFileName) geompy.addToStudy(theShapeForCut, "slot.brep_1") diff --git a/src/SMESH_SWIG/SMESH_controls.py b/src/SMESH_SWIG/SMESH_controls.py index 43c1b5874..a322e42c5 100644 --- a/src/SMESH_SWIG/SMESH_controls.py +++ b/src/SMESH_SWIG/SMESH_controls.py @@ -128,4 +128,16 @@ print "Criterion: Borders at multi-connections = 2 Nb = ", len( anIds ) #print anIds[ i ] +# Criterion : Element Diameter 2D > 10 + +# create group +aGroup = mesh.MakeGroup("Element Diameter 2D > 10", smesh.FACE, smesh.FT_MaxElementLength2D, smesh.FT_MoreThan, 10 ) + +# print result +anIds = aGroup.GetIDs() +print "Criterion: Element Diameter 2D > 10 Nb = ", len( anIds ) +#for i in range( len( anIds ) ): + #print anIds[ i ] + + salome.sg.updateObjBrowser(1) diff --git a/src/SMESH_SWIG/smeshDC.py b/src/SMESH_SWIG/smeshDC.py index de8f32624..a2476107a 100644 --- a/src/SMESH_SWIG/smeshDC.py +++ b/src/SMESH_SWIG/smeshDC.py @@ -50,6 +50,7 @@ ## @defgroup l3_hypos_ghs3dh GHS3D Parameters hypothesis ## @defgroup l3_hypos_blsurf BLSURF Parameters hypothesis ## @defgroup l3_hypos_hexotic Hexotic Parameters hypothesis +## @defgroup l3_hypos_quad Quadrangle Parameters hypothesis ## @defgroup l3_hypos_additi Additional Hypotheses ## @} @@ -87,6 +88,7 @@ ## @defgroup l2_modif_tofromqu Convert to/from Quadratic Mesh ## @} +## @defgroup l1_measurements Measurements import salome import geompyDC @@ -198,6 +200,11 @@ PrecisionConfusion = 1e-07 # TopAbs_State enumeration [TopAbs_IN, TopAbs_OUT, TopAbs_ON, TopAbs_UNKNOWN] = range(4) +# Methods of splitting a hexahedron into tetrahedra +Hex_5Tet, Hex_6Tet, Hex_24Tet = 1, 2, 3 + +# import items of enum QuadType +for e in StdMeshers.QuadType._items: exec('%s = StdMeshers.%s'%(e,e)) ## Converts an angle from degrees to radians def DegreesToRadians(AngleInDegrees): @@ -513,6 +520,20 @@ class smeshDC(SMESH._objref_SMESH_Gen): def EnumToLong(self,theItem): return theItem._v + ## Returns a string representation of the color. + # To be used with filters. + # @param c color value (SALOMEDS.Color) + # @ingroup l1_controls + def ColorToString(self,c): + val = "" + if isinstance(c, SALOMEDS.Color): + val = "%s;%s;%s" % (c.R, c.G, c.B) + elif isinstance(c, str): + val = c + else: + raise ValueError, "Color value should be of string or SALOMEDS.Color type" + return val + ## Gets PointStruct from vertex # @param theVertex a GEOM object(vertex) # @return SMESH.PointStruct @@ -673,6 +694,9 @@ class smeshDC(SMESH._objref_SMESH_Gen): def Concatenate( self, meshes, uniteIdenticalGroups, mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False): mergeTolerance,Parameters = geompyDC.ParseParameters(mergeTolerance) + for i,m in enumerate(meshes): + if isinstance(m, Mesh): + meshes[i] = m.GetMesh() if allGroups: aSmeshMesh = SMESH._objref_SMESH_Gen.ConcatenateWithGroups( self,meshes,uniteIdenticalGroups,mergeNodesAndElements,mergeTolerance) @@ -753,8 +777,40 @@ class smeshDC(SMESH._objref_SMESH_Gen): else: print "Error: The treshold should be a string." return None + elif CritType == FT_CoplanarFaces: + # Checks the treshold + if isinstance(aTreshold, int): + aCriterion.ThresholdID = "%s"%aTreshold + elif isinstance(aTreshold, str): + ID = int(aTreshold) + if ID < 1: + raise ValueError, "Invalid ID of mesh face: '%s'"%aTreshold + aCriterion.ThresholdID = aTreshold + else: + raise ValueError,\ + "The treshold should be an ID of mesh face and not '%s'"%aTreshold + elif CritType == FT_ElemGeomType: + # Checks the treshold + try: + aCriterion.Threshold = self.EnumToLong(aTreshold) + except: + if isinstance(aTreshold, int): + aCriterion.Threshold = aTreshold + else: + print "Error: The treshold should be an integer or SMESH.GeometryType." + return None + pass + pass + elif CritType == FT_GroupColor: + # Checks the treshold + try: + aCriterion.ThresholdStr = self.ColorToString(aTreshold) + except: + print "Error: The threshold value should be of SALOMEDS.Color type" + return None + pass elif CritType in [FT_FreeBorders, FT_FreeEdges, FT_BadOrientedVolume, FT_FreeNodes, - FT_FreeFaces, FT_ElemGeomType, FT_GroupColor]: + FT_FreeFaces, FT_LinearOrQuadratic]: # At this point the treshold is unnecessary if aTreshold == FT_LogicalNOT: aCriterion.UnaryOp = self.EnumToLong(FT_LogicalNOT) @@ -802,6 +858,7 @@ class smeshDC(SMESH._objref_SMESH_Gen): aCriteria = [] aCriteria.append(aCriterion) aFilter.SetCriteria(aCriteria) + aFilterMgr.Destroy() return aFilter ## Creates a numerical functor by its type @@ -826,6 +883,10 @@ class smeshDC(SMESH._objref_SMESH_Gen): return aFilterMgr.CreateArea() elif theCriterion == FT_Volume3D: return aFilterMgr.CreateVolume3D() + elif theCriterion == FT_MaxElementLength2D: + return aFilterMgr.CreateMaxElementLength2D() + elif theCriterion == FT_MaxElementLength3D: + return aFilterMgr.CreateMaxElementLength3D() elif theCriterion == FT_MultiConnection: return aFilterMgr.CreateMultiConnection() elif theCriterion == FT_MultiConnection2D: @@ -858,6 +919,110 @@ class smeshDC(SMESH._objref_SMESH_Gen): pass return d + ## Get minimum distance 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 src2 second source object + # @param id1 node/element id from the first source + # @param id2 node/element id from the second (or first) source + # @param isElem1 @c True if @a id1 is element id, @c False if it is node id + # @param isElem2 @c True if @a id2 is element id, @c False if it is node id + # @return minimum distance value + # @sa GetMinDistance() + # @ingroup l1_measurements + def MinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False): + result = self.GetMinDistance(src1, src2, id1, id2, isElem1, isElem2) + if result is None: + result = 0.0 + 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 src2 second source object + # @param id1 node/element id from the first source + # @param id2 node/element id from the second (or first) source + # @param isElem1 @c True if @a id1 is element id, @c False if it is node id + # @param isElem2 @c True if @a id2 is element id, @c False if it is node id + # @return Measure structure or None if input data is invalid + # @sa MinDistance() + # @ingroup l1_measurements + def GetMinDistance(self, src1, src2=None, id1=0, id2=0, isElem1=False, isElem2=False): + if isinstance(src1, Mesh): src1 = src1.mesh + if isinstance(src2, Mesh): src2 = src2.mesh + if src2 is None and id2 != 0: src2 = src1 + if not hasattr(src1, "_narrow"): return None + src1 = src1._narrow(SMESH.SMESH_IDSource) + if not src1: return None + if id1 != 0: + m = src1.GetMesh() + e = m.GetMeshEditor() + if isElem1: + src1 = e.MakeIDSource([id1], SMESH.FACE) + else: + src1 = e.MakeIDSource([id1], SMESH.NODE) + pass + if hasattr(src2, "_narrow"): + src2 = src2._narrow(SMESH.SMESH_IDSource) + if src2 and id2 != 0: + m = src2.GetMesh() + e = m.GetMeshEditor() + if isElem2: + src2 = e.MakeIDSource([id2], SMESH.FACE) + else: + src2 = e.MakeIDSource([id2], SMESH.NODE) + pass + pass + aMeasurements = self.CreateMeasurements() + 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) + # @sa GetBoundingBox() + # @ingroup l1_measurements + def BoundingBox(self, objects): + result = self.GetBoundingBox(objects) + if result is None: + result = (0.0,)*6 + else: + result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ) + return result + + ## Get measure structure specifying bounding box data of the specified object(s) + # @param objects single source object or list of source objects + # @return Measure structure + # @sa BoundingBox() + # @ingroup l1_measurements + def GetBoundingBox(self, objects): + if isinstance(objects, tuple): + objects = list(objects) + if not isinstance(objects, list): + objects = [objects] + srclist = [] + for o in objects: + if isinstance(o, Mesh): + srclist.append(o.mesh) + elif hasattr(o, "_narrow"): + src = o._narrow(SMESH.SMESH_IDSource) + if src: srclist.append(src) + pass + pass + aMeasurements = self.CreateMeasurements() + result = aMeasurements.BoundingBox(srclist) + aMeasurements.Destroy() + return result + import omniORB #Registering the new proxy for SMESH_Gen omniORB.registerObjref(SMESH._objref_SMESH_Gen._NP_RepositoryId, smeshDC) @@ -1023,6 +1188,24 @@ class Mesh: else: return Mesh_Segment(self, geom) + ## Creates 1D algorithm importing segments conatined in groups of other mesh. + # If the optional \a geom parameter is not set, this algorithm is global. + # Otherwise, this algorithm defines a submesh based on \a geom subshape. + # @param geom If defined the subshape is to be meshed + # @return an instance of Mesh_UseExistingElements class + # @ingroup l3_algos_basic + def UseExisting1DElements(self, geom=0): + return Mesh_UseExistingElements(1,self, geom) + + ## Creates 2D algorithm importing faces conatined in groups of other mesh. + # If the optional \a geom parameter is not set, this algorithm is global. + # Otherwise, this algorithm defines a submesh based on \a geom subshape. + # @param geom If defined the subshape is to be meshed + # @return an instance of Mesh_UseExistingElements class + # @ingroup l3_algos_basic + def UseExisting2DElements(self, geom=0): + return Mesh_UseExistingElements(2,self, geom) + ## Enables creation of nodes and segments usable by 2D algoritms. # The added nodes and segments must be bound to edges and vertices by # SetNodeOnVertex(), SetNodeOnEdge() and SetMeshElementOnShape() @@ -1154,7 +1337,9 @@ class Mesh: return Mesh_RadialPrism3D(self, geom) ## Evaluates size of prospective mesh on a shape - # @return True or False + # @return a list where i-th element is a number of elements of i-th SMESH.EntityType + # To know predicted number of e.g. edges, inquire it this way + # Evaluate()[ EnumToLong( Entity_Edge )] def Evaluate(self, geom=0): if geom == 0 or not isinstance(geom, geompyDC.GEOM._objref_GEOM_Object): if self.geom == 0: @@ -1165,6 +1350,7 @@ class Mesh: ## Computes the mesh and returns the status of the computation + # @param geom geomtrical shape on which mesh data should be computed # @param discardModifs if True and the mesh has been edited since # a last total re-compute and that may prevent successful partial re-compute, # then the mesh is cleaned before Compute() @@ -1583,6 +1769,7 @@ class Mesh: aCriteria.append(Criterion) aFilter.SetCriteria(aCriteria) group = self.MakeGroupByFilter(groupName, aFilter) + aFilterMgr.Destroy() return group ## Creates a mesh group by the given criteria (list of criteria) @@ -1595,6 +1782,7 @@ class Mesh: aFilter = aFilterMgr.CreateFilter() aFilter.SetCriteria(theCriteria) group = self.MakeGroupByFilter(groupName, aFilter) + aFilterMgr.Destroy() return group ## Creates a mesh group by the given filter @@ -1603,9 +1791,9 @@ class Mesh: # @return SMESH_Group # @ingroup l2_grps_create def MakeGroupByFilter(self, groupName, theFilter): - anIds = theFilter.GetElementsId(self.mesh) - anElemType = theFilter.GetElementType() - group = self.MakeGroupByIds(groupName, anElemType, anIds) + group = self.CreateEmptyGroup(theFilter.GetElementType(), groupName) + theFilter.SetMesh( self.mesh ) + group.AddFrom( theFilter ) return group ## Passes mesh elements through the given filter and return IDs of fitting elements @@ -1613,7 +1801,8 @@ class Mesh: # @return a list of ids # @ingroup l1_controls def GetIdsFromFilter(self, theFilter): - return theFilter.GetElementsId(self.mesh) + theFilter.SetMesh( self.mesh ) + return theFilter.GetIDs() ## Verifies whether a 2D mesh element has free edges (edges connected to one face only)\n # Returns a list of special structures (borders). @@ -1624,6 +1813,7 @@ class Mesh: aPredicate = aFilterMgr.CreateFreeEdges() aPredicate.SetMesh(self.mesh) aBorders = aPredicate.GetBorders() + aFilterMgr.Destroy() return aBorders ## Removes a group @@ -1965,7 +2155,7 @@ class Mesh: return self.mesh.GetElementsId() ## Returns the list of IDs of mesh elements with the given type - # @param elementType the required type of elements + # @param elementType the required type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME) # @return list of integer values # @ingroup l1_meshinfo def GetElementsByType(self, elementType): @@ -2143,6 +2333,95 @@ class Mesh: return self.mesh.BaryCenter(id) + # Get mesh measurements information: + # ------------------------------------ + + ## Get minimum distance between two nodes, elements or distance to the origin + # @param id1 first node/element id + # @param id2 second node/element id (if 0, distance from @a id1 to the origin is computed) + # @param isElem1 @c True if @a id1 is element id, @c False if it is node id + # @param isElem2 @c True if @a id2 is element id, @c False if it is node id + # @return minimum distance value + # @sa GetMinDistance() + 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) + # @param isElem1 @c True if @a id1 is element id, @c False if it is node id + # @param isElem2 @c True if @a id2 is element id, @c False if it is node id + # @return Measure structure + # @sa MinDistance() + def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False): + if isElem1: + id1 = self.editor.MakeIDSource([id1], SMESH.FACE) + else: + id1 = self.editor.MakeIDSource([id1], SMESH.NODE) + if id2 != 0: + if isElem2: + id2 = self.editor.MakeIDSource([id2], SMESH.FACE) + else: + id2 = self.editor.MakeIDSource([id2], SMESH.NODE) + 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, + # @c False specifies that @a objects are nodes + # @return tuple of six values (minX, minY, minZ, maxX, maxY, maxZ) + # @sa GetBoundingBox() + def BoundingBox(self, objects=None, isElem=False): + result = self.GetBoundingBox(objects, isElem) + if result is None: + result = (0.0,)*6 + else: + result = (result.minX, result.minY, result.minZ, result.maxX, result.maxY, result.maxZ) + return result + + ## Get measure structure specifying bounding box data 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, + # @c False specifies that @a objects are nodes + # @return Measure structure + # @sa BoundingBox() + def GetBoundingBox(self, IDs=None, isElem=False): + if IDs is None: + IDs = [self.mesh] + elif isinstance(IDs, tuple): + IDs = list(IDs) + if not isinstance(IDs, list): + IDs = [IDs] + if len(IDs) > 0 and isinstance(IDs[0], int): + IDs = [IDs] + srclist = [] + for o in IDs: + if isinstance(o, Mesh): + srclist.append(o.mesh) + elif hasattr(o, "_narrow"): + src = o._narrow(SMESH.SMESH_IDSource) + if src: srclist.append(src) + pass + elif isinstance(o, list): + if isElem: + srclist.append(self.editor.MakeIDSource(o, SMESH.FACE)) + else: + srclist.append(self.editor.MakeIDSource(o, SMESH.NODE)) + pass + pass + aMeasurements = self.smeshpyD.CreateMeasurements() + aMeasure = aMeasurements.BoundingBox(srclist) + aMeasurements.Destroy() + return aMeasure + # Mesh edition (SMESH_MeshEditor functionality): # --------------------------------------------- @@ -2160,6 +2439,12 @@ class Mesh: def RemoveNodes(self, IDsOfNodes): return self.editor.RemoveNodes(IDsOfNodes) + ## Removes all orphan (free) nodes from mesh + # @return number of the removed nodes + # @ingroup l2_modif_del + def RemoveOrphanNodes(self): + return self.editor.RemoveOrphanNodes() + ## Add a node to the mesh by coordinates # @return Id of the new node # @ingroup l2_modif_add @@ -2180,7 +2465,7 @@ class Mesh: # @param IDsOfNodes the list of node IDs for creation of the element. # The order of nodes in this list should correspond to the description # of MED. \n This description is located by the following link: - # http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3. + # http://www.code-aster.org/outils/med/html/modele_de_donnees.html#3. # @return the Id of the new edge # @ingroup l2_modif_add def AddEdge(self, IDsOfNodes): @@ -2191,7 +2476,7 @@ class Mesh: # @param IDsOfNodes the list of node IDs for creation of the element. # The order of nodes in this list should correspond to the description # of MED. \n This description is located by the following link: - # http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3. + # http://www.code-aster.org/outils/med/html/modele_de_donnees.html#3. # @return the Id of the new face # @ingroup l2_modif_add def AddFace(self, IDsOfNodes): @@ -2209,7 +2494,7 @@ class Mesh: # @param IDsOfNodes the list of node IDs for creation of the element. # The order of nodes in this list should correspond to the description # of MED. \n This description is located by the following link: - # http://www.salome-platform.org/salome2/web_med_internet/logiciels/medV2.2.2_doc_html/html/modele_de_donnees.html#3. + # http://www.code-aster.org/outils/med/html/modele_de_donnees.html#3. # @return the Id of the new volumic element # @ingroup l2_modif_add def AddVolume(self, IDsOfNodes): @@ -2506,13 +2791,14 @@ class Mesh: ## Splits volumic elements into tetrahedrons # @param elemIDs either list of elements or mesh or group or submesh - # @param method flags passing splitting method: - # 1 - split the hexahedron into 5 tetrahedrons - # 2 - split the hexahedron into 6 tetrahedrons + # @param method flags passing splitting method: Hex_5Tet, Hex_6Tet, Hex_24Tet + # Hex_5Tet - split the hexahedron into 5 tetrahedrons, etc # @ingroup l2_modif_cutquadr - def SplitVolumesIntoTetra(self, elemIDs, method=1 ): + def SplitVolumesIntoTetra(self, elemIDs, method=Hex_5Tet ): if isinstance( elemIDs, Mesh ): elemIDs = elemIDs.GetMesh() + if ( isinstance( elemIDs, list )): + elemIDs = self.editor.MakeIDSource(elemIDs, SMESH.VOLUME) self.editor.SplitVolumesIntoTetra(elemIDs, method) ## Splits quadrangle faces near triangular facets of volumes @@ -2727,6 +3013,9 @@ class Mesh: ## Converts the mesh to quadratic, deletes old elements, replacing # them with quadratic with the same id. + # @param theForce3d new node creation method: + # 0 - the medium node lies at the geometrical edge from which the mesh element is built + # 1 - the medium node lies at the middle of the line segments connecting start and end node of a mesh element # @ingroup l2_modif_tofromqu def ConvertToQuadratic(self, theForce3d): self.editor.ConvertToQuadratic(theForce3d) @@ -2744,7 +3033,34 @@ class Mesh: # @ingroup l2_modif_edit def Make2DMeshFrom3D(self): return self.editor. Make2DMeshFrom3D() - + + ## Creates missing boundary elements + # @param elements - elements whose boundary is to be checked: + # mesh, group, sub-mesh or list of elements + # @param dimension - defines type of boundary elements to create: + # SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D + # @param groupName - a name of group to store created boundary elements in, + # "" means not to create the group + # @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 + # boundary elements will be copied into the new mesh + # @return tuple (mesh, group) where bondary elements were added to + # @ingroup l2_modif_edit + def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="", + toCopyElements=False, toCopyExistingBondary=False): + if isinstance( elements, Mesh ): + elements = elements.GetMesh() + if ( isinstance( elements, list )): + elemType = SMESH.ALL + if elements: elemType = self.GetElementType( elements[0], iselem=True) + elements = self.editor.MakeIDSource(elements, elemType) + mesh, group = self.editor.MakeBoundaryMesh(elements,dimension,groupName,meshName, + toCopyElements,toCopyExistingBondary) + if mesh: mesh = self.smeshpyD.Mesh(mesh) + return mesh, group + ## Renumber mesh nodes # @ingroup l2_modif_renumber def RenumberNodes(self): @@ -3374,7 +3690,7 @@ class Mesh: ## Scales the object # @param theObject - the object to translate (mesh, submesh, or group) # @param thePoint - base point for scale - # @param theScaleFact - scale factors for axises + # @param theScaleFact - list of 1-3 scale factors for axises # @param Copy - allows copying the translated elements # @param MakeGroups - forces the generation of new groups from existing # ones (if Copy) @@ -3384,7 +3700,7 @@ class Mesh: if ( isinstance( theObject, Mesh )): theObject = theObject.GetMesh() if ( isinstance( theObject, list )): - theObject = self.editor.MakeIDSource(theObject) + theObject = self.editor.MakeIDSource(theObject, SMESH.ALL) thePoint, Parameters = ParsePointStruct(thePoint) self.mesh.SetParameters(Parameters) @@ -3397,7 +3713,7 @@ class Mesh: ## Creates a new mesh from the translated object # @param theObject - the object to translate (mesh, submesh, or group) # @param thePoint - base point for scale - # @param theScaleFact - scale factors for axises + # @param theScaleFact - list of 1-3 scale factors for axises # @param MakeGroups - forces the generation of new groups from existing ones # @param NewMeshName - the name of the newly created mesh # @return instance of Mesh class @@ -3405,7 +3721,7 @@ class Mesh: if (isinstance(theObject, Mesh)): theObject = theObject.GetMesh() if ( isinstance( theObject, list )): - theObject = self.editor.MakeIDSource(theObject) + theObject = self.editor.MakeIDSource(theObject,SMESH.ALL) mesh = self.editor.ScaleMakeMesh(theObject, thePoint, theScaleFact, MakeGroups, NewMeshName) @@ -3530,10 +3846,17 @@ class Mesh: ## Finds groups of ajacent nodes within Tolerance. # @param Tolerance the value of tolerance # @param SubMeshOrGroup SubMesh or Group + # @param exceptNodes list of either SubMeshes, Groups or node IDs to exclude from search # @return the list of groups of nodes # @ingroup l2_modif_trsf - def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance): - return self.editor.FindCoincidentNodesOnPart(SubMeshOrGroup, Tolerance) + def FindCoincidentNodesOnPart (self, SubMeshOrGroup, Tolerance, exceptNodes=[]): + if (isinstance( SubMeshOrGroup, Mesh )): + SubMeshOrGroup = SubMeshOrGroup.GetMesh() + if not isinstance( exceptNodes, list): + exceptNodes = [ exceptNodes ] + if exceptNodes and isinstance( exceptNodes[0], int): + exceptNodes = [ self.editor.MakeIDSource( exceptNodes, SMESH.NODE)] + return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance,exceptNodes) ## Merges nodes # @param GroupsOfNodes the list of groups of nodes @@ -3649,11 +3972,15 @@ class Mesh: # This method provided for convenience works as DoubleNodes() described above. # @param theNodes group of nodes to be doubled # @param theModifiedElems group of elements to be updated. - # @return TRUE if operation has been completed successfully, FALSE otherwise + # @param theMakeGroup forces the generation of a group containing new nodes. + # @return TRUE or a created group if operation has been completed successfully, + # FALSE or None otherwise # @ingroup l2_modif_edit - def DoubleNodeGroup(self, theNodes, theModifiedElems): + def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False): + if theMakeGroup: + return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems) return self.editor.DoubleNodeGroup(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 theNodes list of groups of nodes to be doubled @@ -3692,10 +4019,13 @@ class Mesh: # @param theNodesNot - group of nodes not to replicated # @param theAffectedElems - group of elements to which the replicated nodes # should be associated to. + # @param theMakeGroup forces the generation of a group containing new elements. # @ingroup l2_modif_edit - def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems): + def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems, theMakeGroup=False): + if theMakeGroup: + return self.editor.DoubleNodeElemGroupNew(theElems, theNodesNot, theAffectedElems) return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems) - + ## 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 @@ -3730,6 +4060,86 @@ class Mesh: def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape): return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape) + def _valueFromFunctor(self, funcType, elemId): + fn = self.smeshpyD.GetFunctor(funcType) + fn.SetMesh(self.mesh) + if fn.GetElementType() == self.GetElementType(elemId, True): + val = fn.GetValue(elemId) + 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) + + ## 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) + + ## 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) + + ## Get maximum element length. + # @param elemId mesh element ID + # @return element's maximum length value + # @ingroup l1_measurements + def GetMaxElementLength(self, elemId): + if self.GetElementType(elemId, True) == SMESH.VOLUME: + ftype = SMESH.FT_MaxElementLength3D + else: + ftype = SMESH.FT_MaxElementLength2D + return self._valueFromFunctor(ftype, elemId) + + ## Get aspect ratio of 2D or 3D element. + # @param elemId mesh element ID + # @return element's aspect ratio value + # @ingroup l1_measurements + def GetAspectRatio(self, elemId): + if self.GetElementType(elemId, True) == SMESH.VOLUME: + ftype = SMESH.FT_AspectRatio3D + else: + ftype = SMESH.FT_AspectRatio + return self._valueFromFunctor(ftype, elemId) + + ## Get warping angle of 2D element. + # @param elemId mesh element ID + # @return element's warping angle value + # @ingroup l1_measurements + def GetWarping(self, elemId): + return self._valueFromFunctor(SMESH.FT_Warping, elemId) + + ## Get minimum angle of 2D element. + # @param elemId mesh element ID + # @return element's minimum angle value + # @ingroup l1_measurements + def GetMinimumAngle(self, elemId): + return self._valueFromFunctor(SMESH.FT_MinimumAngle, elemId) + + ## Get taper of 2D element. + # @param elemId mesh element ID + # @return element's taper value + # @ingroup l1_measurements + def GetTaper(self, elemId): + return self._valueFromFunctor(SMESH.FT_Taper, elemId) + + ## Get skew of 2D element. + # @param elemId mesh element ID + # @return element's skew value + # @ingroup l1_measurements + def GetSkew(self, elemId): + return self._valueFromFunctor(SMESH.FT_Skew, elemId) + ## The mother class to define algorithm, it is not recommended to use it directly. # # More details. @@ -3882,7 +4292,8 @@ class Mesh_Algorithm: pass except: name = mesh.geompyD.SubShapeName(geom, piece) - mesh.geompyD.addToStudyInFather(piece, geom, name) + if not name: + name = "%s_%s"%(geom.GetShapeType(), id(geom%1000)) pass self.subm = mesh.mesh.GetSubMesh(geom, algo.GetName()) @@ -4015,6 +4426,8 @@ class Mesh_Segment(Mesh_Algorithm): if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges reversedEdges, UseExisting = [], reversedEdges entry = self.MainShapeEntry() + if reversedEdges and isinstance(reversedEdges[0],geompyDC.GEOM._objref_GEOM_Object): + reversedEdges = [ self.mesh.geompyD.GetSubShapeID(self.mesh.geom, e) for e in reversedEdges ] if s == []: hyp = self.Hypothesis("NumberOfSegments", [n, reversedEdges, entry], UseExisting=UseExisting, @@ -4057,6 +4470,8 @@ class Mesh_Segment(Mesh_Algorithm): def Arithmetic1D(self, start, end, reversedEdges=[], UseExisting=0): if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges reversedEdges, UseExisting = [], reversedEdges + if reversedEdges and isinstance(reversedEdges[0],geompyDC.GEOM._objref_GEOM_Object): + reversedEdges = [ self.mesh.geompyD.GetSubShapeID(self.mesh.geom, e) for e in reversedEdges ] entry = self.MainShapeEntry() hyp = self.Hypothesis("Arithmetic1D", [start, end, reversedEdges, entry], UseExisting=UseExisting, @@ -4093,9 +4508,8 @@ class Mesh_Segment(Mesh_Algorithm): def FixedPoints1D(self, points, nbSegs=[1], reversedEdges=[], UseExisting=0): if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges reversedEdges, UseExisting = [], reversedEdges - if reversedEdges and isinstance( reversedEdges[0], geompyDC.GEOM._objref_GEOM_Object ): - for i in range( len( reversedEdges )): - reversedEdges[i] = self.mesh.geompyD.GetSubShapeID(self.mesh.geom, reversedEdges[i] ) + if reversedEdges and isinstance(reversedEdges[0],geompyDC.GEOM._objref_GEOM_Object): + reversedEdges = [ self.mesh.geompyD.GetSubShapeID(self.mesh.geom, e) for e in reversedEdges ] entry = self.MainShapeEntry() hyp = self.Hypothesis("FixedPoints1D", [points, nbSegs, reversedEdges, entry], UseExisting=UseExisting, @@ -4130,6 +4544,8 @@ class Mesh_Segment(Mesh_Algorithm): def StartEndLength(self, start, end, reversedEdges=[], UseExisting=0): if not isinstance(reversedEdges,list): #old version script, before adding reversedEdges reversedEdges, UseExisting = [], reversedEdges + if reversedEdges and isinstance(reversedEdges[0],geompyDC.GEOM._objref_GEOM_Object): + reversedEdges = [ self.mesh.geompyD.GetSubShapeID(self.mesh.geom, e) for e in reversedEdges ] entry = self.MainShapeEntry() hyp = self.Hypothesis("StartEndLength", [start, end, reversedEdges, entry], UseExisting=UseExisting, @@ -4389,7 +4805,7 @@ class Mesh_Triangle(Mesh_Algorithm): self.Parameters().SetPhyMax(theVal) ## Sets a way to define maximum angular deflection of mesh from CAD model. - # @param theGeometricMesh is: DefaultGeom or Custom + # @param theGeometricMesh is: 0 (None) or 1 (Custom) # @ingroup l3_hypos_blsurf def SetGeometricMesh(self, theGeometricMesh=0): # Parameter of BLSURF algo @@ -4587,48 +5003,96 @@ class Mesh_Triangle(Mesh_Algorithm): # @ingroup l3_algos_basic class Mesh_Quadrangle(Mesh_Algorithm): + params=0 + ## Private constructor. def __init__(self, mesh, geom=0): Mesh_Algorithm.__init__(self) self.Create(mesh, geom, "Quadrangle_2D") + return - ## Defines "QuadranglePreference" hypothesis, forcing construction - # of quadrangles if the number of nodes on the opposite edges is not the same - # while the total number of nodes on edges is even - # - # @ingroup l3_hypos_additi - def QuadranglePreference(self): - hyp = self.Hypothesis("QuadranglePreference", UseExisting=1, - CompareMethod=self.CompareEqualHyp) - return hyp + ## Defines "QuadrangleParameters" hypothesis + # @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. + # - 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. + # - 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 + # same number of segments, the other pair must have an even difference + # between the numbers of segments on the sides. + # @param triangleVertex: vertex of a trilateral geometrical face, around which triangles + # will be created while other elements will be quadrangles. + # Vertex can be either a GEOM_Object or a vertex ID within the + # shape to mesh + # @param UseExisting: if ==true - searches for the existing hypothesis created with + # the same parameters, else (default) - creates a new one + # @ingroup l3_hypos_quad + def QuadrangleParameters(self, quadType=StdMeshers.QUAD_STANDARD, triangleVertex=0, UseExisting=0): + vertexID = triangleVertex + if isinstance( triangleVertex, geompyDC.GEOM._objref_GEOM_Object ): + vertexID = self.mesh.geompyD.GetSubShapeID( self.mesh.geom, triangleVertex ) + if not self.params: + compFun = lambda hyp,args: \ + hyp.GetQuadType() == args[0] and \ + ( hyp.GetTriaVertex()==args[1] or ( hyp.GetTriaVertex()<1 and args[1]<1)) + self.params = self.Hypothesis("QuadrangleParams", [quadType,vertexID], + UseExisting = UseExisting, CompareMethod=compFun) + pass + if self.params.GetQuadType() != quadType: + self.params.SetQuadType(quadType) + if vertexID > 0: + self.params.SetTriaVertex( vertexID ) + return self.params - ## Defines "TrianglePreference" hypothesis, forcing construction - # of triangles in the refinement area if the number of nodes - # on the opposite edges is not the same - # - # @ingroup l3_hypos_additi - def TrianglePreference(self): - hyp = self.Hypothesis("TrianglePreference", UseExisting=1, - CompareMethod=self.CompareEqualHyp) - return hyp + ## Defines "QuadrangleParams" hypothesis with a type of quadrangulation that 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. + # @param reversed if True, transition area is located along the coarser meshed sides. + # @param UseExisting: if ==true - searches for the existing hypothesis created with + # the same parameters, else (default) - creates a new one + # @ingroup l3_hypos_quad + def QuadranglePreference(self, reversed=False, UseExisting=0): + if reversed: + return self.QuadrangleParameters(QUAD_QUADRANGLE_PREF_REVERSED,UseExisting=UseExisting) + return self.QuadrangleParameters(QUAD_QUADRANGLE_PREF,UseExisting=UseExisting) + + ## Defines "QuadrangleParams" hypothesis with a type of quadrangulation that only + # triangles are built in the transition area along the finer meshed sides. + # @param UseExisting: if ==true - searches for the existing hypothesis created with + # the same parameters, else (default) - creates a new one + # @ingroup l3_hypos_quad + def TrianglePreference(self, UseExisting=0): + return self.QuadrangleParameters(QUAD_TRIANGLE_PREF,UseExisting=UseExisting) + + ## Defines "QuadrangleParams" hypothesis with a type of quadrangulation that 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 same number of segments, the other pair must + # have an even difference between the numbers of segments on the sides. + # @param UseExisting: if ==true - searches for the existing hypothesis created with + # the same parameters, else (default) - creates a new one + # @ingroup l3_hypos_quad + def Reduced(self, UseExisting=0): + return self.QuadrangleParameters(QUAD_REDUCED,UseExisting=UseExisting) - ## Defines "QuadrangleParams" hypothesis + ## Defines "QuadrangleParams" hypothesis with QUAD_STANDARD type of quadrangulation # @param vertex: vertex of a trilateral geometrical face, around which triangles # will be created while other elements will be quadrangles. # Vertex can be either a GEOM_Object or a vertex ID within the # shape to mesh # @param UseExisting: if ==true - searches for the existing hypothesis created with # the same parameters, else (default) - creates a new one - # - # @ingroup l3_hypos_additi + # @ingroup l3_hypos_quad def TriangleVertex(self, vertex, UseExisting=0): - vertexID = vertex - if isinstance( vertexID, geompyDC.GEOM._objref_GEOM_Object ): - vertexID = self.mesh.geompyD.GetSubShapeID( self.mesh.geom, vertex ) - hyp = self.Hypothesis("QuadrangleParams", [vertexID], UseExisting = UseExisting, - CompareMethod=lambda hyp,args: hyp.GetTriaVertex()==args[0]) - hyp.SetTriaVertex( vertexID ) - return hyp + return self.QuadrangleParameters(QUAD_STANDARD,vertex,UseExisting) # Public class: Mesh_Tetrahedron @@ -5305,6 +5769,73 @@ class Mesh_RadialQuadrangle1D2D(Mesh_Algorithm): return hyp +# Public class: Mesh_UseExistingElements +# -------------------------------------- +## Defines a Radial Quadrangle 1D2D algorithm +# @ingroup l3_algos_basic +# +class Mesh_UseExistingElements(Mesh_Algorithm): + + def __init__(self, dim, mesh, geom=0): + if dim == 1: + self.Create(mesh, geom, "Import_1D") + else: + self.Create(mesh, geom, "Import_1D2D") + return + + ## Defines "Source edges" hypothesis, specifying groups of edges to import + # @param groups list of groups of edges + # @param toCopyMesh if True, the whole mesh \a groups belong to is imported + # @param toCopyGroups if True, all groups of the mesh \a groups belong to are imported + # @param UseExisting if ==true - searches for the existing hypothesis created with + # the same parameters, else (default) - creates a new one + def SourceEdges(self, groups, toCopyMesh=False, toCopyGroups=False, UseExisting=False): + if self.algo.GetName() == "Import_2D": + raise ValueError, "algoritm dimension mismatch" + hyp = self.Hypothesis("ImportSource1D", [groups, toCopyMesh, toCopyGroups], + UseExisting=UseExisting, CompareMethod=self._compareHyp) + hyp.SetSourceEdges(groups) + hyp.SetCopySourceMesh(toCopyMesh, toCopyGroups) + return hyp + + ## Defines "Source faces" hypothesis, specifying groups of faces to import + # @param groups list of groups of faces + # @param toCopyMesh if True, the whole mesh \a groups belong to is imported + # @param toCopyGroups if True, all groups of the mesh \a groups belong to are imported + # @param UseExisting if ==true - searches for the existing hypothesis created with + # the same parameters, else (default) - creates a new one + def SourceFaces(self, groups, toCopyMesh=False, toCopyGroups=False, UseExisting=False): + if self.algo.GetName() == "Import_1D": + raise ValueError, "algoritm dimension mismatch" + hyp = self.Hypothesis("ImportSource2D", [groups, toCopyMesh, toCopyGroups], + UseExisting=UseExisting, CompareMethod=self._compareHyp) + hyp.SetSourceFaces(groups) + hyp.SetCopySourceMesh(toCopyMesh, toCopyGroups) + return hyp + + def _compareHyp(self,hyp,args): + if hasattr( hyp, "GetSourceEdges"): + entries = hyp.GetSourceEdges() + else: + entries = hyp.GetSourceFaces() + groups = args[0] + toCopyMesh,toCopyGroups = hyp.GetCopySourceMesh() + if len(entries)==len(groups) and toCopyMesh==args[1] and toCopyGroups==args[2]: + entries2 = [] + study = self.mesh.smeshpyD.GetCurrentStudy() + if study: + for g in groups: + ior = salome.orb.object_to_string(g) + sobj = study.FindObjectIOR(ior) + if sobj: entries2.append( sobj.GetID() ) + pass + pass + entries.sort() + entries2.sort() + return entries == entries2 + return False + + # Private class: Mesh_UseExisting # ------------------------------- class Mesh_UseExisting(Mesh_Algorithm): diff --git a/src/StdMeshers/Makefile.am b/src/StdMeshers/Makefile.am index 0312e1f78..08c312ead 100644 --- a/src/StdMeshers/Makefile.am +++ b/src/StdMeshers/Makefile.am @@ -72,7 +72,10 @@ salomeinclude_HEADERS = \ StdMeshers_MaxLength.hxx \ StdMeshers_QuadrangleParams.hxx \ StdMeshers_RadialQuadrangle_1D2D.hxx \ - StdMeshers_HexaFromSkin_3D.hxx + StdMeshers_HexaFromSkin_3D.hxx \ + StdMeshers_ImportSource.hxx \ + StdMeshers_Import_1D.hxx \ + StdMeshers_Import_1D2D.hxx # Libraries targets @@ -123,7 +126,10 @@ dist_libStdMeshers_la_SOURCES = \ StdMeshers_MaxLength.cxx \ StdMeshers_QuadrangleParams.cxx \ StdMeshers_RadialQuadrangle_1D2D.cxx \ - StdMeshers_HexaFromSkin_3D.cxx + StdMeshers_HexaFromSkin_3D.cxx \ + StdMeshers_ImportSource.cxx \ + StdMeshers_Import_1D.cxx \ + StdMeshers_Import_1D2D.cxx # additionnal information to compil and link file diff --git a/src/StdMeshers/StdMeshers_CompositeSegment_1D.hxx b/src/StdMeshers/StdMeshers_CompositeSegment_1D.hxx index 7f003f4ae..4812b4235 100644 --- a/src/StdMeshers/StdMeshers_CompositeSegment_1D.hxx +++ b/src/StdMeshers/StdMeshers_CompositeSegment_1D.hxx @@ -23,7 +23,6 @@ // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_CompositeSegment_1D.hxx // Module : SMESH -// $Header$ // #ifndef _SMESH_CompositeSegment_1D_HXX_ #define _SMESH_CompositeSegment_1D_HXX_ diff --git a/src/StdMeshers/StdMeshers_FaceSide.cxx b/src/StdMeshers/StdMeshers_FaceSide.cxx index 036da0ba9..f882f5c92 100644 --- a/src/StdMeshers/StdMeshers_FaceSide.cxx +++ b/src/StdMeshers/StdMeshers_FaceSide.cxx @@ -452,9 +452,12 @@ void StdMeshers_FaceSide::Reverse() reverse( myEdgeLength ); reverse( myIsUniform ); } - myNormPar[nbEdges-1]=1.; - myPoints.clear(); - myFalsePoints.clear(); + if ( nbEdges > 0 ) + { + myNormPar[nbEdges-1]=1.; + myPoints.clear(); + myFalsePoints.clear(); + } } //================================================================================ diff --git a/src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx b/src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx index 6e8448e0a..e7409c108 100644 --- a/src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx +++ b/src/StdMeshers/StdMeshers_HexaFromSkin_3D.cxx @@ -31,6 +31,7 @@ #include //#include "utilities.h" +#include // Define error message #ifdef _DEBUG_ @@ -53,10 +54,12 @@ namespace { B_BOTTOM=0, B_RIGHT, B_TOP, B_LEFT, B_FRONT, B_BACK, NB_BLOCK_SIDES }; +#ifdef _DEBUG_ // avoid unused variables in release mode const char* SBoxSides[] = //!< names of block sides { "BOTTOM", "RIGHT", "TOP", "LEFT", "FRONT", "BACK", "UNDEFINED" }; +#endif enum EQuadEdge //!< edges of quadrangle side { Q_BOTTOM = 0, Q_RIGHT, Q_TOP, Q_LEFT, NB_QUAD_SIDES @@ -1080,18 +1083,49 @@ bool StdMeshers_HexaFromSkin_3D::Compute(SMESH_Mesh & aMesh, SMESH_MesherHelper* // Add hexahedrons // ---------------- - // find out orientation - const SMDS_MeshNode* n000 = block.getSide(B_BOTTOM).cornerNode( 0, 0 ); - const SMDS_MeshNode* n100 = block.getSide(B_BOTTOM).cornerNode( 1, 0 ); - const SMDS_MeshNode* n010 = block.getSide(B_BOTTOM).cornerNode( 0, 1 ); - const SMDS_MeshNode* n110 = block.getSide(B_BOTTOM).cornerNode( 1, 1 ); - const SMDS_MeshNode* n001 = block.getSide(B_TOP).cornerNode( 0, 0 ); - const SMDS_MeshNode* n101 = block.getSide(B_TOP).cornerNode( 1, 0 ); - const SMDS_MeshNode* n011 = block.getSide(B_TOP).cornerNode( 0, 1 ); - const SMDS_MeshNode* n111 = block.getSide(B_TOP).cornerNode( 1, 1 ); - SMDS_VolumeOfNodes probeVolume (n000,n010,n110,n100, - n001,n011,n111,n101); - bool isForw = SMDS_VolumeTool( &probeVolume ).IsForward(); + // find out orientation by a least distorted hexahedron (issue 0020855); + // the last is defined by evaluating sum of face normals of 8 corner hexahedrons + double badness = numeric_limits::max(); + bool isForw = true; + for ( int xMax = 0; xMax < 2; ++xMax ) + for ( int yMax = 0; yMax < 2; ++yMax ) + for ( int zMax = 0; zMax < 2; ++zMax ) + { + x = xMax ? xSize-1 : 1; + y = yMax ? ySize-1 : 1; + z = zMax ? zSize-1 : 1; + vector< const SMDS_MeshNode* >& col00 = columns[ colIndex( x-1, y-1 )]; + vector< const SMDS_MeshNode* >& col10 = columns[ colIndex( x , y-1 )]; + vector< const SMDS_MeshNode* >& col01 = columns[ colIndex( x-1, y )]; + vector< const SMDS_MeshNode* >& col11 = columns[ colIndex( x , y )]; + + const SMDS_MeshNode* n000 = col00[z-1]; + const SMDS_MeshNode* n100 = col10[z-1]; + const SMDS_MeshNode* n010 = col01[z-1]; + const SMDS_MeshNode* n110 = col11[z-1]; + const SMDS_MeshNode* n001 = col00[z]; + const SMDS_MeshNode* n101 = col10[z]; + const SMDS_MeshNode* n011 = col01[z]; + const SMDS_MeshNode* n111 = col11[z]; + SMDS_VolumeOfNodes probeVolume (n000,n010,n110,n100, + n001,n011,n111,n101); + SMDS_VolumeTool volTool( &probeVolume ); + double Nx=0.,Ny=0.,Nz=0.; + for ( int iFace = 0; iFace < volTool.NbFaces(); ++iFace ) + { + double nx,ny,nz; + volTool.GetFaceNormal( iFace, nx,ny,nz ); + Nx += nx; + Ny += ny; + Nz += nz; + } + double quality = Nx*Nx + Ny*Ny + Nz*Nz; + if ( quality < badness ) + { + badness = quality; + isForw = volTool.IsForward(); + } + } // add elements for ( x = 0; x < xSize-1; ++x ) { diff --git a/src/StdMeshers/StdMeshers_ImportSource.cxx b/src/StdMeshers/StdMeshers_ImportSource.cxx new file mode 100644 index 000000000..1ba39eacf --- /dev/null +++ b/src/StdMeshers/StdMeshers_ImportSource.cxx @@ -0,0 +1,443 @@ +// 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 StdMeshers_ImportSource1D : implementaion of SMESH idl descriptions +// File : StdMeshers_ImportSource1D.cxx +// Module : SMESH +// +#include "StdMeshers_ImportSource.hxx" + +#include "SMESHDS_GroupBase.hxx" +#include "SMESHDS_Mesh.hxx" +#include "SMESH_Algo.hxx" +#include "SMESH_Gen.hxx" +#include "SMESH_Group.hxx" +#include "SMESH_Mesh.hxx" +#include "SMESH_subMeshEventListener.hxx" + +#include "utilities.h" + +#include + +#include + +using namespace std; + +//============================================================================= +/*! + * Creates StdMeshers_ImportSource1D + */ +//============================================================================= + +StdMeshers_ImportSource1D::StdMeshers_ImportSource1D(int hypId, + int studyId, + SMESH_Gen * gen) + :SMESH_Hypothesis(hypId, studyId, gen), + _toCopyMesh(false), + _toCopyGroups(false) +{ + _name = "ImportSource1D"; + _param_algo_dim = 1; // is used by StdMeshers_Import_1D; +} + +//============================================================================= +/*! + * Creates StdMeshers_ImportSource2D + */ +//============================================================================= + +StdMeshers_ImportSource2D::StdMeshers_ImportSource2D(int hypId, + int studyId, + SMESH_Gen * gen) + :StdMeshers_ImportSource1D(hypId, studyId, gen) +{ + _name = "ImportSource2D"; + _param_algo_dim = 2; // is used by StdMeshers_Import_2D; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +StdMeshers_ImportSource1D::~StdMeshers_ImportSource1D() +{ +} +//============================================================================= +/*! + * Sets groups to import elements from + */ +//============================================================================= + +void StdMeshers_ImportSource1D::SetGroups(const std::vector& groups) +{ + if (_groups != groups) + { + _groups = groups; + NotifySubMeshesHypothesisModification(); + } +} + +void StdMeshers_ImportSource1D::SetCopySourceMesh(bool toCopyMesh, bool toCopyGroups) +{ + if ( !toCopyMesh ) toCopyGroups = false; + if ( _toCopyMesh != toCopyMesh || _toCopyGroups != toCopyGroups ) + { + _toCopyMesh = toCopyMesh; _toCopyGroups = toCopyGroups; + NotifySubMeshesHypothesisModification(); + } +} +void StdMeshers_ImportSource1D::GetCopySourceMesh(bool& toCopyMesh, bool& toCopyGroups) const +{ + toCopyMesh = _toCopyMesh; toCopyGroups = _toCopyGroups; +} + +namespace +{ + //================================================================================ + /*! + * \brief Return only alive groups + */ + //================================================================================ + + vector getValidGroups(const vector& groups, + StudyContextStruct* studyContext) + { + vector okGroups; + for ( int i = 0; i < groups.size(); ++i ) + { + try + { + // we expect SIGSEGV on a dead group + OCC_CATCH_SIGNALS; + SMESH_Group* okGroup = 0; + map::iterator itm = itm = studyContext->mapMesh.begin(); + for ( ; !okGroup && itm != studyContext->mapMesh.end(); itm++) + { + SMESH_Mesh::GroupIteratorPtr gIt = itm->second->GetGroups(); + while ( gIt->more() && !okGroup ) + if ( gIt->next() == groups[i] ) + okGroup = groups[i]; + } + if ( okGroup ) + okGroups.push_back( okGroup ); + } + catch(...) + { + } + } + return okGroups; + } + //================================================================================ + /*! + * \brief Pack meshes into a pair of ints + */ + //================================================================================ + + pair getResMapKey(const SMESHDS_Mesh& srcMesh, const SMESHDS_Mesh& tgtMesh) + { + return make_pair( srcMesh.GetPersistentId() , tgtMesh.GetPersistentId() ); + } + //================================================================================ + /*! + * \brief Return a target mesh by a pair of ints + */ + //================================================================================ + + SMESH_Mesh* getTgtMeshByKey( const pair & resMapKey, + StudyContextStruct* studyContext) + { + int tgtID = resMapKey.second; + SMESH_Mesh* tgtMesh = 0; + map::iterator itm = itm = studyContext->mapMesh.begin(); + for ( ; !tgtMesh && itm != studyContext->mapMesh.end(); itm++) + { + tgtMesh = (*itm).second; + if ( tgtMesh->GetMeshDS()->GetPersistentId() != tgtID ) + tgtMesh = 0; + } + return tgtMesh; + } + //================================================================================ + /*! + * \brief Return a target mesh by a pair of ints + */ + //================================================================================ + + int getSrcMeshID( const pair & resMapKey ) + { + return resMapKey.first; + } +} + +//============================================================================= +/*! + * Returns groups to import elements from + */ +//============================================================================= + +const std::vector& StdMeshers_ImportSource1D::GetGroups() const +{ + // filter off deleted groups + vector okGroups = getValidGroups( _groups, + _gen->GetStudyContext(_studyId) ); + if ( okGroups.size() != _groups.size() ) + ((StdMeshers_ImportSource1D*)this)->_groups = okGroups; + + return _groups; +} + +//================================================================================ +/*! + * \brief Return source meshes + */ +//================================================================================ + +std::vector StdMeshers_ImportSource1D::GetSourceMeshes() const +{ + // GetPersistentId()'s of meshes + set meshIDs; + const vector& groups = GetGroups(); + if ( !groups.empty() ) + { + for ( unsigned i = 0; i < groups.size(); ++i ) + { + const SMESHDS_GroupBase* gDS = groups[i]->GetGroupDS(); + int id = gDS->GetMesh()->GetPersistentId(); + meshIDs.insert( id ); + } + } + else + { + if ( _resultGroups.empty() ) + ((StdMeshers_ImportSource1D*)this)->RestoreGroups(_groups); + TResGroupMap::const_iterator key_groups = _resultGroups.begin(); + for ( ; key_groups != _resultGroups.end(); ++key_groups ) + meshIDs.insert( getSrcMeshID( key_groups->first )); + } + + // Find corresponding meshes + vector meshes; + if ( !meshIDs.empty() ) + { + StudyContextStruct* studyContext = _gen->GetStudyContext(_studyId); + for ( set::iterator id = meshIDs.begin(); id != meshIDs.end(); ++id ) + { + map::iterator itm = itm = studyContext->mapMesh.begin(); + for ( ; itm != studyContext->mapMesh.end(); itm++) + { + SMESH_Mesh* mesh = (*itm).second; + if ( mesh->GetMeshDS()->GetPersistentId() == *id ) + { + meshes.push_back( mesh ); + break; + } + } + } + } + return meshes; +} + +//============================================================================= +/*! + * Save _toCopyMesh and _toCopyGroups to a stream + */ +//============================================================================= + +ostream & StdMeshers_ImportSource1D::SaveTo(ostream & save) +{ + resultGroupsToIntVec(); + + save << " " << _toCopyMesh << " " << _toCopyGroups; + save << " " << _resultGroupsStorage.size(); + for ( unsigned i = 0; i < _resultGroupsStorage.size(); ++i ) + save << " " << _resultGroupsStorage[i]; + + return save; +} + +//============================================================================= +/*! + * Load _toCopyMesh and _toCopyGroups from a stream + */ +//============================================================================= + +istream & StdMeshers_ImportSource1D::LoadFrom(istream & load) +{ + load >> _toCopyMesh >> _toCopyGroups; + + _resultGroupsStorage.clear(); + int val; + if ( load >> val ) + { + _resultGroupsStorage.reserve(val); + while ( _resultGroupsStorage.size() < _resultGroupsStorage.capacity() && load >> val ) + _resultGroupsStorage.push_back( val ); + } + return load; +} + +//================================================================================ +/*! + * \brief Convert result groups into _resultGroupsStorage + */ +//================================================================================ + +void StdMeshers_ImportSource1D::resultGroupsToIntVec() +{ + _resultGroupsStorage.clear(); + + // store result groups + TResGroupMap::iterator key2groups = _resultGroups.begin(); + for ( ; key2groups != _resultGroups.end(); ++key2groups ) + { + const pair& key = key2groups->first; + const vector& groups = key2groups->second; + // mesh ids, nb groups + _resultGroupsStorage.push_back( key.first ); + _resultGroupsStorage.push_back( key.second ); + _resultGroupsStorage.push_back( groups.size() ); + for ( unsigned i = 0; i < groups.size(); ++i ) + { + // store group names as sequence of ints each standing for a char + // of a name; that is to avoid pb with names containing white spaces + string name = groups[i]->GetGroupDS()->GetStoreName(); + _resultGroupsStorage.push_back( name.size() ); + for ( unsigned j = 0; j < name.size(); ++j ) + _resultGroupsStorage.push_back( name[j] ); + } + } +} + +//================================================================================ +/*! + * \brief Restore source groups and result groups by _resultGroupsStorage + */ +//================================================================================ + +void StdMeshers_ImportSource1D::RestoreGroups(const std::vector& groups) +{ + _groups = groups; + + _resultGroups.clear(); + int i = 0; + while ( i < _resultGroupsStorage.size() ) + { + int key1 = _resultGroupsStorage[i++]; + int key2 = _resultGroupsStorage[i++]; + pair resMapKey( key1, key2 ); + SMESH_Mesh* mesh = getTgtMeshByKey( resMapKey, _gen->GetStudyContext(_studyId)); + // restore mesh ids at least + _resultGroups.insert( make_pair (resMapKey,vector() )); + + int nbGroups = _resultGroupsStorage[i++]; + for ( int j = 0; j < nbGroups; ++j ) + { + string::size_type nameSize = _resultGroupsStorage[i++]; + string groupName(nameSize, '\0'); + for ( unsigned k = 0; k < nameSize; ++k ) + groupName[k] = (char) _resultGroupsStorage[i++]; + + // find a group by name + if ( mesh ) + { + SMESH_Group* group = 0; + SMESH_Mesh::GroupIteratorPtr gIt = mesh->GetGroups(); + while ( !group && gIt->more() ) + { + group = gIt->next(); + if ( !group->GetGroupDS() || groupName != group->GetGroupDS()->GetStoreName() ) + group = 0; + } + if ( group ) + _resultGroups[ resMapKey ].push_back( group ); + } + } + } +} + +//================================================================================ +/*! + * \brief Remember groups imported from other mesh + * \param groups - result groups + * \param srcMesh - source mesh + * \param tgtMesh - destination mesh + */ +//================================================================================ + +void StdMeshers_ImportSource1D::StoreResultGroups(const std::vector& groups, + const SMESHDS_Mesh& srcMesh, + const SMESHDS_Mesh& tgtMesh) +{ + _resultGroups[ getResMapKey(srcMesh,tgtMesh) ] = groups; +} + +//================================================================================ +/*! + * \brief Return groups imported from other mesh + * \param srcMesh - source mesh + * \param tgtMesh - destination mesh + * \retval const std::vector& - groups + */ +//================================================================================ + +std::vector* +StdMeshers_ImportSource1D::GetResultGroups(const SMESHDS_Mesh& srcMesh, + const SMESHDS_Mesh& tgtMesh) +{ + TResGroupMap::iterator key2groups = _resultGroups.find( getResMapKey(srcMesh,tgtMesh )); + if ( key2groups == _resultGroups.end() ) + return 0; + vector vec = getValidGroups((*key2groups).second, + _gen->GetStudyContext(_studyId) ); + if ( vec.size() != key2groups->second.size()) + key2groups->second = vec; + + return & key2groups->second; +} + +//================================================================================ +/*! + * \brief Initialize ImportSource value by the mesh built on the geometry + * \param theMesh - the built mesh + * \param theShape - the geometry of interest + * \retval bool - true if parameter values have been successfully defined + */ +//================================================================================ + +bool StdMeshers_ImportSource1D::SetParametersByMesh(const SMESH_Mesh*, const TopoDS_Shape&) +{ + return false; +} + +//================================================================================ +/*! + * \brief Initialize my parameter values by default parameters. + * \retval bool - true if parameter values have been successfully defined + */ +//================================================================================ + +bool StdMeshers_ImportSource1D::SetParametersByDefaults(const TDefaults&, const SMESH_Mesh* ) +{ + return false; +} diff --git a/src/StdMeshers/StdMeshers_ImportSource.hxx b/src/StdMeshers/StdMeshers_ImportSource.hxx new file mode 100644 index 000000000..13287cb2e --- /dev/null +++ b/src/StdMeshers/StdMeshers_ImportSource.hxx @@ -0,0 +1,97 @@ +// 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 StdMeshers : implementaion of SMESH idl descriptions +// File : StdMeshers_ImportSource1D.hxx +// Module : SMESH +// +#ifndef _StdMeshers_ImportSource_HXX_ +#define _StdMeshers_ImportSource_HXX_ + +#include "SMESH_StdMeshers.hxx" + +#include "SMESH_Hypothesis.hxx" +#include "Utils_SALOME_Exception.hxx" + +#include +#include + +class SMESH_Group; +class SMESHDS_Mesh; + +//============================================================================== +/*! + * \brief Stores groups to import elements from + */ +//============================================================================== + +class STDMESHERS_EXPORT StdMeshers_ImportSource1D : public SMESH_Hypothesis +{ + public: + StdMeshers_ImportSource1D(int hypId, int studyId, SMESH_Gen * gen); + virtual ~ StdMeshers_ImportSource1D(); + + void SetGroups(const std::vector& groups); + const std::vector& GetGroups() const; + + void SetCopySourceMesh(bool toCopyMesh, bool toCopyGroups); + void GetCopySourceMesh(bool& toCopyMesh, bool& toCopyGroups) const; + + virtual std::ostream & SaveTo(std::ostream & save); + virtual std::istream & LoadFrom(std::istream & load); + virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape); + virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0); + void RestoreGroups(const std::vector& groups); + + void StoreResultGroups(const std::vector& groups, + const SMESHDS_Mesh& srcMesh, + const SMESHDS_Mesh& tgtMesh); + std::vector* GetResultGroups(const SMESHDS_Mesh& srcMesh, + const SMESHDS_Mesh& tgtMesh); + + std::vector GetSourceMeshes() const; + +private: + + std::vector _groups; + bool _toCopyMesh, _toCopyGroups; + + // groups imported using this hypothesis + typedef std::map< std::pair, std::vector > TResGroupMap; + TResGroupMap _resultGroups; + std::vector _resultGroupsStorage; // persistent representation of _resultGroups + + void resultGroupsToIntVec(); +}; + +//============================================================================== +/*! + * \brief Redefines name and dimension of inherited StdMeshers_ImportSource1D + */ +//============================================================================== + +class STDMESHERS_EXPORT StdMeshers_ImportSource2D : public StdMeshers_ImportSource1D +{ + public: + StdMeshers_ImportSource2D(int hypId, int studyId, SMESH_Gen * gen); +}; +#endif diff --git a/src/StdMeshers/StdMeshers_Import_1D.cxx b/src/StdMeshers/StdMeshers_Import_1D.cxx new file mode 100644 index 000000000..fe0f05476 --- /dev/null +++ b/src/StdMeshers/StdMeshers_Import_1D.cxx @@ -0,0 +1,959 @@ +// 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 SMESH : implementaion of SMESH idl descriptions +// File : StdMeshers_Import_1D.cxx +// Module : SMESH +// +#include "StdMeshers_Import_1D.hxx" +#include "StdMeshers_ImportSource.hxx" + +#include "SMDS_MeshElement.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMESHDS_Group.hxx" +#include "SMESHDS_Mesh.hxx" +#include "SMESH_Comment.hxx" +#include "SMESH_Gen.hxx" +#include "SMESH_Group.hxx" +#include "SMESH_HypoFilter.hxx" +#include "SMESH_Mesh.hxx" +#include "SMESH_MesherHelper.hxx" +#include "SMESH_subMesh.hxx" +#include "SMESH_subMeshEventListener.hxx" + +#include "Utils_SALOME_Exception.hxx" +#include "utilities.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +//============================================================================= +/*! + * Creates StdMeshers_Import_1D + */ +//============================================================================= + +StdMeshers_Import_1D::StdMeshers_Import_1D(int hypId, int studyId, SMESH_Gen * gen) + :SMESH_1D_Algo(hypId, studyId, gen), _sourceHyp(0) +{ + MESSAGE("StdMeshers_Import_1D::StdMeshers_Import_1D"); + _name = "Import_1D"; + _shapeType = (1 << TopAbs_EDGE); + + _compatibleHypothesis.push_back("ImportSource1D"); +} + +//============================================================================= +/*! + * Check presence of a hypothesis + */ +//============================================================================= + +bool StdMeshers_Import_1D::CheckHypothesis + (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus) +{ + _sourceHyp = 0; + + const list &hyps = GetUsedHypothesis(aMesh, aShape); + if ( hyps.size() == 0 ) + { + aStatus = SMESH_Hypothesis::HYP_MISSING; + return false; // can't work with no hypothesis + } + + if ( hyps.size() > 1 ) + { + aStatus = SMESH_Hypothesis::HYP_ALREADY_EXIST; + return false; + } + + const SMESHDS_Hypothesis *theHyp = hyps.front(); + + string hypName = theHyp->GetName(); + + if (hypName == _compatibleHypothesis.front()) + { + _sourceHyp = (StdMeshers_ImportSource1D *)theHyp; + aStatus = SMESH_Hypothesis::HYP_OK; + return true; + } + + aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE; + return true; +} + +//================================================================================ +namespace // INTERNAL STUFF +//================================================================================ +{ + int getSubmeshIDForCopiedMesh(const SMESHDS_Mesh* srcMeshDS, SMESH_Mesh* tgtMesh); + + enum _ListenerDataType + { + WAIT_HYP_MODIF=1, // data indicating awaiting for valid parameters of src hyp + SRC_HYP // data storing ImportSource hyp + }; + //================================================================================ + /*! + * \brief _ListenerData holding ImportSource hyp holding in its turn + * imported groups + */ + struct _ListenerData : public SMESH_subMeshEventListenerData + { + const StdMeshers_ImportSource1D* _srcHyp; + _ListenerData(const StdMeshers_ImportSource1D* h): + SMESH_subMeshEventListenerData(/*isDeletable=*/true), _srcHyp(h) + { + myType = SRC_HYP; + } + }; + //================================================================================ + /*! + * \brief Container of data dedicated to one source mesh + */ + struct _ImportData + { + const SMESH_Mesh* _srcMesh; + 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; + + SMESHDS_SubMesh* _importMeshSubDS; // submesh storing a copy of _srcMesh + int _importMeshSubID; // id of _importMeshSubDS + + _ImportData(const SMESH_Mesh* srcMesh=0): + _srcMesh(srcMesh), _importMeshSubDS(0),_importMeshSubID(-1) {} + + void removeImportedMesh( SMESHDS_Mesh* meshDS ) + { + if ( !_importMeshSubDS ) return; + SMDS_ElemIteratorPtr eIt = _importMeshSubDS->GetElements(); + while ( eIt->more() ) + meshDS->RemoveFreeElement( eIt->next(), _importMeshSubDS, /*fromGroups=*/false ); + SMDS_NodeIteratorPtr nIt = _importMeshSubDS->GetNodes(); + while ( nIt->more() ) + meshDS->RemoveFreeNode( nIt->next(), _importMeshSubDS, /*fromGroups=*/false ); + _n2n.clear(); + _e2e.clear(); + } + void removeGroups( SMESH_subMesh* subM, const StdMeshers_ImportSource1D* srcHyp ) + { + if ( !srcHyp ) return; + SMESH_Mesh* tgtMesh = subM->GetFather(); + const SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS(); + const SMESHDS_Mesh* srcMeshDS = _srcMesh->GetMeshDS(); + vector* groups = + const_cast(srcHyp)->GetResultGroups(*srcMeshDS,*tgtMeshDS); + if ( groups ) + { + for ( unsigned i = 0; i < groups->size(); ++i ) + tgtMesh->RemoveGroup( groups->at(i)->GetGroupDS()->GetID() ); + groups->clear(); + } + } + void trackHypParams( SMESH_subMesh* sm, const StdMeshers_ImportSource1D* srcHyp ) + { + if ( !srcHyp ) return; + bool toCopyMesh, toCopyGroups; + srcHyp->GetCopySourceMesh(toCopyMesh, toCopyGroups); + + if ( toCopyMesh )_copyMeshSubM.insert( sm ); + else _copyMeshSubM.erase( sm ); + + if ( toCopyGroups ) _copyGroupSubM.insert( sm ); + else _copyGroupSubM.erase( sm ); + } + }; + //================================================================================ + /*! + * Listener notified on events of an imported submesh + */ + class _Listener : public SMESH_subMeshEventListener + { + typedef map< SMESH_Mesh*, list< _ImportData > > TMesh2ImpData; + TMesh2ImpData _tgtMesh2ImportData; + + _Listener():SMESH_subMeshEventListener(/*isDeletable=*/false){} + + public: + // 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(); + } + + //-------------------------------------------------------------------------------- + /*! + * \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 ); + + return iData; + } + //-------------------------------------------------------------------------------- + /*! + * \brief 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 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 ) + { + 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 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 ) + { + 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 ) + { + // clear submeshes + if ( !d->_computedSubM.empty() ) + { + 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 ); + } + } + // remove imported mesh and groups + d->removeImportedMesh( sm->GetFather()->GetMeshDS() ); + + if ( data ) + d->removeGroups( sm, data->_srcHyp ); + } + } + 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*/) + { + if ( data && data->myType == WAIT_HYP_MODIF ) + { + 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 ); + } + } + else + { + SMESH_Gen* gen = subMesh->GetFather()->GetGen(); + SMESH_Algo* algo = gen->GetAlgo(*subMesh->GetFather(),subMesh->GetSubShape() ); + + 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::iterator smIt = d->_subM.begin(); + for( ; smIt != d->_subM.end(); ++smIt ) + if ( (*smIt)->IsMeshComputed() ) + d->_computedSubM.insert( *smIt); + } + } + } + } + }; // class _Listener + + //================================================================================ + /*! + * \brief Return an ID of submesh to store nodes and elements of a copied mesh + */ + //================================================================================ + + int getSubmeshIDForCopiedMesh(const SMESHDS_Mesh* srcMeshDS, + SMESH_Mesh* tgtMesh) + { + // To get SMESH_subMesh corresponding to srcMeshDS we need to have a shape + // for which SMESHDS_Mesh::IsGroupOfSubShapes() returns true. + // And this shape must be different from subshapes of the main shape. + // So we create a compound containing + // 1) some sub-shapes of SMESH_Mesh::PseudoShape() corresponding to + // srcMeshDS->GetPersistentId() + // 2) the 1-st vertex of the main shape to assure + // SMESHDS_Mesh::IsGroupOfSubShapes(shape)==true + TopoDS_Shape shapeForSrcMesh; + TopTools_IndexedMapOfShape pseudoSubShapes; + TopExp::MapShapes( SMESH_Mesh::PseudoShape(), pseudoSubShapes ); + + // index of pseudoSubShapes corresponding to srcMeshDS + int subIndex = srcMeshDS->GetPersistentId() % pseudoSubShapes.Extent(); + int nbSubShapes = 1 + srcMeshDS->GetPersistentId() / pseudoSubShapes.Extent(); + + // try to find already present shapeForSrcMesh + SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS(); + for ( int i = tgtMeshDS->MaxShapeIndex(); i > 0 && shapeForSrcMesh.IsNull(); --i ) + { + const TopoDS_Shape& s = tgtMeshDS->IndexToShape(i); + if ( s.ShapeType() != TopAbs_COMPOUND ) break; + TopoDS_Iterator sSubIt( s ); + for ( int iSub = 0; iSub < nbSubShapes && sSubIt.More(); ++iSub, sSubIt.Next() ) + if ( pseudoSubShapes( subIndex+iSub ).IsSame( sSubIt.Value())) + if ( iSub+1 == nbSubShapes ) + { + shapeForSrcMesh = s; + break; + } + } + if ( shapeForSrcMesh.IsNull() ) + { + // make a new shapeForSrcMesh + BRep_Builder aBuilder; + TopoDS_Compound comp; + aBuilder.MakeCompound( comp ); + shapeForSrcMesh = comp; + for ( int iSub = 0; iSub < nbSubShapes; ++iSub ) + aBuilder.Add( comp, pseudoSubShapes( subIndex+iSub )); + TopExp_Explorer vExp( tgtMeshDS->ShapeToMesh(), TopAbs_VERTEX ); + aBuilder.Add( comp, vExp.Current() ); + } + SMESH_subMesh* sm = tgtMesh->GetSubMesh( shapeForSrcMesh ); + SMESHDS_SubMesh* smDS = sm->GetSubMeshDS(); + if ( !smDS ) + smDS = tgtMeshDS->NewSubMesh( sm->GetId() ); + + // make ordinary submesh from a complex one + if ( smDS->IsComplexSubmesh() ) + { + list< const SMESHDS_SubMesh* > subSM; + SMESHDS_SubMeshIteratorPtr smIt = smDS->GetSubMeshIterator(); + while ( smIt->more() ) subSM.push_back( smIt->next() ); + list< const SMESHDS_SubMesh* >::iterator sub = subSM.begin(); + for ( ; sub != subSM.end(); ++sub) + smDS->RemoveSubMesh( *sub ); + } + return sm->GetId(); + } + + //================================================================================ + /*! + * \brief Return a submesh to store nodes and elements of a copied mesh + * and set event listeners in order to clear + * imported mesh and groups as soon as submesh state requires it + */ + //================================================================================ + + SMESHDS_SubMesh* getSubmeshForCopiedMesh(const SMESH_Mesh* srcMesh, + SMESH_Mesh* tgtMesh, + const TopoDS_Shape& tgtShape, + StdMeshers_Import_1D::TNodeNodeMap*& n2n, + StdMeshers_Import_1D::TElemElemMap*& e2e, + bool & toCopyGroups) + { + StdMeshers_Import_1D::getMaps( srcMesh, tgtMesh, n2n,e2e ); + + _ImportData* iData = _Listener::getImportData(srcMesh,tgtMesh); + + SMESH_subMesh* importedSM = tgtMesh->GetSubMesh( tgtShape ); + iData->_computedSubM.insert( importedSM ); + if ( iData->_computedSubM.size() != iData->_subM.size() ) + return 0; // not all submeshes computed yet + + toCopyGroups = !iData->_copyGroupSubM.empty(); + + if ( !iData->_copyMeshSubM.empty()) + { + // make submesh to store a copied mesh + int smID = getSubmeshIDForCopiedMesh( srcMesh->GetMeshDS(), tgtMesh ); + SMESHDS_SubMesh* subDS = tgtMesh->GetMeshDS()->NewSubMesh( smID ); + + iData->_importMeshSubID = smID; + iData->_importMeshSubDS = subDS; + return subDS; + } + return 0; + } + +} // namespace + + +//============================================================================= +/*! + * Import elements from the other mesh + */ +//============================================================================= + +bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & theShape) +{ + if ( !_sourceHyp ) return false; + + const vector& srcGroups = _sourceHyp->GetGroups(); + if ( srcGroups.empty() ) + return error("Invalid source groups"); + + SMESH_MesherHelper helper(theMesh); + helper.SetSubShape(theShape); + SMESHDS_Mesh* tgtMesh = theMesh.GetMeshDS(); + + const TopoDS_Edge& geomEdge = TopoDS::Edge( theShape ); + const double edgeTol = BRep_Tool::Tolerance( geomEdge ); + const int shapeID = tgtMesh->ShapeToIndex( geomEdge ); + + set subShapeIDs; + subShapeIDs.insert( shapeID ); + + // get nodes on vertices + list < SMESH_MeshEditor::TNodeXYZ > vertexNodes; + list < SMESH_MeshEditor::TNodeXYZ >::iterator vNIt; + TopExp_Explorer vExp( theShape, TopAbs_VERTEX ); + for ( ; vExp.More(); vExp.Next() ) + { + const TopoDS_Vertex& v = TopoDS::Vertex( vExp.Current() ); + if ( !subShapeIDs.insert( tgtMesh->ShapeToIndex( v )).second ) + continue; // closed edge + const SMDS_MeshNode* n = SMESH_Algo::VertexNode( v, tgtMesh ); + if ( !n ) + { + _gen->Compute(theMesh,v,/*anUpward=*/true); + n = SMESH_Algo::VertexNode( v, tgtMesh ); + if ( !n ) return false; // very strange + } + vertexNodes.push_back( SMESH_MeshEditor::TNodeXYZ( n )); + } + + // import edges from groups + TNodeNodeMap* n2n; + TElemElemMap* e2e; + for ( int iG = 0; iG < srcGroups.size(); ++iG ) + { + const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS(); + + const int meshID = srcGroup->GetMesh()->GetPersistentId(); + const SMESH_Mesh* srcMesh = GetMeshByPersistentID( meshID ); + if ( !srcMesh ) continue; + getMaps( srcMesh, &theMesh, n2n, e2e ); + + SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements(); + vector newNodes; + SMDS_MeshNode tmpNode(0,0,0); + double u; + while ( srcElems->more() ) // loop on group contents + { + const SMDS_MeshElement* edge = srcElems->next(); + // find or create nodes of a new edge + newNodes.resize( edge->NbNodes() ); + newNodes.back() = 0; + SMDS_MeshElement::iterator node = edge->begin_nodes(); + for ( unsigned i = 0; i < newNodes.size(); ++i, ++node ) + { + TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first; + if ( n2nIt->second ) + { + if ( !subShapeIDs.count( n2nIt->second->GetPosition()->GetShapeId() )) + break; + } + else + { + // find an existing vertex node + for ( vNIt = vertexNodes.begin(); vNIt != vertexNodes.end(); ++vNIt) + if ( vNIt->SquareDistance( *node ) < 10 * edgeTol * edgeTol) + { + (*n2nIt).second = vNIt->_node; + vertexNodes.erase( vNIt ); + break; + } + } + if ( !n2nIt->second ) + { + // find out if node lies on theShape + tmpNode.setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z()); + if ( helper.CheckNodeU( geomEdge, &tmpNode, u, 10 * edgeTol, /*force=*/true )) + { + SMDS_MeshNode* newNode = tgtMesh->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z()); + n2nIt->second = newNode; + tgtMesh->SetNodeOnEdge( newNode, shapeID, u ); + } + } + if ( !(newNodes[i] = n2nIt->second )) + break; + } + if ( !newNodes.back() ) + continue; // not all nodes of edge lie on theShape + + // make a new edge + SMDS_MeshElement * newEdge; + if ( newNodes.size() == 3 ) + newEdge = tgtMesh->AddEdge( newNodes[0], newNodes[1], newNodes[2] ); + else + newEdge = tgtMesh->AddEdge( newNodes[0], newNodes[1]); + tgtMesh->SetMeshElementOnShape( newEdge, shapeID ); + e2e->insert( make_pair( edge, newEdge )); + } + } + if ( n2n->empty()) + return error("Empty source groups"); + + // check if the whole geom edge is covered by imported segments; + // the check consist in passing by segments from one vetrex node to another + bool isEdgeMeshed = false; + if ( SMESHDS_SubMesh* tgtSM = tgtMesh->MeshElements( theShape )) + { + const TopoDS_Vertex& v = ( vExp.ReInit(), TopoDS::Vertex( vExp.Current() )); + const SMDS_MeshNode* n = SMESH_Algo::VertexNode( v, tgtMesh ); + const SMDS_MeshElement* seg = 0; + SMDS_ElemIteratorPtr segIt = n->GetInverseElementIterator(SMDSAbs_Edge); + while ( segIt->more() && !seg ) + if ( !tgtSM->Contains( seg = segIt->next())) + seg = 0; + int nbPassedSegs = 0; + while ( seg ) + { + ++nbPassedSegs; + const SMDS_MeshNode* n2 = seg->GetNode(0); + n = ( n2 == n ? seg->GetNode(1) : n2 ); + if ( n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX ) + break; + const SMDS_MeshElement* seg2 = 0; + segIt = n->GetInverseElementIterator(SMDSAbs_Edge); + while ( segIt->more() && !seg2 ) + if ( seg == ( seg2 = segIt->next())) + seg2 = 0; + seg = seg2; + } + if (nbPassedSegs > 0 && tgtSM->NbElements() > nbPassedSegs ) + return error( "Source elements overlap one another"); + + isEdgeMeshed = ( tgtSM->NbElements() == nbPassedSegs && + n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX ); + } + if ( !isEdgeMeshed ) + return error( "Source elements don't cover totally the geometrical edge" ); + + // copy meshes + vector srcMeshes = _sourceHyp->GetSourceMeshes(); + for ( unsigned i = 0; i < srcMeshes.size(); ++i ) + importMesh( srcMeshes[i], theMesh, _sourceHyp, theShape ); + + return true; +} + +//================================================================================ +/*! + * \brief Copy mesh and groups + */ +//================================================================================ + +void StdMeshers_Import_1D::importMesh(const SMESH_Mesh* srcMesh, + SMESH_Mesh & tgtMesh, + StdMeshers_ImportSource1D* srcHyp, + const TopoDS_Shape& tgtShape) +{ + // get submesh to store the imported mesh + TNodeNodeMap* n2n; + TElemElemMap* e2e; + bool toCopyGroups; + SMESHDS_SubMesh* tgtSubMesh = + getSubmeshForCopiedMesh( srcMesh, &tgtMesh, tgtShape, n2n, e2e, toCopyGroups ); + if ( !tgtSubMesh || tgtSubMesh->NbNodes() + tgtSubMesh->NbElements() > 0 ) + return; // not to copy srcMeshDS twice + + SMESHDS_Mesh* tgtMeshDS = tgtMesh.GetMeshDS(); + SMESH_MeshEditor additor( &tgtMesh ); + + // 1. Copy mesh + + vector newNodes; + const SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS(); + SMDS_ElemIteratorPtr eIt = srcMeshDS->elementsIterator(); + while ( eIt->more() ) + { + const SMDS_MeshElement* elem = eIt->next(); + TElemElemMap::iterator e2eIt = e2e->insert( make_pair( elem, (SMDS_MeshElement*)0 )).first; + if ( e2eIt->second ) continue; // already copied by Compute() + newNodes.resize( elem->NbNodes() ); + SMDS_MeshElement::iterator node = elem->begin_nodes(); + for ( unsigned i = 0; i < newNodes.size(); ++i, ++node ) + { + TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first; + if ( !n2nIt->second ) + { + (*n2nIt).second = tgtMeshDS->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z()); + tgtSubMesh->AddNode( n2nIt->second ); + } + newNodes[i] = n2nIt->second; + } + const SMDS_MeshElement* newElem = + tgtMeshDS->FindElement( newNodes, elem->GetType(), /*noMedium=*/false ); + if ( !newElem ) + { + newElem = additor.AddElement( newNodes, elem->GetType(), elem->IsPoly()); + tgtSubMesh->AddElement( newElem ); + } + if ( toCopyGroups ) + (*e2eIt).second = newElem; + } + // copy free nodes + if ( srcMeshDS->NbNodes() > n2n->size() ) + { + SMDS_NodeIteratorPtr nIt = srcMeshDS->nodesIterator(); + while( nIt->more() ) + { + const SMDS_MeshNode* node = nIt->next(); + if ( node->NbInverseElements() == 0 ) + { + const SMDS_MeshNode* newNode = tgtMeshDS->AddNode( node->X(), node->Y(), node->Z()); + n2n->insert( make_pair( node, newNode )); + tgtSubMesh->AddNode( newNode ); + } + } + } + + // 2. Copy groups + + vector resultGroups; + if ( toCopyGroups ) + { + // collect names of existing groups to assure uniqueness of group names within a type + map< SMDSAbs_ElementType, set > namesByType; + SMESH_Mesh::GroupIteratorPtr groupIt = tgtMesh.GetGroups(); + while ( groupIt->more() ) + { + SMESH_Group* tgtGroup = groupIt->next(); + namesByType[ tgtGroup->GetGroupDS()->GetType() ].insert( tgtGroup->GetName() ); + } + if (srcMesh) + { + SMESH_Mesh::GroupIteratorPtr groupIt = srcMesh->GetGroups(); + while ( groupIt->more() ) + { + SMESH_Group* srcGroup = groupIt->next(); + SMESHDS_GroupBase* srcGroupDS = srcGroup->GetGroupDS(); + string name = srcGroup->GetName(); + int nb = 1; + while ( !namesByType[ srcGroupDS->GetType() ].insert( name ).second ) + name = SMESH_Comment(srcGroup->GetName()) << "_imported_" << nb++; + SMESH_Group* newGroup = tgtMesh.AddGroup( srcGroupDS->GetType(), name.c_str(), nb ); + SMESHDS_Group* newGroupDS = (SMESHDS_Group*)newGroup->GetGroupDS(); + resultGroups.push_back( newGroup ); + + eIt = srcGroupDS->GetElements(); + if ( srcGroupDS->GetType() == SMDSAbs_Node ) + while (eIt->more()) + { + TNodeNodeMap::iterator n2nIt = n2n->find((const SMDS_MeshNode*) eIt->next() ); + if ( n2nIt != n2n->end() && n2nIt->second ) + newGroupDS->SMDSGroup().Add((*n2nIt).second ); + } + else + while (eIt->more()) + { + TElemElemMap::iterator e2eIt = e2e->find( eIt->next() ); + if ( e2eIt != e2e->end() && e2eIt->second ) + newGroupDS->SMDSGroup().Add((*e2eIt).second ); + } + } + } + } + n2n->clear(); + e2e->clear(); + + // Remember created groups in order to remove them as soon as the srcHyp is + // modified or something other similar happens. Store them in a hypothesis + // as it stores its values anyway + srcHyp->StoreResultGroups( resultGroups, *srcMeshDS, *tgtMeshDS ); +} + +//============================================================================= +/*! + * \brief Set needed event listeners and create a submesh for a copied mesh + * + * This method is called only if a submesh has HYP_OK algo_state. + */ +//============================================================================= + +void StdMeshers_Import_1D::setEventListener(SMESH_subMesh* subMesh, + StdMeshers_ImportSource1D* sourceHyp) +{ + if ( sourceHyp ) + { + vector srcMeshes = sourceHyp->GetSourceMeshes(); + if ( srcMeshes.empty() ) + _Listener::waitHypModification( subMesh ); + for ( unsigned i = 0; i < srcMeshes.size(); ++i ) + // set a listener to remove the imported mesh and groups + _Listener::storeImportSubmesh( subMesh, srcMeshes[i], sourceHyp ); + } +} +void StdMeshers_Import_1D::SetEventListener(SMESH_subMesh* subMesh) +{ + if ( !_sourceHyp ) + { + const TopoDS_Shape& tgtShape = subMesh->GetSubShape(); + SMESH_Mesh* tgtMesh = subMesh->GetFather(); + Hypothesis_Status aStatus; + CheckHypothesis( *tgtMesh, tgtShape, aStatus ); + } + setEventListener( subMesh, _sourceHyp ); +} + +void StdMeshers_Import_1D::SubmeshRestored(SMESH_subMesh* subMesh) +{ + SetEventListener(subMesh); +} + +//============================================================================= +/*! + * Predict nb of mesh entities created by Compute() + */ +//============================================================================= + +bool StdMeshers_Import_1D::Evaluate(SMESH_Mesh & theMesh, + const TopoDS_Shape & theShape, + MapShapeNbElems& aResMap) +{ + if ( !_sourceHyp ) return false; + + const vector& srcGroups = _sourceHyp->GetGroups(); + if ( srcGroups.empty() ) + return error("Invalid source groups"); + + vector aVec(SMDSEntity_Last,0); + + bool toCopyMesh, toCopyGroups; + _sourceHyp->GetCopySourceMesh(toCopyMesh, toCopyGroups); + if ( toCopyMesh ) // the whole mesh is copied + { + vector srcMeshes = _sourceHyp->GetSourceMeshes(); + for ( unsigned i = 0; i < srcMeshes.size(); ++i ) + { + SMESH_subMesh* sm = getSubMeshOfCopiedMesh( theMesh, *srcMeshes[i]); + if ( !sm || aResMap.count( sm )) continue; // already counted + aVec.assign( SMDSEntity_Last, 0); + const SMDS_MeshInfo& aMeshInfo = srcMeshes[i]->GetMeshDS()->GetMeshInfo(); + for (int i = 0; i < SMDSEntity_Last; i++) + aVec[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i); + } + } + else + { + SMESH_MesherHelper helper(theMesh); + + const TopoDS_Edge& geomEdge = TopoDS::Edge( theShape ); + const double edgeTol = helper.MaxTolerance( geomEdge ); + + // take into account nodes on vertices + TopExp_Explorer vExp( theShape, TopAbs_VERTEX ); + for ( ; vExp.More(); vExp.Next() ) + theMesh.GetSubMesh( vExp.Current())->Evaluate( aResMap ); + + // count edges imported from groups + int nbEdges = 0, nbQuadEdges = 0; + for ( int iG = 0; iG < srcGroups.size(); ++iG ) + { + const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS(); + SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements(); + SMDS_MeshNode tmpNode(0,0,0); + while ( srcElems->more() ) // loop on group contents + { + const SMDS_MeshElement* edge = srcElems->next(); + // find out if edge is located on geomEdge by projecting + // a middle of edge to geomEdge + SMESH_MeshEditor::TNodeXYZ p1( edge->GetNode(0)); + SMESH_MeshEditor::TNodeXYZ p2( edge->GetNode(1)); + gp_XYZ middle = ( p1 + p2 ) / 2.; + tmpNode.setXYZ( middle.X(), middle.Y(), middle.Z()); + double u = 0; + if ( helper.CheckNodeU( geomEdge, &tmpNode, u, 10 * edgeTol, /*force=*/true )) + ++( edge->IsQuadratic() ? nbQuadEdges : nbEdges); + } + } + + int nbNodes = nbEdges + 2 * nbQuadEdges - 1; + + aVec[SMDSEntity_Node ] = nbNodes; + aVec[SMDSEntity_Edge ] = nbEdges; + aVec[SMDSEntity_Quad_Edge] = nbQuadEdges; + } + + SMESH_subMesh * sm = theMesh.GetSubMesh(theShape); + aResMap.insert(make_pair(sm,aVec)); + + return true; +} + +//================================================================================ +/*! + * \brief Return node-node and element-element maps for import of geiven source mesh + */ +//================================================================================ + +void StdMeshers_Import_1D::getMaps(const SMESH_Mesh* srcMesh, + SMESH_Mesh* tgtMesh, + TNodeNodeMap*& n2n, + TElemElemMap*& e2e) +{ + _ImportData* iData = _Listener::getImportData(srcMesh,tgtMesh); + n2n = &iData->_n2n; + e2e = &iData->_e2e; + if ( iData->_copyMeshSubM.empty() ) + { + n2n->clear(); + e2e->clear(); + } +} + +//================================================================================ +/*! + * \brief Return submesh corresponding to the copied mesh + */ +//================================================================================ + +SMESH_subMesh* StdMeshers_Import_1D::getSubMeshOfCopiedMesh( SMESH_Mesh& tgtMesh, + SMESH_Mesh& srcMesh ) +{ + _ImportData* iData = _Listener::getImportData(&srcMesh,&tgtMesh); + if ( iData->_copyMeshSubM.empty() ) return 0; + SMESH_subMesh* sm = tgtMesh.GetSubMeshContaining( iData->_importMeshSubID ); + return sm; +} + diff --git a/src/StdMeshers/StdMeshers_Import_1D.hxx b/src/StdMeshers/StdMeshers_Import_1D.hxx new file mode 100644 index 000000000..a3ab382fb --- /dev/null +++ b/src/StdMeshers/StdMeshers_Import_1D.hxx @@ -0,0 +1,81 @@ +// 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 SMESH : implementaion of SMESH idl descriptions +// Module : SMESH +// +#ifndef _SMESH_Import_1D_HXX_ +#define _SMESH_Import_1D_HXX_ + +#include "SMESH_StdMeshers.hxx" + +#include "SMESH_1D_Algo.hxx" +#include "SMDS_MeshElement.hxx" + +class StdMeshers_ImportSource1D; + +/*! + * \brief Copy elements from other the mesh + */ +class STDMESHERS_EXPORT StdMeshers_Import_1D: public SMESH_1D_Algo +{ +public: + StdMeshers_Import_1D(int hypId, int studyId, SMESH_Gen* gen); + + virtual bool CheckHypothesis(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus); + + virtual bool Compute (SMESH_Mesh & aMesh, const TopoDS_Shape & aShape); + virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap); + + virtual void SetEventListener(SMESH_subMesh* subMesh); + virtual void SubmeshRestored(SMESH_subMesh* subMesh); + + // internal utilities + + typedef std::map TNodeNodeMap; + typedef std::map TElemElemMap; + + static void getMaps(const SMESH_Mesh* srcMesh, + SMESH_Mesh* tgtMesh, + TNodeNodeMap*& n2n, + TElemElemMap*& e2e); + + static void importMesh(const SMESH_Mesh* srcMesh, + SMESH_Mesh & tgtMesh, + StdMeshers_ImportSource1D* srcHyp, + const TopoDS_Shape& tgtShape); + + static void setEventListener( SMESH_subMesh* subMesh, + StdMeshers_ImportSource1D* sourceHyp ); + + static SMESH_subMesh* getSubMeshOfCopiedMesh( SMESH_Mesh& tgtMesh, + SMESH_Mesh& srcMesh ); + + private: + + StdMeshers_ImportSource1D* _sourceHyp; +}; + +#endif diff --git a/src/StdMeshers/StdMeshers_Import_1D2D.cxx b/src/StdMeshers/StdMeshers_Import_1D2D.cxx new file mode 100644 index 000000000..5513a1077 --- /dev/null +++ b/src/StdMeshers/StdMeshers_Import_1D2D.cxx @@ -0,0 +1,643 @@ +// 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 SMESH : implementaion of SMESH idl descriptions +// File : StdMeshers_Import_1D2D.cxx +// Module : SMESH +// +#include "StdMeshers_Import_1D2D.hxx" + +#include "StdMeshers_Import_1D.hxx" +#include "StdMeshers_ImportSource.hxx" + +#include "SMDS_MeshElement.hxx" +#include "SMDS_MeshNode.hxx" +#include "SMESHDS_Group.hxx" +#include "SMESHDS_Mesh.hxx" +#include "SMESH_Comment.hxx" +#include "SMESH_Gen.hxx" +#include "SMESH_Group.hxx" +#include "SMESH_Mesh.hxx" +#include "SMESH_MesherHelper.hxx" +#include "SMESH_subMesh.hxx" + +#include "Utils_SALOME_Exception.hxx" +#include "utilities.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace std; + +//============================================================================= +/*! + * Creates StdMeshers_Import_1D2D + */ +//============================================================================= + +StdMeshers_Import_1D2D::StdMeshers_Import_1D2D(int hypId, int studyId, SMESH_Gen * gen) + :SMESH_2D_Algo(hypId, studyId, gen), _sourceHyp(0) +{ + MESSAGE("StdMeshers_Import_1D2D::StdMeshers_Import_1D2D"); + _name = "Import_1D2D"; + _shapeType = (1 << TopAbs_FACE); + + _compatibleHypothesis.push_back("ImportSource2D"); + _requireDescretBoundary = false; +} + +//============================================================================= +/*! + * Check presence of a hypothesis + */ +//============================================================================= + +bool StdMeshers_Import_1D2D::CheckHypothesis + (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus) +{ + _sourceHyp = 0; + + const list &hyps = GetUsedHypothesis(aMesh, aShape); + if ( hyps.size() == 0 ) + { + aStatus = SMESH_Hypothesis::HYP_MISSING; + return false; // can't work with no hypothesis + } + + if ( hyps.size() > 1 ) + { + aStatus = SMESH_Hypothesis::HYP_ALREADY_EXIST; + return false; + } + + const SMESHDS_Hypothesis *theHyp = hyps.front(); + + string hypName = theHyp->GetName(); + + if (hypName == _compatibleHypothesis.front()) + { + _sourceHyp = (StdMeshers_ImportSource1D *)theHyp; + aStatus = SMESH_Hypothesis::HYP_OK; + return true; + } + + aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE; + return true; +} + +namespace +{ + /*! + * \brief OrientedLink additionally storing a medium node + */ + struct TLink : public SMESH_OrientedLink + { + const SMDS_MeshNode* _medium; + TLink( const SMDS_MeshNode* n1, + const SMDS_MeshNode* n2, + const SMDS_MeshNode* medium=0) + : SMESH_OrientedLink( n1,n2 ), _medium( medium ) {} + }; +} + +//============================================================================= +/*! + * Import elements from the other mesh + */ +//============================================================================= + +bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & theShape) +{ + if ( !_sourceHyp ) return false; + + const vector& srcGroups = _sourceHyp->GetGroups(); + if ( srcGroups.empty() ) + return error("Invalid source groups"); + + SMESH_MesherHelper helper(theMesh); + helper.SetSubShape(theShape); + SMESHDS_Mesh* tgtMesh = theMesh.GetMeshDS(); + + const TopoDS_Face& geomFace = TopoDS::Face( theShape ); + const double faceTol = helper.MaxTolerance( geomFace ); + const int shapeID = tgtMesh->ShapeToIndex( geomFace ); + 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(); + gp_Pnt p; gp_Vec du, dv; + + set subShapeIDs; + subShapeIDs.insert( shapeID ); + + // get nodes on vertices + list < SMESH_MeshEditor::TNodeXYZ > vertexNodes; + list < SMESH_MeshEditor::TNodeXYZ >::iterator vNIt; + TopExp_Explorer exp( theShape, TopAbs_VERTEX ); + for ( ; exp.More(); exp.Next() ) + { + const TopoDS_Vertex& v = TopoDS::Vertex( exp.Current() ); + if ( !subShapeIDs.insert( tgtMesh->ShapeToIndex( v )).second ) + continue; + const SMDS_MeshNode* n = SMESH_Algo::VertexNode( v, tgtMesh ); + if ( !n ) + { + _gen->Compute(theMesh,v,/*anUpward=*/true); + n = SMESH_Algo::VertexNode( v, tgtMesh ); + if ( !n ) return false; // very strange + } + vertexNodes.push_back( SMESH_MeshEditor::TNodeXYZ( n )); + } + + // to count now many times a link between nodes encounters + map linkCount; + map::iterator link2Nb; + + // ========================= + // Import faces from groups + // ========================= + + StdMeshers_Import_1D::TNodeNodeMap* n2n; + StdMeshers_Import_1D::TElemElemMap* e2e; + vector newNodes; + for ( int iG = 0; iG < srcGroups.size(); ++iG ) + { + const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS(); + + const int meshID = srcGroup->GetMesh()->GetPersistentId(); + const SMESH_Mesh* srcMesh = GetMeshByPersistentID( meshID ); + if ( !srcMesh ) continue; + StdMeshers_Import_1D::getMaps( srcMesh, &theMesh, n2n, e2e ); + + SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements(); + SMDS_MeshNode tmpNode(0,0,0); + gp_XY uv; + while ( srcElems->more() ) // loop on group contents + { + const SMDS_MeshElement* face = srcElems->next(); + // find or create nodes of a new face + newNodes.resize( face->NbNodes() ); + newNodes.back() = 0; + int nbCreatedNodes = 0; + SMDS_MeshElement::iterator node = face->begin_nodes(); + for ( unsigned i = 0; i < newNodes.size(); ++i, ++node ) + { + TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first; + if ( n2nIt->second ) + { + if ( !subShapeIDs.count( n2nIt->second->GetPosition()->GetShapeId() )) + break; + } + else + { + // find an existing vertex node + for ( vNIt = vertexNodes.begin(); vNIt != vertexNodes.end(); ++vNIt) + if ( vNIt->SquareDistance( *node ) < 10 * faceTol * faceTol) + { + (*n2nIt).second = vNIt->_node; + vertexNodes.erase( vNIt ); + break; + } + } + if ( !n2nIt->second ) + { + // find out if node lies on theShape + tmpNode.setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z()); + if ( helper.CheckNodeUV( geomFace, &tmpNode, uv, 10 * faceTol, /*force=*/true )) + { + SMDS_MeshNode* newNode = tgtMesh->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z()); + n2nIt->second = newNode; + tgtMesh->SetNodeOnFace( newNode, shapeID, uv.X(), uv.Y() ); + nbCreatedNodes++; + } + } + if ( !(newNodes[i] = n2nIt->second )) + break; + } + if ( !newNodes.back() ) + continue; // not all nodes of the face lie on theShape + + // try to find already created face + SMDS_MeshElement * newFace = 0; + if ( nbCreatedNodes == 0 && + tgtMesh->FindElement(newNodes, SMDSAbs_Face, /*noMedium=*/false)) + continue; // repeated face in source groups already created + + // check future face orientation + if ( toCheckOri ) + { + int iNode = -1; + gp_Vec geomNorm; + do + { + uv = helper.GetNodeUV( geomFace, newNodes[++iNode] ); + surface->D1( uv.X(),uv.Y(), p, du,dv ); + geomNorm = du ^ dv; + } + while ( geomNorm.SquareMagnitude() < 1e-6 && iNode+1 < face->NbCornerNodes()); + + int iNext = helper.WrapIndex( iNode+1, face->NbCornerNodes() ); + int iPrev = helper.WrapIndex( iNode-1, face->NbCornerNodes() ); + + SMESH_MeshEditor::TNodeXYZ prevNode( newNodes[iPrev] ); + SMESH_MeshEditor::TNodeXYZ curNode ( newNodes[iNode] ); + SMESH_MeshEditor::TNodeXYZ nextNode( newNodes[iNext] ); + gp_Vec n1n0( prevNode - curNode); + gp_Vec n1n2( nextNode - curNode ); + gp_Vec meshNorm = n1n2 ^ n1n0; + + if ( geomNorm * meshNorm < 0 ) + std::reverse( newNodes.begin(), newNodes.end() ); + } + + // make a new face + switch ( newNodes.size() ) + { + case 3: + newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2] ); + break; + case 4: + newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2], newNodes[3] ); + break; + case 6: + newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2], + newNodes[3], newNodes[4], newNodes[5]); + break; + case 8: + newFace = tgtMesh->AddFace( newNodes[0], newNodes[1], newNodes[2], newNodes[3], + newNodes[4], newNodes[5], newNodes[6], newNodes[7]); + break; + default: continue; + } + tgtMesh->SetMeshElementOnShape( newFace, shapeID ); + e2e->insert( make_pair( face, newFace )); + + // collect links + int nbNodes = face->NbCornerNodes(); + const SMDS_MeshNode* medium = 0; + for ( int i = 0; i < nbNodes; ++i ) + { + const SMDS_MeshNode* n1 = newNodes[i]; + const SMDS_MeshNode* n2 = newNodes[ (i+1)%nbNodes ]; + if ( newFace->IsQuadratic() ) + medium = newNodes[i+nbNodes]; + link2Nb = linkCount.insert( make_pair( TLink( n1, n2, medium ), 0)).first; + ++link2Nb->second; + } + } + } + + // ========================================================== + // Put nodes on geom edges and create edges on them; + // check if the whole geom face is covered by imported faces + // ========================================================== + + vector< TopoDS_Edge > edges; + for ( exp.Init( theShape, TopAbs_EDGE ); exp.More(); exp.Next() ) + if ( subShapeIDs.insert( tgtMesh->ShapeToIndex( exp.Current() )).second ) + edges.push_back( TopoDS::Edge( exp.Current() )); + + bool isFaceMeshed = false; + if ( SMESHDS_SubMesh* tgtSM = tgtMesh->MeshElements( theShape )) + { + // the imported mesh is valid if all external links (encountered once) + // lie on geom edges + subShapeIDs.erase( shapeID ); // to contain edges and vertices only + double u, f, l; + for ( link2Nb = linkCount.begin(); link2Nb != linkCount.end(); ++link2Nb) + { + const TLink& link = (*link2Nb).first; + int nbFaces = link2Nb->second; + if ( nbFaces == 1 ) + { + // check if the link lie on face boundary + bool nodesOnBoundary = true; + list< TopoDS_Shape > bndShapes; + for ( int is1stN = 0; is1stN < 2 && nodesOnBoundary; ++is1stN ) + { + const SMDS_MeshNode* n = is1stN ? link.node1() : link.node2(); + if ( !subShapeIDs.count( n->GetPosition()->GetShapeId() )) + { + for ( unsigned iE = 0; iE < edges.size(); ++iE ) + if ( helper.CheckNodeU( edges[iE], n, u, 10 * faceTol, /*force=*/true )) + { + BRep_Tool::Range(edges[iE],f,l); + if ( Abs(u-f) < 2 * faceTol || Abs(u-l) < 2 * faceTol ) + // duplicated node on vertex + return error("Source elements overlap one another"); + tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)n, edges[iE], u ); + break; + } + nodesOnBoundary = subShapeIDs.count( n->GetPosition()->GetShapeId()); + } + if ( nodesOnBoundary ) + { + TopoDS_Shape s = helper.GetSubShapeByNode( n, tgtMesh ); + if ( s.ShapeType() == TopAbs_VERTEX ) + bndShapes.push_front( s ); // vertex first + else + bndShapes.push_back( s ); // edges last + } + } + if ( !nodesOnBoundary ) + break; // free internal link + if ( bndShapes.front().ShapeType() == TopAbs_EDGE && + bndShapes.front() != bndShapes.back() ) + break; // link nodes on different geom edges + + // find geom edge the link is on + if ( bndShapes.back().ShapeType() != TopAbs_EDGE ) + { + // find geom edge by two vertices + TopoDS_Shape geomEdge; + PShapeIteratorPtr edgeIt = helper.GetAncestors( bndShapes.back(), theMesh, TopAbs_EDGE ); + while ( edgeIt->more() ) + { + geomEdge = *(edgeIt->next()); + if ( !helper.IsSubShape( bndShapes.front(), geomEdge )) + geomEdge.Nullify(); + } + if ( geomEdge.IsNull() ) + break; // vertices belong to different edges -> free internal link + bndShapes.push_back( geomEdge ); + } + + // create an edge if not yet exists + newNodes.resize(2); + newNodes[0] = link.node1(), newNodes[1] = link.node2(); + const SMDS_MeshElement* edge = tgtMesh->FindElement( newNodes, SMDSAbs_Edge ); + if ( edge ) continue; + + if ( link._reversed ) std::swap( newNodes[0], newNodes[1] ); + if ( link._medium ) + { + newNodes.push_back( link._medium ); + edge = tgtMesh->AddEdge( newNodes[0], newNodes[1], newNodes[2] ); + + TopoDS_Edge geomEdge = TopoDS::Edge(bndShapes.back()); + helper.CheckNodeU( geomEdge, link._medium, u, 10*faceTol, /*force=*/true ); + 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; + + tgtMesh->SetMeshElementOnShape( edge, bndShapes.back() ); + } + else if ( nbFaces > 2 ) + { + return error( "Non-manifold source mesh"); + } + } + isFaceMeshed = ( link2Nb == linkCount.end() && !linkCount.empty()); + if ( isFaceMeshed ) + { + // check that source faces do not overlap: + // there must be only two edges sharing each vertex and bound to sub-edges of theShape + SMESH_MeshEditor editor( &theMesh ); + set::iterator subID = subShapeIDs.begin(); + for ( ; subID != subShapeIDs.end(); ++subID ) + { + const TopoDS_Shape& s = tgtMesh->IndexToShape( *subID ); + if ( s.ShapeType() != TopAbs_VERTEX ) continue; + const SMDS_MeshNode* n = SMESH_Algo::VertexNode( TopoDS::Vertex(s), tgtMesh ); + SMDS_ElemIteratorPtr eIt = n->GetInverseElementIterator(SMDSAbs_Edge); + int nbEdges = 0; + while ( eIt->more() ) + { + const SMDS_MeshElement* edge = eIt->next(); + int sId = editor.FindShape( edge ); + nbEdges += subShapeIDs.count( sId ); + } + if ( nbEdges < 2 ) + return false; // weird + if ( nbEdges > 2 ) + return error( "Source elements overlap one another"); + } + } + } + if ( !isFaceMeshed ) + return error( "Source elements don't cover totally the geometrical face" ); + + // notify sub-meshes of edges on computation + for ( unsigned iE = 0; iE < edges.size(); ++iE ) + theMesh.GetSubMesh( edges[iE] )->ComputeStateEngine(SMESH_subMesh::CHECK_COMPUTE_STATE); + + // ============ + // Copy meshes + // ============ + + vector srcMeshes = _sourceHyp->GetSourceMeshes(); + for ( unsigned i = 0; i < srcMeshes.size(); ++i ) + StdMeshers_Import_1D::importMesh( srcMeshes[i], theMesh, _sourceHyp, theShape ); + + return true; +} + +//============================================================================= +/*! + * \brief Set needed event listeners and create a submesh for a copied mesh + * + * This method is called only if a submesh has HYP_OK algo_state. + */ +//============================================================================= + +void StdMeshers_Import_1D2D::SetEventListener(SMESH_subMesh* subMesh) +{ + if ( !_sourceHyp ) + { + const TopoDS_Shape& tgtShape = subMesh->GetSubShape(); + SMESH_Mesh* tgtMesh = subMesh->GetFather(); + Hypothesis_Status aStatus; + CheckHypothesis( *tgtMesh, tgtShape, aStatus ); + } + StdMeshers_Import_1D::setEventListener( subMesh, _sourceHyp ); +} +void StdMeshers_Import_1D2D::SubmeshRestored(SMESH_subMesh* subMesh) +{ + SetEventListener(subMesh); +} + +//============================================================================= +/*! + * Predict nb of mesh entities created by Compute() + */ +//============================================================================= + +bool StdMeshers_Import_1D2D::Evaluate(SMESH_Mesh & theMesh, + const TopoDS_Shape & theShape, + MapShapeNbElems& aResMap) +{ + if ( !_sourceHyp ) return false; + + const vector& srcGroups = _sourceHyp->GetGroups(); + if ( srcGroups.empty() ) + return error("Invalid source groups"); + + vector aVec(SMDSEntity_Last,0); + + bool toCopyMesh, toCopyGroups; + _sourceHyp->GetCopySourceMesh(toCopyMesh, toCopyGroups); + if ( toCopyMesh ) // the whole mesh is copied + { + vector srcMeshes = _sourceHyp->GetSourceMeshes(); + for ( unsigned i = 0; i < srcMeshes.size(); ++i ) + { + SMESH_subMesh* sm = StdMeshers_Import_1D::getSubMeshOfCopiedMesh( theMesh, *srcMeshes[i]); + if ( !sm || aResMap.count( sm )) continue; // already counted + const SMDS_MeshInfo& aMeshInfo = srcMeshes[i]->GetMeshDS()->GetMeshInfo(); + for (int i = 0; i < SMDSEntity_Last; i++) + aVec[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i); + } + } + else + { + // std-like iterator used to get coordinates of nodes of mesh element + typedef SMDS_StdIterator< SMESH_MeshEditor::TNodeXYZ, SMDS_ElemIteratorPtr > TXyzIterator; + + SMESH_MesherHelper helper(theMesh); + helper.SetSubShape(theShape); + + const TopoDS_Face& geomFace = TopoDS::Face( theShape ); + const double faceTol = helper.MaxTolerance( geomFace ); + + // take into account nodes on vertices + TopExp_Explorer exp( theShape, TopAbs_VERTEX ); + for ( ; exp.More(); exp.Next() ) + theMesh.GetSubMesh( exp.Current())->Evaluate( aResMap ); + + // to count now many times a link between nodes encounters, + // negative nb additionally means that a link is quadratic + map linkCount; + map::iterator link2Nb; + + // count faces and nodes imported from groups + set allNodes; + gp_XY uv; + for ( int iG = 0; iG < srcGroups.size(); ++iG ) + { + const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS(); + SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements(); + SMDS_MeshNode tmpNode(0,0,0); + while ( srcElems->more() ) // loop on group contents + { + const SMDS_MeshElement* face = srcElems->next(); + // find out if face is located on geomEdge by projecting + // a gravity center of face to geomFace + gp_XYZ gc(0,0,0); + gc = accumulate( TXyzIterator(face->nodesIterator()), TXyzIterator(), gc)/face->NbNodes(); + tmpNode.setXYZ( gc.X(), gc.Y(), gc.Z()); + if ( helper.CheckNodeUV( geomFace, &tmpNode, uv, 10 * faceTol, /*force=*/true )) + { + ++aVec[ face->GetEntityType() ]; + + // collect links + int nbConers = face->NbCornerNodes(); + for ( int i = 0; i < face->NbNodes(); ++i ) + { + const SMDS_MeshNode* n1 = face->GetNode(i); + allNodes.insert( n1 ); + if ( i < nbConers ) + { + const SMDS_MeshNode* n2 = face->GetNode( (i+1)%nbConers ); + link2Nb = linkCount.insert( make_pair( SMESH_TLink( n1, n2 ), 0)).first; + if ( (*link2Nb).second ) + link2Nb->second += (link2Nb->second < 0 ) ? -1 : 1; + else + link2Nb->second += ( face->IsQuadratic() ) ? -1 : 1; + } + } + } + } + } + + int nbNodes = allNodes.size(); + allNodes.clear(); + + // count nodes and edges on geom edges + + double u; + for ( exp.Init(theShape, TopAbs_EDGE); exp.More(); exp.Next() ) + { + TopoDS_Edge geomEdge = TopoDS::Edge( exp.Current() ); + SMESH_subMesh* sm = theMesh.GetSubMesh( geomEdge ); + vector& edgeVec = aResMap[sm]; + if ( edgeVec.empty() ) + { + edgeVec.resize(SMDSEntity_Last,0); + for ( link2Nb = linkCount.begin(); link2Nb != linkCount.end(); ) + { + const SMESH_TLink& link = (*link2Nb).first; + int nbFacesOfLink = Abs( link2Nb->second ); + bool eraseLink = ( nbFacesOfLink != 1 ); + if ( nbFacesOfLink == 1 ) + { + if ( helper.CheckNodeU( geomEdge, link.node1(), u, 10*faceTol, /*force=*/true )&& + helper.CheckNodeU( geomEdge, link.node2(), u, 10*faceTol, /*force=*/true )) + { + bool isQuadratic = ( link2Nb->second < 0 ); + ++edgeVec[ isQuadratic ? SMDSEntity_Quad_Edge : SMDSEntity_Edge ]; + ++edgeVec[ SMDSEntity_Node ]; + --nbNodes; + eraseLink = true; + } + } + if ( eraseLink ) + linkCount.erase(link2Nb++); + else + link2Nb++; + } + if ( edgeVec[ SMDSEntity_Node] > 0 ) + --edgeVec[ SMDSEntity_Node ]; // for one node on vertex + } + else if ( !helper.IsSeamShape( geomEdge ) || + geomEdge.Orientation() == TopAbs_FORWARD ) + { + nbNodes -= 1+edgeVec[ SMDSEntity_Node ]; + } + } + + aVec[SMDSEntity_Node] = nbNodes; + } + + SMESH_subMesh * sm = theMesh.GetSubMesh(theShape); + aResMap.insert(make_pair(sm,aVec)); + + return true; +} diff --git a/src/StdMeshers/StdMeshers_Import_1D2D.hxx b/src/StdMeshers/StdMeshers_Import_1D2D.hxx new file mode 100644 index 000000000..5733c2f48 --- /dev/null +++ b/src/StdMeshers/StdMeshers_Import_1D2D.hxx @@ -0,0 +1,60 @@ +// 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 SMESH : implementaion of SMESH idl descriptions +// Module : SMESH +// +#ifndef _SMESH_Import_2D_HXX_ +#define _SMESH_Import_2D_HXX_ + +#include "SMESH_StdMeshers.hxx" + +#include "SMESH_2D_Algo.hxx" +#include "SMDS_MeshElement.hxx" + +class StdMeshers_ImportSource1D; + +/*! + * \brief Copy elements from other the mesh + */ +class STDMESHERS_EXPORT StdMeshers_Import_1D2D: public SMESH_2D_Algo +{ +public: + StdMeshers_Import_1D2D(int hypId, int studyId, SMESH_Gen* gen); + + virtual bool CheckHypothesis(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus); + + virtual bool Compute (SMESH_Mesh & aMesh, const TopoDS_Shape & aShape); + virtual bool Evaluate(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, + MapShapeNbElems& aResMap); + + virtual void SetEventListener(SMESH_subMesh* subMesh); + virtual void SubmeshRestored(SMESH_subMesh* subMesh); + + private: + + StdMeshers_ImportSource1D* _sourceHyp; +}; + +#endif diff --git a/src/StdMeshers/StdMeshers_Penta_3D.cxx b/src/StdMeshers/StdMeshers_Penta_3D.cxx index bdab94ece..b9d46da9e 100644 --- a/src/StdMeshers/StdMeshers_Penta_3D.cxx +++ b/src/StdMeshers/StdMeshers_Penta_3D.cxx @@ -676,22 +676,16 @@ void StdMeshers_Penta_3D::MakeVolumeMesh() if ( aN.size() < nbFaceNodes * 2 ) aN.resize( nbFaceNodes * 2 ); // - k=0; - aItNodes=pE0->nodesIterator(); - while (aItNodes->more()) { - //const SMDS_MeshElement* pNode = aItNodes->next(); - const SMDS_MeshNode* pNode = - static_cast (aItNodes->next()); - if(myTool->IsMedium(pNode)) - continue; + for ( k=0; kGetNode(k); +// if(myTool->IsMedium(pNode)) +// continue; aID0 = pNode->GetID(); aJ[k] = GetIndexOnLayer(aID0); if (!myErrorStatus->IsOK()) { MESSAGE("StdMeshers_Penta_3D::MakeVolumeMesh"); return; } - // - ++k; } // bool forward = true; diff --git a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx index eaf669e58..38028c2d7 100644 --- a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx +++ b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx @@ -44,6 +44,7 @@ #include "utilities.h" +#include #include #include #include @@ -53,6 +54,8 @@ #include #include #include +#include +#include #include #include #include @@ -61,22 +64,22 @@ #include #include #include -#include -#include + +#include using namespace std; #define RETURN_BAD_RESULT(msg) { MESSAGE(")-: Error: " << msg); return false; } #define CONT_BAD_RESULT(msg) { MESSAGE(")-: Error: " << msg); continue; } -#define SHOW_VERTEX(v,msg) \ +#define SHOW_SHAPE(v,msg) \ // { \ // if ( (v).IsNull() ) cout << msg << " NULL SHAPE" << endl; \ // else if ((v).ShapeType() == TopAbs_VERTEX) {\ // gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( (v) ));\ -// cout<()<<" ( "<()<ShapeToIndex(S), theMeshDS[1]->ShapeToIndex(S) ); + return long(S.TShape().operator->()); + } + //================================================================================ /*! * \brief Write shape for debug purposes @@ -116,31 +127,24 @@ namespace { */ //================================================================================ - void Reverse( list< TopoDS_Edge > & edges, const int nbEdges ) + void Reverse( list< TopoDS_Edge > & edges, const int nbEdges, const int firstEdge=0) { SHOW_LIST("BEFORE REVERSE", edges); list< TopoDS_Edge >::iterator eIt = edges.begin(); - if ( edges.size() == nbEdges ) - { - edges.reverse(); - } - else // reverse only the given nb of edges + std::advance( eIt, firstEdge ); + list< TopoDS_Edge >::iterator eBackIt = eIt; + for ( int i = 0; i < nbEdges; ++i, ++eBackIt ) + eBackIt->Reverse(); // reverse edge + // reverse list + --eBackIt; + while ( eIt != eBackIt ) { - // look for the last edge to be reversed - list< TopoDS_Edge >::iterator eBackIt = edges.begin(); - for ( int i = 1; i < nbEdges; ++i ) - ++eBackIt; - // reverse - while ( eIt != eBackIt ) { - std::swap( *eIt, *eBackIt ); - SHOW_LIST("# AFTER SWAP", edges) + std::swap( *eIt, *eBackIt ); + SHOW_LIST("# AFTER SWAP", edges) if ( (++eIt) != eBackIt ) --eBackIt; - } } - for ( eIt = edges.begin(); eIt != edges.end(); ++eIt ) - eIt->Reverse(); SHOW_LIST("ATFER REVERSE", edges) } @@ -351,6 +355,26 @@ namespace { return true; } + //================================================================================ + /*! + * \brief Return true if uv position of the vIndex-th vertex of edge on face is close + * enough to given uv + */ + //================================================================================ + + bool sameVertexUV( const TopoDS_Edge& edge, + const TopoDS_Face& face, + const int& vIndex, + const gp_Pnt2d& uv, + const double& tol2d ) + { + TopoDS_Vertex VV[2]; + TopExp::Vertices( edge, VV[0], VV[1], true); + gp_Pnt2d v1UV = BRep_Tool::Parameters( VV[vIndex], face); + double dist2d = v1UV.Distance( uv ); + return dist2d < tol2d; + } + } // namespace //======================================================================= @@ -381,7 +405,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the // case TopAbs_EDGE: // case ...: // } - // else try to accosiate in different ways: + // 4) else try to accosiate in different ways: // a) accosiate shapes by propagation and other simple cases // switch ( ShapeType ) { // case TopAbs_EDGE: @@ -390,8 +414,11 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the // b) find association of a couple of vertices and recall self. // + theMeshDS[0] = theMesh1->GetMeshDS(); // debug + theMeshDS[1] = theMesh2->GetMeshDS(); + // ================================================================================= - // Is it the case of associating a group member -> another group? (PAL16202, 16203) + // 1) Is it the case of associating a group member -> another group? (PAL16202, 16203) // ================================================================================= if ( theShape1.ShapeType() != theShape2.ShapeType() ) { TopoDS_Shape group1, group2; @@ -412,7 +439,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the bool bidirect = ( !theShape1.IsSame( theShape2 )); // ============ - // Is partner? + // 2) Is partner? // ============ bool partner = theShape1.IsPartner( theShape2 ); TopTools_DataMapIteratorOfDataMapOfShapeShape vvIt( theMap ); @@ -438,7 +465,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the if ( !theMap.IsEmpty() ) { //====================================================================== - // HAS initial vertex association + // 3) HAS initial vertex association //====================================================================== switch ( theShape1.ShapeType() ) { // ---------------------------------------------------------------------- @@ -448,6 +475,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the RETURN_BAD_RESULT("Wrong map extent " << theMap.Extent() ); TopoDS_Edge edge1 = TopoDS::Edge( theShape1 ); TopoDS_Edge edge2 = TopoDS::Edge( theShape2 ); + if ( edge1.Orientation() >= TopAbs_INTERNAL ) edge1.Orientation( TopAbs_FORWARD ); + if ( edge2.Orientation() >= TopAbs_INTERNAL ) edge2.Orientation( TopAbs_FORWARD ); TopoDS_Vertex VV1[2], VV2[2]; TopExp::Vertices( edge1, VV1[0], VV1[1] ); TopExp::Vertices( edge2, VV2[0], VV2[1] ); @@ -463,6 +492,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the // ---------------------------------------------------------------------- TopoDS_Face face1 = TopoDS::Face( theShape1 ); TopoDS_Face face2 = TopoDS::Face( theShape2 ); + if ( face1.Orientation() >= TopAbs_INTERNAL ) face1.Orientation( TopAbs_FORWARD ); + if ( face2.Orientation() >= TopAbs_INTERNAL ) face2.Orientation( TopAbs_FORWARD ); TopoDS_Vertex VV1[2], VV2[2]; // find a not closed edge of face1 both vertices of which are associated @@ -510,6 +541,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the TopExp_Explorer exp ( theShape1, TopAbs_EDGE ); for ( ; VV2[ 1 ].IsNull() && exp.More(); exp.Next() ) { edge1 = TopoDS::Edge( exp.Current() ); + if ( edge1.Orientation() >= TopAbs_INTERNAL ) edge1.Orientation( TopAbs_FORWARD ); TopExp::Vertices( edge1 , VV1[0], VV1[1] ); if ( theMap.IsBound( VV1[0] )) { VV2[ 0 ] = TopoDS::Vertex( theMap( VV1[0] )); @@ -673,7 +705,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the if ( !initAssocOK ) { // for shell association there must be an edge with both vertices bound TopoDS_Vertex v1, v2; - TopExp::Vertices( TopoDS::Edge( it1.Value()), v1, v2 ); + TopExp::Vertices( TopoDS::Edge( it1.Value().Oriented(TopAbs_FORWARD)), v1, v2 ); initAssocOK = ( theMap.IsBound( v1 ) && theMap.IsBound( v2 )); } } @@ -876,7 +908,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the } // end case of available initial vertex association //====================================================================== - // NO INITIAL VERTEX ASSOCIATION + // 4) NO INITIAL VERTEX ASSOCIATION //====================================================================== switch ( theShape1.ShapeType() ) { @@ -922,6 +954,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the { TopoDS_Face face1 = TopoDS::Face(theShape1); TopoDS_Face face2 = TopoDS::Face(theShape2); + if ( face1.Orientation() >= TopAbs_INTERNAL ) face1.Orientation( TopAbs_FORWARD ); + if ( face2.Orientation() >= TopAbs_INTERNAL ) face2.Orientation( TopAbs_FORWARD ); TopoDS_Edge edge1, edge2; // get outer edge of theShape1 edge1 = TopoDS::Edge( OuterShape( face1, TopAbs_EDGE )); @@ -1105,7 +1139,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the if ( edge.IsNull() || edge.ShapeType() != TopAbs_EDGE ) RETURN_BAD_RESULT("Edge not found"); - TopExp::Vertices( TopoDS::Edge( edge ), VV1[0], VV1[1]); + TopExp::Vertices( TopoDS::Edge( edge.Oriented(TopAbs_FORWARD)), VV1[0], VV1[1]); if ( VV1[0].IsSame( VV1[1] )) RETURN_BAD_RESULT("Only closed edges"); @@ -1161,19 +1195,23 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, list< TopoDS_Edge > & edges1, list< TopoDS_Edge > & edges2) { - list< int > nbVInW1, nbVInW2; - for ( int outer_wire_algo = 0; outer_wire_algo < 2; ++outer_wire_algo ) + bool OK = false; + list< int > nbEInW1, nbEInW2; + int i_ok_wire_algo = -1; + for ( int outer_wire_algo = 0; outer_wire_algo < 2 && !OK; ++outer_wire_algo ) { edges1.clear(); edges2.clear(); - if ( SMESH_Block::GetOrderedEdges( face1, VV1[0], edges1, nbVInW1, outer_wire_algo) != - SMESH_Block::GetOrderedEdges( face2, VV2[0], edges2, nbVInW2, outer_wire_algo) ) + if ( SMESH_Block::GetOrderedEdges( face1, VV1[0], edges1, nbEInW1, outer_wire_algo) != + SMESH_Block::GetOrderedEdges( face2, VV2[0], edges2, nbEInW2, outer_wire_algo) ) CONT_BAD_RESULT("Different number of wires in faces "); - if ( nbVInW1.front() != nbVInW2.front() ) + if ( nbEInW1 != nbEInW2 ) CONT_BAD_RESULT("Different number of edges in faces: " << - nbVInW1.front() << " != " << nbVInW2.front()); + nbEInW1.front() << " != " << nbEInW2.front()); + + i_ok_wire_algo = outer_wire_algo; // Define if we need to reverse one of wires to make edges in lists match each other @@ -1186,9 +1224,9 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, // check if the second vertex belongs to the first or last edge in the wire if ( !VV1[1].IsSame( TopExp::FirstVertex( *edgeIt, true ))) { bool KO = true; // belongs to none - if ( nbVInW1.size() > 1 ) { // several wires + if ( nbEInW1.size() > 1 ) { // several wires edgeIt = edges1.begin(); - for ( int i = 1; i < nbVInW1.front(); ++i ) ++edgeIt; + std::advance( edgeIt, nbEInW1.front()-1 ); KO = !VV1[1].IsSame( TopExp::FirstVertex( *edgeIt, true )); } if ( KO ) @@ -1201,9 +1239,9 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, // check if the second vertex belongs to the first or last edge in the wire if ( !VV2[1].IsSame( TopExp::FirstVertex( *edgeIt, true ))) { bool KO = true; // belongs to none - if ( nbVInW2.size() > 1 ) { // several wires + if ( nbEInW2.size() > 1 ) { // several wires edgeIt = edges2.begin(); - for ( int i = 1; i < nbVInW2.front(); ++i ) ++edgeIt; + std::advance( edgeIt, nbEInW2.front()-1 ); KO = !VV2[1].IsSame( TopExp::FirstVertex( *edgeIt, true )); } if ( KO ) @@ -1212,13 +1250,83 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, } if ( reverse ) { - Reverse( edges2 , nbVInW2.front()); + Reverse( edges2 , nbEInW2.front()); if (( VV1[1].IsSame( TopExp::LastVertex( edges1.front(), true ))) != ( VV2[1].IsSame( TopExp::LastVertex( edges2.front(), true )))) CONT_BAD_RESULT("GetOrderedEdges() failed"); } + OK = true; + + } // loop algos getting an outer wire + + // Try to orient all (if !OK) or only internal wires (issue 0020996) by UV similarity + if (( !OK || nbEInW1.size() > 1 ) && i_ok_wire_algo > -1 ) + { + // Check that Vec(VV1[0],VV1[1]) in 2D on face1 is the same + // as Vec(VV2[0],VV2[1]) on face2 + double vTol = BRep_Tool::Tolerance( VV1[0] ); + BRepAdaptor_Surface surface1( face1, false ); + double vTolUV = + surface1.UResolution( vTol ) + surface1.VResolution( vTol ); // let's be tolerant + gp_Pnt2d v0f1UV = BRep_Tool::Parameters( VV1[0], face1 ); + gp_Pnt2d v0f2UV = BRep_Tool::Parameters( VV2[0], face2 ); + gp_Pnt2d v1f1UV = BRep_Tool::Parameters( VV1[1], face1 ); + gp_Pnt2d v1f2UV = BRep_Tool::Parameters( VV2[1], face2 ); + gp_Vec2d v01f1Vec( v0f1UV, v1f1UV ); + gp_Vec2d v01f2Vec( v0f2UV, v1f2UV ); + if ( Abs( v01f1Vec.X()-v01f2Vec.X()) < vTolUV && Abs( v01f1Vec.Y()-v01f2Vec.Y()) < vTolUV ) + { + if ( i_ok_wire_algo != 1 ) + { + edges1.clear(); + edges2.clear(); + SMESH_Block::GetOrderedEdges( face1, VV1[0], edges1, nbEInW1, i_ok_wire_algo); + SMESH_Block::GetOrderedEdges( face2, VV2[0], edges2, nbEInW2, i_ok_wire_algo); + } + gp_XY dUV = v0f2UV.XY() - v0f1UV.XY(); // UV shift between 2 faces + // skip edges of the outer wire (if the outer wire is OK) + list< int >::iterator nbEInW = nbEInW1.begin(); + list< TopoDS_Edge >::iterator edge1Beg = edges1.begin(), edge2Beg = edges2.begin(); + if ( OK ) + { + for ( int i = 0; i < *nbEInW; ++i ) + ++edge1Beg, ++edge2Beg; + ++nbEInW; + } + for ( ; nbEInW != nbEInW1.end(); ++nbEInW ) // loop on wires + { + // reach an end of edges of a current wire + list< TopoDS_Edge >::iterator edge1End = edge1Beg, edge2End = edge2Beg; + for ( int i = 0; i < *nbEInW; ++i ) + ++edge1End, ++edge2End; + // rotate edges2 untill coincident with edges1 in 2D + v0f1UV = BRep_Tool::Parameters( TopExp::FirstVertex(*edge1Beg,true), face1 ); + v1f1UV = BRep_Tool::Parameters( TopExp::LastVertex (*edge1Beg,true), face1 ); + v0f1UV.ChangeCoord() += dUV; + v1f1UV.ChangeCoord() += dUV; + int i = *nbEInW; + while ( --i > 0 && !sameVertexUV( *edge2Beg, face2, 0, v0f1UV, vTolUV )) + edges2.splice( edge2End, edges2, edge2Beg++ ); // move edge2Beg to place before edge2End + if ( sameVertexUV( *edge2Beg, face2, 0, v0f1UV, vTolUV )) + { + if ( nbEInW == nbEInW1.begin() ) + OK = true; // OK is for the first wire + // reverse edges2 if needed + if ( !sameVertexUV( *edge2Beg, face2, 1, v1f1UV, vTolUV )) + { + Reverse( edges2 , *nbEInW, distance( edges2.begin(),edge2Beg )); + // set correct edge2End + edge2End = edges2.begin(); + std::advance( edge2End, std::accumulate( nbEInW1.begin(), nbEInW, *nbEInW)); + } + } + // prepare to the next wire loop + edge1Beg = edge1End, edge2Beg = edge2End; + } + } } - return nbVInW2.front(); + + return OK ? nbEInW1.front() : 0; } //======================================================================= @@ -1271,8 +1379,8 @@ bool StdMeshers_ProjectionUtils::InsertAssociation( const TopoDS_Shape& theShape const bool theBidirectional) { if ( !theShape1.IsNull() && !theShape2.IsNull() ) { - SHOW_VERTEX(theShape1,"Assoc "); - SHOW_VERTEX(theShape2," to "); + SHOW_SHAPE(theShape1,"Assoc "); + SHOW_SHAPE(theShape2," to "); bool isNew = ( theAssociationMap.Bind( theShape1, theShape2 )); if ( theBidirectional ) theAssociationMap.Bind( theShape2, theShape1 ); diff --git a/src/StdMeshers/StdMeshers_Propagation.cxx b/src/StdMeshers/StdMeshers_Propagation.cxx index 8b88ce99a..481803839 100644 --- a/src/StdMeshers/StdMeshers_Propagation.cxx +++ b/src/StdMeshers/StdMeshers_Propagation.cxx @@ -30,6 +30,7 @@ #include "SMDS_SetIterator.hxx" #include "SMESH_Algo.hxx" +#include "SMESH_Gen.hxx" #include "SMESH_HypoFilter.hxx" #include "SMESH_Mesh.hxx" #include "SMESH_subMesh.hxx" @@ -40,7 +41,7 @@ #include #define DBGMSG(txt) \ -// cout << txt << endl; + // cout << txt << endl; using namespace std; @@ -347,6 +348,10 @@ namespace { oppSM->ComputeStateEngine( SMESH_subMesh::CLEAN ); oppData->SetState( IN_CHAIN ); DBGMSG( "set IN_CHAIN on " << oppSM->GetId() ); + if ( oppSM->GetAlgoState() != SMESH_subMesh::HYP_OK ) + // make oppSM check algo state + if ( SMESH_Algo* algo = mesh->GetGen()->GetAlgo( *mesh, anOppE )) + oppSM->AlgoStateEngine(SMESH_subMesh::ADD_FATHER_ALGO,algo); } else { oppData->SetState( LAST_IN_CHAIN ); @@ -455,6 +460,7 @@ namespace { void PropagationMgr::Set(SMESH_subMesh * submesh) { + if ( findData( submesh )) return; DBGMSG( "PropagationMgr::Set() on " << submesh->GetId() ); EventListenerData* data = new PropagationMgrData(); submesh->SetEventListener( getListener(), data, submesh ); diff --git a/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx b/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx index 1ca7e5b12..8e2718dd0 100644 --- a/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx +++ b/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx @@ -25,8 +25,10 @@ // #include "StdMeshers_QuadToTriaAdaptor.hxx" -#include -#include +#include "SMDS_SetIterator.hxx" + +#include "SMESH_Algo.hxx" +#include "SMESH_MesherHelper.hxx" #include #include @@ -44,9 +46,297 @@ using namespace std; enum EQuadNature { NOT_QUAD, QUAD, DEGEN_QUAD }; - // sdt-like iterator used to get coordinates of nodes of mesh element +// std-like iterator used to get coordinates of nodes of mesh element typedef SMDS_StdIterator< SMESH_MeshEditor::TNodeXYZ, SMDS_ElemIteratorPtr > TXyzIterator; +namespace +{ + const int Q2TAbs_TmpTriangle = SMDSEntity_Last + 1; + + //================================================================================ + /*! + * \brief Temporary face. It's key feature is that it adds itself to an apex node + * as inverse element, so that tmp triangles of a piramid can be easily found + */ + //================================================================================ + + class STDMESHERS_EXPORT Q2TAdaptor_Triangle : public SMDS_MeshFace + { + const SMDS_MeshNode* _nodes[3]; + public: + Q2TAdaptor_Triangle(const SMDS_MeshNode* apexNode, + const SMDS_MeshNode* node2, + const SMDS_MeshNode* node3) + { + _nodes[0]=0; ChangeApex(apexNode); + _nodes[1]=node2; + _nodes[2]=node3; + } + ~Q2TAdaptor_Triangle() { MarkAsRemoved(); } + void ChangeApex(const SMDS_MeshNode* node) + { + MarkAsRemoved(); + _nodes[0]=node; + const_cast(node)->AddInverseElement(this); + } + void MarkAsRemoved() + { + if ( _nodes[0] ) + const_cast(_nodes[0])->RemoveInverseElement(this), _nodes[0] = 0; + } + bool IsRemoved() const { return !_nodes[0]; } + virtual int NbNodes() const { return 3; } + virtual const SMDS_MeshNode* GetNode(const int ind) const { return _nodes[ind]; } + virtual SMDSAbs_EntityType GetEntityType() const + { + return SMDSAbs_EntityType( Q2TAbs_TmpTriangle ); + } + virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const + { + if ( type == SMDSAbs_Node ) + return SMDS_ElemIteratorPtr( new SMDS_NodeArrayElemIterator( _nodes, _nodes+3 )); + throw SALOME_Exception(LOCALIZED("Not implemented")); + } + }; + + //================================================================================ + /*! + * \brief Return true if two nodes of triangles are equal + */ + //================================================================================ + + bool EqualTriangles(const SMDS_MeshElement* F1,const SMDS_MeshElement* F2) + { + return + ( F1->GetNode(1)==F2->GetNode(2) && F1->GetNode(2)==F2->GetNode(1) ) || + ( F1->GetNode(1)==F2->GetNode(1) && F1->GetNode(2)==F2->GetNode(2) ); + } + + //================================================================================ + /*! + * \brief Merge the two pyramids (i.e. fuse their apex) and others already merged with them + */ + //================================================================================ + + void MergePiramids( const SMDS_MeshElement* PrmI, + const SMDS_MeshElement* PrmJ, + SMESHDS_Mesh* meshDS, + set & nodesToMove) + { + const SMDS_MeshNode* Nrem = PrmJ->GetNode(4); // node to remove + int nbJ = Nrem->NbInverseElements( SMDSAbs_Volume ); + SMESH_MeshEditor::TNodeXYZ Pj( Nrem ); + + // an apex node to make common to all merged pyramids + SMDS_MeshNode* CommonNode = const_cast(PrmI->GetNode(4)); + if ( CommonNode == Nrem ) return; // already merged + int nbI = CommonNode->NbInverseElements( SMDSAbs_Volume ); + SMESH_MeshEditor::TNodeXYZ Pi( CommonNode ); + gp_XYZ Pnew = ( nbI*Pi + nbJ*Pj ) / (nbI+nbJ); + CommonNode->setXYZ( Pnew.X(), Pnew.Y(), Pnew.Z() ); + + nodesToMove.insert( CommonNode ); + nodesToMove.erase ( Nrem ); + + // find and remove coincided faces of merged pyramids + SMDS_ElemIteratorPtr triItI = CommonNode->GetInverseElementIterator(SMDSAbs_Face); + while ( triItI->more() ) + { + const SMDS_MeshElement* FI = triItI->next(); + const SMDS_MeshElement* FJEqual = 0; + SMDS_ElemIteratorPtr triItJ = Nrem->GetInverseElementIterator(SMDSAbs_Face); + while ( !FJEqual && triItJ->more() ) + { + const SMDS_MeshElement* FJ = triItJ->next(); + if ( EqualTriangles( FJ, FI )) + FJEqual = FJ; + } + if ( FJEqual ) + { + ((Q2TAdaptor_Triangle*) FI)->MarkAsRemoved(); + ((Q2TAdaptor_Triangle*) FJEqual)->MarkAsRemoved(); + } + } + + // set the common apex node to pyramids and triangles merged with J + SMDS_ElemIteratorPtr itJ = Nrem->GetInverseElementIterator(); + while ( itJ->more() ) + { + const SMDS_MeshElement* elem = itJ->next(); + if ( elem->GetType() == SMDSAbs_Volume ) // pyramid + { + vector< const SMDS_MeshNode* > nodes( elem->begin_nodes(), elem->end_nodes() ); + nodes[4] = CommonNode; + meshDS->ChangeElementNodes( elem, &nodes[0], nodes.size()); + } + else if ( elem->GetEntityType() == Q2TAbs_TmpTriangle ) // tmp triangle + { + ((Q2TAdaptor_Triangle*) elem )->ChangeApex( CommonNode ); + } + } + ASSERT( Nrem->NbInverseElements() == 0 ); + meshDS->RemoveFreeNode( Nrem, + meshDS->MeshElements( Nrem->GetPosition()->GetShapeId()), + /*fromGroups=*/false); + } + + //================================================================================ + /*! + * \brief Return true if two adjacent pyramids are too close one to another + * so that a tetrahedron to built between them would have too poor quality + */ + //================================================================================ + + bool TooCloseAdjacent( const SMDS_MeshElement* PrmI, + const SMDS_MeshElement* PrmJ, + const bool hasShape) + { + const SMDS_MeshNode* nApexI = PrmI->GetNode(4); + const SMDS_MeshNode* nApexJ = PrmJ->GetNode(4); + if ( nApexI == nApexJ || + nApexI->GetPosition()->GetShapeId() != nApexJ->GetPosition()->GetShapeId() ) + return false; + + // Find two common base nodes and their indices within PrmI and PrmJ + const SMDS_MeshNode* baseNodes[2] = { 0,0 }; + int baseNodesIndI[2], baseNodesIndJ[2]; + for ( int i = 0; i < 4 ; ++i ) + { + int j = PrmJ->GetNodeIndex( PrmI->GetNode(i)); + if ( j >= 0 ) + { + int ind = baseNodes[0] ? 1:0; + if ( baseNodes[ ind ]) + return false; // pyramids with a common base face + baseNodes [ ind ] = PrmI->GetNode(i); + baseNodesIndI[ ind ] = i; + baseNodesIndJ[ ind ] = j; + } + } + if ( !baseNodes[1] ) return false; // not adjacent + + // Get normals of triangles sharing baseNodes + gp_XYZ apexI = SMESH_MeshEditor::TNodeXYZ( nApexI ); + gp_XYZ apexJ = SMESH_MeshEditor::TNodeXYZ( nApexJ ); + gp_XYZ base1 = SMESH_MeshEditor::TNodeXYZ( baseNodes[0]); + gp_XYZ base2 = SMESH_MeshEditor::TNodeXYZ( baseNodes[1]); + gp_Vec baseVec( base1, base2 ); + gp_Vec baI( base1, apexI ); + gp_Vec baJ( base1, apexJ ); + gp_Vec nI = baseVec.Crossed( baI ); + gp_Vec nJ = baseVec.Crossed( baJ ); + + // Check angle between normals + double angle = nI.Angle( nJ ); + bool tooClose = ( angle < 15 * PI180 ); + + // Check if pyramids collide + bool isOutI, isOutJ; + if ( !tooClose && baI * baJ > 0 ) + { + // find out if nI points outside of PrmI or inside + int dInd = baseNodesIndI[1] - baseNodesIndI[0]; + isOutI = ( abs(dInd)==1 ) ? dInd < 0 : dInd > 0; + + // find out sign of projection of nJ to baI + double proj = baI * nJ; + + tooClose = isOutI ? proj > 0 : proj < 0; + } + + // Check if PrmI and PrmJ are in same domain + if ( tooClose && !hasShape ) + { + // check order of baseNodes within pyramids, it must be opposite + int dInd = baseNodesIndJ[1] - baseNodesIndJ[0]; + isOutJ = ( abs(dInd)==1 ) ? dInd < 0 : dInd > 0; + if ( isOutJ == isOutI ) + return false; // other domain + + // check absence of a face separating domains between pyramids + TIDSortedElemSet emptySet, avoidSet; + int i1, i2; + while ( const SMDS_MeshElement* f = + SMESH_MeshEditor::FindFaceInSet( baseNodes[0], baseNodes[1], + emptySet, avoidSet, &i1, &i2 )) + { + avoidSet.insert( f ); + + // face node other than baseNodes + int otherNodeInd = 0; + while ( otherNodeInd == i1 || otherNodeInd == i2 ) otherNodeInd++; + const SMDS_MeshNode* otherFaceNode = f->GetNode( otherNodeInd ); + + // check if f is a base face of either of pyramids + if ( f->NbCornerNodes() == 4 && + ( PrmI->GetNodeIndex( otherFaceNode ) >= 0 || + PrmJ->GetNodeIndex( otherFaceNode ) >= 0 )) + continue; // f is a base quadrangle + + // check projections of face direction (baOFN) to triange normals (nI and nJ) + gp_Vec baOFN( base1, SMESH_MeshEditor::TNodeXYZ( otherFaceNode )); + ( isOutI ? nJ : nI ).Reverse(); + if ( nI * baOFN > 0 && nJ * baOFN > 0 ) + { + tooClose = false; // f is between pyramids + break; + } + } + } + + return tooClose; + } + + //================================================================================ + /*! + * \brief Merges adjacent pyramids + */ + //================================================================================ + + void MergeAdjacent(const SMDS_MeshElement* PrmI, + SMESH_Mesh& mesh, + set& nodesToMove) + { + TIDSortedElemSet adjacentPyrams, mergedPyrams; + for(int k=0; k<4; k++) // loop on 4 base nodes of PrmI + { + const SMDS_MeshNode* n = PrmI->GetNode(k); + SMDS_ElemIteratorPtr vIt = n->GetInverseElementIterator( SMDSAbs_Volume ); + while ( vIt->more() ) + { + const SMDS_MeshElement* PrmJ = vIt->next(); + if ( PrmJ->NbCornerNodes() != 5 || !adjacentPyrams.insert( PrmJ ).second ) + continue; + if ( PrmI != PrmJ && TooCloseAdjacent( PrmI, PrmJ, mesh.HasShapeToMesh() )) + { + MergePiramids( PrmI, PrmJ, mesh.GetMeshDS(), nodesToMove ); + mergedPyrams.insert( PrmJ ); + } + } + } + if ( !mergedPyrams.empty() ) + { + TIDSortedElemSet::iterator prm; +// for (prm = mergedPyrams.begin(); prm != mergedPyrams.end(); ++prm) +// MergeAdjacent( *prm, mesh, nodesToMove ); + + for (prm = adjacentPyrams.begin(); prm != adjacentPyrams.end(); ++prm) + MergeAdjacent( *prm, mesh, nodesToMove ); + } + } +} + +//================================================================================ +/*! + * \brief Constructor + */ +//================================================================================ + +StdMeshers_QuadToTriaAdaptor::StdMeshers_QuadToTriaAdaptor(): + myElemSearcher(0), myNbTriangles(0) +{ +} + //================================================================================ /*! * \brief Destructor @@ -66,9 +356,8 @@ StdMeshers_QuadToTriaAdaptor::~StdMeshers_QuadToTriaAdaptor() } myResMap.clear(); -// TF2PyramMap::iterator itp = myPyram2Trias.begin(); -// for(; itp!=myPyram2Trias.end(); itp++) -// cout << itp->second << endl; + if ( myElemSearcher ) delete myElemSearcher; + myElemSearcher=0; } @@ -120,7 +409,7 @@ static bool HasIntersection3(const gp_Pnt& P, const gp_Pnt& PC, gp_Pnt& Pint, return false; if( IAICQ.NbPoints() == 1 ) { gp_Pnt PIn = IAICQ.Point(1); - double preci = 1.e-6; + const double preci = 1.e-10 * P.Distance(PC); // check if this point is internal for segment [PC,P] bool IsExternal = ( (PC.X()-PIn.X())*(P.X()-PIn.X()) > preci ) || @@ -133,32 +422,34 @@ static bool HasIntersection3(const gp_Pnt& P, const gp_Pnt& PC, gp_Pnt& Pint, gp_Vec V1(PIn,P1); gp_Vec V2(PIn,P2); gp_Vec V3(PIn,P3); - if( V1.Magnitude()(myElemSearcher); + + //SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); //cout<<" CheckIntersection: meshDS->NbFaces() = "<NbFaces()<MeshElements(aShapeFace); - if ( aSubMeshDSFace ) { - SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements(); - while ( iteratorElem->more() ) { // loop on elements on a face - const SMDS_MeshElement* face = iteratorElem->next(); - Handle(TColgp_HSequenceOfPnt) aContour = new TColgp_HSequenceOfPnt; - SMDS_ElemIteratorPtr nodeIt = face->nodesIterator(); - int nbN = face->NbNodes(); - if( face->IsQuadratic() ) - nbN /= 2; - for ( int i = 0; i < nbN; ++i ) { - const SMDS_MeshNode* node = static_cast( nodeIt->next() ); - aContour->Append(gp_Pnt(node->X(), node->Y(), node->Z())); - } - if( HasIntersection(P, PC, Pres, aContour) ) { - res = true; - double tmp = PC.Distance(Pres); - if(tmp suspectElems; + searcher->GetElementsNearLine( line, SMDSAbs_Face, suspectElems); + +// for (TopExp_Explorer exp(aShape,TopAbs_FACE);exp.More();exp.Next()) { +// const TopoDS_Shape& aShapeFace = exp.Current(); +// if(aShapeFace==NotCheckedFace) +// continue; +// const SMESHDS_SubMesh * aSubMeshDSFace = meshDS->MeshElements(aShapeFace); +// if ( aSubMeshDSFace ) { +// SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements(); +// while ( iteratorElem->more() ) { // loop on elements on a face +// const SMDS_MeshElement* face = iteratorElem->next(); + for ( int i = 0; i < suspectElems.size(); ++i ) + { + const SMDS_MeshElement* face = suspectElems[i]; + if ( face == NotCheckedFace ) continue; + Handle(TColgp_HSequenceOfPnt) aContour = new TColgp_HSequenceOfPnt; + for ( int i = 0; i < face->NbCornerNodes(); ++i ) + aContour->Append( SMESH_MeshEditor::TNodeXYZ( face->GetNode(i) )); + if( HasIntersection(P, PC, Pres, aContour) ) { + res = true; + double tmp = PC.Distance(Pres); + if(tmpGetNode(1)==F2->GetNode(2) && F1->GetNode(2)==F2->GetNode(1) ) || - ( F1->GetNode(1)==F2->GetNode(1) && F1->GetNode(2)==F2->GetNode(2) ); -} - //================================================================================ /*! * \brief Prepare data for the given face @@ -288,9 +580,11 @@ int StdMeshers_QuadToTriaAdaptor::Preparation(const SMDS_MeshElement* face gp_Vec& VNorm, const SMDS_MeshElement** volumes) { - if( face->NbNodes() != ( face->IsQuadratic() ? 8 : 4 )) - if( face->NbNodes() != 4 ) - return NOT_QUAD; + if( face->NbCornerNodes() != 4 ) + { + myNbTriangles += int( face->NbCornerNodes() == 3 ); + return NOT_QUAD; + } int i = 0; gp_XYZ xyzC(0., 0., 0.); @@ -403,21 +697,26 @@ int StdMeshers_QuadToTriaAdaptor::Preparation(const SMDS_MeshElement* face bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) { myResMap.clear(); - myPyram2Trias.clear(); + myPyramids.clear(); + myNbTriangles = 0; + myShape = aShape; SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); SMESH_MesherHelper helper(aMesh); helper.IsQuadraticSubMesh(aShape); helper.SetElementsOnShape( true ); - for (TopExp_Explorer exp(aShape,TopAbs_FACE);exp.More();exp.Next()) { + for (TopExp_Explorer exp(aShape,TopAbs_FACE);exp.More();exp.Next()) + { const TopoDS_Shape& aShapeFace = exp.Current(); const SMESHDS_SubMesh * aSubMeshDSFace = meshDS->MeshElements( aShapeFace ); - if ( aSubMeshDSFace ) { + if ( aSubMeshDSFace ) + { bool isRev = SMESH_Algo::IsReversedSubMesh( TopoDS::Face(aShapeFace), meshDS ); SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements(); - while ( iteratorElem->more() ) { // loop on elements on a face + while ( iteratorElem->more() ) // loop on elements on a geometrical face + { const SMDS_MeshElement* face = iteratorElem->next(); //cout<GetID() = "<GetID()<second; for(i=0; i<4; i++) - triaList.push_back( new SMDS_FaceOfNodes( NewNode, FNodes[i], FNodes[i+1] )); + triaList.push_back( new Q2TAdaptor_Triangle( NewNode, FNodes[i], FNodes[i+1] )); - // create pyramid + // create a pyramid if ( isRev ) swap( FNodes[1], FNodes[3]); SMDS_MeshVolume* aPyram = helper.AddVolume( FNodes[0], FNodes[1], FNodes[2], FNodes[3], NewNode ); - myPyram2Trias.insert(make_pair(aPyram, & triaList)); + myPyramids.push_back(aPyram); + } // end loop on elements on a face submesh } } // end for(TopExp_Explorer exp(aShape,TopAbs_FACE);exp.More();exp.Next()) { @@ -508,30 +809,30 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape return Compute2ndPart(aMesh); } - -//======================================================================= -//function : Compute -//purpose : -//======================================================================= +//================================================================================ +/*! + * \brief Computes pyramids in mesh with no shape + */ +//================================================================================ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) { myResMap.clear(); - myPyram2Trias.clear(); + myPyramids.clear(); SMESH_MesherHelper helper(aMesh); helper.IsQuadraticSubMesh(aMesh.GetShapeToMesh()); helper.SetElementsOnShape( true ); - SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + if ( !myElemSearcher ) + myElemSearcher = SMESH_MeshEditor(&aMesh).GetElementSearcher(); + SMESH_ElementSearcher* searcher = const_cast(myElemSearcher); - SMDS_FaceIteratorPtr fIt = meshDS->facesIterator(); - TIDSortedElemSet sortedFaces; // 0020279: control the "random" use when using mesh algorithms - while( fIt->more()) sortedFaces.insert( fIt->next() ); + SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); - TIDSortedElemSet::iterator itFace = sortedFaces.begin(), fEnd = sortedFaces.end(); - for ( ; itFace != fEnd; ++itFace ) + SMDS_FaceIteratorPtr fIt = meshDS->facesIterator(/*idInceasingOrder=*/true); + while( fIt->more()) { - const SMDS_MeshElement* face = *itFace; + const SMDS_MeshElement* face = fIt->next(); if ( !face ) continue; //cout<GetID() = "<GetID()<Value(1).Distance(PN->Value(2)) + PN->Value(2).Distance(PN->Value(3)); @@ -566,8 +867,13 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) double dist1 = RealLast(); double dist2 = RealLast(); gp_Pnt Pres1,Pres2; - for (TIDSortedElemSet::iterator itF = sortedFaces.begin(); itF != fEnd; ++itF ) { - const SMDS_MeshElement* F = *itF; + + gp_Ax1 line( PC, VNorm ); + vector< const SMDS_MeshElement* > suspectElems; + searcher->GetElementsNearLine( line, SMDSAbs_Face, suspectElems); + + for ( int iF = 0; iF < suspectElems.size(); ++iF ) { + const SMDS_MeshElement* F = suspectElems[iF]; if(F==face) continue; Handle(TColgp_HSequenceOfPnt) aContour = new TColgp_HSequenceOfPnt; for ( int i = 0; i < 4; ++i ) @@ -610,9 +916,9 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) } } if(!IsRev) - NewFace = new SMDS_FaceOfNodes( FNodes[0], FNodes[1], FNodes[2] ); + NewFace = new Q2TAdaptor_Triangle( FNodes[0], FNodes[1], FNodes[2] ); else - NewFace = new SMDS_FaceOfNodes( FNodes[0], FNodes[2], FNodes[1] ); + NewFace = new Q2TAdaptor_Triangle( FNodes[0], FNodes[2], FNodes[1] ); aList.push_back(NewFace); myResMap.insert(make_pair(face,aList)); continue; @@ -646,9 +952,14 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) bool intersected[2] = { false, false }; double dist [2] = { RealLast(), RealLast() }; gp_Pnt intPnt[2]; - for (TIDSortedElemSet::iterator itF = sortedFaces.begin(); itF != fEnd; ++itF ) + + gp_Ax1 line( PC, tmpDir ); + vector< const SMDS_MeshElement* > suspectElems; + searcher->GetElementsNearLine( line, SMDSAbs_Face, suspectElems); + + for ( int iF = 0; iF < suspectElems.size(); ++iF ) { - const SMDS_MeshElement* F = *itF; + const SMDS_MeshElement* F = suspectElems[iF]; if(F==face) continue; Handle(TColgp_HSequenceOfPnt) aContour = new TColgp_HSequenceOfPnt; int nbN = F->NbNodes() / ( F->IsQuadratic() ? 2 : 1 ); @@ -683,11 +994,11 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) // add triangles to result map TTriaList& aList = myResMap.insert( make_pair( face, TTriaList()))->second; for(i=0; i<4; i++) { - SMDS_FaceOfNodes* NewFace; + SMDS_MeshFace* NewFace; if(isRev) - NewFace = new SMDS_FaceOfNodes( NewNode, FNodes[i], FNodes[i+1] ); + NewFace = new Q2TAdaptor_Triangle( NewNode, FNodes[i], FNodes[i+1] ); else - NewFace = new SMDS_FaceOfNodes( NewNode, FNodes[i+1], FNodes[i] ); + NewFace = new Q2TAdaptor_Triangle( NewNode, FNodes[i+1], FNodes[i] ); aList.push_back(NewFace); } // create a pyramid @@ -696,231 +1007,162 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) aPyram = helper.AddVolume( FNodes[0], FNodes[1], FNodes[2], FNodes[3], NewNode ); else aPyram = helper.AddVolume( FNodes[0], FNodes[3], FNodes[2], FNodes[1], NewNode ); - myPyram2Trias.insert(make_pair(aPyram, & aList)); + myPyramids.push_back(aPyram); } } // end loop on all faces return Compute2ndPart(aMesh); } -//======================================================================= -//function : Compute2ndPart -//purpose : Update created pyramids and faces to avoid their intersection -//======================================================================= +//================================================================================ +/*! + * \brief Update created pyramids and faces to avoid their intersection + */ +//================================================================================ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh) { + if(myPyramids.empty()) + return true; + SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + int i, j, k, myShapeID = myPyramids[0]->GetNode(4)->GetPosition()->GetShapeId(); - // check intersections between created pyramids + if ( !myElemSearcher ) + myElemSearcher = SMESH_MeshEditor(&aMesh).GetElementSearcher(); + SMESH_ElementSearcher* searcher = const_cast(myElemSearcher); - if(myPyram2Trias.empty()) - return true; + set nodesToMove; - int k = 0; + // check adjacent pyramids - // for each pyramid store list of merged pyramids with their faces - typedef map< const SMDS_MeshElement*, list< TPyram2Trias::iterator > > TPyram2Merged; - TPyram2Merged MergesInfo; + for ( i = 0; i < myPyramids.size(); ++i ) + { + const SMDS_MeshElement* PrmI = myPyramids[i]; + MergeAdjacent( PrmI, aMesh, nodesToMove ); + } // iterate on all pyramids - TPyram2Trias::iterator itPi = myPyram2Trias.begin(), itPEnd = myPyram2Trias.end(); - for ( ; itPi != itPEnd; ++itPi ) + for ( i = 0; i < myPyramids.size(); ++i ) { - const SMDS_MeshElement* PrmI = itPi->first; - TPyram2Merged::iterator pMergesI = MergesInfo.find( PrmI ); - - TXyzIterator xyzIt( PrmI->nodesIterator() ); - vector PsI( xyzIt, TXyzIterator() ); + const SMDS_MeshElement* PrmI = myPyramids[i]; // compare PrmI with all the rest pyramids - bool NeedMove = false; - TPyram2Trias::iterator itPj = itPi; - for ( ++itPj; itPj != itPEnd; ++itPj ) + + // collect adjacent pyramids and nodes coordinates of PrmI + set checkedPyrams; + vector PsI(5); + for(k=0; k<5; k++) // loop on 4 base nodes of PrmI + { + const SMDS_MeshNode* n = PrmI->GetNode(k); + PsI[k] = SMESH_MeshEditor::TNodeXYZ( n ); + SMDS_ElemIteratorPtr vIt = n->GetInverseElementIterator( SMDSAbs_Volume ); + while ( vIt->more() ) + checkedPyrams.insert( vIt->next() ); + } + + // check intersection with distant pyramids + for(k=0; k<4; k++) // loop on 4 base nodes of PrmI { - const SMDS_MeshElement* PrmJ = itPj->first; - TPyram2Merged::iterator pMergesJ = MergesInfo.find( PrmJ ); - - // check if two pyramids already merged - if ( pMergesJ != MergesInfo.end() && - find(pMergesJ->second.begin(),pMergesJ->second.end(), itPi )!=pMergesJ->second.end()) - continue; // already merged - - xyzIt = TXyzIterator( PrmJ->nodesIterator() ); - vector PsJ( xyzIt, TXyzIterator() ); - - bool hasInt = false; - gp_Pnt Pint; - for(k=0; k<4 && !hasInt; k++) { - gp_Vec Vtmp(PsI[k],PsI[4]); - gp_Pnt Pshift = PsI[k].XYZ() + Vtmp.XYZ() * 0.01; - hasInt = + gp_Vec Vtmp(PsI[k],PsI[4]); + gp_Pnt Pshift = PsI[k].XYZ() + Vtmp.XYZ() * 0.01; // base node moved a bit to apex + + gp_Ax1 line( PsI[k], Vtmp ); + vector< const SMDS_MeshElement* > suspectPyrams; + searcher->GetElementsNearLine( line, SMDSAbs_Volume, suspectPyrams); + + for ( j = 0; j < suspectPyrams.size(); ++j ) + { + const SMDS_MeshElement* PrmJ = suspectPyrams[j]; + if ( PrmJ == PrmI || PrmJ->NbCornerNodes() != 5 ) + continue; + if ( myShapeID != PrmJ->GetNode(4)->GetPosition()->GetShapeId()) + continue; // pyramid from other SOLID + if ( PrmI->GetNode(4) == PrmJ->GetNode(4) ) + continue; // pyramids PrmI and PrmJ already merged + if ( !checkedPyrams.insert( PrmJ ).second ) + continue; // already checked + + TXyzIterator xyzIt( PrmJ->nodesIterator() ); + vector PsJ( xyzIt, TXyzIterator() ); + + gp_Pnt Pint; + bool hasInt = ( HasIntersection3( Pshift, PsI[4], Pint, PsJ[0], PsJ[1], PsJ[4]) || HasIntersection3( Pshift, PsI[4], Pint, PsJ[1], PsJ[2], PsJ[4]) || HasIntersection3( Pshift, PsI[4], Pint, PsJ[2], PsJ[3], PsJ[4]) || HasIntersection3( Pshift, PsI[4], Pint, PsJ[3], PsJ[0], PsJ[4]) ); - } - for(k=0; k<4 && !hasInt; k++) { - gp_Vec Vtmp(PsJ[k],PsJ[4]); - gp_Pnt Pshift = PsJ[k].XYZ() + Vtmp.XYZ() * 0.01; - hasInt = - ( HasIntersection3( Pshift, PsJ[4], Pint, PsI[0], PsI[1], PsI[4]) || - HasIntersection3( Pshift, PsJ[4], Pint, PsI[1], PsI[2], PsI[4]) || - HasIntersection3( Pshift, PsJ[4], Pint, PsI[2], PsI[3], PsI[4]) || - HasIntersection3( Pshift, PsJ[4], Pint, PsI[3], PsI[0], PsI[4]) ); - } - if(hasInt) { - // count common nodes of base faces of two pyramids - int nbc = 0; - for(k=0; k<4; k++) - nbc += int ( PrmI->GetNodeIndex( PrmJ->GetNode(k) ) >= 0 ); - //cout<<" nbc = "<0) + if ( hasInt ) { - // Merge the two pyramids and others already merged with them + // count common nodes of base faces of two pyramids + int nbc = 0; + for (k=0; k<4; k++) + nbc += int ( PrmI->GetNodeIndex( PrmJ->GetNode(k) ) >= 0 ); - // initialize merge info of pyramids - if ( pMergesI == MergesInfo.end() ) // first merge of PrmI - { - pMergesI = MergesInfo.insert( make_pair( PrmI, list())).first; - pMergesI->second.push_back( itPi ); - } - if ( pMergesJ == MergesInfo.end() ) // first merge of PrmJ - { - pMergesJ = MergesInfo.insert( make_pair( PrmJ, list())).first; - pMergesJ->second.push_back( itPj ); - } - int nbI = pMergesI->second.size(), nbJ = pMergesJ->second.size(); - - // an apex node to make common to all merged pyramids - SMDS_MeshNode* CommonNode = const_cast(PrmI->GetNode(4)); - CommonNode->setXYZ( ( nbI*PsI[4].X() + nbJ*PsJ[4].X() ) / (nbI+nbJ), - ( nbI*PsI[4].Y() + nbJ*PsJ[4].Y() ) / (nbI+nbJ), - ( nbI*PsI[4].Z() + nbJ*PsJ[4].Z() ) / (nbI+nbJ) ); - NeedMove = true; - const SMDS_MeshNode* Nrem = PrmJ->GetNode(4); // node to remove - - list< TPyram2Trias::iterator >& aMergesI = pMergesI->second; - list< TPyram2Trias::iterator >& aMergesJ = pMergesJ->second; - - // find and remove coincided faces of merged pyramids - list< TPyram2Trias::iterator >::iterator itPttI, itPttJ; - TTriaList::iterator trI, trJ; - for ( itPttI = aMergesI.begin(); itPttI != aMergesI.end(); ++itPttI ) + if ( nbc == 4 ) + continue; // pyrams have a common base face + + if(nbc>0) { - TTriaList* triaListI = (*itPttI)->second; - for ( trI = triaListI->begin(); trI != triaListI->end(); ) - { - const SMDS_FaceOfNodes* FI = *trI; - - for ( itPttJ = aMergesJ.begin(); itPttJ != aMergesJ.end() && FI; ++itPttJ ) - { - TTriaList* triaListJ = (*itPttJ)->second; - for ( trJ = triaListJ->begin(); trJ != triaListJ->end(); ) - { - const SMDS_FaceOfNodes* FJ = *trJ; - - if( EqualTriangles(FI,FJ) ) - { - delete FI; - delete FJ; - FI = FJ = 0; - trI = triaListI->erase( trI ); - trJ = triaListJ->erase( trJ ); - break; // only one triangle of a pyramid can coincide with another pyramid - } - ++trJ; - } - } - if ( FI ) ++trI; // increament if triangle not deleted - } + // Merge the two pyramids and others already merged with them + MergePiramids( PrmI, PrmJ, meshDS, nodesToMove ); } + else { // nbc==0 - // set the common apex node to pyramids and triangles merged with J - for ( itPttJ = aMergesJ.begin(); itPttJ != aMergesJ.end(); ++itPttJ ) - { - const SMDS_MeshElement* Prm = (*itPttJ)->first; - TTriaList* triaList = (*itPttJ)->second; - - vector< const SMDS_MeshNode* > nodes( Prm->begin_nodes(), Prm->end_nodes() ); - nodes[4] = CommonNode; - meshDS->ChangeElementNodes( Prm, &nodes[0], nodes.size()); - - for ( TTriaList::iterator trIt = triaList->begin(); trIt != triaList->end(); ++trIt ) - { - SMDS_FaceOfNodes* Ftria = const_cast< SMDS_FaceOfNodes*>( *trIt ); - const SMDS_MeshNode* NF[3] = { CommonNode, Ftria->GetNode(1), Ftria->GetNode(2)}; - Ftria->ChangeNodes(NF, 3); + // decrease height of pyramids + gp_XYZ PCi(0,0,0), PCj(0,0,0); + for(k=0; k<4; k++) { + PCi += PsI[k].XYZ(); + PCj += PsJ[k].XYZ(); } + PCi /= 4; PCj /= 4; + gp_Vec VN1(PCi,PsI[4]); + gp_Vec VN2(PCj,PsJ[4]); + gp_Vec VI1(PCi,Pint); + gp_Vec VI2(PCj,Pint); + double ang1 = fabs(VN1.Angle(VI1)); + double ang2 = fabs(VN2.Angle(VI2)); + double coef1 = 0.5 - (( ang1(PrmI->GetNode(4)); + aNode1->setXYZ( PCi.X()+VN1.X(), PCi.Y()+VN1.Y(), PCi.Z()+VN1.Z() ); + SMDS_MeshNode* aNode2 = const_cast(PrmJ->GetNode(4)); + aNode2->setXYZ( PCj.X()+VN2.X(), PCj.Y()+VN2.Y(), PCj.Z()+VN2.Z() ); + nodesToMove.insert( aNode1 ); + nodesToMove.insert( aNode2 ); } + // fix intersections that could appear after apex movement + MergeAdjacent( PrmI, aMesh, nodesToMove ); + MergeAdjacent( PrmJ, aMesh, nodesToMove ); - // join MergesInfo of merged pyramids - for ( k = 0, itPttI = aMergesI.begin(); k < nbI; ++itPttI, ++k ) - { - const SMDS_MeshElement* PrmI = (*itPttI)->first; - list< TPyram2Trias::iterator >& merges = MergesInfo[ PrmI ]; - merges.insert( merges.end(), aMergesJ.begin(), aMergesJ.end() ); - } - for ( k = 0, itPttJ = aMergesJ.begin(); k < nbJ; ++itPttJ, ++k ) - { - const SMDS_MeshElement* PrmJ = (*itPttJ)->first; - list< TPyram2Trias::iterator >& merges = MergesInfo[ PrmJ ]; - merges.insert( merges.end(), aMergesI.begin(), aMergesI.end() ); - } + } // end if(hasInt) + } // loop on suspectPyrams + } // loop on 4 base nodes of PrmI - // removing node - meshDS->RemoveNode(Nrem); - } - else { // nbc==0 + } // loop on all pyramids - // decrease height of pyramids - gp_XYZ PC1(0,0,0), PC2(0,0,0); - for(k=0; k<4; k++) { - PC1 += PsI[k].XYZ(); - PC2 += PsJ[k].XYZ(); - } - PC1 /= 4; PC2 /= 4; - gp_Vec VN1(PC1,PsI[4]); - gp_Vec VI1(PC1,Pint); - gp_Vec VN2(PC2,PsJ[4]); - gp_Vec VI2(PC2,Pint); - double ang1 = fabs(VN1.Angle(VI1)); - double ang2 = fabs(VN2.Angle(VI2)); - double h1,h2; - if(ang1>PI/3.) - h1 = VI1.Magnitude()/2; - else - h1 = VI1.Magnitude()*cos(ang1); - if(ang2>PI/3.) - h2 = VI2.Magnitude()/2; - else - h2 = VI2.Magnitude()*cos(ang2); - double coef1 = 0.5; - if(ang1(PrmI->GetNode(4)); - aNode1->setXYZ( PC1.X()+VN1.X(), PC1.Y()+VN1.Y(), PC1.Z()+VN1.Z() ); - SMDS_MeshNode* aNode2 = const_cast(PrmJ->GetNode(4)); - aNode2->setXYZ( PC2.X()+VN2.X(), PC2.Y()+VN2.Y(), PC2.Z()+VN2.Z() ); - NeedMove = true; - } - } // end if(hasInt) - } - if( NeedMove && !meshDS->IsEmbeddedMode() ) - { - const SMDS_MeshNode* apex = PrmI->GetNode( 4 ); - meshDS->MoveNode( apex, apex->X(), apex->Y(), apex->Z() ); - } + if( !nodesToMove.empty() && !meshDS->IsEmbeddedMode() ) + { + set::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 @@ -931,10 +1173,23 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh) if ( q2t->first == q2tPrev->first ) q2tPrev->second.splice( q2tPrev->second.end(), q2t->second ); } + // delete removed triangles and count resulting nb of triangles + for ( q2t = myResMap.begin(); q2t != myResMap.end(); ++q2t ) + { + TTriaList & trias = q2t->second; + for ( TTriaList::iterator tri = trias.begin(); tri != trias.end(); ) + if ( ((const Q2TAdaptor_Triangle*) *tri)->IsRemoved() ) + delete *tri, trias.erase( tri++ ); + else + tri++, myNbTriangles++; + } - myPyram2Trias.clear(); // no more needed + myPyramids.clear(); // no more needed myDegNodes.clear(); + delete myElemSearcher; + myElemSearcher=0; + return true; } @@ -944,11 +1199,8 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh) */ //================================================================================ -const list* StdMeshers_QuadToTriaAdaptor::GetTriangles (const SMDS_MeshElement* aQuad) +const list* StdMeshers_QuadToTriaAdaptor::GetTriangles (const SMDS_MeshElement* aQuad) { TQuad2Trias::iterator it = myResMap.find(aQuad); - if( it != myResMap.end() ) { - return & it->second; - } - return 0; + return ( it != myResMap.end() ? & it->second : 0 ); } diff --git a/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.hxx b/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.hxx index 79017c20d..ceccb2542 100644 --- a/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.hxx +++ b/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.hxx @@ -25,14 +25,14 @@ #define _SMESH_QuadToTriaAdaptor_HXX_ #include "SMESH_StdMeshers.hxx" -#include "SMDS_FaceOfNodes.hxx" class SMESH_Mesh; +class SMESH_ElementSearcher; class SMDS_MeshElement; class SMDS_MeshNode; -class Handle(TColgp_HArray1OfPnt); -class Handle(TColgp_HArray1OfVec); -class TopoDS_Shape; +class SMDS_MeshFace; +class Handle_TColgp_HArray1OfPnt; +class Handle_TColgp_HArray1OfVec; class gp_Pnt; class gp_Vec; @@ -41,9 +41,15 @@ class gp_Vec; #include #include +#include + +/*! + * \brief "Transforms" quadrilateral faces into triangular ones by creation of pyramids + */ class STDMESHERS_EXPORT StdMeshers_QuadToTriaAdaptor { public: + StdMeshers_QuadToTriaAdaptor(); ~StdMeshers_QuadToTriaAdaptor(); @@ -51,15 +57,22 @@ public: bool Compute(SMESH_Mesh& aMesh); - const std::list* GetTriangles(const SMDS_MeshElement* aFace); + const std::list* GetTriangles(const SMDS_MeshElement* aFace); + + /*! + * \brief Return sum of generated and already present triangles + */ + int TotalNbOfTriangles() const { return myNbTriangles; } + + TopoDS_Shape GetShape() const { return myShape; } protected: //bool CheckDegenerate(const SMDS_MeshElement* aFace); int Preparation(const SMDS_MeshElement* face, - Handle(TColgp_HArray1OfPnt)& PN, - Handle(TColgp_HArray1OfVec)& VN, + Handle_TColgp_HArray1OfPnt& PN, + Handle_TColgp_HArray1OfVec& VN, std::vector& FNodes, gp_Pnt& PC, gp_Vec& VNorm, const SMDS_MeshElement** volumes=0); @@ -67,19 +80,24 @@ protected: bool CheckIntersection(const gp_Pnt& P, const gp_Pnt& PC, gp_Pnt& Pint, SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, - const TopoDS_Shape& NotCheckedFace); + const SMDS_MeshElement* NotCheckedFace); bool Compute2ndPart(SMESH_Mesh& aMesh); - typedef std::list TTriaList; - typedef std::multimap TQuad2Trias; - typedef std::map TPyram2Trias; + + typedef std::list TTriaList; + typedef std::multimap TQuad2Trias; TQuad2Trias myResMap; - TPyram2Trias myPyram2Trias; + std::vector myPyramids; std::list< const SMDS_MeshNode* > myDegNodes; + const SMESH_ElementSearcher* myElemSearcher; + + int myNbTriangles; + + TopoDS_Shape myShape; }; #endif diff --git a/src/StdMeshers/StdMeshers_QuadrangleParams.cxx b/src/StdMeshers/StdMeshers_QuadrangleParams.cxx index 07cd7f649..c0e106364 100644 --- a/src/StdMeshers/StdMeshers_QuadrangleParams.cxx +++ b/src/StdMeshers/StdMeshers_QuadrangleParams.cxx @@ -16,12 +16,11 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // - // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_QuadrangleParams.cxx // Author : Sergey KUUL, OCC // Module : SMESH -// + #include "StdMeshers_QuadrangleParams.hxx" #include "SMESH_Algo.hxx" @@ -41,38 +40,36 @@ using namespace std; //============================================================================= /*! - * + * */ //============================================================================= - StdMeshers_QuadrangleParams::StdMeshers_QuadrangleParams(int hypId, int studyId, SMESH_Gen * gen) - :SMESH_Hypothesis(hypId, studyId, gen) + : SMESH_Hypothesis(hypId, studyId, gen) { _name = "QuadrangleParams"; _param_algo_dim = 2; _triaVertexID = -1; + _quadType = QUAD_STANDARD; } //============================================================================= /*! - * + * */ //============================================================================= - StdMeshers_QuadrangleParams::~StdMeshers_QuadrangleParams() { } //============================================================================= /*! - * + * */ //============================================================================= - -void StdMeshers_QuadrangleParams::SetTriaVertex(int id) +void StdMeshers_QuadrangleParams::SetTriaVertex (int id) { - if ( id != _triaVertexID ) { + if (id != _triaVertexID) { _triaVertexID = id; NotifySubMeshesHypothesisModification(); } @@ -80,22 +77,36 @@ void StdMeshers_QuadrangleParams::SetTriaVertex(int id) //============================================================================= /*! - * + * */ //============================================================================= +void StdMeshers_QuadrangleParams::SetQuadType (StdMeshers_QuadType type) +{ + if (type != _quadType) { + _quadType = type; + NotifySubMeshesHypothesisModification(); + } +} +//============================================================================= +/*! + * + */ +//============================================================================= ostream & StdMeshers_QuadrangleParams::SaveTo(ostream & save) { - save << _triaVertexID << " " << _objEntry; + if (_objEntry.size() == 0) + save << _triaVertexID << " UNDEFINED " << int(_quadType); + else + save << _triaVertexID << " " << _objEntry << " " << int(_quadType); return save; } //============================================================================= /*! - * + * */ //============================================================================= - istream & StdMeshers_QuadrangleParams::LoadFrom(istream & load) { bool isOK = true; @@ -104,16 +115,22 @@ istream & StdMeshers_QuadrangleParams::LoadFrom(istream & load) load.clear(ios::badbit | load.rdstate()); isOK = (load >> _objEntry); + if (!isOK) + load.clear(ios::badbit | load.rdstate()); + + int type; + isOK = (load >> type); + if (isOK) + _quadType = StdMeshers_QuadType(type); return load; } //============================================================================= /*! - * + * */ //============================================================================= - ostream & operator <<(ostream & save, StdMeshers_QuadrangleParams & hyp) { return hyp.SaveTo( save ); @@ -121,10 +138,9 @@ ostream & operator <<(ostream & save, StdMeshers_QuadrangleParams & hyp) //============================================================================= /*! - * + * */ //============================================================================= - istream & operator >>(istream & load, StdMeshers_QuadrangleParams & hyp) { return hyp.LoadFrom( load ); @@ -138,7 +154,6 @@ istream & operator >>(istream & load, StdMeshers_QuadrangleParams & hyp) * \retval bool - true if parameter values have been successfully defined */ //================================================================================ - bool StdMeshers_QuadrangleParams::SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape) { @@ -154,10 +169,8 @@ bool StdMeshers_QuadrangleParams::SetParametersByMesh(const SMESH_Mesh* theMesh, * \retval bool - true if parameter values have been successfully defined */ //================================================================================ - bool StdMeshers_QuadrangleParams::SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* /*mesh*/) { return true; } - diff --git a/src/StdMeshers/StdMeshers_QuadrangleParams.hxx b/src/StdMeshers/StdMeshers_QuadrangleParams.hxx index da37f0755..d880c5008 100644 --- a/src/StdMeshers/StdMeshers_QuadrangleParams.hxx +++ b/src/StdMeshers/StdMeshers_QuadrangleParams.hxx @@ -16,22 +16,29 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // - // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_QuadrangleParams.hxx // Author : Sergey KUUL, OCC // Module : SMESH -// + #ifndef _SMESH_QUADRANGLEPARAMS_HXX_ #define _SMESH_QUADRANGLEPARAMS_HXX_ - - #include "SMESH_StdMeshers.hxx" #include "SMESH_Hypothesis.hxx" #include "Utils_SALOME_Exception.hxx" +enum StdMeshers_QuadType + { + QUAD_STANDARD, + QUAD_TRIANGLE_PREF, + QUAD_QUADRANGLE_PREF, + QUAD_QUADRANGLE_PREF_REVERSED, + QUAD_REDUCED, + QUAD_NB_TYPES + }; + class STDMESHERS_EXPORT StdMeshers_QuadrangleParams: public SMESH_Hypothesis { @@ -39,13 +46,14 @@ public: StdMeshers_QuadrangleParams(int hypId, int studyId, SMESH_Gen* gen); virtual ~StdMeshers_QuadrangleParams(); - void SetTriaVertex(int id); - - void SetObjectEntry( const char* entry ) { _objEntry = entry; } + void SetTriaVertex (int id); + int GetTriaVertex() const { return _triaVertexID; } + void SetObjectEntry (const char* entry) { _objEntry = entry; } const char* GetObjectEntry() { return _objEntry.c_str(); } - int GetTriaVertex() const { return _triaVertexID; } + void SetQuadType (StdMeshers_QuadType type); + StdMeshers_QuadType GetQuadType() const { return _quadType; } virtual std::ostream & SaveTo(std::ostream & save); virtual std::istream & LoadFrom(std::istream & load); @@ -71,8 +79,9 @@ public: const SMESH_Mesh* theMesh=0); protected: - int _triaVertexID; - std::string _objEntry; + int _triaVertexID; + std::string _objEntry; + StdMeshers_QuadType _quadType; }; #endif diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx index 1c0cf5e5b..1075db412 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx @@ -18,14 +18,11 @@ // 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 SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_Quadrangle_2D.cxx -// Moved here from SMESH_Quadrangle_2D.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// + #include "StdMeshers_Quadrangle_2D.hxx" #include "StdMeshers_FaceSide.hxx" @@ -49,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -116,69 +114,75 @@ bool StdMeshers_Quadrangle_2D::CheckHypothesis bool isOk = true; aStatus = SMESH_Hypothesis::HYP_OK; - const list &hyps = + const list & hyps = GetUsedHypothesis(aMesh, aShape, false); - const SMESHDS_Hypothesis *theHyp = 0; - - if( hyps.size() == 1 ) { - myTriaVertexID = -1; - theHyp = hyps.front(); - if(strcmp("QuadrangleParams", theHyp->GetName()) == 0) { - const StdMeshers_QuadrangleParams* theHyp1 = - (const StdMeshers_QuadrangleParams*)theHyp; - myTriaVertexID = theHyp1->GetTriaVertex(); - myQuadranglePreference= false; - myTrianglePreference= false; - } - if(strcmp("QuadranglePreference", theHyp->GetName()) == 0) { - myQuadranglePreference= true; - myTrianglePreference= false; - myTriaVertexID = -1; - } - else if(strcmp("TrianglePreference", theHyp->GetName()) == 0){ - myQuadranglePreference= false; - myTrianglePreference= true; - myTriaVertexID = -1; + const SMESHDS_Hypothesis * aHyp = 0; + + myTriaVertexID = -1; + myQuadType = QUAD_STANDARD; + myQuadranglePreference = false; + myTrianglePreference = false; + + bool isFirstParams = true; + + // First assigned hypothesis (if any) is processed now + if (hyps.size() > 0) { + aHyp = hyps.front(); + if (strcmp("QuadrangleParams", aHyp->GetName()) == 0) { + const StdMeshers_QuadrangleParams* aHyp1 = + (const StdMeshers_QuadrangleParams*)aHyp; + myTriaVertexID = aHyp1->GetTriaVertex(); + myQuadType = aHyp1->GetQuadType(); + if (myQuadType == QUAD_QUADRANGLE_PREF || + myQuadType == QUAD_QUADRANGLE_PREF_REVERSED) + myQuadranglePreference = true; + else if (myQuadType == QUAD_TRIANGLE_PREF) + myTrianglePreference = true; + } + else if (strcmp("QuadranglePreference", aHyp->GetName()) == 0) { + isFirstParams = false; + myQuadranglePreference = true; + } + else if (strcmp("TrianglePreference", aHyp->GetName()) == 0){ + isFirstParams = false; + myTrianglePreference = true; + } + else { + isFirstParams = false; } } - else if( hyps.size() > 1 ) { - theHyp = hyps.front(); - if(strcmp("QuadrangleParams", theHyp->GetName()) == 0) { - const StdMeshers_QuadrangleParams* theHyp1 = - (const StdMeshers_QuadrangleParams*)theHyp; - myTriaVertexID = theHyp1->GetTriaVertex(); - theHyp = hyps.back(); - if(strcmp("QuadranglePreference", theHyp->GetName()) == 0) { - myQuadranglePreference= true; - myTrianglePreference= false; + // Second(last) assigned hypothesis (if any) is processed now + if (hyps.size() > 1) { + aHyp = hyps.back(); + if (isFirstParams) { + if (strcmp("QuadranglePreference", aHyp->GetName()) == 0) { + myQuadranglePreference = true; + myTrianglePreference = false; + myQuadType = QUAD_STANDARD; } - else if(strcmp("TrianglePreference", theHyp->GetName()) == 0){ - myQuadranglePreference= false; - myTrianglePreference= true; + else if (strcmp("TrianglePreference", aHyp->GetName()) == 0){ + myQuadranglePreference = false; + myTrianglePreference = true; + myQuadType = QUAD_STANDARD; } } else { - if(strcmp("QuadranglePreference", theHyp->GetName()) == 0) { - myQuadranglePreference= true; - myTrianglePreference= false; + const StdMeshers_QuadrangleParams* aHyp2 = + (const StdMeshers_QuadrangleParams*)aHyp; + myTriaVertexID = aHyp2->GetTriaVertex(); + + if (!myQuadranglePreference && !myTrianglePreference) { // priority of hypos + myQuadType = aHyp2->GetQuadType(); + if (myQuadType == QUAD_QUADRANGLE_PREF || + myQuadType == QUAD_QUADRANGLE_PREF_REVERSED) + myQuadranglePreference = true; + else if (myQuadType == QUAD_TRIANGLE_PREF) + myTrianglePreference = true; } - else if(strcmp("TrianglePreference", theHyp->GetName()) == 0){ - myQuadranglePreference= false; - myTrianglePreference= true; - } - const StdMeshers_QuadrangleParams* theHyp2 = - (const StdMeshers_QuadrangleParams*)hyps.back(); - myTriaVertexID = theHyp2->GetTriaVertex(); } } - else { - myQuadranglePreference = false; - myTrianglePreference = false; - myTriaVertexID = -1; - } - return isOk; } @@ -197,17 +201,17 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); aMesh.GetSubMesh(aShape); - SMESH_MesherHelper helper(aMesh); + SMESH_MesherHelper helper (aMesh); myTool = &helper; _quadraticMesh = myTool->IsQuadraticSubMesh(aShape); - FaceQuadStruct *quad = CheckNbEdges( aMesh, aShape ); - std::auto_ptr quadDeleter( quad ); // to delete quad at exit from Compute() + FaceQuadStruct *quad = CheckNbEdges(aMesh, aShape); + std::auto_ptr quadDeleter (quad); // to delete quad at exit from Compute() if (!quad) return false; - if(myQuadranglePreference) { + if (myQuadranglePreference) { int n1 = quad->side[0]->NbPoints(); int n2 = quad->side[1]->NbPoints(); int n3 = quad->side[2]->NbPoints(); @@ -215,12 +219,27 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, int nfull = n1+n2+n3+n4; int ntmp = nfull/2; ntmp = ntmp*2; - if( nfull==ntmp && ( (n1!=n3) || (n2!=n4) ) ) { + if (nfull == ntmp && ((n1 != n3) || (n2 != n4))) { // special path for using only quandrangle faces bool ok = ComputeQuadPref(aMesh, aShape, quad); return ok; } } + else if (myQuadType == QUAD_REDUCED) { + int n1 = quad->side[0]->NbPoints(); + int n2 = quad->side[1]->NbPoints(); + int n3 = quad->side[2]->NbPoints(); + int n4 = quad->side[3]->NbPoints(); + int n13 = n1 - n3; + int n24 = n2 - n4; + int n13tmp = n13/2; n13tmp = n13tmp*2; + int n24tmp = n24/2; n24tmp = n24tmp*2; + if ((n1 == n3 && n2 != n4 && n24tmp == n24) || + (n2 == n4 && n1 != n3 && n13tmp == n13)) { + bool ok = ComputeReduced(aMesh, aShape, quad); + return ok; + } + } // set normalized grid on unit square in parametric domain @@ -242,7 +261,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, Handle(Geom_Surface) S = BRep_Tool::Surface(F); // internal mesh nodes - int i, j, geomFaceID = meshDS->ShapeToIndex( F ); + int i, j, geomFaceID = meshDS->ShapeToIndex(F); for (i = 1; i < nbhoriz - 1; i++) { for (j = 1; j < nbvertic - 1; j++) { int ij = j * nbhoriz + i; @@ -287,19 +306,19 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, c = quad->uv_grid[(j + 1) * nbhoriz + i + 1].node; d = quad->uv_grid[(j + 1) * nbhoriz + i].node; SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); - if(face) { + if (face) { meshDS->SetMeshElementOnShape(face, geomFaceID); } } } - const vector& uv_e0 = quad->side[0]->GetUVPtStruct(true,0 ); + const vector& uv_e0 = quad->side[0]->GetUVPtStruct(true,0); const vector& uv_e1 = quad->side[1]->GetUVPtStruct(false,1); - const vector& uv_e2 = quad->side[2]->GetUVPtStruct(true,1 ); + const vector& uv_e2 = quad->side[2]->GetUVPtStruct(true,1); const vector& uv_e3 = quad->side[3]->GetUVPtStruct(false,0); - if ( uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty() ) - return error( COMPERR_BAD_INPUT_MESH ); + if (uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty()) + return error(COMPERR_BAD_INPUT_MESH); double eps = Precision::Confusion(); @@ -364,7 +383,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, if (near == g) { // make triangle SMDS_MeshFace* face = myTool->AddFace(a, b, c); - if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { // make quadrangle if (near - 1 < ilow) @@ -373,9 +392,9 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, d = quad->uv_grid[nbhoriz + near - 1].node; //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); - if(!myTrianglePreference){ + if (!myTrianglePreference){ SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); - if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { SplitQuad(meshDS, geomFaceID, a, b, c, d); @@ -390,7 +409,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, else d = quad->uv_grid[nbhoriz + k - 1].node; SMDS_MeshFace* face = myTool->AddFace(a, c, d); - if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } } g = near; @@ -452,7 +471,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, if (near == g) { // make triangle SMDS_MeshFace* face = myTool->AddFace(a, b, c); - if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { // make quadrangle if (near + 1 > iup) @@ -460,9 +479,9 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, else d = quad->uv_grid[nbhoriz*(nbvertic - 2) + near + 1].node; //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); - if(!myTrianglePreference){ + if (!myTrianglePreference){ SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); - if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { SplitQuad(meshDS, geomFaceID, a, b, c, d); @@ -476,7 +495,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, else d = quad->uv_grid[nbhoriz*(nbvertic - 2) + k + 1].node; SMDS_MeshFace* face = myTool->AddFace(a, c, d); - if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } } g = near; @@ -524,7 +543,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, if (near == g) { // make triangle SMDS_MeshFace* face = myTool->AddFace(a, b, c); - if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { // make quadrangle if (near - 1 < jlow) @@ -533,9 +552,9 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, d = quad->uv_grid[nbhoriz*near - 2].node; //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); - if(!myTrianglePreference){ + if (!myTrianglePreference){ SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); - if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { SplitQuad(meshDS, geomFaceID, a, b, c, d); @@ -549,7 +568,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, else d = quad->uv_grid[nbhoriz*k - 2].node; SMDS_MeshFace* face = myTool->AddFace(a, c, d); - if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } } g = near; @@ -594,7 +613,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, if (near == g) { // make triangle SMDS_MeshFace* face = myTool->AddFace(a, b, c); - if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { // make quadrangle if (near + 1 > jup) @@ -602,9 +621,9 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, else d = quad->uv_grid[nbhoriz*(near + 1) + 1].node; //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d); - if(!myTrianglePreference){ + if (!myTrianglePreference){ SMDS_MeshFace* face = myTool->AddFace(a, b, c, d); - if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } else { SplitQuad(meshDS, geomFaceID, a, b, c, d); @@ -618,7 +637,7 @@ bool StdMeshers_Quadrangle_2D::Compute (SMESH_Mesh& aMesh, else d = quad->uv_grid[nbhoriz*(k + 1) + 1].node; SMDS_MeshFace* face = myTool->AddFace(a, c, d); - if(face) meshDS->SetMeshElementOnShape(face, geomFaceID); + if (face) meshDS->SetMeshElementOnShape(face, geomFaceID); } } g = near; @@ -647,17 +666,17 @@ bool StdMeshers_Quadrangle_2D::Evaluate(SMESH_Mesh& aMesh, std::vector aNbNodes(4); bool IsQuadratic = false; - if( !CheckNbEdgesForEvaluate( aMesh, aShape, aResMap, aNbNodes, IsQuadratic ) ) { + if (!CheckNbEdgesForEvaluate(aMesh, aShape, aResMap, aNbNodes, IsQuadratic)) { std::vector aResVec(SMDSEntity_Last); - for(int i=SMDSEntity_Node; iGetComputeError(); - smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this)); + smError.reset(new SMESH_ComputeError(COMPERR_ALGO_FAILED,"Submesh can not be evaluated",this)); return false; } - if(myQuadranglePreference) { + if (myQuadranglePreference) { int n1 = aNbNodes[0]; int n2 = aNbNodes[1]; int n3 = aNbNodes[2]; @@ -665,7 +684,7 @@ bool StdMeshers_Quadrangle_2D::Evaluate(SMESH_Mesh& aMesh, int nfull = n1+n2+n3+n4; int ntmp = nfull/2; ntmp = ntmp*2; - if( nfull==ntmp && ( (n1!=n3) || (n2!=n4) ) ) { + if (nfull==ntmp && ((n1!=n3) || (n2!=n4))) { // special path for using only quandrangle faces return EvaluateQuadPref(aMesh, aShape, aNbNodes, aResMap, IsQuadratic); //return true; @@ -685,27 +704,27 @@ bool StdMeshers_Quadrangle_2D::Evaluate(SMESH_Mesh& aMesh, int dv = Max(nbright, nbleft) - nbvertic; //int kdh = 0; - //if(dh>0) kdh = 1; + //if (dh>0) kdh = 1; //int kdv = 0; - //if(dv>0) kdv = 1; + //if (dv>0) kdv = 1; int nbNodes = (nbhoriz-2)*(nbvertic-2); //int nbFaces3 = dh + dv + kdh*(nbvertic-1)*2 + kdv*(nbhoriz-1)*2; int nbFaces3 = dh + dv; - //if( kdh==1 && kdv==1 ) nbFaces3 -= 2; - //if( dh>0 && dv>0 ) nbFaces3 -= 2; + //if (kdh==1 && kdv==1) nbFaces3 -= 2; + //if (dh>0 && dv>0) nbFaces3 -= 2; //int nbFaces4 = (nbhoriz-1-kdh)*(nbvertic-1-kdv); int nbFaces4 = (nbhoriz-1)*(nbvertic-1); std::vector aVec(SMDSEntity_Last); - for(int i=SMDSEntity_Node; i= TopAbs_INTERNAL ) F.Orientation( TopAbs_FORWARD ); const bool ignoreMediumNodes = _quadraticMesh; // verify 1 wire only, with 4 edges @@ -775,113 +795,113 @@ FaceQuadStruct* StdMeshers_Quadrangle_2D::CheckNbEdges(SMESH_Mesh & aMes int nbSides = 0; list< TopoDS_Edge >::iterator edgeIt = edges.begin(); - if ( nbEdgesInWire.front() == 3 ) // exactly 3 edges + if (nbEdgesInWire.front() == 3) // exactly 3 edges { SMESH_Comment comment; SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); - if ( myTriaVertexID == -1) + if (myTriaVertexID == -1) { comment << "No Base vertex parameter provided for a trilateral geometrical face"; } else { TopoDS_Vertex V = TopoDS::Vertex(meshDS->IndexToShape(myTriaVertexID)); - if ( !V.IsNull() ) { + if (!V.IsNull()) { TopoDS_Edge E1,E2,E3; - for(; edgeIt != edges.end(); ++edgeIt) { + for (; edgeIt != edges.end(); ++edgeIt) { TopoDS_Edge E = *edgeIt; TopoDS_Vertex VF, VL; TopExp::Vertices(E, VF, VL, true); - if( VF.IsSame(V) ) + if (VF.IsSame(V)) E1 = E; - else if( VL.IsSame(V) ) + else if (VL.IsSame(V)) E3 = E; else E2 = E; } - if ( !E1.IsNull() && !E2.IsNull() && !E3.IsNull() ) + if (!E1.IsNull() && !E2.IsNull() && !E3.IsNull()) { - quad->side.push_back( new StdMeshers_FaceSide(F, E1, &aMesh, true, ignoreMediumNodes)); - quad->side.push_back( new StdMeshers_FaceSide(F, E2, &aMesh, true, ignoreMediumNodes)); - quad->side.push_back( new StdMeshers_FaceSide(F, E3, &aMesh, false,ignoreMediumNodes)); + quad->side.push_back(new StdMeshers_FaceSide(F, E1, &aMesh, true, ignoreMediumNodes)); + quad->side.push_back(new StdMeshers_FaceSide(F, E2, &aMesh, true, ignoreMediumNodes)); + quad->side.push_back(new StdMeshers_FaceSide(F, E3, &aMesh, false,ignoreMediumNodes)); const vector& UVPSleft = quad->side[0]->GetUVPtStruct(true,0); /* vector& UVPStop = */quad->side[1]->GetUVPtStruct(false,1); /* vector& UVPSright = */quad->side[2]->GetUVPtStruct(true,1); const SMDS_MeshNode* aNode = UVPSleft[0].node; - gp_Pnt2d aPnt2d( UVPSleft[0].u, UVPSleft[0].v ); - quad->side.push_back( new StdMeshers_FaceSide(aNode, aPnt2d, quad->side[1])); + gp_Pnt2d aPnt2d(UVPSleft[0].u, UVPSleft[0].v); + quad->side.push_back(new StdMeshers_FaceSide(aNode, aPnt2d, quad->side[1])); return quad; } } comment << "Invalid Base vertex parameter: " << myTriaVertexID << " is not among ["; TopTools_MapOfShape vMap; - for ( TopExp_Explorer v( aShape, TopAbs_VERTEX ); v.More(); v.Next()) - if ( vMap.Add( v.Current() )) - comment << meshDS->ShapeToIndex( v.Current() ) << ( vMap.Extent()==3 ? "]" : ", "); + for (TopExp_Explorer v(aShape, TopAbs_VERTEX); v.More(); v.Next()) + if (vMap.Add(v.Current())) + comment << meshDS->ShapeToIndex(v.Current()) << (vMap.Extent()==3 ? "]" : ", "); } - error( comment ); + error(comment); delete quad; return quad = 0; } - else if ( nbEdgesInWire.front() == 4 ) { // exactly 4 edges - for ( ; edgeIt != edges.end(); ++edgeIt, nbSides++ ) - quad->side.push_back( new StdMeshers_FaceSide(F, *edgeIt, &aMesh, + else if (nbEdgesInWire.front() == 4) { // exactly 4 edges + for (; edgeIt != edges.end(); ++edgeIt, nbSides++) + quad->side.push_back(new StdMeshers_FaceSide(F, *edgeIt, &aMesh, nbSides 4 ) { // more than 4 edges - try to unite some + else if (nbEdgesInWire.front() > 4) { // more than 4 edges - try to unite some list< TopoDS_Edge > sideEdges; - while ( !edges.empty()) { + while (!edges.empty()) { sideEdges.clear(); - sideEdges.splice( sideEdges.end(), edges, edges.begin()); // edges.front() -> sideEdges.end() + sideEdges.splice(sideEdges.end(), edges, edges.begin()); // edges.front() -> sideEdges.end() bool sameSide = true; - while ( !edges.empty() && sameSide ) { - sameSide = SMESH_Algo::IsContinuous( sideEdges.back(), edges.front() ); - if ( sameSide ) - sideEdges.splice( sideEdges.end(), edges, edges.begin()); + while (!edges.empty() && sameSide) { + sameSide = SMESH_Algo::IsContinuous(sideEdges.back(), edges.front()); + if (sameSide) + sideEdges.splice(sideEdges.end(), edges, edges.begin()); } - if ( nbSides == 0 ) { // go backward from the first edge + if (nbSides == 0) { // go backward from the first edge sameSide = true; - while ( !edges.empty() && sameSide ) { - sameSide = SMESH_Algo::IsContinuous( sideEdges.front(), edges.back() ); - if ( sameSide ) - sideEdges.splice( sideEdges.begin(), edges, --edges.end()); + while (!edges.empty() && sameSide) { + sameSide = SMESH_Algo::IsContinuous(sideEdges.front(), edges.back()); + if (sameSide) + sideEdges.splice(sideEdges.begin(), edges, --edges.end()); } } - quad->side.push_back( new StdMeshers_FaceSide(F, sideEdges, &aMesh, + quad->side.push_back(new StdMeshers_FaceSide(F, sideEdges, &aMesh, nbSidesside.clear(); quad->side.reserve(nbEdgesInWire.front()); nbSides = 0; SMESH_Block::GetOrderedEdges (F, V, edges, nbEdgesInWire); - while ( !edges.empty()) { + while (!edges.empty()) { sideEdges.clear(); - sideEdges.splice( sideEdges.end(), edges, edges.begin()); + sideEdges.splice(sideEdges.end(), edges, edges.begin()); bool sameSide = true; - while ( !edges.empty() && sameSide ) { + while (!edges.empty() && sameSide) { sameSide = - SMESH_Algo::IsContinuous( sideEdges.back(), edges.front() ) && - twoEdgesMeatAtVertex( sideEdges.back(), edges.front(), aMesh ); - if ( sameSide ) - sideEdges.splice( sideEdges.end(), edges, edges.begin()); + SMESH_Algo::IsContinuous(sideEdges.back(), edges.front()) && + twoEdgesMeatAtVertex(sideEdges.back(), edges.front(), aMesh); + if (sameSide) + sideEdges.splice(sideEdges.end(), edges, edges.begin()); } - if ( nbSides == 0 ) { // go backward from the first edge + if (nbSides == 0) { // go backward from the first edge sameSide = true; - while ( !edges.empty() && sameSide ) { + while (!edges.empty() && sameSide) { sameSide = - SMESH_Algo::IsContinuous( sideEdges.front(), edges.back() ) && - twoEdgesMeatAtVertex( sideEdges.front(), edges.back(), aMesh ); - if ( sameSide ) - sideEdges.splice( sideEdges.begin(), edges, --edges.end()); + SMESH_Algo::IsContinuous(sideEdges.front(), edges.back()) && + twoEdgesMeatAtVertex(sideEdges.front(), edges.back(), aMesh); + if (sameSide) + sideEdges.splice(sideEdges.begin(), edges, --edges.end()); } } - quad->side.push_back( new StdMeshers_FaceSide(F, sideEdges, &aMesh, + quad->side.push_back(new StdMeshers_FaceSide(F, sideEdges, &aMesh, nbSidesside[i]->NbEdges(); ++e ) - MESSAGE ( myTool->GetMeshDS()->ShapeToIndex( quad->side[i]->Edge( e )) << " " ); - MESSAGE ( ")\n" ); + MESSAGE ("StdMeshers_Quadrangle_2D. Edge IDs of " << nbSides << " sides:\n"); + for (int i = 0; i < nbSides; ++i) { + MESSAGE (" ("); + for (int e = 0; e < quad->side[i]->NbEdges(); ++e) + MESSAGE (myTool->GetMeshDS()->ShapeToIndex(quad->side[i]->Edge(e)) << " "); + MESSAGE (")\n"); } //cout << endl; #endif - if ( !nbSides ) + if (!nbSides) nbSides = nbEdgesInWire.front(); error(COMPERR_BAD_SHAPE, TComm("Face must have 4 sides but not ") << nbSides); delete quad; @@ -937,51 +957,51 @@ bool StdMeshers_Quadrangle_2D::CheckNbEdgesForEvaluate(SMESH_Mesh& aMesh, int nbSides = 0; list< TopoDS_Edge >::iterator edgeIt = edges.begin(); - SMESH_subMesh * sm = aMesh.GetSubMesh( *edgeIt ); + SMESH_subMesh * sm = aMesh.GetSubMesh(*edgeIt); MapShapeNbElemsItr anIt = aResMap.find(sm); - if(anIt==aResMap.end()) { + if (anIt==aResMap.end()) { return false; } std::vector aVec = (*anIt).second; IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]); - if ( nbEdgesInWire.front() == 3 ) { // exactly 3 edges - if(myTriaVertexID>0) { + if (nbEdgesInWire.front() == 3) { // exactly 3 edges + if (myTriaVertexID>0) { SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); TopoDS_Vertex V = TopoDS::Vertex(meshDS->IndexToShape(myTriaVertexID)); - if(!V.IsNull()) { + if (!V.IsNull()) { TopoDS_Edge E1,E2,E3; - for(; edgeIt != edges.end(); ++edgeIt) { + for (; edgeIt != edges.end(); ++edgeIt) { TopoDS_Edge E = TopoDS::Edge(*edgeIt); TopoDS_Vertex VF, VL; TopExp::Vertices(E, VF, VL, true); - if( VF.IsSame(V) ) + if (VF.IsSame(V)) E1 = E; - else if( VL.IsSame(V) ) + else if (VL.IsSame(V)) E3 = E; else E2 = E; } SMESH_subMesh * sm = aMesh.GetSubMesh(E1); MapShapeNbElemsItr anIt = aResMap.find(sm); - if(anIt==aResMap.end()) return false; + if (anIt==aResMap.end()) return false; std::vector aVec = (*anIt).second; - if(IsQuadratic) + if (IsQuadratic) aNbNodes[0] = (aVec[SMDSEntity_Node]-1)/2 + 2; else aNbNodes[0] = aVec[SMDSEntity_Node] + 2; sm = aMesh.GetSubMesh(E2); anIt = aResMap.find(sm); - if(anIt==aResMap.end()) return false; + if (anIt==aResMap.end()) return false; aVec = (*anIt).second; - if(IsQuadratic) + if (IsQuadratic) aNbNodes[1] = (aVec[SMDSEntity_Node]-1)/2 + 2; else aNbNodes[1] = aVec[SMDSEntity_Node] + 2; sm = aMesh.GetSubMesh(E3); anIt = aResMap.find(sm); - if(anIt==aResMap.end()) return false; + if (anIt==aResMap.end()) return false; aVec = (*anIt).second; - if(IsQuadratic) + if (IsQuadratic) aNbNodes[2] = (aVec[SMDSEntity_Node]-1)/2 + 2; else aNbNodes[2] = aVec[SMDSEntity_Node] + 2; @@ -991,50 +1011,50 @@ bool StdMeshers_Quadrangle_2D::CheckNbEdgesForEvaluate(SMESH_Mesh& aMesh, } } } - if ( nbEdgesInWire.front() == 4 ) { // exactly 4 edges - for(; edgeIt != edges.end(); edgeIt++) { - SMESH_subMesh * sm = aMesh.GetSubMesh( *edgeIt ); + if (nbEdgesInWire.front() == 4) { // exactly 4 edges + for (; edgeIt != edges.end(); edgeIt++) { + SMESH_subMesh * sm = aMesh.GetSubMesh(*edgeIt); MapShapeNbElemsItr anIt = aResMap.find(sm); - if(anIt==aResMap.end()) { + if (anIt==aResMap.end()) { return false; } std::vector aVec = (*anIt).second; - if(IsQuadratic) + if (IsQuadratic) aNbNodes[nbSides] = (aVec[SMDSEntity_Node]-1)/2 + 2; else aNbNodes[nbSides] = aVec[SMDSEntity_Node] + 2; nbSides++; } } - else if ( nbEdgesInWire.front() > 4 ) { // more than 4 edges - try to unite some + else if (nbEdgesInWire.front() > 4) { // more than 4 edges - try to unite some list< TopoDS_Edge > sideEdges; - while ( !edges.empty()) { + while (!edges.empty()) { sideEdges.clear(); - sideEdges.splice( sideEdges.end(), edges, edges.begin()); // edges.front() -> sideEdges.end() + sideEdges.splice(sideEdges.end(), edges, edges.begin()); // edges.front() -> sideEdges.end() bool sameSide = true; - while ( !edges.empty() && sameSide ) { - sameSide = SMESH_Algo::IsContinuous( sideEdges.back(), edges.front() ); - if ( sameSide ) - sideEdges.splice( sideEdges.end(), edges, edges.begin()); + while (!edges.empty() && sameSide) { + sameSide = SMESH_Algo::IsContinuous(sideEdges.back(), edges.front()); + if (sameSide) + sideEdges.splice(sideEdges.end(), edges, edges.begin()); } - if ( nbSides == 0 ) { // go backward from the first edge + if (nbSides == 0) { // go backward from the first edge sameSide = true; - while ( !edges.empty() && sameSide ) { - sameSide = SMESH_Algo::IsContinuous( sideEdges.front(), edges.back() ); - if ( sameSide ) - sideEdges.splice( sideEdges.begin(), edges, --edges.end()); + while (!edges.empty() && sameSide) { + sameSide = SMESH_Algo::IsContinuous(sideEdges.front(), edges.back()); + if (sameSide) + sideEdges.splice(sideEdges.begin(), edges, --edges.end()); } } list::iterator ite = sideEdges.begin(); aNbNodes[nbSides] = 1; - for(; ite!=sideEdges.end(); ite++) { - SMESH_subMesh * sm = aMesh.GetSubMesh( *ite ); + for (; ite!=sideEdges.end(); ite++) { + SMESH_subMesh * sm = aMesh.GetSubMesh(*ite); MapShapeNbElemsItr anIt = aResMap.find(sm); - if(anIt==aResMap.end()) { + if (anIt==aResMap.end()) { return false; } std::vector aVec = (*anIt).second; - if(IsQuadratic) + if (IsQuadratic) aNbNodes[nbSides] += (aVec[SMDSEntity_Node]-1)/2 + 1; else aNbNodes[nbSides] += aVec[SMDSEntity_Node] + 1; @@ -1045,37 +1065,37 @@ bool StdMeshers_Quadrangle_2D::CheckNbEdgesForEvaluate(SMESH_Mesh& aMesh, if (nbSides < 4) { nbSides = 0; SMESH_Block::GetOrderedEdges (F, V, edges, nbEdgesInWire); - while ( !edges.empty()) { + while (!edges.empty()) { sideEdges.clear(); - sideEdges.splice( sideEdges.end(), edges, edges.begin()); + sideEdges.splice(sideEdges.end(), edges, edges.begin()); bool sameSide = true; - while ( !edges.empty() && sameSide ) { + while (!edges.empty() && sameSide) { sameSide = - SMESH_Algo::IsContinuous( sideEdges.back(), edges.front() ) && - twoEdgesMeatAtVertex( sideEdges.back(), edges.front(), aMesh ); - if ( sameSide ) - sideEdges.splice( sideEdges.end(), edges, edges.begin()); + SMESH_Algo::IsContinuous(sideEdges.back(), edges.front()) && + twoEdgesMeatAtVertex(sideEdges.back(), edges.front(), aMesh); + if (sameSide) + sideEdges.splice(sideEdges.end(), edges, edges.begin()); } - if ( nbSides == 0 ) { // go backward from the first edge + if (nbSides == 0) { // go backward from the first edge sameSide = true; - while ( !edges.empty() && sameSide ) { + while (!edges.empty() && sameSide) { sameSide = - SMESH_Algo::IsContinuous( sideEdges.front(), edges.back() ) && - twoEdgesMeatAtVertex( sideEdges.front(), edges.back(), aMesh ); - if ( sameSide ) - sideEdges.splice( sideEdges.begin(), edges, --edges.end()); + SMESH_Algo::IsContinuous(sideEdges.front(), edges.back()) && + twoEdgesMeatAtVertex(sideEdges.front(), edges.back(), aMesh); + if (sameSide) + sideEdges.splice(sideEdges.begin(), edges, --edges.end()); } } list::iterator ite = sideEdges.begin(); aNbNodes[nbSides] = 1; - for(; ite!=sideEdges.end(); ite++) { - SMESH_subMesh * sm = aMesh.GetSubMesh( *ite ); + for (; ite!=sideEdges.end(); ite++) { + SMESH_subMesh * sm = aMesh.GetSubMesh(*ite); MapShapeNbElemsItr anIt = aResMap.find(sm); - if(anIt==aResMap.end()) { + if (anIt==aResMap.end()) { return false; } std::vector aVec = (*anIt).second; - if(IsQuadratic) + if (IsQuadratic) aNbNodes[nbSides] += (aVec[SMDSEntity_Node]-1)/2 + 1; else aNbNodes[nbSides] += aVec[SMDSEntity_Node] + 1; @@ -1085,7 +1105,7 @@ bool StdMeshers_Quadrangle_2D::CheckNbEdgesForEvaluate(SMESH_Mesh& aMesh, } } if (nbSides != 4) { - if ( !nbSides ) + if (!nbSides) nbSides = nbEdgesInWire.front(); error(COMPERR_BAD_SHAPE, TComm("Face must have 4 sides but not ") << nbSides); return false; @@ -1110,13 +1130,12 @@ FaceQuadStruct *StdMeshers_Quadrangle_2D::CheckAnd2Dcompute FaceQuadStruct *quad = CheckNbEdges(aMesh, aShape); - if(!quad) return 0; + if (!quad) return 0; // set normalized grid on unit square in parametric domain bool stat = SetNormalizedGrid(aMesh, aShape, quad); - if(!stat) { - if(!quad) - delete quad; + if (!stat) { + if (quad) delete quad; quad = 0; } @@ -1140,13 +1159,21 @@ faceQuadStruct::~faceQuadStruct() namespace { inline const vector& GetUVPtStructIn(FaceQuadStruct* quad, int i, int nbSeg) { - bool isXConst = ( i == BOTTOM_SIDE || i == TOP_SIDE ); - double constValue = ( i == BOTTOM_SIDE || i == LEFT_SIDE ) ? 0 : 1; + bool isXConst = (i == BOTTOM_SIDE || i == TOP_SIDE); + double constValue = (i == BOTTOM_SIDE || i == LEFT_SIDE) ? 0 : 1; return quad->isEdgeOut[i] ? quad->side[i]->SimulateUVPtStruct(nbSeg,isXConst,constValue) : quad->side[i]->GetUVPtStruct(isXConst,constValue); } + inline gp_UV CalcUV(double x, double y, + const gp_UV& a0,const gp_UV& a1,const gp_UV& a2,const gp_UV& a3, + const gp_UV& p0,const gp_UV& p1,const gp_UV& p2,const gp_UV& p3) + { + return + ((1 - y) * p0 + x * p1 + y * p2 + (1 - x) * p3 ) - + ((1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3); + } } //============================================================================= @@ -1193,14 +1220,14 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh, UVPtStruct *uv_grid = quad->uv_grid = new UVPtStruct[nbvertic * nbhoriz]; - const vector& uv_e0 = GetUVPtStructIn( quad, 0, nbhoriz - 1 ); - const vector& uv_e1 = GetUVPtStructIn( quad, 1, nbvertic - 1 ); - const vector& uv_e2 = GetUVPtStructIn( quad, 2, nbhoriz - 1 ); - const vector& uv_e3 = GetUVPtStructIn( quad, 3, nbvertic - 1 ); + const vector& uv_e0 = GetUVPtStructIn(quad, 0, nbhoriz - 1); + const vector& uv_e1 = GetUVPtStructIn(quad, 1, nbvertic - 1); + const vector& uv_e2 = GetUVPtStructIn(quad, 2, nbhoriz - 1); + const vector& uv_e3 = GetUVPtStructIn(quad, 3, nbvertic - 1); - if ( uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty() ) - //return error( "Can't find nodes on sides"); - return error( COMPERR_BAD_INPUT_MESH ); + if (uv_e0.empty() || uv_e1.empty() || uv_e2.empty() || uv_e3.empty()) + //return error("Can't find nodes on sides"); + return error(COMPERR_BAD_INPUT_MESH); // nodes Id on "in" edges if (! quad->isEdgeOut[0]) { @@ -1253,10 +1280,10 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh, } // 4 --- projection on 2d domain (u,v) - gp_UV a0( uv_e0.front().u, uv_e0.front().v ); - gp_UV a1( uv_e0.back().u, uv_e0.back().v ); - gp_UV a2( uv_e2.back().u, uv_e2.back().v ); - gp_UV a3( uv_e2.front().u, uv_e2.front().v ); + gp_UV a0(uv_e0.front().u, uv_e0.front().v); + gp_UV a1(uv_e0.back().u, uv_e0.back().v); + gp_UV a2(uv_e2.back().u, uv_e2.back().v); + gp_UV a3(uv_e2.front().u, uv_e2.front().v); for (int i = 0; i < nbhoriz; i++) { for (int j = 0; j < nbvertic; j++) { @@ -1274,8 +1301,7 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh, gp_UV p2 = quad->side[2]->Value2d(param_2).XY(); gp_UV p3 = quad->side[3]->Value2d(param_3).XY(); - gp_UV uv = (1 - y) * p0 + x * p1 + y * p2 + (1 - x) * p3; - uv -= (1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3; + gp_UV uv = CalcUV(x,y, a0,a1,a2,a3, p0,p1,p2,p3); uv_grid[ij].u = uv.X(); uv_grid[ij].v = uv.Y(); @@ -1292,11 +1318,11 @@ bool StdMeshers_Quadrangle_2D::SetNormalizedGrid (SMESH_Mesh & aMesh, static void ShiftQuad(FaceQuadStruct* quad, const int num, bool) { StdMeshers_FaceSide* side[4] = { quad->side[0], quad->side[1], quad->side[2], quad->side[3] }; - for (int i = BOTTOM_SIDE; i < NB_SIDES; ++i ) { - int id = ( i + num ) % NB_SIDES; - bool wasForward = ( i < TOP_SIDE ); - bool newForward = ( id < TOP_SIDE ); - if ( wasForward != newForward ) + for (int i = BOTTOM_SIDE; i < NB_SIDES; ++i) { + int id = (i + num) % NB_SIDES; + bool wasForward = (i < TOP_SIDE); + bool newForward = (id < TOP_SIDE); + if (wasForward != newForward) side[ i ]->Reverse(); quad->side[ id ] = side[ i ]; } @@ -1312,9 +1338,9 @@ static gp_UV CalcUV(double x0, double x1, double y0, double y1, const gp_UV& a0, const gp_UV& a1, const gp_UV& a2, const gp_UV& a3) { - const vector& uv_eb = quad->side[0]->GetUVPtStruct(true,0 ); + const vector& uv_eb = quad->side[0]->GetUVPtStruct(true,0); const vector& uv_er = quad->side[1]->GetUVPtStruct(false,1); - const vector& uv_et = quad->side[2]->GetUVPtStruct(true,1 ); + const vector& uv_et = quad->side[2]->GetUVPtStruct(true,1); const vector& uv_el = quad->side[3]->GetUVPtStruct(false,0); double x = (x0 + y0 * (x1 - x0)) / (1 - (y1 - y0) * (x1 - x0)); @@ -1330,9 +1356,7 @@ static gp_UV CalcUV(double x0, double x1, double y0, double y1, gp_UV p2 = quad->side[TOP_SIDE ]->Value2d(param_t).XY(); gp_UV p3 = quad->side[LEFT_SIDE ]->Value2d(param_l).XY(); - gp_UV uv = p0 * (1 - y) + p1 * x + p2 * y + p3 * (1 - x); - - uv -= (1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3; + gp_UV uv = CalcUV(x,y, a0,a1,a2,a3, p0,p1,p2,p3); return uv; } @@ -1347,27 +1371,12 @@ static gp_UV CalcUV2(double x, double y, const gp_UV& a0, const gp_UV& a1, const gp_UV& a2, const gp_UV& a3) { - const vector& uv_eb = quad->side[0]->GetUVPtStruct(true,0 ); - const vector& uv_er = quad->side[1]->GetUVPtStruct(false,1); - const vector& uv_et = quad->side[2]->GetUVPtStruct(true,1 ); - const vector& uv_el = quad->side[3]->GetUVPtStruct(false,0); - - //double x = (x0 + y0 * (x1 - x0)) / (1 - (y1 - y0) * (x1 - x0)); - //double y = y0 + x * (y1 - y0); - - double param_b = uv_eb[0].normParam + x * (uv_eb.back().normParam - uv_eb[0].normParam); - double param_t = uv_et[0].normParam + x * (uv_et.back().normParam - uv_et[0].normParam); - double param_r = uv_er[0].normParam + y * (uv_er.back().normParam - uv_er[0].normParam); - double param_l = uv_el[0].normParam + y * (uv_el.back().normParam - uv_el[0].normParam); - - gp_UV p0 = quad->side[BOTTOM_SIDE]->Value2d(param_b).XY(); - gp_UV p1 = quad->side[RIGHT_SIDE ]->Value2d(param_r).XY(); - gp_UV p2 = quad->side[TOP_SIDE ]->Value2d(param_t).XY(); - gp_UV p3 = quad->side[LEFT_SIDE ]->Value2d(param_l).XY(); + gp_UV p0 = quad->side[BOTTOM_SIDE]->Value2d(x).XY(); + gp_UV p1 = quad->side[RIGHT_SIDE ]->Value2d(y).XY(); + gp_UV p2 = quad->side[TOP_SIDE ]->Value2d(x).XY(); + gp_UV p3 = quad->side[LEFT_SIDE ]->Value2d(y).XY(); - gp_UV uv = p0 * (1 - y) + p1 * x + p2 * y + p3 * (1 - x); - - uv -= (1 - x) * (1 - y) * a0 + x * (1 - y) * a1 + x * y * a2 + (1 - x) * y * a3; + gp_UV uv = CalcUV(x,y, a0,a1,a2,a3, p0,p1,p2,p3); return uv; } @@ -1387,20 +1396,14 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, // of meshing after implementation new variant // for bug 0016220 from Mantis. bool OldVersion = false; + if (myQuadType == QUAD_QUADRANGLE_PREF_REVERSED) + OldVersion = true; SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); const TopoDS_Face& F = TopoDS::Face(aShape); Handle(Geom_Surface) S = BRep_Tool::Surface(F); -// const TopoDS_Wire& W = BRepTools::OuterWire(F); bool WisF = true; -// if(W.Orientation()==TopAbs_FORWARD) -// WisF = true; - //if(WisF) cout<<"W is FORWARD"<ShapeToIndex( F ); + int i,j,geomFaceID = meshDS->ShapeToIndex(F); int nb = quad->side[0]->NbPoints(); int nr = quad->side[1]->NbPoints(); @@ -1409,8 +1412,8 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, int dh = abs(nb-nt); int dv = abs(nr-nl); - if( dh>=dv ) { - if( nt>nb ) { + if (dh>=dv) { + if (nt>nb) { // it is a base case => not shift quad but me be replacement is need ShiftQuad(quad,0,WisF); } @@ -1420,7 +1423,7 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, } } else { - if( nr>nl ) { + if (nr>nl) { // we have to shift quad on 1 ShiftQuad(quad,1,WisF); } @@ -1469,7 +1472,7 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, // 0------------0 // 0 bottom 1 - if(dh>dv) { + if (dh>dv) { addv = (dh-dv)/2; nbv = nbv + addv; } @@ -1478,82 +1481,81 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, nbh = nbh + addh; } - const vector& uv_eb = quad->side[0]->GetUVPtStruct(true,0 ); + const vector& uv_eb = quad->side[0]->GetUVPtStruct(true,0); const vector& uv_er = quad->side[1]->GetUVPtStruct(false,1); - const vector& uv_et = quad->side[2]->GetUVPtStruct(true,1 ); + const vector& uv_et = quad->side[2]->GetUVPtStruct(true,1); const vector& uv_el = quad->side[3]->GetUVPtStruct(false,0); - if ( uv_eb.size() != nb || uv_er.size() != nr || uv_et.size() != nt || uv_el.size() != nl ) - return error( COMPERR_BAD_INPUT_MESH ); + if (uv_eb.size() != nb || uv_er.size() != nr || uv_et.size() != nt || uv_el.size() != nl) + return error(COMPERR_BAD_INPUT_MESH); // arrays for normalized params //cout<<"Dump B:"<X()<<","<Y()<<","<Z()<<")"<0) { + if (dl>0) { // add top nodes - for(i=1; i<=dl; i++) + for (i=1; i<=dl; i++) NodesL.SetValue(i+1,nl,uv_et[i].node); // create and add needed nodes TColgp_SequenceOfXY UVtmp; - for(i=1; i<=dl; i++) { + for (i=1; i<=dl; i++) { double x0 = npt.Value(i+1); double x1 = x0; // diagonal node @@ -1564,9 +1566,9 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, SMDS_MeshNode * N = meshDS->AddNode(P.X(), P.Y(), P.Z()); meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); NodesL.SetValue(i+1,1,N); - if(UVL.Length()AddNode(P.X(), P.Y(), P.Z()); meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); NodesL.SetValue(i+1,j,N); - if( i==dl ) UVtmp.Append(UV); + if (i==dl) UVtmp.Append(UV); } } - for(i=1; i<=UVtmp.Length() && UVL.Length()X()<<","<Y()<<","<Z()<<")"; // } // cout<AddFace(NodesL.Value(i,j), NodesL.Value(i+1,j), NodesL.Value(i+1,j+1), NodesL.Value(i,j+1)); - if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = myTool->AddFace(NodesL.Value(i,j), NodesL.Value(i,j+1), NodesL.Value(i+1,j+1), NodesL.Value(i+1,j)); - if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } } } } else { // fill UVL using c2d - for(i=1; i0) { + if (dr>0) { // add top nodes - for(i=1; i<=dr; i++) + for (i=1; i<=dr; i++) NodesR.SetValue(i+1,1,uv_et[nt-1-i].node); // create and add needed nodes TColgp_SequenceOfXY UVtmp; - for(i=1; i<=dr; i++) { + for (i=1; i<=dr; i++) { double x0 = npt.Value(nt-i); double x1 = x0; // diagonal node @@ -1635,9 +1637,9 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, SMDS_MeshNode * N = meshDS->AddNode(P.X(), P.Y(), P.Z()); meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); NodesR.SetValue(i+1,nr,N); - if(UVR.Length()AddNode(P.X(), P.Y(), P.Z()); meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); NodesR.SetValue(i+1,j,N); - if( i==dr ) UVtmp.Prepend(UV); + if (i==dr) UVtmp.Prepend(UV); } } - for(i=1; i<=UVtmp.Length() && UVR.Length()AddFace(NodesR.Value(i,j), NodesR.Value(i+1,j), NodesR.Value(i+1,j+1), NodesR.Value(i,j+1)); - if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = myTool->AddFace(NodesR.Value(i,j), NodesR.Value(i,j+1), NodesR.Value(i+1,j+1), NodesR.Value(i+1,j)); - if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } } } } else { // fill UVR using c2d - for(i=1; iAddNode(P.X(), P.Y(), P.Z()); meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); NodesC.SetValue(i,nbv-nnn+j,N); + if ( j==1 ) + UVT.Append( UV ); } } // add diagonal layers //cout<<"UVL.Length()="<Value(u,v); + gp_UV A2 = UVR.Value(nbv-nnn); + gp_UV A3 = UVL.Value(nbv-nnn); + for (i=1; iValue(UV.X(),UV.Y()); SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z()); - meshDS->SetNodeOnFace(N, geomFaceID, u, v); + meshDS->SetNodeOnFace(N, geomFaceID, UV.X(),UV.Y()); NodesC.SetValue(j,i+1,N); } } // create faces - for(i=1; iAddFace(NodesC.Value(i,j), NodesC.Value(i+1,j), NodesC.Value(i+1,j+1), NodesC.Value(i,j+1)); - if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i,j+1), NodesC.Value(i+1,j+1), NodesC.Value(i+1,j)); - if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } } } @@ -1752,39 +1761,35 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, // step1: create faces for bottom rectangle domain StdMeshers_Array2OfNode NodesBRD(1,nb,1,nnn-1); // fill UVL and UVR using c2d - for(j=0; jValue(u,v); + for (j=2; jValue(UV.X(),UV.Y()); SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z()); - meshDS->SetNodeOnFace(N, geomFaceID, u, v); + meshDS->SetNodeOnFace(N, geomFaceID, UV.X(),UV.Y()); NodesBRD.SetValue(j,i+1,N); - } } - int nbf=0; - for(j=1; jAddFace(NodesBRD.Value(i,j), NodesBRD.Value(i+1,j), NodesBRD.Value(i+1,j+1), NodesBRD.Value(i,j+1)); - if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = myTool->AddFace(NodesBRD.Value(i,j), NodesBRD.Value(i,j+1), NodesBRD.Value(i+1,j+1), NodesBRD.Value(i+1,j)); - if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } } } @@ -1792,19 +1797,19 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, // create faces for region C StdMeshers_Array2OfNode NodesC(1,nb,1,drl+1+addv); // add nodes from previous region - for(j=1; j<=nb; j++) { + for (j=1; j<=nb; j++) { NodesC.SetValue(j,1,NodesBRD.Value(j,nnn-1)); } - if( (drl+addv) > 0 ) { + if ((drl+addv) > 0) { int n1,n2; - if(nr>nl) { + if (nr>nl) { n1 = 1; n2 = drl + 1; TColgp_SequenceOfXY UVtmp; double drparam = npr.Value(nr) - npr.Value(nnn-1); double dlparam = npl.Value(nnn) - npl.Value(nnn-1); double y0,y1; - for(i=1; i<=drl; i++) { + for (i=1; i<=drl; i++) { // add existed nodes from right edge NodesC.SetValue(nb,i+1,uv_er[nnn+i-2].node); //double dtparam = npt.Value(i+1); @@ -1812,7 +1817,7 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, double dpar = (y1 - npr.Value(nnn-1))/drparam; y0 = npl.Value(nnn-1) + dpar*dlparam; // param on left edge double dy = y1 - y0; - for(j=1; jValue(UV.X(),UV.Y()); @@ -1848,14 +1853,14 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, double drparam = npr.Value(nnn) - npr.Value(nnn-1); double y0 = npl.Value(nnn-1); double y1 = npr.Value(nnn-1); - for(i=1; i<=drl; i++) { + for (i=1; i<=drl; i++) { // add existed nodes from right edge NodesC.SetValue(1,i+1,uv_el[nnn+i-2].node); y0 = npl.Value(nnn+i-1); // param on left edge double dpar = (y0 - npl.Value(nnn-1))/dlparam; y1 = npr.Value(nnn-1) + dpar*drparam; // param on right edge double dy = y1 - y0; - for(j=2; j<=nb; j++) { + for (j=2; j<=nb; j++) { double x = npb.Value(j)*npt.Value(nt-i); double y = y0 + dy*x; gp_UV UV = CalcUV2(x, y, quad, a0, a1, a2, a3); @@ -1867,13 +1872,13 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, } double dy0 = (1-y0)/(addv+1); double dy1 = (1-y1)/(addv+1); - for(i=1; i<=addv; i++) { + for (i=1; i<=addv; i++) { double yy0 = y0 + dy0*i; double yy1 = y1 + dy1*i; double dyy = yy1 - yy0; - for(j=1; j<=nb; j++) { + for (j=1; j<=nb; j++) { double x = npt.Value(i+1) + - npb.Value(j) * ( npt.Value(nt-i-drl) - npt.Value(i+1) ); + npb.Value(j) * (npt.Value(nt-i-drl) - npt.Value(i+1)); double y = yy0 + dyy*x; gp_UV UV = CalcUV2(x, y, quad, a0, a1, a2, a3); gp_Pnt P = S->Value(UV.X(),UV.Y()); @@ -1884,57 +1889,55 @@ bool StdMeshers_Quadrangle_2D::ComputeQuadPref (SMESH_Mesh & aMesh, } } // create faces - for(j=1; j<=drl+addv; j++) { - for(i=1; iAddFace(NodesC.Value(i,j), NodesC.Value(i+1,j), NodesC.Value(i+1,j+1), NodesC.Value(i,j+1)); - if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i,j+1), NodesC.Value(i+1,j+1), NodesC.Value(i+1,j)); - if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } } } // end nr=n2; i--) { + for (i=drl+addv; i>=n2; i--) { nnn++; NodesLast.SetValue(nnn,1,NodesC.Value(nb,i)); } - for(i=1; iAddFace(NodesLast.Value(i,1), NodesLast.Value(i+1,1), NodesLast.Value(i+1,2), NodesLast.Value(i,2)); - if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } else { SMDS_MeshFace* F = myTool->AddFace(NodesLast.Value(i,1), NodesLast.Value(i,2), NodesLast.Value(i+1,2), NodesLast.Value(i+1,2)); - if(F) meshDS->SetMeshElementOnShape(F, geomFaceID); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); } } - } // if( (drl+addv) > 0 ) + } // if ((drl+addv) > 0) } // end new version implementation @@ -1959,6 +1962,8 @@ bool StdMeshers_Quadrangle_2D::EvaluateQuadPref(SMESH_Mesh & aMesh, // of meshing after implementation new variant // for bug 0016220 from Mantis. bool OldVersion = false; + if (myQuadType == QUAD_QUADRANGLE_PREF_REVERSED) + OldVersion = true; const TopoDS_Face& F = TopoDS::Face(aShape); Handle(Geom_Surface) S = BRep_Tool::Surface(F); @@ -1970,8 +1975,8 @@ bool StdMeshers_Quadrangle_2D::EvaluateQuadPref(SMESH_Mesh & aMesh, int dh = abs(nb-nt); int dv = abs(nr-nl); - if( dh>=dv ) { - if( nt>nb ) { + if (dh>=dv) { + if (nt>nb) { // it is a base case => not shift } else { @@ -1983,7 +1988,7 @@ bool StdMeshers_Quadrangle_2D::EvaluateQuadPref(SMESH_Mesh & aMesh, } } else { - if( nr>nl ) { + if (nr>nl) { // we have to shift quad on 1 nb = aNbNodes[3]; nr = aNbNodes[0]; @@ -2006,7 +2011,7 @@ bool StdMeshers_Quadrangle_2D::EvaluateQuadPref(SMESH_Mesh & aMesh, int addh = 0; int addv = 0; - if(dh>dv) { + if (dh>dv) { addv = (dh-dv)/2; nbv = nbv + addv; } @@ -2016,7 +2021,7 @@ bool StdMeshers_Quadrangle_2D::EvaluateQuadPref(SMESH_Mesh & aMesh, } int dl,dr; - if(OldVersion) { + if (OldVersion) { // add some params to right and left after the first param // insert to right dr = nbv - nr; @@ -2028,14 +2033,14 @@ bool StdMeshers_Quadrangle_2D::EvaluateQuadPref(SMESH_Mesh & aMesh, int nbNodes = 0; int nbFaces = 0; - if(OldVersion) { + if (OldVersion) { // step1: create faces for left domain - if(dl>0) { + if (dl>0) { nbNodes += dl*(nl-1); nbFaces += dl*(nl-1); } // step2: create faces for right domain - if(dr>0) { + if (dr>0) { nbNodes += dr*(nr-1); nbFaces += dr*(nr-1); } @@ -2052,11 +2057,11 @@ bool StdMeshers_Quadrangle_2D::EvaluateQuadPref(SMESH_Mesh & aMesh, } // end new version implementation std::vector aVec(SMDSEntity_Last); - for(int i=SMDSEntity_Node; iX(),theNode3->Y(),theNode3->Z()); gp_Pnt d(theNode4->X(),theNode4->Y(),theNode4->Z()); SMDS_MeshFace* face; - if(a.Distance(c) > b.Distance(d)){ + if (a.Distance(c) > b.Distance(d)){ face = myTool->AddFace(theNode2, theNode4 , theNode1); - if(face) theMeshDS->SetMeshElementOnShape(face, theFaceID ); + if (face) theMeshDS->SetMeshElementOnShape(face, theFaceID); face = myTool->AddFace(theNode2, theNode3, theNode4); - if(face) theMeshDS->SetMeshElementOnShape(face, theFaceID ); + if (face) theMeshDS->SetMeshElementOnShape(face, theFaceID); } else{ face = myTool->AddFace(theNode1, theNode2 ,theNode3); - if(face) theMeshDS->SetMeshElementOnShape(face, theFaceID ); + if (face) theMeshDS->SetMeshElementOnShape(face, theFaceID); face = myTool->AddFace(theNode1, theNode3, theNode4); - if(face) theMeshDS->SetMeshElementOnShape(face, theFaceID ); + if (face) theMeshDS->SetMeshElementOnShape(face, theFaceID); } } +//======================================================================= +/*! + * Implementation of Reduced algorithm (meshing with quadrangles only) + */ +//======================================================================= +bool StdMeshers_Quadrangle_2D::ComputeReduced (SMESH_Mesh & aMesh, + const TopoDS_Shape& aShape, + FaceQuadStruct* quad) +{ + SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); + const TopoDS_Face& F = TopoDS::Face(aShape); + Handle(Geom_Surface) S = BRep_Tool::Surface(F); + int i,j,geomFaceID = meshDS->ShapeToIndex(F); + + int nb = quad->side[0]->NbPoints(); + int nr = quad->side[1]->NbPoints(); + int nt = quad->side[2]->NbPoints(); + int nl = quad->side[3]->NbPoints(); + + // Simple Reduce 8->6->4->2 (3 steps) Multiple Reduce 8->2 (1 step) + // + // .-----.-----.-----.-----. .-----.-----.-----.-----. + // | / \ | / \ | | / \ | / \ | + // | / .--.--. \ | | / \ | / \ | + // | / / | \ \ | | / .----.----. \ | + // .---.---.---.---.---.---. | / / \ | / \ \ | + // | / / \ | / \ \ | | / / \ | / \ \ | + // | / / .-.-. \ \ | | / / .---.---. \ \ | + // | / / / | \ \ \ | | / / / \ | / \ \ \ | + // .--.--.--.--.--.--.--.--. | / / / \ | / \ \ \ | + // | / / / \ | / \ \ \ | | / / / .-.-. \ \ \ | + // | / / / .-.-. \ \ \ | | / / / / | \ \ \ \ | + // | / / / / | \ \ \ \ | | / / / / | \ \ \ \ | + // .-.-.-.--.--.--.--.-.-.-. .-.-.-.--.--.--.--.-.-.-. + + bool MultipleReduce = false; + { + int nb1 = nb; + int nr1 = nr; + int nt1 = nt; + int nl1 = nl; + + if (nr == nl) { + if (nb < nt) { + nt1 = nb; + nb1 = nt; + } + } + else if (nb == nt) { + nl1 = nb; // and == nt + nr1 = nb; // and == nt + if (nl < nr) { + nt1 = nl; + nb1 = nr; + } + else { + nt1 = nr; + nb1 = nl; + } + } + else { + return false; + } + + // number of rows and columns + int nrows = nr1 - 1; // and also == nl1 - 1 + int ncol_top = nt1 - 1; + int ncol_bot = nb1 - 1; + int npair_top = ncol_top / 2; + // maximum number of bottom elements for "linear" simple reduce + //int max_lin = ncol_top + npair_top * 2 * nrows; + // maximum number of bottom elements for "tree" simple reduce + int max_tree = npair_top * pow(2.0, nrows + 1); + if (ncol_top > npair_top * 2) { + int delta = ncol_bot - max_tree; + for (int irow = 1; irow < nrows; irow++) { + int nfour = delta / 4; + delta -= nfour*2; + } + if (delta <= (ncol_top - npair_top * 2)) + max_tree = ncol_bot; + } + + if (ncol_bot > max_tree) + MultipleReduce = true; + } + + if (MultipleReduce) { // == ComputeQuadPref QUAD_QUADRANGLE_PREF_REVERSED + //================================================== + int dh = abs(nb-nt); + int dv = abs(nr-nl); + + if (dh >= dv) { + if (nt > nb) { + // it is a base case => not shift quad but may be replacement is need + ShiftQuad(quad,0,true); + } + else { + // we have to shift quad on 2 + ShiftQuad(quad,2,true); + } + } + else { + if (nr > nl) { + // we have to shift quad on 1 + ShiftQuad(quad,1,true); + } + else { + // we have to shift quad on 3 + ShiftQuad(quad,3,true); + } + } + + nb = quad->side[0]->NbPoints(); + nr = quad->side[1]->NbPoints(); + nt = quad->side[2]->NbPoints(); + nl = quad->side[3]->NbPoints(); + dh = abs(nb-nt); + dv = abs(nr-nl); + int nbh = Max(nb,nt); + int nbv = Max(nr,nl); + int addh = 0; + int addv = 0; + + if (dh>dv) { + addv = (dh-dv)/2; + nbv = nbv + addv; + } + else { // dv>=dh + addh = (dv-dh)/2; + nbh = nbh + addh; + } + + const vector& uv_eb = quad->side[0]->GetUVPtStruct(true,0); + const vector& uv_er = quad->side[1]->GetUVPtStruct(false,1); + const vector& uv_et = quad->side[2]->GetUVPtStruct(true,1); + const vector& uv_el = quad->side[3]->GetUVPtStruct(false,0); + + if (uv_eb.size() != nb || uv_er.size() != nr || uv_et.size() != nt || uv_el.size() != nl) + return error(COMPERR_BAD_INPUT_MESH); + + // arrays for normalized params + TColStd_SequenceOfReal npb, npr, npt, npl; + for (j = 0; j < nb; j++) { + npb.Append(uv_eb[j].normParam); + } + for (i = 0; i < nr; i++) { + npr.Append(uv_er[i].normParam); + } + for (j = 0; j < nt; j++) { + npt.Append(uv_et[j].normParam); + } + for (i = 0; i < nl; i++) { + npl.Append(uv_el[i].normParam); + } + + int dl,dr; + // orientation of face and 3 main domain for future faces + // 0 top 1 + // 1------------1 + // | | | | + // | | | | + // | L | | R | + // left | | | | rigth + // | / \ | + // | / C \ | + // |/ \| + // 0------------0 + // 0 bottom 1 + + // add some params to right and left after the first param + // insert to right + dr = nbv - nr; + double dpr = (npr.Value(2) - npr.Value(1))/(dr+1); + for (i=1; i<=dr; i++) { + npr.InsertAfter(1,npr.Value(2)-dpr); + } + // insert to left + dl = nbv - nl; + dpr = (npl.Value(2) - npl.Value(1))/(dl+1); + for (i=1; i<=dl; i++) { + npl.InsertAfter(1,npl.Value(2)-dpr); + } + + gp_XY a0 (uv_eb.front().u, uv_eb.front().v); + gp_XY a1 (uv_eb.back().u, uv_eb.back().v); + gp_XY a2 (uv_et.back().u, uv_et.back().v); + gp_XY a3 (uv_et.front().u, uv_et.front().v); + + int nnn = Min(nr,nl); + // auxilary sequence of XY for creation nodes + // in the bottom part of central domain + // it's length must be == nbv-nnn-1 + TColgp_SequenceOfXY UVL; + TColgp_SequenceOfXY UVR; + //================================================== + + // step1: create faces for left domain + StdMeshers_Array2OfNode NodesL(1,dl+1,1,nl); + // add left nodes + for (j=1; j<=nl; j++) + NodesL.SetValue(1,j,uv_el[j-1].node); + if (dl>0) { + // add top nodes + for (i=1; i<=dl; i++) + NodesL.SetValue(i+1,nl,uv_et[i].node); + // create and add needed nodes + TColgp_SequenceOfXY UVtmp; + for (i=1; i<=dl; i++) { + double x0 = npt.Value(i+1); + double x1 = x0; + // diagonal node + double y0 = npl.Value(i+1); + double y1 = npr.Value(i+1); + gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3); + gp_Pnt P = S->Value(UV.X(),UV.Y()); + SMDS_MeshNode * N = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); + NodesL.SetValue(i+1,1,N); + if (UVL.Length()Value(UV.X(),UV.Y()); + SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); + NodesL.SetValue(i+1,j,N); + if (i==dl) UVtmp.Append(UV); + } + } + for (i=1; i<=UVtmp.Length() && UVL.Length()AddFace(NodesL.Value(i,j), NodesL.Value(i+1,j), + NodesL.Value(i+1,j+1), NodesL.Value(i,j+1)); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); + } + } + } + else { + // fill UVL using c2d + for (i=1; i0) { + // add top nodes + for (i=1; i<=dr; i++) + NodesR.SetValue(i+1,1,uv_et[nt-1-i].node); + // create and add needed nodes + TColgp_SequenceOfXY UVtmp; + for (i=1; i<=dr; i++) { + double x0 = npt.Value(nt-i); + double x1 = x0; + // diagonal node + double y0 = npl.Value(i+1); + double y1 = npr.Value(i+1); + gp_UV UV = CalcUV(x0, x1, y0, y1, quad, a0, a1, a2, a3); + gp_Pnt P = S->Value(UV.X(),UV.Y()); + SMDS_MeshNode * N = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); + NodesR.SetValue(i+1,nr,N); + if (UVR.Length()Value(UV.X(),UV.Y()); + SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); + NodesR.SetValue(i+1,j,N); + if (i==dr) UVtmp.Prepend(UV); + } + } + for (i=1; i<=UVtmp.Length() && UVR.Length()AddFace(NodesR.Value(i,j), NodesR.Value(i+1,j), + NodesR.Value(i+1,j+1), NodesR.Value(i,j+1)); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); + } + } + } + else { + // fill UVR using c2d + for (i=1; iValue(UV.X(),UV.Y()); + SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(N, geomFaceID, UV.X(), UV.Y()); + NodesC.SetValue(i,nbv-nnn+j,N); + } + } + // add diagonal layers + for (i=1; iValue(u,v); + SMDS_MeshNode* N = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(N, geomFaceID, u, v); + NodesC.SetValue(j,i+1,N); + } + } + // create faces + for (i=1; iAddFace(NodesC.Value(i,j), NodesC.Value(i+1,j), + NodesC.Value(i+1,j+1), NodesC.Value(i,j+1)); + if (F) meshDS->SetMeshElementOnShape(F, geomFaceID); + } + } + // TODO ??? + } // end Multiple Reduce implementation + else { // Simple Reduce (!MultipleReduce) + //========================================================= + if (nr == nl) { + if (nt < nb) { + // it is a base case => not shift quad + //ShiftQuad(quad,0,true); + } + else { + // we have to shift quad on 2 + ShiftQuad(quad,2,true); + } + } + else { + if (nl > nr) { + // we have to shift quad on 1 + ShiftQuad(quad,1,true); + } + else { + // we have to shift quad on 3 + ShiftQuad(quad,3,true); + } + } + + nb = quad->side[0]->NbPoints(); + nr = quad->side[1]->NbPoints(); + nt = quad->side[2]->NbPoints(); + nl = quad->side[3]->NbPoints(); + + // number of rows and columns + int nrows = nr - 1; // and also == nl - 1 + int ncol_top = nt - 1; + int ncol_bot = nb - 1; + int npair_top = ncol_top / 2; + // maximum number of bottom elements for "linear" simple reduce + int max_lin = ncol_top + npair_top * 2 * nrows; + // maximum number of bottom elements for "tree" simple reduce + //int max_tree = npair_top * pow(2, nrows + 1); + + //if (ncol_bot > max_tree) + // MultipleReduce = true; + + const vector& uv_eb = quad->side[0]->GetUVPtStruct(true,0); + const vector& uv_er = quad->side[1]->GetUVPtStruct(false,1); + const vector& uv_et = quad->side[2]->GetUVPtStruct(true,1); + const vector& uv_el = quad->side[3]->GetUVPtStruct(false,0); + + if (uv_eb.size() != nb || uv_er.size() != nr || uv_et.size() != nt || uv_el.size() != nl) + return error(COMPERR_BAD_INPUT_MESH); + + // arrays for normalized params + TColStd_SequenceOfReal npb, npr, npt, npl; + for (j = 0; j < nb; j++) { + npb.Append(uv_eb[j].normParam); + } + for (i = 0; i < nr; i++) { + npr.Append(uv_er[i].normParam); + } + for (j = 0; j < nt; j++) { + npt.Append(uv_et[j].normParam); + } + for (i = 0; i < nl; i++) { + npl.Append(uv_el[i].normParam); + } + + // We will ajust new points to this grid + if (!SetNormalizedGrid(aMesh, aShape, quad)) + return false; + + // TODO ??? + gp_XY a0 (uv_eb.front().u, uv_eb.front().v); + gp_XY a1 (uv_eb.back().u, uv_eb.back().v); + gp_XY a2 (uv_et.back().u, uv_et.back().v); + gp_XY a3 (uv_et.front().u, uv_et.front().v); + //========================================================= + + TColStd_SequenceOfInteger curr_base, next_base; + TColStd_SequenceOfReal curr_par_u, curr_par_v; + TColStd_SequenceOfReal next_par_u, next_par_v; + StdMeshers_Array2OfNode NodesBRD (1,nb, 1,nr); + for (j = 1; j <= nb; j++) { + NodesBRD.SetValue(j, 1, uv_eb[j - 1].node); // bottom + curr_base.Append(j); + next_base.Append(-1); + curr_par_u.Append(uv_eb[j-1].u); + curr_par_v.Append(uv_eb[j-1].v); + next_par_u.Append(0.); + next_par_v.Append(0.); + } + for (j = 1; j <= nt; j++) { + NodesBRD.SetValue(j, nr, uv_et[j - 1].node); // top + } + + int curr_base_len = nb; + int next_base_len = 0; + + if (ncol_bot > max_lin) { + // "tree" simple reduce 2->4->8->16->32->... + // + // .---------------.---------------.---------------.---------------. nr + // | \ | / | \ | / | + // | \ .-------.-------. / | \ .-------.-------. / | + // | | | | | | | | | + // .-------.-------.-------.-------.-------.-------.-------.-------. + // |\ | /|\ | /|\ | /|\ | /| + // | \.---.---./ | \.---.---./ | \.---.---./ | \.---.---./ | i + // | | | | | | | | | | | | | | | | | + // .---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---. + // |\ | /|\ | /|\ | /|\ | /|\ | /|\ | /|\ | /|\ | /| + // | .-.-. | .-.-. | .-.-. | .-.-. | .-.-. | .-.-. | .-.-. | .-.-. | + // | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + // .-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. 1 + // 1 j nb + + for (i = 1; i < nr; i++) { // layer by layer + // left + NodesBRD.SetValue(1, i+1, uv_el[i].node); + next_base.SetValue(++next_base_len, 1); + // right + NodesBRD.SetValue(nb, i+1, uv_er[i].node); + + next_par_u.SetValue(next_base_len, uv_el[i].u); + next_par_v.SetValue(next_base_len, uv_el[i].v); + + // to stop reducing, if number of nodes reaches nt + int delta = curr_base_len - nt; + + //double du = uv_er[i].u - uv_el[i].u; + //double dv = uv_er[i].v - uv_el[i].v; + + // to calculate normalized parameter, we must know number of points in next layer + int nb_four = (curr_base_len - 1) / 4; + int nb_next = nb_four*2 + (curr_base_len - nb_four*4); + if (nb_next < nt) nb_next = nt; + + for (j = 1; j + 4 <= curr_base_len && delta > 0; j += 4, delta -= 2) { + // add one "HH": nodes a,b,c,d,e and faces 1,2,3,4,5,6 + // + // .-----a-----b i + 1 + // |\ 5 | 6 /| + // | \ | / | + // | c--d--e | + // |1 |2 |3 |4 | + // | | | | | + // .--.--.--.--. i + // + // j j+2 j+4 + + double u,v; + + // a (i + 1, j + 2) + const SMDS_MeshNode* Na; + next_base_len++; + next_base.SetValue(next_base_len, curr_base.Value(j + 2)); + if (i + 1 == nr) { // top + Na = uv_et[next_base_len - 1].node; + NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Na); + u = uv_et[next_base_len - 1].u; + v = uv_et[next_base_len - 1].v; + } + else { + //double norm_par = double(next_base_len - 1)/double(nb_next - 1); + //u = uv_el[i].u + du * norm_par; + //v = uv_el[i].v + dv * norm_par; + { + double rel = double(next_base_len - 1) * double(nt - 1) / double(nb_next - 1) + 1; + int nearest_node_j = (int)rel; + rel -= nearest_node_j; + int ij = (i + 1 - 1) * nt + (nearest_node_j - 1); + double u1 = quad->uv_grid[ij].u; + double v1 = quad->uv_grid[ij].v; + double u2 = quad->uv_grid[ij + 1].u; + double v2 = quad->uv_grid[ij + 1].v; + double duj = (u2 - u1) * rel; + double dvj = (v2 - v1) * rel; + u = u1 + duj; + v = v1 + dvj; + } + //u = uv_el[i].u + du*npb.Value(curr_base.Value(j + 2)); + //v = uv_el[i].v + dv*npb.Value(curr_base.Value(j + 2)); + gp_Pnt P = S->Value(u,v); + SMDS_MeshNode* Na1 = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(Na1, geomFaceID, u, v); + NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Na1); + Na = Na1; + } + next_par_u.SetValue(next_base_len, u); + next_par_v.SetValue(next_base_len, v); + + // b (i + 1, j + 4) + const SMDS_MeshNode* Nb; + next_base_len++; + next_base.SetValue(next_base_len, curr_base.Value(j + 4)); + if (i + 1 == nr) { // top + Nb = uv_et[next_base_len - 1].node; + NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nb); + u = uv_et[next_base_len - 1].u; + v = uv_et[next_base_len - 1].v; + } + else if (j + 4 == curr_base_len) { // right + Nb = NodesBRD.Value(next_base.Value(next_base_len), i + 1); + u = uv_er[i].u; + v = uv_er[i].v; + } + else { + //double norm_par = double(next_base_len - 1)/double(nb_next - 1); + //u = uv_el[i].u + du * norm_par; + //v = uv_el[i].v + dv * norm_par; + { + double rel = double(next_base_len - 1) * double(nt - 1) / double(nb_next - 1) + 1; + int nearest_node_j = (int)rel; + rel -= nearest_node_j; + int ij = (i + 1 - 1) * nt + (nearest_node_j - 1); + double u1 = quad->uv_grid[ij].u; + double v1 = quad->uv_grid[ij].v; + double u2 = quad->uv_grid[ij + 1].u; + double v2 = quad->uv_grid[ij + 1].v; + double duj = (u2 - u1) * rel; + double dvj = (v2 - v1) * rel; + u = u1 + duj; + v = v1 + dvj; + } + //u = uv_el[i].u + du*npb.Value(curr_base.Value(j + 4)); + //v = uv_el[i].v + dv*npb.Value(curr_base.Value(j + 4)); + gp_Pnt P = S->Value(u,v); + SMDS_MeshNode* Nb1 = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(Nb1, geomFaceID, u, v); + NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nb1); + Nb = Nb1; + } + next_par_u.SetValue(next_base_len, u); + next_par_v.SetValue(next_base_len, v); + + // c + u = (curr_par_u.Value(j + 2) + next_par_u.Value(next_base_len - 2)) / 2.0; + v = (curr_par_v.Value(j + 2) + next_par_v.Value(next_base_len - 2)) / 2.0; + gp_Pnt P = S->Value(u,v); + SMDS_MeshNode* Nc = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(Nc, geomFaceID, u, v); + + // d + u = (curr_par_u.Value(j + 2) + next_par_u.Value(next_base_len - 1)) / 2.0; + v = (curr_par_v.Value(j + 2) + next_par_v.Value(next_base_len - 1)) / 2.0; + P = S->Value(u,v); + SMDS_MeshNode* Nd = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(Nd, geomFaceID, u, v); + + // e + u = (curr_par_u.Value(j + 2) + next_par_u.Value(next_base_len)) / 2.0; + v = (curr_par_v.Value(j + 2) + next_par_v.Value(next_base_len)) / 2.0; + P = S->Value(u,v); + SMDS_MeshNode* Ne = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(Ne, geomFaceID, u, v); + + // Faces + SMDS_MeshFace* F1 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j + 0), i), + NodesBRD.Value(curr_base.Value(j + 1), i), + Nc, + NodesBRD.Value(next_base.Value(next_base_len - 2), i + 1)); + if (F1) meshDS->SetMeshElementOnShape(F1, geomFaceID); + + SMDS_MeshFace* F2 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j + 1), i), + NodesBRD.Value(curr_base.Value(j + 2), i), + Nd, Nc); + if (F2) meshDS->SetMeshElementOnShape(F2, geomFaceID); + + SMDS_MeshFace* F3 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j + 2), i), + NodesBRD.Value(curr_base.Value(j + 3), i), + Ne, Nd); + if (F3) meshDS->SetMeshElementOnShape(F3, geomFaceID); + + SMDS_MeshFace* F4 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j + 3), i), + NodesBRD.Value(curr_base.Value(j + 4), i), + Nb, Ne); + if (F4) meshDS->SetMeshElementOnShape(F4, geomFaceID); + + SMDS_MeshFace* F5 = myTool->AddFace(Nc, Nd, Na, + NodesBRD.Value(next_base.Value(next_base_len - 2), i + 1)); + if (F5) meshDS->SetMeshElementOnShape(F5, geomFaceID); + + SMDS_MeshFace* F6 = myTool->AddFace(Nd, Ne, Nb, Na); + if (F6) meshDS->SetMeshElementOnShape(F6, geomFaceID); + } + + // not reduced side elements (if any) + for (; j < curr_base_len; j++) { + // f (i + 1, j + 1) + const SMDS_MeshNode* Nf; + double u,v; + next_base.SetValue(++next_base_len, curr_base.Value(j + 1)); + if (i + 1 == nr) { // top + Nf = uv_et[next_base_len - 1].node; + NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nf); + u = uv_et[next_base_len - 1].u; + v = uv_et[next_base_len - 1].v; + } + else if (j + 1 == curr_base_len) { // right + Nf = NodesBRD.Value(next_base.Value(next_base_len), i + 1); + u = uv_er[i].u; + v = uv_er[i].v; + } + else { + //double norm_par = double(next_base_len - 1)/double(nb_next - 1); + //u = uv_el[i].u + du * norm_par; + //v = uv_el[i].v + dv * norm_par; + { + double rel = double(next_base_len - 1) * double(nt - 1) / double(nb_next - 1) + 1; + int nearest_node_j = (int)rel; + rel -= nearest_node_j; + int ij = (i + 1 - 1) * nt + (nearest_node_j - 1); + double u1 = quad->uv_grid[ij].u; + double v1 = quad->uv_grid[ij].v; + double u2 = quad->uv_grid[ij + 1].u; + double v2 = quad->uv_grid[ij + 1].v; + double duj = (u2 - u1) * rel; + double dvj = (v2 - v1) * rel; + u = u1 + duj; + v = v1 + dvj; + } + //u = uv_el[i].u + du*npb.Value(curr_base.Value(j + 1)); + //v = uv_el[i].v + dv*npb.Value(curr_base.Value(j + 1)); + gp_Pnt P = S->Value(u,v); + SMDS_MeshNode* Nf1 = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(Nf1, geomFaceID, u, v); + NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nf1); + Nf = Nf1; + } + next_par_u.SetValue(next_base_len, u); + next_par_v.SetValue(next_base_len, v); + SMDS_MeshFace* F1 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j), i), + NodesBRD.Value(curr_base.Value(j + 1), i), + NodesBRD.Value(next_base.Value(next_base_len), i + 1), + NodesBRD.Value(next_base.Value(next_base_len - 1), i + 1)); + if (F1) meshDS->SetMeshElementOnShape(F1, geomFaceID); + } + curr_base_len = next_base_len; + curr_base = next_base; + curr_par_u = next_par_u; + curr_par_v = next_par_v; + next_base_len = 0; + } + } // end "tree" simple reduce + else { + // "linear" simple reduce 4->8->12->16 (3 steps) + // + // .---------------.---------------.---------------.---------------. nr + // | \ | / | \ | / | + // | \ .-------.-------. / | \ .-------.-------. / | + // | | | | | | | | | + // .-------.-------.-------.-------.-------.-------.-------.-------. + // | / \ | / \ | / \ | / \ | + // | / \.----.----./ \ | / \.----.----./ \ | i + // | / | | | \ | / | | | \ | + // .-----.----.----.----.----.-----.-----.----.----.----.----.-----. + // | / / \ | / \ \ | / / \ | / \ \ | + // | / / .-.-. \ \ | / / .-.-. \ \ | + // | / / / | \ \ \ | / / / | \ \ \ | + // .---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---. 1 + // 1 j nb + + // nt = 5, nb = 7, nr = 4 + //int delta_all = 2; + //int delta_one_col = 6; + //int nb_col = 0; + //int remainder = 2; + //if (remainder > 0) nb_col++; + //nb_col = 1; + //int free_left = 1; + //free_left += 2; + //int free_middle = 4; + + int delta_all = nb - nt; + int delta_one_col = (nr - 1) * 2; + int nb_col = delta_all / delta_one_col; + int remainder = delta_all - nb_col * delta_one_col; + if (remainder > 0) { + nb_col++; + } + int free_left = ((nt - 1) - nb_col * 2) / 2; + free_left += nr - 2; + int free_middle = (nr - 2) * 2; + if (remainder > 0 && nb_col == 1) { + int nb_rows_short_col = remainder / 2; + int nb_rows_thrown = (nr - 1) - nb_rows_short_col; + free_left -= nb_rows_thrown; + } + + // nt = 5, nb = 17, nr = 4 + //int delta_all = 12; + //int delta_one_col = 6; + //int nb_col = 2; + //int remainder = 0; + //int free_left = 2; + //int free_middle = 4; + + for (i = 1; i < nr; i++, free_middle -= 2, free_left -= 1) { // layer by layer + // left + NodesBRD.SetValue(1, i+1, uv_el[i].node); + next_base.SetValue(++next_base_len, 1); + // right + NodesBRD.SetValue(nb, i+1, uv_er[i].node); + + // left + next_par_u.SetValue(next_base_len, uv_el[i].u); + next_par_v.SetValue(next_base_len, uv_el[i].v); + + // to calculate normalized parameter, we must know number of points in next layer + int nb_next = curr_base_len - nb_col * 2; + if (remainder > 0 && i > remainder / 2) + // take into account short "column" + nb_next += 2; + if (nb_next < nt) nb_next = nt; + + // not reduced left elements + for (j = 1; j <= free_left; j++) { + // f (i + 1, j + 1) + const SMDS_MeshNode* Nf; + double u,v; + next_base.SetValue(++next_base_len, curr_base.Value(j + 1)); + if (i + 1 == nr) { // top + Nf = uv_et[next_base_len - 1].node; + NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nf); + u = uv_et[next_base_len - 1].u; + v = uv_et[next_base_len - 1].v; + } + else { + { + double rel = double(next_base_len - 1) * double(nt - 1) / double(nb_next - 1) + 1; + int nearest_node_j = (int)rel; + rel -= nearest_node_j; + int ij = (i + 1 - 1) * nt + (nearest_node_j - 1); + double u1 = quad->uv_grid[ij].u; + double v1 = quad->uv_grid[ij].v; + double u2 = quad->uv_grid[ij + 1].u; + double v2 = quad->uv_grid[ij + 1].v; + double duj = (u2 - u1) * rel; + double dvj = (v2 - v1) * rel; + u = u1 + duj; + v = v1 + dvj; + } + gp_Pnt P = S->Value(u,v); + SMDS_MeshNode* Nf1 = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(Nf1, geomFaceID, u, v); + NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nf1); + Nf = Nf1; + } + next_par_u.SetValue(next_base_len, u); + next_par_v.SetValue(next_base_len, v); + SMDS_MeshFace* F1 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j), i), + NodesBRD.Value(curr_base.Value(j + 1), i), + NodesBRD.Value(next_base.Value(next_base_len), i + 1), + NodesBRD.Value(next_base.Value(next_base_len - 1), i + 1)); + if (F1) meshDS->SetMeshElementOnShape(F1, geomFaceID); + } + + for (int icol = 1; icol <= nb_col; icol++) { + + if (remainder > 0 && icol == nb_col && i > remainder / 2) + // stop short "column" + break; + + // add one "HH": nodes a,b,c,d,e and faces 1,2,3,4,5,6 + // + // .-----a-----b i + 1 + // |\ 5 | 6 /| + // | \ | / | + // | c--d--e | + // |1 |2 |3 |4 | + // | | | | | + // .--.--.--.--. i + // + // j j+2 j+4 + + double u,v; + + // a (i + 1, j + 2) + const SMDS_MeshNode* Na; + next_base_len++; + next_base.SetValue(next_base_len, curr_base.Value(j + 2)); + if (i + 1 == nr) { // top + Na = uv_et[next_base_len - 1].node; + NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Na); + u = uv_et[next_base_len - 1].u; + v = uv_et[next_base_len - 1].v; + } + else { + { + double rel = double(next_base_len - 1) * double(nt - 1) / double(nb_next - 1) + 1; + int nearest_node_j = (int)rel; + rel -= nearest_node_j; + int ij = (i + 1 - 1) * nt + (nearest_node_j - 1); + double u1 = quad->uv_grid[ij].u; + double v1 = quad->uv_grid[ij].v; + double u2 = quad->uv_grid[ij + 1].u; + double v2 = quad->uv_grid[ij + 1].v; + double duj = (u2 - u1) * rel; + double dvj = (v2 - v1) * rel; + u = u1 + duj; + v = v1 + dvj; + } + gp_Pnt P = S->Value(u,v); + SMDS_MeshNode* Na1 = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(Na1, geomFaceID, u, v); + NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Na1); + Na = Na1; + } + next_par_u.SetValue(next_base_len, u); + next_par_v.SetValue(next_base_len, v); + + // b (i + 1, j + 4) + const SMDS_MeshNode* Nb; + next_base_len++; + next_base.SetValue(next_base_len, curr_base.Value(j + 4)); + if (i + 1 == nr) { // top + Nb = uv_et[next_base_len - 1].node; + NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nb); + u = uv_et[next_base_len - 1].u; + v = uv_et[next_base_len - 1].v; + } + else if (j + 4 == curr_base_len) { // right + Nb = NodesBRD.Value(next_base.Value(next_base_len), i + 1); + u = uv_er[i].u; + v = uv_er[i].v; + } + else { + { + double rel = double(next_base_len - 1) * double(nt - 1) / double(nb_next - 1) + 1; + int nearest_node_j = (int)rel; + rel -= nearest_node_j; + int ij = (i + 1 - 1) * nt + (nearest_node_j - 1); + double u1 = quad->uv_grid[ij].u; + double v1 = quad->uv_grid[ij].v; + double u2 = quad->uv_grid[ij + 1].u; + double v2 = quad->uv_grid[ij + 1].v; + double duj = (u2 - u1) * rel; + double dvj = (v2 - v1) * rel; + u = u1 + duj; + v = v1 + dvj; + } + gp_Pnt P = S->Value(u,v); + SMDS_MeshNode* Nb1 = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(Nb1, geomFaceID, u, v); + NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nb1); + Nb = Nb1; + } + next_par_u.SetValue(next_base_len, u); + next_par_v.SetValue(next_base_len, v); + + // c + u = (curr_par_u.Value(j + 2) + next_par_u.Value(next_base_len - 2)) / 2.0; + v = (curr_par_v.Value(j + 2) + next_par_v.Value(next_base_len - 2)) / 2.0; + gp_Pnt P = S->Value(u,v); + SMDS_MeshNode* Nc = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(Nc, geomFaceID, u, v); + + // d + u = (curr_par_u.Value(j + 2) + next_par_u.Value(next_base_len - 1)) / 2.0; + v = (curr_par_v.Value(j + 2) + next_par_v.Value(next_base_len - 1)) / 2.0; + P = S->Value(u,v); + SMDS_MeshNode* Nd = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(Nd, geomFaceID, u, v); + + // e + u = (curr_par_u.Value(j + 2) + next_par_u.Value(next_base_len)) / 2.0; + v = (curr_par_v.Value(j + 2) + next_par_v.Value(next_base_len)) / 2.0; + P = S->Value(u,v); + SMDS_MeshNode* Ne = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(Ne, geomFaceID, u, v); + + // Faces + SMDS_MeshFace* F1 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j + 0), i), + NodesBRD.Value(curr_base.Value(j + 1), i), + Nc, + NodesBRD.Value(next_base.Value(next_base_len - 2), i + 1)); + if (F1) meshDS->SetMeshElementOnShape(F1, geomFaceID); + + SMDS_MeshFace* F2 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j + 1), i), + NodesBRD.Value(curr_base.Value(j + 2), i), + Nd, Nc); + if (F2) meshDS->SetMeshElementOnShape(F2, geomFaceID); + + SMDS_MeshFace* F3 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j + 2), i), + NodesBRD.Value(curr_base.Value(j + 3), i), + Ne, Nd); + if (F3) meshDS->SetMeshElementOnShape(F3, geomFaceID); + + SMDS_MeshFace* F4 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j + 3), i), + NodesBRD.Value(curr_base.Value(j + 4), i), + Nb, Ne); + if (F4) meshDS->SetMeshElementOnShape(F4, geomFaceID); + + SMDS_MeshFace* F5 = myTool->AddFace(Nc, Nd, Na, + NodesBRD.Value(next_base.Value(next_base_len - 2), i + 1)); + if (F5) meshDS->SetMeshElementOnShape(F5, geomFaceID); + + SMDS_MeshFace* F6 = myTool->AddFace(Nd, Ne, Nb, Na); + if (F6) meshDS->SetMeshElementOnShape(F6, geomFaceID); + + j += 4; + + // not reduced middle elements + if (icol < nb_col) { + if (remainder > 0 && icol == nb_col - 1 && i > remainder / 2) + // pass middle elements before stopped short "column" + break; + + int free_add = free_middle; + if (remainder > 0 && icol == nb_col - 1) + // next "column" is short + free_add -= (nr - 1) - (remainder / 2); + + for (int imiddle = 1; imiddle <= free_add; imiddle++) { + // f (i + 1, j + imiddle) + const SMDS_MeshNode* Nf; + double u,v; + next_base.SetValue(++next_base_len, curr_base.Value(j + imiddle)); + if (i + 1 == nr) { // top + Nf = uv_et[next_base_len - 1].node; + NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nf); + u = uv_et[next_base_len - 1].u; + v = uv_et[next_base_len - 1].v; + } + else if (j + imiddle == curr_base_len) { // right + Nf = NodesBRD.Value(next_base.Value(next_base_len), i + 1); + u = uv_er[i].u; + v = uv_er[i].v; + } + else { + { + double rel = double(next_base_len - 1) * double(nt - 1) / double(nb_next - 1) + 1; + int nearest_node_j = (int)rel; + rel -= nearest_node_j; + int ij = (i + 1 - 1) * nt + (nearest_node_j - 1); + double u1 = quad->uv_grid[ij].u; + double v1 = quad->uv_grid[ij].v; + double u2 = quad->uv_grid[ij + 1].u; + double v2 = quad->uv_grid[ij + 1].v; + double duj = (u2 - u1) * rel; + double dvj = (v2 - v1) * rel; + u = u1 + duj; + v = v1 + dvj; + } + gp_Pnt P = S->Value(u,v); + SMDS_MeshNode* Nf1 = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(Nf1, geomFaceID, u, v); + NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nf1); + Nf = Nf1; + } + next_par_u.SetValue(next_base_len, u); + next_par_v.SetValue(next_base_len, v); + SMDS_MeshFace* F1 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j - 1 + imiddle), i), + NodesBRD.Value(curr_base.Value(j + imiddle), i), + NodesBRD.Value(next_base.Value(next_base_len), i + 1), + NodesBRD.Value(next_base.Value(next_base_len - 1), i + 1)); + if (F1) meshDS->SetMeshElementOnShape(F1, geomFaceID); + } + j += free_add; + } + } + + // not reduced right elements + for (; j < curr_base_len; j++) { + // f (i + 1, j + 1) + const SMDS_MeshNode* Nf; + double u,v; + next_base.SetValue(++next_base_len, curr_base.Value(j + 1)); + if (i + 1 == nr) { // top + Nf = uv_et[next_base_len - 1].node; + NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nf); + u = uv_et[next_base_len - 1].u; + v = uv_et[next_base_len - 1].v; + } + else if (j + 1 == curr_base_len) { // right + Nf = NodesBRD.Value(next_base.Value(next_base_len), i + 1); + u = uv_er[i].u; + v = uv_er[i].v; + } + else { + { + double rel = double(next_base_len - 1) * double(nt - 1) / double(nb_next - 1) + 1; + int nearest_node_j = (int)rel; + rel -= nearest_node_j; + int ij = (i + 1 - 1) * nt + (nearest_node_j - 1); + double u1 = quad->uv_grid[ij].u; + double v1 = quad->uv_grid[ij].v; + double u2 = quad->uv_grid[ij + 1].u; + double v2 = quad->uv_grid[ij + 1].v; + double duj = (u2 - u1) * rel; + double dvj = (v2 - v1) * rel; + u = u1 + duj; + v = v1 + dvj; + } + gp_Pnt P = S->Value(u,v); + SMDS_MeshNode* Nf1 = meshDS->AddNode(P.X(), P.Y(), P.Z()); + meshDS->SetNodeOnFace(Nf1, geomFaceID, u, v); + NodesBRD.SetValue(next_base.Value(next_base_len), i + 1, Nf1); + Nf = Nf1; + } + next_par_u.SetValue(next_base_len, u); + next_par_v.SetValue(next_base_len, v); + SMDS_MeshFace* F1 = myTool->AddFace(NodesBRD.Value(curr_base.Value(j), i), + NodesBRD.Value(curr_base.Value(j + 1), i), + NodesBRD.Value(next_base.Value(next_base_len), i + 1), + NodesBRD.Value(next_base.Value(next_base_len - 1), i + 1)); + if (F1) meshDS->SetMeshElementOnShape(F1, geomFaceID); + } + + curr_base_len = next_base_len; + curr_base = next_base; + curr_par_u = next_par_u; + curr_par_v = next_par_v; + next_base_len = 0; + } + } // end "linear" simple reduce + } // end Simple Reduce implementation + + bool isOk = true; + return isOk; +} diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx index 74c64f6f0..56741ec76 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.hxx @@ -19,19 +19,20 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // - // SMESH SMESH : implementaion of SMESH idl descriptions // File : StdMeshers_Quadrangle_2D.hxx // Moved here from SMESH_Quadrangle_2D.hxx // Author : Paul RASCLE, EDF // Module : SMESH // $Header$ -// + #ifndef _SMESH_QUADRANGLE_2D_HXX_ #define _SMESH_QUADRANGLE_2D_HXX_ #include "SMESH_StdMeshers.hxx" +#include "StdMeshers_QuadrangleParams.hxx" + #include "SMESH_2D_Algo.hxx" #include "Utils_SALOME_Exception.hxx" @@ -120,6 +121,10 @@ protected: const TopoDS_Face& F, const TopoDS_Edge& E, double first, double last, int nb_segm); + bool ComputeReduced (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + FaceQuadStruct* quad); + // true if QuadranglePreference hypothesis is assigned that forces // construction of quadrangles if the number of nodes on opposite edges // is not the same in the case where the global number of nodes on edges @@ -130,6 +135,8 @@ protected: int myTriaVertexID; + StdMeshers_QuadType myQuadType; + SMESH_MesherHelper* myTool; // tool for working with quadratic elements }; diff --git a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx index d03470fb3..cbf6f5692 100644 --- a/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx +++ b/src/StdMeshers/StdMeshers_RadialQuadrangle_1D2D.cxx @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -570,6 +571,8 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, if (!GetSortedNodesOnEdge(aMesh.GetMeshDS(),LinEdge1,true,theNodes)) return error("Invalid mesh on a straight edge"); + Nodes1.resize( myLayerPositions.size()+1 ); + Nodes2.resize( myLayerPositions.size()+1 ); vector< const SMDS_MeshNode* > *pNodes1 = &Nodes1, *pNodes2 = &Nodes2; bool nodesFromP0ToP1 = ( theNodes.rbegin()->second == NF ); if ( !nodesFromP0ToP1 ) std::swap( pNodes1, pNodes2 ); @@ -580,8 +583,8 @@ bool StdMeshers_RadialQuadrangle_1D2D::Compute(SMESH_Mesh& aMesh, { (*pNodes1)[i] = ritn->second; (*pNodes2)[i] = itn->second; - Points.Append( gpXYZ( Nodes1[i])); - Pnts2d1.Append( myHelper->GetNodeUV( F, Nodes1[i])); + Points.Prepend( gpXYZ( Nodes1[i])); + Pnts2d1.Prepend( myHelper->GetNodeUV( F, Nodes1[i])); } NC = const_cast( itn->second ); Points.Remove( Nodes1.size() ); @@ -1030,9 +1033,25 @@ bool StdMeshers_RadialQuadrangle_1D2D::computeLayerPositions(const gp_Pnt& vector< double > nodeParams; GetNodeParamOnEdge( mesh->GetMeshDS(), linEdge, nodeParams ); + // nb of present nodes must be different in cases of 1 and 2 straight edges + + TopoDS_Vertex VV[2]; + TopExp::Vertices( linEdge, VV[0], VV[1]); + const gp_Pnt* points[] = { &p1, &p2 }; + gp_Pnt vPoints[] = { BRep_Tool::Pnt(VV[0]), BRep_Tool::Pnt(VV[1]) }; + const double tol[] = { BRep_Tool::Tolerance(VV[0]), BRep_Tool::Tolerance(VV[1]) }; + bool pointsAreOnVertices = true; + for ( int iP = 0; iP < 2 && pointsAreOnVertices; ++iP ) + pointsAreOnVertices = ( points[iP]->Distance( vPoints[0] ) < tol[0] || + points[iP]->Distance( vPoints[1] ) < tol[1] ); + + int nbNodes = nodeParams.size() - 2; // 2 straight edges + if ( !pointsAreOnVertices ) + nbNodes = ( nodeParams.size() - 3 ) / 2; // 1 straight edge + if ( myLayerPositions.empty() ) { - myLayerPositions.resize( nodeParams.size() - 2 ); + myLayerPositions.resize( nbNodes ); } else if ( myDistributionHypo || myNbLayerHypo ) { @@ -1048,8 +1067,10 @@ bool StdMeshers_RadialQuadrangle_1D2D::computeLayerPositions(const gp_Pnt& mesh->GetSubMesh( linEdge )->ComputeStateEngine( SMESH_subMesh::CLEAN ); if ( linEdgeComputed ) *linEdgeComputed = false; } - else if ( myLayerPositions.size() != nodeParams.size()-2 ) { - return error("Radial edge is meshed by other algorithm"); + else { + + if ( myLayerPositions.size() != nbNodes ) + return error("Radial edge is meshed by other algorithm"); } } } diff --git a/src/StdMeshers/StdMeshers_Regular_1D.cxx b/src/StdMeshers/StdMeshers_Regular_1D.cxx index 391bd38c3..951414c53 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.cxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.cxx @@ -119,9 +119,8 @@ bool StdMeshers_Regular_1D::CheckHypothesis _hypType = NONE; _quadraticMesh = false; - const bool ignoreAuxiliaryHyps = false; const list & hyps = - GetUsedHypothesis(aMesh, aShape, ignoreAuxiliaryHyps); + GetUsedHypothesis(aMesh, aShape, /*ignoreAuxiliaryHyps=*/false); // find non-auxiliary hypothesis const SMESHDS_Hypothesis *theHyp = 0; @@ -377,10 +376,14 @@ static void compensateError(double a1, double an, } double q = dUn / ( nPar - 1 ); - if ( !adjustNeighbors2an ) { - for ( itU = theParams.rbegin(), i = 1; i < nPar; itU++, i++ ) { + if ( !adjustNeighbors2an ) + { + q = Abs( dUn / ( Utgt - Un )); // factor of segment length change + for ( itU = theParams.rbegin(), i = 1; i < nPar; i++ ) { + double prevU = *itU; (*itU) += dUn; - dUn -= q; + ++itU; + dUn = q * (*itU - prevU) * (prevU-U1)/(Un-U1); } } else { @@ -627,7 +630,7 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh, bool computed = sm->IsMeshComputed(); if (!computed) { if (sm->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE) { - sm->ComputeStateEngine(SMESH_subMesh::COMPUTE); + _gen->Compute( theMesh, _mainEdge, /*anUpward=*/true); computed = sm->IsMeshComputed(); } } @@ -731,6 +734,9 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh, double a1 = _value[ BEG_LENGTH_IND ]; double an = _value[ END_LENGTH_IND ]; double q = ( theLength - a1 ) / ( theLength - an ); + if ( q < theLength/1e6 || 1.01*theLength < a1 + an) + return error ( SMESH_Comment("Invalid segment lengths (")< numeric_limits::min() ? ( 1+( an-a1 )/q ) : ( 1+theLength/a1 )); @@ -941,23 +950,43 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t if (!idFirst || !idLast) return error( COMPERR_BAD_INPUT_MESH, "No node on vertex"); + // remove elements created by e.g. patern mapping (PAL21999) + // CLEAN event is incorrectly ptopagated seemingly due to Propagation hyp + // so TEMPORARY solution is to clean the submesh manually + //theMesh.GetSubMesh(theShape)->ComputeStateEngine( SMESH_subMesh::CLEAN ); + if (SMESHDS_SubMesh * subMeshDS = meshDS->MeshElements(theShape)) + { + SMDS_ElemIteratorPtr ite = subMeshDS->GetElements(); + while (ite->more()) + meshDS->RemoveFreeElement(ite->next(), subMeshDS); + SMDS_NodeIteratorPtr itn = subMeshDS->GetNodes(); + while (itn->more()) { + const SMDS_MeshNode * node = itn->next(); + if ( node->NbInverseElements() == 0 ) + meshDS->RemoveFreeNode(node, subMeshDS); + else + meshDS->RemoveNode(node); + } + } + if (!Curve.IsNull()) { list< double > params; bool reversed = false; if ( theMesh.GetShapeToMesh().ShapeType() >= TopAbs_WIRE ) { + // if the shape to mesh is WIRE or EDGE reversed = ( EE.Orientation() == TopAbs_REVERSED ); } if ( !_mainEdge.IsNull() ) { + // take into account reversing the edge the hypothesis is propagated from reversed = ( _mainEdge.Orientation() == TopAbs_REVERSED ); + int mainID = meshDS->ShapeToIndex(_mainEdge); + if ( std::find( _revEdgesIDs.begin(), _revEdgesIDs.end(), mainID) != _revEdgesIDs.end()) + reversed = !reversed; } - else if ( _revEdgesIDs.size() > 0 ) { - for ( int i = 0; i < _revEdgesIDs.size(); i++) { - if ( _revEdgesIDs[i] == shapeID ) { - reversed = !reversed; - } - } - } + // take into account this edge reversing + if ( std::find( _revEdgesIDs.begin(), _revEdgesIDs.end(), shapeID) != _revEdgesIDs.end()) + reversed = !reversed; BRepAdaptor_Curve C3d( E ); double length = EdgeLength( E ); @@ -982,7 +1011,6 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t parLast = f; } */ - for (list::iterator itU = params.begin(); itU != params.end(); itU++) { double param = *itU; gp_Pnt P = Curve->Value(param); @@ -1158,10 +1186,9 @@ StdMeshers_Regular_1D::GetUsedHypothesis(SMESH_Mesh & aMesh, SMESH_HypoFilter auxiliaryFilter, compatibleFilter; auxiliaryFilter.Init( SMESH_HypoFilter::IsAuxiliary() ); - const bool ignoreAux = true; - InitCompatibleHypoFilter( compatibleFilter, ignoreAux ); + InitCompatibleHypoFilter( compatibleFilter, /*ignoreAux=*/true ); - // get non-auxiliary assigned to aShape + // get non-auxiliary assigned directly to aShape int nbHyp = aMesh.GetHypotheses( aShape, compatibleFilter, _usedHypList, false ); if (nbHyp == 0 && aShape.ShapeType() == TopAbs_EDGE) diff --git a/src/StdMeshersGUI/Makefile.am b/src/StdMeshersGUI/Makefile.am index 7e76cbe67..9d9875d14 100644 --- a/src/StdMeshersGUI/Makefile.am +++ b/src/StdMeshersGUI/Makefile.am @@ -16,13 +16,12 @@ # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # - # SMESH StdMeshersGUI : GUI for StdMeshers plugin # File : Makefile.in # Author : Julia DOROVSKIKH # Modified by : Alexander BORODIN (OCN) - autotools usage # Module : SMESH -# + include $(top_srcdir)/adm_local/unix/make_common_starter.am # header files @@ -33,12 +32,14 @@ salomeinclude_HEADERS = \ StdMeshersGUI_DistrTable.h \ StdMeshersGUI_NbSegmentsCreator.h \ StdMeshersGUI_ObjectReferenceParamWdg.h \ + StdMeshersGUI_QuadrangleParamWdg.h \ StdMeshersGUI_LayerDistributionParamWdg.h \ StdMeshersGUI_FixedPointsParamWdg.h \ StdMeshersGUI_SubShapeSelectorWdg.h # Libraries targets lib_LTLIBRARIES = libStdMeshersGUI.la + dist_libStdMeshersGUI_la_SOURCES = \ StdMeshersGUI.cxx \ StdMeshersGUI_StdHypothesisCreator.cxx \ @@ -46,6 +47,7 @@ dist_libStdMeshersGUI_la_SOURCES = \ StdMeshersGUI_DistrTable.cxx \ StdMeshersGUI_NbSegmentsCreator.cxx \ StdMeshersGUI_ObjectReferenceParamWdg.cxx \ + StdMeshersGUI_QuadrangleParamWdg.cxx \ StdMeshersGUI_LayerDistributionParamWdg.cxx \ StdMeshersGUI_FixedPointsParamWdg.cxx \ StdMeshersGUI_SubShapeSelectorWdg.cxx @@ -56,6 +58,7 @@ MOC_FILES = \ StdMeshersGUI_DistrTable_moc.cxx \ StdMeshersGUI_NbSegmentsCreator_moc.cxx \ StdMeshersGUI_ObjectReferenceParamWdg_moc.cxx \ + StdMeshersGUI_QuadrangleParamWdg_moc.cxx \ StdMeshersGUI_LayerDistributionParamWdg_moc.cxx \ StdMeshersGUI_FixedPointsParamWdg_moc.cxx \ StdMeshersGUI_SubShapeSelectorWdg_moc.cxx @@ -100,4 +103,5 @@ libStdMeshersGUI_la_LDFLAGS = \ # resources files nodist_salomeres_DATA= \ StdMeshers_images.qm \ - StdMeshers_msg_en.qm + StdMeshers_msg_en.qm \ + StdMeshers_msg_fr.qm diff --git a/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.h b/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.h index f50b19433..a66a82552 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.h +++ b/src/StdMeshersGUI/StdMeshersGUI_NbSegmentsCreator.h @@ -92,7 +92,7 @@ private: QLabel *myLScale, *myLTable, *myLExpr, *myInfo; QGridLayout* myGroupLayout; int myTableRow, myPreviewRow; - QRadioButton* myCutNeg; + //QRadioButton* myCutNeg; QGroupBox* myReversedEdgesBox; StdMeshersGUI_SubShapeSelectorWdg* myDirectionWidget; diff --git a/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.cxx b/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.cxx index 06f2431ec..e69489aeb 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.cxx @@ -35,9 +35,11 @@ #include #include #include +#include // SALOME KERNEL incldues #include +#include // Qt includes #include @@ -54,8 +56,8 @@ //================================================================================ StdMeshersGUI_ObjectReferenceParamWdg::StdMeshersGUI_ObjectReferenceParamWdg -( SUIT_SelectionFilter* f, QWidget* parent) - : QWidget( parent ) +( SUIT_SelectionFilter* f, QWidget* parent, bool multiSelection) + : QWidget( parent ), myMultiSelection( multiSelection ) { myFilter = f; init(); @@ -69,8 +71,8 @@ StdMeshersGUI_ObjectReferenceParamWdg::StdMeshersGUI_ObjectReferenceParamWdg //================================================================================ StdMeshersGUI_ObjectReferenceParamWdg::StdMeshersGUI_ObjectReferenceParamWdg -( MeshObjectType objType, QWidget* parent ) - : QWidget( parent ) +( MeshObjectType objType, QWidget* parent, bool multiSelection ) + : QWidget( parent ), myMultiSelection( multiSelection ) { myFilter = new SMESH_TypeFilter( objType ); init(); @@ -84,7 +86,10 @@ StdMeshersGUI_ObjectReferenceParamWdg::StdMeshersGUI_ObjectReferenceParamWdg StdMeshersGUI_ObjectReferenceParamWdg::~StdMeshersGUI_ObjectReferenceParamWdg() { if ( myFilter ) + { + mySelectionMgr->removeFilter( myFilter ); delete myFilter; + } } @@ -184,7 +189,7 @@ void StdMeshersGUI_ObjectReferenceParamWdg::AvoidSimultaneousSelection void StdMeshersGUI_ObjectReferenceParamWdg::SetObject(CORBA::Object_ptr obj) { - myObject = CORBA::Object::_nil(); + myObjects.clear(); myObjNameLineEdit->setText( "" ); myParamValue = ""; @@ -194,11 +199,43 @@ void StdMeshersGUI_ObjectReferenceParamWdg::SetObject(CORBA::Object_ptr obj) if ( sobj ) { std::string name = sobj->GetName(); myObjNameLineEdit->setText( name.c_str() ); - myObject = CORBA::Object::_duplicate( obj ); + myObjects.push_back( CORBA::Object::_duplicate( obj )); myParamValue = sobj->GetID().c_str(); } } +//================================================================================ +/*! + * \brief Initialize selected objects + * \param objects - entries of objects + */ +//================================================================================ + +void StdMeshersGUI_ObjectReferenceParamWdg::SetObjects(SMESH::string_array_var& objects) +{ + myObjects.clear(); + myObjNameLineEdit->setText( "" ); + myParamValue = ""; + + for ( unsigned i = 0; i < objects->length(); ++i ) + { + _PTR(Study) aStudy = SMESH::GetActiveStudyDocument(); + _PTR(SObject) aSObj = aStudy->FindObjectID(objects[i].in()); + CORBA::Object_var anObj = SMESH::SObjectToObject(aSObj,aStudy); + if ( !CORBA::is_nil( anObj )) { + std::string name = aSObj->GetName(); + QString text = myObjNameLineEdit->text(); + if ( !text.isEmpty() ) + text += " "; + text += name.c_str(); + myObjNameLineEdit->setText( text ); + myObjects.push_back( anObj ); + myParamValue += " "; + myParamValue += objects[i]; + } + } +} + //================================================================================ /*! * \brief Takes selected object @@ -212,7 +249,26 @@ void StdMeshersGUI_ObjectReferenceParamWdg::onSelectionDone() SALOME_ListIO aList; mySelectionMgr->selectedObjects(aList); if (aList.Extent() == 1) + { obj = SMESH::IObjectToObject( aList.First() ); - SetObject( obj.in() ); + SetObject( obj.in() ); + } + else if (myMultiSelection) + { + SMESH::string_array_var objIds = new SMESH::string_array; + objIds->length( aList.Extent()); + SALOME_ListIteratorOfListIO io( aList ); + int i = 0; + for ( ; io.More(); io.Next(), ++i ) + { + Handle(SALOME_InteractiveObject) anIO = io.Value(); + if ( anIO->hasEntry() ) + objIds[i] = anIO->getEntry(); + else + i--; + } + objIds->length(i); + SetObjects( objIds ); + } } } diff --git a/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.h b/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.h index c5fabc25e..e8c387194 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.h +++ b/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.h @@ -37,6 +37,8 @@ // CORBA includes #include +#include CORBA_SERVER_HEADER(SMESH_Mesh) + class SUIT_SelectionFilter; class SMESHGUI; class LightApp_SelectionMgr; @@ -52,22 +54,29 @@ class STDMESHERSGUI_EXPORT StdMeshersGUI_ObjectReferenceParamWdg : public QWidge public: StdMeshersGUI_ObjectReferenceParamWdg( SUIT_SelectionFilter* filter, - QWidget* parent); + QWidget* parent, + bool multiSelection=false); StdMeshersGUI_ObjectReferenceParamWdg( MeshObjectType objType, - QWidget* parent); + QWidget* parent, + bool multiSelection=false); ~StdMeshersGUI_ObjectReferenceParamWdg(); void SetObject(CORBA::Object_ptr obj); + void SetObjects(SMESH::string_array_var& objEntries); + template - typename TInterface::_var_type GetObject() const { - if ( IsObjectSelected() ) return TInterface::_narrow(myObject); + typename TInterface::_var_type GetObject(unsigned i=0) const { + if ( IsObjectSelected(i) ) return TInterface::_narrow(myObjects[i]); return TInterface::_nil(); } + int NbObjects() const { return myObjects.size(); } + QString GetValue() const { return myParamValue; } - bool IsObjectSelected() const { return !CORBA::is_nil(myObject); } + bool IsObjectSelected(unsigned i=0) const + { return i < myObjects.size() && !CORBA::is_nil(myObjects[i]); } void AvoidSimultaneousSelection( StdMeshersGUI_ObjectReferenceParamWdg* other); @@ -97,7 +106,10 @@ private: void init(); private: - CORBA::Object_var myObject; + + bool myMultiSelection; + std::vector myObjects; + SUIT_SelectionFilter* myFilter; bool mySelectionActivated; diff --git a/src/StdMeshersGUI/StdMeshersGUI_QuadrangleParamWdg.cxx b/src/StdMeshersGUI/StdMeshersGUI_QuadrangleParamWdg.cxx new file mode 100644 index 000000000..ccb38c670 --- /dev/null +++ b/src/StdMeshersGUI/StdMeshersGUI_QuadrangleParamWdg.cxx @@ -0,0 +1,100 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : StdMeshersGUI_QuadrangleParamWdg.cxx +// Author : Open CASCADE S.A.S. (jfa) +// SMESH includes + +#include "StdMeshersGUI_QuadrangleParamWdg.h" + +#include "SMESHGUI.h" + +#include "SUIT_ResourceMgr.h" + +// Qt includes +#include +#include +#include +#include + +// IDL includes +#include +#include CORBA_CLIENT_HEADER(SMESH_BasicHypothesis) + +#define SPACING 6 +#define MARGIN 0 + +//================================================================================ +// function : Constructor +// purpose : +//================================================================================ +StdMeshersGUI_QuadrangleParamWdg::StdMeshersGUI_QuadrangleParamWdg (QWidget * parent) + : QWidget(parent), + myType(0) +{ + myType = new QButtonGroup (this); + + QGridLayout* typeLay = new QGridLayout( this ); + + typeLay->setMargin(MARGIN); + typeLay->setSpacing(SPACING); + + QString aTypeKey ("SMESH_QUAD_TYPE_%1"); + QString aPictKey ("ICON_StdMeshers_Quadrangle_Params_%1"); + + int itype = 0; + for (; itype < int(StdMeshers::QUAD_NB_TYPES); itype++) { + QRadioButton* rbi = new QRadioButton (tr(aTypeKey.arg(itype).toLatin1()), this); + QPixmap pmi (SMESHGUI::resourceMgr()->loadPixmap("SMESH", tr(aPictKey.arg(itype).toLatin1()))); + QLabel* pli = new QLabel (this); + pli->setPixmap(pmi); + typeLay->addWidget(rbi, itype, 0, 1, 1); + typeLay->addWidget(pli, itype, 1, 1, 1); + myType->addButton(rbi, itype); + } + myType->button(0)->setChecked(true); + + setLayout(typeLay); + setMinimumWidth(300); +} + +//================================================================================ +// function : Destructor +// purpose : +//================================================================================ +StdMeshersGUI_QuadrangleParamWdg::~StdMeshersGUI_QuadrangleParamWdg() +{ +} + +//================================================================================= +// function : SetType +// purpose : +//================================================================================= +void StdMeshersGUI_QuadrangleParamWdg::SetType (int theType) +{ + myType->button(theType)->setChecked(true); +} + +//================================================================================= +// function : GetType +// purpose : +//================================================================================= +int StdMeshersGUI_QuadrangleParamWdg::GetType() +{ + return myType->checkedId(); +} diff --git a/src/StdMeshersGUI/StdMeshersGUI_QuadrangleParamWdg.h b/src/StdMeshersGUI/StdMeshersGUI_QuadrangleParamWdg.h new file mode 100644 index 000000000..2d5abdc45 --- /dev/null +++ b/src/StdMeshersGUI/StdMeshersGUI_QuadrangleParamWdg.h @@ -0,0 +1,49 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// File : StdMeshersGUI_QuadrangleParamWdg.h +// Author : Open CASCADE S.A.S. (jfa) + +#ifndef STDMESHERSGUI_QUADRANGLEPARAMWDG_H +#define STDMESHERSGUI_QUADRANGLEPARAMWDG_H + +// SMESH includes +#include "SMESH_StdMeshersGUI.hxx" + +// Qt includes +#include + +class QButtonGroup; + +class STDMESHERSGUI_EXPORT StdMeshersGUI_QuadrangleParamWdg : public QWidget +{ + Q_OBJECT + +public: + StdMeshersGUI_QuadrangleParamWdg (QWidget* parent = 0); + ~StdMeshersGUI_QuadrangleParamWdg(); + + void SetType (int theType); + int GetType (); + +private: + // Quadranle preference, Triangle preference, Reduced + QButtonGroup* myType; +}; + +#endif // STDMESHERSGUI_QUADRANGLEPARAMWDG_H diff --git a/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx b/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx index 8fd24f351..9595e67a0 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_StdHypothesisCreator.cxx @@ -19,23 +19,26 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // +// File : StdMeshersGUI_StdHypothesisCreator.cxx +// Author : Alexander SOLOVYOV, Open CASCADE S.A.S. +// SMESH includes -// File : StdMeshersGUI_StdHypothesisCreator.cxx -// Author : Alexander SOLOVYOV, Open CASCADE S.A.S. -// SMESH includes -// #include "StdMeshersGUI_StdHypothesisCreator.h" #include #include #include #include + #include #include -#include "StdMeshersGUI_ObjectReferenceParamWdg.h" + +#include "StdMeshersGUI_FixedPointsParamWdg.h" #include "StdMeshersGUI_LayerDistributionParamWdg.h" +#include "StdMeshersGUI_ObjectReferenceParamWdg.h" +#include "StdMeshersGUI_QuadrangleParamWdg.h" #include "StdMeshersGUI_SubShapeSelectorWdg.h" -#include "StdMeshersGUI_FixedPointsParamWdg.h" + #include // SALOME GUI includes @@ -45,6 +48,7 @@ #include #include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) #include CORBA_SERVER_HEADER(SMESH_Mesh) +#include CORBA_SERVER_HEADER(SMESH_Group) // Qt includes #include @@ -187,10 +191,10 @@ namespace { */ //================================================================================ - class TDoubleSliderWith2Lables: public QWidget + class TDoubleSliderWith2Labels: public QWidget { public: - TDoubleSliderWith2Lables( const QString& leftLabel, const QString& rightLabel, + TDoubleSliderWith2Labels( const QString& leftLabel, const QString& rightLabel, const double initValue, const double bottom, const double top , const double precision, QWidget * parent=0 , const char * name=0 ) @@ -199,7 +203,7 @@ namespace { setObjectName(name); QHBoxLayout* aHBoxL = new QHBoxLayout(this); - + if ( !leftLabel.isEmpty() ) { QLabel* aLeftLabel = new QLabel( this ); aLeftLabel->setText( leftLabel ); @@ -258,6 +262,25 @@ namespace { return SMESH::SMESH_Mesh::_nil(); } //================================================================================ + /*! + * \brief Retrieve SMESH_Mesh held by widget + */ + //================================================================================ + + inline SMESH::ListOfGroups_var groupsFromWdg(const QWidget* wdg) + { + SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups; + const StdMeshersGUI_ObjectReferenceParamWdg * objRefWdg = + dynamic_cast( wdg ); + if ( objRefWdg ) + { + groups->length( objRefWdg->NbObjects() ); + for ( unsigned i = 0; i < groups->length(); ++i ) + groups[i] = objRefWdg->GetObject< SMESH::SMESH_GroupBase >(i); + } + return groups; + } + //================================================================================ /*! * \brief creates a filter for selection of shapes of given dimension * \param dim - dimension @@ -314,6 +337,15 @@ namespace { w->SetObject( object.in() ); return w; } + QWidget* newObjRefParamWdg( SUIT_SelectionFilter* filter, + SMESH::string_array_var& objEntries) + { + StdMeshersGUI_ObjectReferenceParamWdg* w = + new StdMeshersGUI_ObjectReferenceParamWdg( filter, 0, /*multiSel=*/true); + w->SetObjects( objEntries ); + w->activateSelection(); + return w; + } //================================================================================ /*! @@ -379,6 +411,12 @@ bool StdMeshersGUI_StdHypothesisCreator::checkParams( QString& msg ) const if ( ok ) deactivateObjRefParamWdg( customWidgets() ); } + else if ( hypType().startsWith("ImportSource" )) + { + StdMeshersGUI_ObjectReferenceParamWdg* w = + widget< StdMeshersGUI_ObjectReferenceParamWdg >( 0 ); + ok = ( w->IsObjectSelected() ); + } else if ( hypType() == "LayerDistribution" || hypType() == "LayerDistribution2D" ) { StdMeshersGUI_LayerDistributionParamWdg* w = @@ -387,9 +425,11 @@ bool StdMeshersGUI_StdHypothesisCreator::checkParams( QString& msg ) const } else if ( hypType() == "QuadrangleParams" ) { - StdMeshersGUI_SubShapeSelectorWdg* w = - widget< StdMeshersGUI_SubShapeSelectorWdg >( 0 ); - ok = ( w->GetListSize() > 0 ); + //StdMeshersGUI_SubShapeSelectorWdg* w = + // widget< StdMeshersGUI_SubShapeSelectorWdg >( 0 ); + //ok = ( w->GetListSize() > 0 ); + //StdMeshersGUI_QuadrangleParamWdg* w = + // widget< StdMeshersGUI_QuadrangleParamWdg >( 1 ); } return ok; } @@ -604,18 +644,43 @@ QString StdMeshersGUI_StdHypothesisCreator::storeParams() const geomFromWdg ( getWidgetForParam( 3 )), // tgt1 geomFromWdg ( getWidgetForParam( 5 ))); // tgt2 } + else if( hypType()=="ImportSource1D" ) + { + StdMeshers::StdMeshers_ImportSource1D_var h = + StdMeshers::StdMeshers_ImportSource1D::_narrow( hypothesis() ); + + SMESH::ListOfGroups_var groups = groupsFromWdg( getWidgetForParam( 0 )); + h->SetSourceEdges( groups.in() ); + QCheckBox* toCopyMesh = widget< QCheckBox >( 1 ); + QCheckBox* toCopyGroups = widget< QCheckBox >( 2 ); + h->SetCopySourceMesh( toCopyMesh->isChecked(), toCopyGroups->isChecked()); + } + else if( hypType()=="ImportSource2D" ) + { + StdMeshers::StdMeshers_ImportSource2D_var h = + StdMeshers::StdMeshers_ImportSource2D::_narrow( hypothesis() ); + + SMESH::ListOfGroups_var groups = groupsFromWdg( getWidgetForParam( 0 )); + h->SetSourceFaces( groups.in() ); + QCheckBox* toCopyMesh = widget< QCheckBox >( 1 ); + QCheckBox* toCopyGroups = widget< QCheckBox >( 2 ); + h->SetCopySourceMesh( toCopyMesh->isChecked(), toCopyGroups->isChecked()); + } else if( hypType()=="QuadrangleParams" ) { StdMeshers::StdMeshers_QuadrangleParams_var h = StdMeshers::StdMeshers_QuadrangleParams::_narrow( hypothesis() ); - StdMeshersGUI_SubShapeSelectorWdg* w = + StdMeshersGUI_SubShapeSelectorWdg* w1 = widget< StdMeshersGUI_SubShapeSelectorWdg >( 0 ); - if (w) { - if( w->GetListSize() > 0 ) { - h->SetTriaVertex( w->GetListOfIDs()[0] ); // getlist must be called once - const char * entry = w->GetMainShapeEntry(); - h->SetObjectEntry( entry ); + StdMeshersGUI_QuadrangleParamWdg* w2 = + widget< StdMeshersGUI_QuadrangleParamWdg >( 1 ); + if (w1 && w2) { + if (w1->GetListSize() > 0) { + h->SetTriaVertex(w1->GetListOfIDs()[0]); // getlist must be called once + const char * entry = w1->GetMainShapeEntry(); + h->SetObjectEntry(entry); } + h->SetQuadType(StdMeshers::QuadType(w2->GetType())); } } } @@ -860,8 +925,10 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const item.myName = tr( "SMESH_FINENESS_PARAM" ); //item.myValue = h->GetFineness(); p.append( item ); - customWidgets()->append - ( new TDoubleSliderWith2Lables( "0 ", " 1", h->GetFineness(), 0, 1, 0.01, 0 )); + SMESHGUI_SpinBox* _autoLengthSpinBox = new SMESHGUI_SpinBox(dlg()); + _autoLengthSpinBox->RangeStepAndValidator(0, 1, 0.01, "length_precision"); + _autoLengthSpinBox->SetValue(h->GetFineness()); + customWidgets()->append( _autoLengthSpinBox); } else if( hypType()=="NumberOfLayers" ) { @@ -982,13 +1049,63 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const customWidgets()->append( newObjRefParamWdg( filterForShapeOfDim( 0 ), h->GetTargetVertex( 2 ))); } - else if( hypType()=="QuadrangleParams" ) + else if( hypType()=="ImportSource1D" ) + { + StdMeshers::StdMeshers_ImportSource1D_var h = + StdMeshers::StdMeshers_ImportSource1D::_narrow( hyp ); + + SMESH::string_array_var groupEntries = h->GetSourceEdges(); + CORBA::Boolean toCopyMesh, toCopyGroups; + h->GetCopySourceMesh(toCopyMesh, toCopyGroups); + + item.myName = tr( "SMESH_SOURCE_EDGES" ); p.append( item ); + customWidgets()->append( newObjRefParamWdg( new SMESH_TypeFilter( GROUP_EDGE ), + groupEntries)); + + item.myName = tr( "SMESH_COPY_MESH" ); p.append( item ); + QCheckBox* aQCheckBox = new QCheckBox(dlg()); + aQCheckBox->setChecked( toCopyMesh ); + connect( aQCheckBox, SIGNAL( stateChanged(int) ), this, SLOT( onValueChanged() )); + customWidgets()->append( aQCheckBox ); + + item.myName = tr( "SMESH_TO_COPY_GROUPS" ); p.append( item ); + aQCheckBox = new QCheckBox(dlg()); + aQCheckBox->setChecked( toCopyGroups ); + aQCheckBox->setEnabled( toCopyMesh ); + customWidgets()->append( aQCheckBox ); + } + else if( hypType()=="ImportSource2D" ) + { + StdMeshers::StdMeshers_ImportSource2D_var h = + StdMeshers::StdMeshers_ImportSource2D::_narrow( hyp ); + + SMESH::string_array_var groupEntries = h->GetSourceFaces(); + CORBA::Boolean toCopyMesh, toCopyGroups; + h->GetCopySourceMesh(toCopyMesh, toCopyGroups); + + item.myName = tr( "SMESH_SOURCE_FACES" ); p.append( item ); + customWidgets()->append( newObjRefParamWdg( new SMESH_TypeFilter( GROUP_FACE ), + groupEntries)); + + item.myName = tr( "SMESH_COPY_MESH" ); p.append( item ); + QCheckBox* aQCheckBox = new QCheckBox(dlg()); + aQCheckBox->setChecked( toCopyMesh ); + connect( aQCheckBox, SIGNAL( stateChanged(int) ), this, SLOT( onValueChanged() )); + customWidgets()->append( aQCheckBox ); + + item.myName = tr( "SMESH_COPY_GROUPS" ); p.append( item ); + aQCheckBox = new QCheckBox(dlg()); + aQCheckBox->setChecked( toCopyGroups ); + aQCheckBox->setEnabled( toCopyMesh ); + customWidgets()->append( aQCheckBox ); + } + else if (hypType() == "QuadrangleParams") { StdMeshers::StdMeshers_QuadrangleParams_var h = - StdMeshers::StdMeshers_QuadrangleParams::_narrow( hyp ); + StdMeshers::StdMeshers_QuadrangleParams::_narrow(hyp); - item.myName = tr( "SMESH_BASE_VERTEX" ); - p.append( item ); + item.myName = tr("SMESH_BASE_VERTEX"); + p.append(item); StdMeshersGUI_SubShapeSelectorWdg* aDirectionWidget = new StdMeshersGUI_SubShapeSelectorWdg(); @@ -996,21 +1113,32 @@ bool StdMeshersGUI_StdHypothesisCreator::stdParams( ListOfStdParams& p ) const aDirectionWidget->SetSubShType(TopAbs_VERTEX); QString anEntry = SMESHGUI_GenericHypothesisCreator::getShapeEntry(); QString aMainEntry = SMESHGUI_GenericHypothesisCreator::getMainShapeEntry(); - if ( anEntry == "" ) + if (anEntry == "") anEntry = h->GetObjectEntry(); - aDirectionWidget->SetGeomShapeEntry( anEntry ); - aDirectionWidget->SetMainShapeEntry( aMainEntry ); - if ( !isCreation() ) { + aDirectionWidget->SetGeomShapeEntry(anEntry); + aDirectionWidget->SetMainShapeEntry(aMainEntry); + if (!isCreation()) { SMESH::long_array_var aVec = new SMESH::long_array; int vertID = h->GetTriaVertex(); - if(vertID>0) { + if (vertID > 0) { aVec->length(1); aVec[0] = vertID; - aDirectionWidget->SetListOfIDs( aVec ); + aDirectionWidget->SetListOfIDs(aVec); } } - aDirectionWidget->showPreview( true ); - customWidgets()->append ( aDirectionWidget ); + aDirectionWidget->showPreview(true); + + item.myName = tr("SMESH_QUAD_TYPE"); + p.append(item); + + StdMeshersGUI_QuadrangleParamWdg* aTypeWidget = + new StdMeshersGUI_QuadrangleParamWdg(); + if (!isCreation()) { + aTypeWidget->SetType(int(h->GetQuadType())); + } + + customWidgets()->append(aDirectionWidget); + customWidgets()->append(aTypeWidget); } else res = false; @@ -1129,6 +1257,8 @@ QString StdMeshersGUI_StdHypothesisCreator::hypTypeName( const QString& t ) cons types.insert( "ProjectionSource1D", "PROJECTION_SOURCE_1D" ); types.insert( "ProjectionSource2D", "PROJECTION_SOURCE_2D" ); types.insert( "ProjectionSource3D", "PROJECTION_SOURCE_3D" ); + types.insert( "ImportSource1D", "IMPORT_SOURCE_1D" ); + types.insert( "ImportSource2D", "IMPORT_SOURCE_2D" ); types.insert( "NumberOfLayers", "NUMBER_OF_LAYERS" ); types.insert( "LayerDistribution", "LAYER_DISTRIBUTION" ); types.insert( "NumberOfLayers2D", "NUMBER_OF_LAYERS_2D" ); @@ -1181,9 +1311,9 @@ bool StdMeshersGUI_StdHypothesisCreator::getParamFromCustomWidget( StdParam & pa QWidget* widget) const { if ( hypType()=="AutomaticLength" ) { - TDoubleSliderWith2Lables* w = dynamic_cast( widget ); + SMESHGUI_SpinBox* w = dynamic_cast( widget ); if ( w ) { - param.myValue = w->value(); + param.myValue = w->GetValue(); return true; } } @@ -1215,6 +1345,13 @@ bool StdMeshersGUI_StdHypothesisCreator::getParamFromCustomWidget( StdParam & pa param.myValue = w->GetValue(); return true; } + if ( widget->inherits( "StdMeshersGUI_QuadrangleParamWdg" )) + { + //const StdMeshersGUI_QuadrangleParamWdg * w = + // static_cast( widget ); + param.myValue = "QuadType"; + return true; + } if ( widget->inherits( "StdMeshersGUI_FixedPointsParamWdg" )) { const StdMeshersGUI_FixedPointsParamWdg * w = @@ -1222,6 +1359,12 @@ bool StdMeshersGUI_StdHypothesisCreator::getParamFromCustomWidget( StdParam & pa param.myValue = w->GetValue(); return true; } + if ( widget->inherits( "QCheckBox" )) + { + //const QCheckBox * w = static_cast( widget ); + //param.myValue = w->isChecked(); + return true; + } return false; } @@ -1233,7 +1376,8 @@ bool StdMeshersGUI_StdHypothesisCreator::getParamFromCustomWidget( StdParam & pa void StdMeshersGUI_StdHypothesisCreator::onReject() { - if ( hypType().startsWith("ProjectionSource" )) + if ( hypType().startsWith("ProjectionSource" ) || + hypType().startsWith("ImportSource" )) { // Uninstall filters of StdMeshersGUI_ObjectReferenceParamWdg deactivateObjRefParamWdg( customWidgets() ); @@ -1242,13 +1386,14 @@ void StdMeshersGUI_StdHypothesisCreator::onReject() //================================================================================ /*! - * \brief + * \brief Update widgets dependent on paramWidget */ //================================================================================ void StdMeshersGUI_StdHypothesisCreator::valueChanged( QWidget* paramWidget) { - if ( hypType() == "MaxLength" && paramWidget == getWidgetForParam(1) ) { + if ( hypType() == "MaxLength" && paramWidget == getWidgetForParam(1) ) + { getWidgetForParam(0)->setEnabled( !widget< QCheckBox >( 1 )->isChecked() ); if ( !getWidgetForParam(0)->isEnabled() ) { StdMeshers::StdMeshers_MaxLength_var h = @@ -1256,6 +1401,20 @@ void StdMeshersGUI_StdHypothesisCreator::valueChanged( QWidget* paramWidget) widget< QtxDoubleSpinBox >( 0 )->setValue( h->GetPreestimatedLength() ); } } + else if ( hypType().startsWith("ImportSource") && paramWidget == getWidgetForParam(1) ) + { + QCheckBox* toCopyMesh = (QCheckBox*) paramWidget; + QCheckBox* toCopyGroups = widget< QCheckBox >( 2 ); + if ( !toCopyMesh->isChecked() ) + { + toCopyGroups->setChecked( false ); + toCopyGroups->setEnabled( false ); + } + else + { + toCopyGroups->setEnabled( true ); + } + } } //================================================================================ diff --git a/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx b/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx index 4bc2b7549..9a8e3827c 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx @@ -24,14 +24,15 @@ #include "StdMeshersGUI_SubShapeSelectorWdg.h" // SMESH Includes -#include +#include "SMESH_Type.h" #include "SMESHGUI_MeshUtils.h" -#include -#include -#include +#include "SMESH_Actor.h" +#include "SMESH_PreviewActorsCollection.h" +#include "SMESH_ActorUtils.h" #include "SMESHGUI_GroupUtils.h" #include "SMESH_Gen_i.hxx" #include "SMESHGUI_GEOMGenUtils.h" +#include "SMESH_LogicalFilter.hxx" // SVTK Includes #include @@ -49,6 +50,8 @@ // GEOM Includes #include +#include +#include // Qt includes #include @@ -63,10 +66,12 @@ #include #include #include +#include // SALOME KERNEL includes #include + #define SPACING 6 #define MARGIN 0 @@ -128,6 +133,14 @@ StdMeshersGUI_SubShapeSelectorWdg::~StdMeshersGUI_SubShapeSelectorWdg() myEntry = ""; myParamValue = ""; myMainShape.Nullify(); + + if ( mySelectionMgr && myFilter ) + mySelectionMgr->removeFilter( myFilter ); + delete myFilter; myFilter=0; + + SUIT_SelectionFilter* filter; + foreach( filter, myGeomFilters ) + delete filter; } //================================================================================ @@ -153,6 +166,16 @@ void StdMeshersGUI_SubShapeSelectorWdg::init() if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) aViewWindow->SetSelectionMode( ActorSelection ); + + SalomeApp_Study* study = mySMESHGUI->activeStudy(); + GEOM_EdgeFilter* edgeFilter = new GEOM_EdgeFilter(study,StdSelect_AnyEdge); + GEOM_CompoundFilter* gpoupFilter = new GEOM_CompoundFilter(study); + gpoupFilter->addSubType( TopAbs_EDGE ); + myGeomFilters.append( edgeFilter ); + myGeomFilters.append( gpoupFilter ); + myFilter = new SMESH_LogicalFilter( myGeomFilters, SMESH_LogicalFilter::LO_OR ); + mySelectionMgr->installFilter( myFilter ); + connect( myAddButton, SIGNAL(clicked()), SLOT(onAdd())); connect( myRemoveButton, SIGNAL(clicked()), SLOT(onRemove())); @@ -222,7 +245,8 @@ void StdMeshersGUI_SubShapeSelectorWdg::SelectionIntoArgument() aFatherEntry = aGeomFatherObj->GetStudyEntry(); } - if ( aFatherEntry != "" && ( aFatherEntry == myEntry || aFatherEntry == aMainFatherEntry ) ) { + if ( aFatherEntry != "" && ( aFatherEntry == myEntry || aFatherEntry == aMainFatherEntry ) ) + { if ( aGeomObj->GetType() == 37 /*GEOM_GROUP*/ ) { // Selected Group that belongs the main object GEOMBase::GetShape(aGeomObj, shape); if ( !shape.IsNull() ) { @@ -258,7 +282,7 @@ void StdMeshersGUI_SubShapeSelectorWdg::SelectionIntoArgument() } } // update add button - myAddButton->setEnabled( myListWidget->count() < myMaxSize && mySelectedIDs.size() > 0 && ( mySelectedIDs.size() <= myMaxSize || myMaxSize == -1 ) ); + myAddButton->setEnabled( ( myListWidget->count() < myMaxSize || myMaxSize == -1 ) && mySelectedIDs.size() > 0 && ( mySelectedIDs.size() <= myMaxSize || myMaxSize == -1 ) ); //Connect Selected Ids in viewer and dialog's Ids list myListWidget->clearSelection(); diff --git a/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.h b/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.h index b29840bdf..591d28b6f 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.h +++ b/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.h @@ -45,6 +45,7 @@ class QListWidget; class SMESH_Actor; class SMESH_PreviewActorsCollection; class vtkRenderer; +class SUIT_SelectionFilter; class STDMESHERSGUI_EXPORT StdMeshersGUI_SubShapeSelectorWdg : public QWidget { @@ -119,6 +120,8 @@ private: TopAbs_ShapeEnum mySubShType; SMESH_PreviewActorsCollection* myPreviewActor; + QList myGeomFilters; + SUIT_SelectionFilter* myFilter; }; #endif // STDMESHERSGUI_SUBSHAPESELECTORWDG_H diff --git a/src/StdMeshersGUI/StdMeshers_images.ts b/src/StdMeshersGUI/StdMeshers_images.ts index da9130846..87444b56a 100644 --- a/src/StdMeshersGUI/StdMeshers_images.ts +++ b/src/StdMeshersGUI/StdMeshers_images.ts @@ -89,6 +89,18 @@ ICON_DLG_PROJECTION_SOURCE_3D mesh_hypo_source_3d.png + + ICON_DLG_QUADRANGLE_PARAMS + mesh_hypo_length.png + + + ICON_DLG_IMPORT_SOURCE_1D + mesh_hypo_source_edge.png + + + ICON_DLG_IMPORT_SOURCE_2D + mesh_hypo_source_face.png + ICON_DLG_SEGMENT_LENGTH_AROUND_VERTEX mesh_hypo_length.png @@ -241,9 +253,28 @@ ICON_SMESH_TREE_HYPO_StartEndLength mesh_tree_hypo_length.png + + + StdMeshersGUI_QuadrangleParamWdg + + ICON_StdMeshers_Quadrangle_Params_0 + mesh_quadrangle_standard.png + - ICON_DLG_QUADRANGLE_PARAMS - mesh_hypo_length.png + ICON_StdMeshers_Quadrangle_Params_1 + mesh_quadrangle_triapref.png + + + ICON_StdMeshers_Quadrangle_Params_2 + mesh_quadrangle_quadpref.png + + + ICON_StdMeshers_Quadrangle_Params_3 + mesh_quadrangle_quadpref_reversed.png + + + ICON_StdMeshers_Quadrangle_Params_4 + mesh_quadrangle_reduced.png diff --git a/src/StdMeshersGUI/StdMeshers_msg_en.ts b/src/StdMeshersGUI/StdMeshers_msg_en.ts index 574646e01..75888dfa3 100644 --- a/src/StdMeshersGUI/StdMeshers_msg_en.ts +++ b/src/StdMeshersGUI/StdMeshers_msg_en.ts @@ -1,380 +1,417 @@ + - - - - @default - - SMESH_ARITHMETIC_1D_HYPOTHESIS - Arithmetic 1D - - - SMESH_ARITHMETIC_1D_PARAM - Arithmetic Reason - - - SMESH_ARITHMETIC_1D_TITLE - Hypothesis Construction - - - SMESH_AUTOMATIC_LENGTH_HYPOTHESIS - Automatic Length - - - SMESH_AUTOMATIC_LENGTH_TITLE - Hypothesis Construction - - - SMESH_CONV_MODE - Conversion mode - - - SMESH_CUT_NEG_MODE - Cut negative - - - SMESH_DEFLECTION1D_HYPOTHESIS - Deflection 1D - - - SMESH_DEFLECTION1D_PARAM - Deflection - - - SMESH_DEFLECTION1D_TITLE - Hypothesis Construction - - - SMESH_DENSITY_FUNC - Density function - - - SMESH_DISTR - Distribution - - - SMESH_DISTR_EXPR - Distribution with analitic density - - - SMESH_DISTR_REGULAR - Equidistant distribution - - - SMESH_DISTR_SCALE - Scale distribution - - - SMESH_DISTR_TAB - Distribution with table density - - - SMESH_DISTR_TYPE - Type of distribution - - - SMESH_END_LENGTH_PARAM - End Length - - - SMESH_EXPR_FUNC - Density function f(t) = - - - SMESH_EXP_MODE - Exponent - - - SMESH_FINENESS_PARAM - Fineness - - - SMESH_FUNC_DOMAIN - Warning: function must be defined on segment [0..1] - - - SMESH_INSERT_ROW - Insert row - - - SMESH_INVALID_FUNCTION - Function is invalid - - - SMESH_LAYERS_DISTRIBUTION - 1D Hypothesis - - - SMESH_LAYER_DISTRIBUTION_HYPOTHESIS - Distribution of Layers - - - SMESH_LAYER_DISTRIBUTION_TITLE - Hypothesis Construction - - - SMESH_LOCAL_LENGTH_HYPOTHESIS - Average Length - - - SMESH_LOCAL_LENGTH_PARAM - Length - - - SMESH_LOCAL_LENGTH_PRECISION - Precision - - - SMESH_LOCAL_LENGTH_TITLE - Hypothesis Construction - - - SMESH_FIXED_POINTS_1D_HYPOTHESIS - Fixed points 1D - - - SMESH_FIXED_POINTS_1D_TITLE - Hypothesis Construction - - - SMESH_MAX_LENGTH_HYPOTHESIS - Max Length - - - SMESH_USE_PREESTIMATED_LENGTH - Use preestimated length - - - SMESH_MAX_LENGTH_TITLE - Hypothesis Construction - - - SMESH_MAX_ELEMENT_AREA_HYPOTHESIS - Max. Element Area - - - SMESH_MAX_ELEMENT_AREA_PARAM - Max. Area - - - SMESH_MAX_ELEMENT_AREA_TITLE - Hypothesis Construction - - - SMESH_MAX_ELEMENT_VOLUME_HYPOTHESIS - Max. Element Volume - - - SMESH_MAX_ELEMENT_VOLUME_PARAM - Max. Volume - - - SMESH_MAX_ELEMENT_VOLUME_TITLE - Hypothesis Construction - - - SMESH_NB_SEGMENTS_HYPOTHESIS - Number of Segments - - - SMESH_NB_SEGMENTS_PARAM - Number of Segments - - - SMESH_NB_SEGMENTS_SCALE_PARAM - Scale Factor - - - SMESH_NB_SEGMENTS_TITLE - Hypothesis Construction - - - SMESH_NO_CONV - No conversion - - - SMESH_NUMBER_OF_LAYERS - Number of Layers - - - SMESH_NUMBER_OF_LAYERS_HYPOTHESIS - Radial Prism Parameter - - - SMESH_NUMBER_OF_LAYERS_2D_HYPOTHESIS - Radial Quadrangle Parameter - - - SMESH_NUMBER_OF_LAYERS_TITLE - Hypothesis Construction - - - SMESH_NUMBER_OF_LAYERS_2D_TITLE - Hypothesis Construction - - - SMESH_PROJECTION_SOURCE_1D_HYPOTHESIS - Projection Source 1D - - - SMESH_PROJECTION_SOURCE_1D_TITLE - Hypothesis Construction - - - SMESH_PROJECTION_SOURCE_2D_HYPOTHESIS - Projection Source 2D - - - SMESH_PROJECTION_SOURCE_2D_TITLE - Hypothesis Construction - - - SMESH_PROJECTION_SOURCE_3D_HYPOTHESIS - Projection Source 3D - - - SMESH_PROJECTION_SOURCE_3D_TITLE - Hypothesis Construction - - - SMESH_REMOVE_ROW - Remove row - - - SMESH_REVERSED_EDGES - Reversed Edges - - - SMESH_FIXED_POINTS - Fixed Points - - - SMESH_RANGE - Range - - - SMESH_NB_SEGMENTS - Nb. Segments - - - SMESH_SAME_NB_SEGMENTS - Same Nb. Segments for All Intervals - - - SMESH_BASE_VERTEX - Base vertex - - - SMESH_SEGMENT_LENGTH_AROUND_VERTEX_HYPOTHESIS - Segment Length Around Vertex - - - SMESH_SEGMENT_LENGTH_AROUND_VERTEX_PARAM - Length - - - SMESH_SEGMENT_LENGTH_AROUND_VERTEX_TITLE - Hypothesis Construction - - - SMESH_SOURCE_3DSHAPE - 3D shape - - - SMESH_SOURCE_EDGE - Edge - - - SMESH_SOURCE_FACE - Face - - - SMESH_SOURCE_MESH - Mesh - - - SMESH_SOURCE_VERTEX - Source Vertex - - - SMESH_SOURCE_VERTEX1 - Source Vertex 1 - - - SMESH_SOURCE_VERTEX2 - Source Vertex 2 - - - SMESH_START_END_LENGTH_HYPOTHESIS - Start and End local Length - - - SMESH_START_END_LENGTH_TITLE - Hypothesis Construction - - - SMESH_START_LENGTH_PARAM - Start Length - - - SMESH_TAB_FUNC - Table function - - - SMESH_TARGET_VERTEX - Target Vertex - - - SMESH_TARGET_VERTEX1 - Target Vertex 1 - - - SMESH_TARGET_VERTEX2 - Target Vertex 2 - - - SMESH_QUADRANGLE_PARAMS_HYPOTHESIS - Quadrangle parameters - - - SMESH_QUADRANGLE_PARAMS_TITLE - Hypothesis Construction - - - - StdMeshersGUI_LayerDistributionParamWdg - - CHANGE_TYPE - Change Type - - - CREATE - Create - - - EDIT - Edit - - + + + @default + + SMESH_ARITHMETIC_1D_HYPOTHESIS + Arithmetic 1D + + + SMESH_ARITHMETIC_1D_PARAM + Arithmetic Reason + + + SMESH_ARITHMETIC_1D_TITLE + Hypothesis Construction + + + SMESH_AUTOMATIC_LENGTH_HYPOTHESIS + Automatic Length + + + SMESH_AUTOMATIC_LENGTH_TITLE + Hypothesis Construction + + + SMESH_CONV_MODE + Conversion mode + + + SMESH_CUT_NEG_MODE + Cut negative + + + SMESH_DEFLECTION1D_HYPOTHESIS + Deflection 1D + + + SMESH_DEFLECTION1D_PARAM + Deflection + + + SMESH_DEFLECTION1D_TITLE + Hypothesis Construction + + + SMESH_DENSITY_FUNC + Density function + + + SMESH_DISTR + Distribution + + + SMESH_DISTR_EXPR + Distribution with analitic density + + + SMESH_DISTR_REGULAR + Equidistant distribution + + + SMESH_DISTR_SCALE + Scale distribution + + + SMESH_DISTR_TAB + Distribution with table density + + + SMESH_DISTR_TYPE + Type of distribution + + + SMESH_END_LENGTH_PARAM + End Length + + + SMESH_EXPR_FUNC + Density function f(t) = + + + SMESH_EXP_MODE + Exponent + + + SMESH_FINENESS_PARAM + Fineness + + + SMESH_FUNC_DOMAIN + Warning: function must be defined on segment [0..1] + + + SMESH_INSERT_ROW + Insert row + + + SMESH_INVALID_FUNCTION + Function is invalid + + + SMESH_LAYERS_DISTRIBUTION + 1D Hypothesis + + + SMESH_LAYER_DISTRIBUTION_HYPOTHESIS + Distribution of Layers + + + SMESH_LAYER_DISTRIBUTION_TITLE + Hypothesis Construction + + + SMESH_LOCAL_LENGTH_HYPOTHESIS + Local Length + + + SMESH_LOCAL_LENGTH_PARAM + Length + + + SMESH_LOCAL_LENGTH_PRECISION + Precision + + + SMESH_LOCAL_LENGTH_TITLE + Hypothesis Construction + + + SMESH_FIXED_POINTS_1D_HYPOTHESIS + Fixed points 1D + + + SMESH_FIXED_POINTS_1D_TITLE + Hypothesis Construction + + + SMESH_MAX_LENGTH_HYPOTHESIS + Max Length + + + SMESH_USE_PREESTIMATED_LENGTH + Use preestimated length + + + SMESH_MAX_LENGTH_TITLE + Hypothesis Construction + + + SMESH_MAX_ELEMENT_AREA_HYPOTHESIS + Max. Element Area + + + SMESH_MAX_ELEMENT_AREA_PARAM + Max. Area + + + SMESH_MAX_ELEMENT_AREA_TITLE + Hypothesis Construction + + + SMESH_MAX_ELEMENT_VOLUME_HYPOTHESIS + Max. Element Volume + + + SMESH_MAX_ELEMENT_VOLUME_PARAM + Max. Volume + + + SMESH_MAX_ELEMENT_VOLUME_TITLE + Hypothesis Construction + + + SMESH_NB_SEGMENTS_HYPOTHESIS + Number of Segments + + + SMESH_NB_SEGMENTS_PARAM + Number of Segments + + + SMESH_NB_SEGMENTS_SCALE_PARAM + Scale Factor + + + SMESH_NB_SEGMENTS_TITLE + Hypothesis Construction + + + SMESH_NO_CONV + No conversion + + + SMESH_NUMBER_OF_LAYERS + Number of Layers + + + SMESH_NUMBER_OF_LAYERS_HYPOTHESIS + Radial Prism Parameter + + + SMESH_NUMBER_OF_LAYERS_2D_HYPOTHESIS + Radial Quadrangle Parameter + + + SMESH_NUMBER_OF_LAYERS_TITLE + Hypothesis Construction + + + SMESH_NUMBER_OF_LAYERS_2D_TITLE + Hypothesis Construction + + + SMESH_PROJECTION_SOURCE_1D_HYPOTHESIS + Projection Source 1D + + + SMESH_PROJECTION_SOURCE_1D_TITLE + Hypothesis Construction + + + SMESH_PROJECTION_SOURCE_2D_HYPOTHESIS + Projection Source 2D + + + SMESH_PROJECTION_SOURCE_2D_TITLE + Hypothesis Construction + + + SMESH_PROJECTION_SOURCE_3D_HYPOTHESIS + Projection Source 3D + + + SMESH_PROJECTION_SOURCE_3D_TITLE + Hypothesis Construction + + + SMESH_IMPORT_SOURCE_1D_HYPOTHESIS + Source edges + + + SMESH_IMPORT_SOURCE_1D_TITLE + Hypothesis Construction + + + SMESH_IMPORT_SOURCE_2D_HYPOTHESIS + Source faces + + + SMESH_IMPORT_SOURCE_2D_TITLE + Hypothesis Construction + + + SMESH_REMOVE_ROW + Remove row + + + SMESH_REVERSED_EDGES + Reversed Edges + + + SMESH_FIXED_POINTS + Fixed Points + + + SMESH_RANGE + Range + + + SMESH_NB_SEGMENTS + Nb. Segments + + + SMESH_SAME_NB_SEGMENTS + Same Nb. Segments for All Intervals + + + SMESH_BASE_VERTEX + Base vertex + + + SMESH_SEGMENT_LENGTH_AROUND_VERTEX_HYPOTHESIS + Segment Length Around Vertex + + + SMESH_SEGMENT_LENGTH_AROUND_VERTEX_PARAM + Length + + + SMESH_SEGMENT_LENGTH_AROUND_VERTEX_TITLE + Hypothesis Construction + + + SMESH_SOURCE_3DSHAPE + 3D shape + + + SMESH_SOURCE_EDGE + Edge + + + SMESH_SOURCE_EDGES + Groups of Edges + + + SMESH_SOURCE_FACE + Face + + + SMESH_SOURCE_FACES + Groups of Faces + + + SMESH_SOURCE_MESH + Mesh + + + SMESH_COPY_MESH + To copy mesh + + + SMESH_TO_COPY_GROUPS + To copy groups + + + SMESH_SOURCE_VERTEX + Source Vertex + + + SMESH_SOURCE_VERTEX1 + Source Vertex 1 + + + SMESH_SOURCE_VERTEX2 + Source Vertex 2 + + + SMESH_START_END_LENGTH_HYPOTHESIS + Start and End local Length + + + SMESH_START_END_LENGTH_TITLE + Hypothesis Construction + + + SMESH_START_LENGTH_PARAM + Start Length + + + SMESH_TAB_FUNC + Table function + + + SMESH_TARGET_VERTEX + Target Vertex + + + SMESH_TARGET_VERTEX1 + Target Vertex 1 + + + SMESH_TARGET_VERTEX2 + Target Vertex 2 + + + SMESH_QUADRANGLE_PARAMS_HYPOTHESIS + Quadrangle parameters + + + SMESH_QUADRANGLE_PARAMS_TITLE + Hypothesis Construction + + + SMESH_QUAD_TYPE + Type + + + + StdMeshersGUI_QuadrangleParamWdg + + SMESH_QUAD_TYPE_0 + Standard + + + SMESH_QUAD_TYPE_1 + Triangle preference + + + SMESH_QUAD_TYPE_2 + Quadrangle preference + + + SMESH_QUAD_TYPE_3 + Quadrangle preference (reversed) + + + SMESH_QUAD_TYPE_4 + Reduced + + + + StdMeshersGUI_LayerDistributionParamWdg + + CHANGE_TYPE + Change Type + + + CREATE + Create + + + EDIT + Edit + + diff --git a/src/StdMeshersGUI/StdMeshers_msg_fr.ts b/src/StdMeshersGUI/StdMeshers_msg_fr.ts new file mode 100755 index 000000000..5f3e75f46 --- /dev/null +++ b/src/StdMeshersGUI/StdMeshers_msg_fr.ts @@ -0,0 +1,385 @@ + + + + + @default + + SMESH_ARITHMETIC_1D_HYPOTHESIS + Arithmétique 1D + + + SMESH_ARITHMETIC_1D_PARAM + Raison arithmétique + + + SMESH_ARITHMETIC_1D_TITLE + Construction de l'hypothèse + + + SMESH_AUTOMATIC_LENGTH_HYPOTHESIS + Longueur automatique + + + SMESH_AUTOMATIC_LENGTH_TITLE + Construction de l'hypothèse + + + SMESH_CONV_MODE + Mode de conversion + + + SMESH_CUT_NEG_MODE + Section négative + + + SMESH_DEFLECTION1D_HYPOTHESIS + Déflection 1D + + + SMESH_DEFLECTION1D_PARAM + Déflection + + + SMESH_DEFLECTION1D_TITLE + Construction de l'hypothèse + + + SMESH_DENSITY_FUNC + Fonction de densité + + + SMESH_DISTR + Distribution + + + SMESH_DISTR_EXPR + Distribution de densité analytique + + + SMESH_DISTR_REGULAR + Distribution équidistante + + + SMESH_DISTR_SCALE + Progression géométrique + + + SMESH_DISTR_TAB + Table de densités + + + SMESH_DISTR_TYPE + Type de distribution + + + SMESH_END_LENGTH_PARAM + Longueur finale + + + SMESH_EXPR_FUNC + Expression de la densité f(t) = + + + SMESH_EXP_MODE + Exposant + + + SMESH_FINENESS_PARAM + Finesse + + + SMESH_FUNC_DOMAIN + Avertissement: il faut définir la fonction sur le segment [0..1] + + + SMESH_INSERT_ROW + Insérer une ligne + + + SMESH_INVALID_FUNCTION + La fonction n'est pas valide + + + SMESH_LAYERS_DISTRIBUTION + Hypothèse 1D + + + SMESH_LAYER_DISTRIBUTION_HYPOTHESIS + Distribution des couches + + + SMESH_LAYER_DISTRIBUTION_TITLE + Construction de l'hypothèse + + + SMESH_LOCAL_LENGTH_HYPOTHESIS + Longueur moyennne + + + SMESH_LOCAL_LENGTH_PARAM + Longueur + + + SMESH_LOCAL_LENGTH_PRECISION + Précision + + + SMESH_LOCAL_LENGTH_TITLE + Construction de l'hypothèse + + + SMESH_FIXED_POINTS_1D_HYPOTHESIS + Points fixes 1D + + + SMESH_FIXED_POINTS_1D_TITLE + Construction de l'hypothèse + + + SMESH_MAX_LENGTH_HYPOTHESIS + Longueur maximale + + + SMESH_USE_PREESTIMATED_LENGTH + Utiliser la longueur pré-estimée + + + SMESH_MAX_LENGTH_TITLE + Construction de l'hypothèse + + + SMESH_MAX_ELEMENT_AREA_HYPOTHESIS + Aire maximale d'une maille + + + SMESH_MAX_ELEMENT_AREA_PARAM + Aire maximale + + + SMESH_MAX_ELEMENT_AREA_TITLE + Construction de l'hypothèse + + + SMESH_MAX_ELEMENT_VOLUME_HYPOTHESIS + Volume maximal d'une maille + + + SMESH_MAX_ELEMENT_VOLUME_PARAM + Volume maximal + + + SMESH_MAX_ELEMENT_VOLUME_TITLE + Construction de l'hypothèse + + + SMESH_NB_SEGMENTS_HYPOTHESIS + Nombre de segments + + + SMESH_NB_SEGMENTS_PARAM + Nombre de segments + + + SMESH_NB_SEGMENTS_SCALE_PARAM + Facteur d'échelle + + + SMESH_NB_SEGMENTS_TITLE + Construction de l'hypothèse + + + SMESH_NO_CONV + Sans conversion + + + SMESH_NUMBER_OF_LAYERS + Nombre de couches + + + SMESH_NUMBER_OF_LAYERS_HYPOTHESIS + Paramètre des prismes radiaux + + + SMESH_NUMBER_OF_LAYERS_2D_HYPOTHESIS + Paramètre des quadrangles radiaux + + + SMESH_NUMBER_OF_LAYERS_TITLE + Construction de l'hypothèse + + + SMESH_NUMBER_OF_LAYERS_2D_TITLE + Construction de l'hypothèse + + + SMESH_PROJECTION_SOURCE_1D_HYPOTHESIS + Source pour le projection 1D + + + SMESH_PROJECTION_SOURCE_1D_TITLE + Construction de l'hypothèse + + + SMESH_PROJECTION_SOURCE_2D_HYPOTHESIS + Source pour la projection 2D + + + SMESH_PROJECTION_SOURCE_2D_TITLE + Construction de l'hypothèse + + + SMESH_PROJECTION_SOURCE_3D_HYPOTHESIS + Source pour la projection 3D + + + SMESH_PROJECTION_SOURCE_3D_TITLE + Construction de l'hypothèse + + + SMESH_REMOVE_ROW + Supprimer une ligne + + + SMESH_REVERSED_EDGES + Arêtes inversées + + + SMESH_FIXED_POINTS + Points fixés + + + SMESH_RANGE + Intervalle + + + SMESH_NB_SEGMENTS + Nb. segments + + + SMESH_SAME_NB_SEGMENTS + Le même Nb. segments dans chaque intervalle + + + SMESH_BASE_VERTEX + Point de base + + + SMESH_SEGMENT_LENGTH_AROUND_VERTEX_HYPOTHESIS + Longueur des segments autour d'un point + + + SMESH_SEGMENT_LENGTH_AROUND_VERTEX_PARAM + Longueur + + + SMESH_SEGMENT_LENGTH_AROUND_VERTEX_TITLE + Construction de l'hypothèse + + + SMESH_SOURCE_3DSHAPE + Objet 3D + + + SMESH_SOURCE_EDGE + Arête + + + SMESH_SOURCE_FACE + Face + + + SMESH_SOURCE_MESH + Maillage + + + SMESH_SOURCE_VERTEX + Point source + + + SMESH_SOURCE_VERTEX1 + Point source 1 + + + SMESH_SOURCE_VERTEX2 + Point source 2 + + + SMESH_START_END_LENGTH_HYPOTHESIS + Start and end local Length + + + SMESH_START_END_LENGTH_TITLE + Construction de l'hypothèse + + + SMESH_START_LENGTH_PARAM + Longueur initiale + + + SMESH_TAB_FUNC + Table de valeurs de la fonction + + + SMESH_TARGET_VERTEX + Point cible + + + SMESH_TARGET_VERTEX1 + Point cible 1 + + + SMESH_TARGET_VERTEX2 + Point cible 2 + + + SMESH_QUADRANGLE_PARAMS_HYPOTHESIS + Paramètres pour le maillage quadrangulaire + + + SMESH_QUADRANGLE_PARAMS_TITLE + Construction de l'hypothèse + + + SMESH_QUAD_TYPE + Type + + + + StdMeshersGUI_QuadrangleParamWdg + + SMESH_QUAD_TYPE_0 + Standard + + + SMESH_QUAD_TYPE_1 + Triangles privilégiés + + + SMESH_QUAD_TYPE_2 + Quadrangles privilégiés + + + SMESH_QUAD_TYPE_3 + Quadrangles privilégiés (inversé) + + + SMESH_QUAD_TYPE_4 + Réduction + + + + StdMeshersGUI_LayerDistributionParamWdg + + CHANGE_TYPE + Changer le type + + + CREATE + Créer + + + EDIT + Editer + + + diff --git a/src/StdMeshers_I/Makefile.am b/src/StdMeshers_I/Makefile.am index 3331c0b36..17d7c9f6f 100644 --- a/src/StdMeshers_I/Makefile.am +++ b/src/StdMeshers_I/Makefile.am @@ -63,7 +63,11 @@ salomeinclude_HEADERS = \ StdMeshers_MaxLength_i.hxx \ StdMeshers_QuadrangleParams_i.hxx \ StdMeshers_RadialQuadrangle_1D2D_i.hxx \ - SMESH_StdMeshers_I.hxx + SMESH_StdMeshers_I.hxx \ + StdMeshers_ImportSource1D_i.hxx \ + StdMeshers_ImportSource2D_i.hxx \ + StdMeshers_Import_1D_i.hxx \ + StdMeshers_Import_1D2D_i.hxx # Libraries targets lib_LTLIBRARIES = libStdMeshersEngine.la @@ -105,7 +109,11 @@ dist_libStdMeshersEngine_la_SOURCES = \ StdMeshers_TrianglePreference_i.cxx \ StdMeshers_MaxLength_i.cxx \ StdMeshers_QuadrangleParams_i.cxx \ - StdMeshers_RadialQuadrangle_1D2D_i.cxx + StdMeshers_RadialQuadrangle_1D2D_i.cxx \ + StdMeshers_ImportSource1D_i.cxx \ + StdMeshers_ImportSource2D_i.cxx \ + StdMeshers_Import_1D_i.cxx \ + StdMeshers_Import_1D2D_i.cxx # additionnal information to compil and link file libStdMeshersEngine_la_CPPFLAGS = \ diff --git a/src/StdMeshers_I/StdMeshers_Deflection1D_i.cxx b/src/StdMeshers_I/StdMeshers_Deflection1D_i.cxx index 3c0859e23..61416d23c 100644 --- a/src/StdMeshers_I/StdMeshers_Deflection1D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_Deflection1D_i.cxx @@ -25,7 +25,6 @@ // Moved here from SMESH_LocalLength_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #include "StdMeshers_Deflection1D_i.hxx" #include "SMESH_Gen_i.hxx" diff --git a/src/StdMeshers_I/StdMeshers_ImportSource1D_i.cxx b/src/StdMeshers_I/StdMeshers_ImportSource1D_i.cxx new file mode 100644 index 000000000..4d33ec8bb --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_ImportSource1D_i.cxx @@ -0,0 +1,280 @@ +// 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 SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_ImportSource1D_i.cxx +// Module : SMESH +// +#include "StdMeshers_ImportSource1D_i.hxx" + +#include "SMESH_Gen.hxx" +#include "SMESH_Gen_i.hxx" +#include "SMESH_Group_i.hxx" +#include "SMESH_PythonDump.hxx" +#include "StdMeshers_ObjRefUlils.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +#include + +#include CORBA_SERVER_HEADER(SMESH_Group) + +using namespace std; + +//============================================================================= +/*! + * StdMeshers_ImportSource1D_i::StdMeshers_ImportSource1D_i + * + * Constructor + */ +//============================================================================= + +StdMeshers_ImportSource1D_i::StdMeshers_ImportSource1D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ) +{ + MESSAGE( "StdMeshers_ImportSource1D_i::StdMeshers_ImportSource1D_i" ); + myBaseImpl = new ::StdMeshers_ImportSource1D( theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); + _groupEntries = new SMESH::string_array(); +} + +//============================================================================= +/*! + * StdMeshers_ImportSource1D_i::~StdMeshers_ImportSource1D_i + * + * Destructor + */ +//============================================================================= + +StdMeshers_ImportSource1D_i::~StdMeshers_ImportSource1D_i() +{ + MESSAGE( "StdMeshers_ImportSource1D_i::~StdMeshers_ImportSource1D_i" ); +} + +//============================================================================= +/*! + * SetSourceEdges + */ +//============================================================================= + +void StdMeshers_ImportSource1D_i::SetSourceEdges(const SMESH::ListOfGroups& groups) +{ + MESSAGE( "StdMeshers_ImportSource1D_i::SetSourceEdges" ); + ASSERT( myBaseImpl ); + try + { + std::vector smesh_groups; + std::vector entries; + SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy(); + for ( int i = 0; i < groups.length(); ++i ) + if ( SMESH_GroupBase_i* gp_i = SMESH::DownCast( groups[i] )) + { + if ( gp_i->GetType() != SMESH::EDGE ) + THROW_SALOME_CORBA_EXCEPTION("Wrong group type", SALOME::BAD_PARAM); + smesh_groups.push_back( gp_i->GetSmeshGroup() ); + + SALOMEDS::SObject_var so = SMESH_Gen_i::GetSMESHGen()->ObjectToSObject(study, groups[i]); + if ( !so->_is_nil()) + { + CORBA::String_var entry = so->GetID(); + entries.push_back( entry.in() ); + } + } + this->GetImpl()->SetGroups( smesh_groups ); + + _groupEntries = new SMESH::string_array; + _groupEntries->length( entries.size ()); + for ( int i = 0; i < entries.size(); ++i ) + _groupEntries[i] = entries[i].c_str(); + } + catch ( SALOME_Exception& S_ex ) + { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM ); + } + + // Update Python script + SMESH::TPythonDump() << _this() << ".SetSourceEdges( " << groups << " )"; +} + +//============================================================================= +/*! + * Return entries of groups + */ +//============================================================================= + +SMESH::string_array* StdMeshers_ImportSource1D_i::GetSourceEdges() +{ + MESSAGE( "StdMeshers_ImportSource1D_i::GetImportSource" ); + SMESH::string_array_var res = new SMESH::string_array( _groupEntries ); + return res._retn(); +} + +//================================================================================ +/*! + * \brief Set to copy mesh and groups + */ +//================================================================================ + +void StdMeshers_ImportSource1D_i::SetCopySourceMesh(CORBA::Boolean toCopyMesh, + CORBA::Boolean toCopyGroups) +{ + GetImpl()->SetCopySourceMesh(toCopyMesh,toCopyGroups); + SMESH::TPythonDump() << _this() << ".SetCopySourceMesh( " + << toCopyMesh << ", " << toCopyGroups << " )"; +} + +//================================================================================ +/*! + * \brief Return "to copy mesh and groups" + */ +//================================================================================ + +void StdMeshers_ImportSource1D_i::GetCopySourceMesh(CORBA::Boolean& toCopyMesh, + CORBA::Boolean& toCopyGroups) +{ + GetImpl()->GetCopySourceMesh(toCopyMesh,toCopyGroups); +} + +//================================================================================ +/*! + * \brief Write parameters in a string + * \retval char* - resulting string + */ +//================================================================================ + +char* StdMeshers_ImportSource1D_i::SaveTo() +{ + std::ostringstream os; + os << " " << _groupEntries->length(); + + SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy(); + for ( int i = 0; i < _groupEntries->length(); ++i ) + { + // entry + os << " " << _groupEntries[i]; + + // id + SALOMEDS::SObject_var groupSO = study->FindObjectID( _groupEntries[i] ); + CORBA::Object_var groupObj; + if ( !groupSO->_is_nil() ) + groupObj = groupSO->GetObject(); + StdMeshers_ObjRefUlils::SaveToStream( groupObj, os ); + } + + myBaseImpl->SaveTo( os ); + + return CORBA::string_dup( os.str().c_str() ); +} + +//================================================================================ +/*! + * \brief Retrieve parameters from the string + * \param theStream - the input string + */ +//================================================================================ + +void StdMeshers_ImportSource1D_i::LoadFrom( const char* theStream ) +{ + std::istringstream is( theStream ); + + int nbGroups; + is >> nbGroups; + + _groupEntries = new SMESH::string_array; + _groupEntries->length( nbGroups ); + std::string id, entry; + for ( int i = 0; i < _groupEntries->length(); ++i ) + { + if ( is >> entry ) + _groupEntries[i] = entry.c_str(); + else + { + _groupEntries->length( i ); + is.clear(ios::badbit | is.rdstate()); + break; + } + if ( is >> id ) + _groupIDs.push_back( id ); + else + { + is.clear(ios::badbit | is.rdstate()); + break; + } + } + + myBaseImpl->LoadFrom( is ); +} + +//================================================================================ +/*! + * \brief Retrieve groups by their ids loaded by LoadFrom() + * This is possible only when all meshes are fully loaded + */ +//================================================================================ + +void StdMeshers_ImportSource1D_i::UpdateAsMeshesRestored() +{ + std::vector smesh_groups; + for ( unsigned i = 0; i < _groupIDs.size(); ++i ) + { + std::istringstream is( _groupIDs[i].c_str() ); + SMESH::SMESH_GroupBase_var group = + StdMeshers_ObjRefUlils::LoadObjectFromStream( is ); + if ( SMESH_GroupBase_i* gp_i = SMESH::DownCast( group )) + smesh_groups.push_back( gp_i->GetSmeshGroup() ); + } + GetImpl()->RestoreGroups(smesh_groups); +} + +//============================================================================= +/*! + * StdMeshers_ImportSource1D_i::GetImpl + * + * Get implementation + */ +//============================================================================= + +::StdMeshers_ImportSource1D* StdMeshers_ImportSource1D_i::GetImpl() +{ + MESSAGE( "StdMeshers_ImportSource1D_i::GetImpl" ); + return ( ::StdMeshers_ImportSource1D* )myBaseImpl; +} + +//================================================================================ +/*! + * \brief Verify whether hypothesis supports given entity type + * \param type - dimension (see SMESH::Dimension enumeration) + * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise + * + * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration) + */ +//================================================================================ +CORBA::Boolean StdMeshers_ImportSource1D_i::IsDimSupported( SMESH::Dimension type ) +{ + return type == SMESH::DIM_1D; +} + diff --git a/src/StdMeshers_I/StdMeshers_ImportSource1D_i.hxx b/src/StdMeshers_I/StdMeshers_ImportSource1D_i.hxx new file mode 100644 index 000000000..216244a62 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_ImportSource1D_i.hxx @@ -0,0 +1,74 @@ +// 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 SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_ImportSource1D_i.hxx +// Module : SMESH +// +#ifndef _SMESH_ImportSource1D_I_HXX_ +#define _SMESH_ImportSource1D_I_HXX_ + +#include "SMESH_StdMeshers_I.hxx" + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_Hypothesis_i.hxx" +#include "StdMeshers_ImportSource.hxx" + +class SMESH_Gen; + +class STDMESHERS_I_EXPORT StdMeshers_ImportSource1D_i: + public virtual POA_StdMeshers::StdMeshers_ImportSource1D, + public virtual SMESH_Hypothesis_i +{ + public: + // Constructor + StdMeshers_ImportSource1D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_ImportSource1D_i(); + + void SetSourceEdges(const ::SMESH::ListOfGroups& groups); + SMESH::string_array* GetSourceEdges(); + void SetCopySourceMesh(::CORBA::Boolean toCopyMesh, ::CORBA::Boolean toCopyGroups); + void GetCopySourceMesh(::CORBA::Boolean& toCopyMesh, ::CORBA::Boolean& toCopyGroups); + + // Get implementation + ::StdMeshers_ImportSource1D* GetImpl(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); + + // Redefined Persistence + virtual char* SaveTo(); + virtual void LoadFrom( const char* theStream ); + virtual void UpdateAsMeshesRestored(); + + private: + SMESH::string_array_var _groupEntries; + std::vector< std::string > _groupIDs; +}; + +#endif + diff --git a/src/StdMeshers_I/StdMeshers_ImportSource2D_i.cxx b/src/StdMeshers_I/StdMeshers_ImportSource2D_i.cxx new file mode 100644 index 000000000..b2221a426 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_ImportSource2D_i.cxx @@ -0,0 +1,280 @@ +// 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 SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_ImportSource2D_i.cxx +// Module : SMESH +// +#include "StdMeshers_ImportSource2D_i.hxx" + +#include "SMESH_Gen.hxx" +#include "SMESH_Gen_i.hxx" +#include "SMESH_Group_i.hxx" +#include "SMESH_PythonDump.hxx" +#include "StdMeshers_ObjRefUlils.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +#include + +#include CORBA_SERVER_HEADER(SMESH_Group) + +using namespace std; + +//============================================================================= +/*! + * StdMeshers_ImportSource2D_i::StdMeshers_ImportSource2D_i + * + * Constructor + */ +//============================================================================= + +StdMeshers_ImportSource2D_i::StdMeshers_ImportSource2D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ) +{ + MESSAGE( "StdMeshers_ImportSource2D_i::StdMeshers_ImportSource2D_i" ); + myBaseImpl = new ::StdMeshers_ImportSource2D( theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); + _groupEntries = new SMESH::string_array(); +} + +//============================================================================= +/*! + * StdMeshers_ImportSource2D_i::~StdMeshers_ImportSource2D_i + * + * Destructor + */ +//============================================================================= + +StdMeshers_ImportSource2D_i::~StdMeshers_ImportSource2D_i() +{ + MESSAGE( "StdMeshers_ImportSource2D_i::~StdMeshers_ImportSource2D_i" ); +} + +//============================================================================= +/*! + * SetSourceFaces + */ +//============================================================================= + +void StdMeshers_ImportSource2D_i::SetSourceFaces(const SMESH::ListOfGroups& groups) +{ + MESSAGE( "StdMeshers_ImportSource2D_i::SetSourceFaces" ); + ASSERT( myBaseImpl ); + try + { + std::vector smesh_groups; + std::vector entries; + SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy(); + for ( int i = 0; i < groups.length(); ++i ) + if ( SMESH_GroupBase_i* gp_i = SMESH::DownCast( groups[i] )) + { + if ( gp_i->GetType() != SMESH::FACE ) + THROW_SALOME_CORBA_EXCEPTION("Wrong group type", SALOME::BAD_PARAM); + smesh_groups.push_back( gp_i->GetSmeshGroup() ); + + SALOMEDS::SObject_var so = SMESH_Gen_i::GetSMESHGen()->ObjectToSObject(study, groups[i]); + if ( !so->_is_nil()) + { + CORBA::String_var entry = so->GetID(); + entries.push_back( entry.in() ); + } + } + this->GetImpl()->SetGroups( smesh_groups ); + + _groupEntries = new SMESH::string_array; + _groupEntries->length( entries.size ()); + for ( int i = 0; i < entries.size(); ++i ) + _groupEntries[i] = entries[i].c_str(); + } + catch ( SALOME_Exception& S_ex ) + { + THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM ); + } + + // Update Python script + SMESH::TPythonDump() << _this() << ".SetSourceFaces( " << groups << " )"; +} + +//============================================================================= +/*! + * Return entries of groups + */ +//============================================================================= + +SMESH::string_array* StdMeshers_ImportSource2D_i::GetSourceFaces() +{ + MESSAGE( "StdMeshers_ImportSource2D_i::GetImportSource" ); + SMESH::string_array_var res = new SMESH::string_array( _groupEntries ); + return res._retn(); +} + +//================================================================================ +/*! + * \brief Set to copy mesh and groups + */ +//================================================================================ + +void StdMeshers_ImportSource2D_i::SetCopySourceMesh(CORBA::Boolean toCopyMesh, + CORBA::Boolean toCopyGroups) +{ + GetImpl()->SetCopySourceMesh(toCopyMesh,toCopyGroups); + SMESH::TPythonDump() << _this() << ".SetCopySourceMesh( " + << toCopyMesh << ", " << toCopyGroups << " )"; +} + +//================================================================================ +/*! + * \brief Return "to copy mesh and groups" + */ +//================================================================================ + +void StdMeshers_ImportSource2D_i::GetCopySourceMesh(CORBA::Boolean& toCopyMesh, + CORBA::Boolean& toCopyGroups) +{ + GetImpl()->GetCopySourceMesh(toCopyMesh,toCopyGroups); +} + +//================================================================================ +/*! + * \brief Write parameters in a string + * \retval char* - resulting string + */ +//================================================================================ + +char* StdMeshers_ImportSource2D_i::SaveTo() +{ + std::ostringstream os; + os << " " << _groupEntries->length(); + + SALOMEDS::Study_var study = SMESH_Gen_i::GetSMESHGen()->GetCurrentStudy(); + for ( int i = 0; i < _groupEntries->length(); ++i ) + { + // entry + os << " " << _groupEntries[i]; + + // id + SALOMEDS::SObject_var groupSO = study->FindObjectID( _groupEntries[i] ); + CORBA::Object_var groupObj; + if ( !groupSO->_is_nil() ) + groupObj = groupSO->GetObject(); + StdMeshers_ObjRefUlils::SaveToStream( groupObj, os ); + } + + myBaseImpl->SaveTo( os ); + + return CORBA::string_dup( os.str().c_str() ); +} + +//================================================================================ +/*! + * \brief Retrieve parameters from the string + * \param theStream - the input string + */ +//================================================================================ + +void StdMeshers_ImportSource2D_i::LoadFrom( const char* theStream ) +{ + std::istringstream is( theStream ); + + int nbGroups; + is >> nbGroups; + + _groupEntries = new SMESH::string_array; + _groupEntries->length( nbGroups ); + std::string id, entry; + for ( int i = 0; i < _groupEntries->length(); ++i ) + { + if ( is >> entry ) + _groupEntries[i] = entry.c_str(); + else + { + _groupEntries->length( i ); + is.clear(ios::badbit | is.rdstate()); + break; + } + if ( is >> id ) + _groupIDs.push_back( id ); + else + { + is.clear(ios::badbit | is.rdstate()); + break; + } + } + + myBaseImpl->LoadFrom( is ); +} + +//================================================================================ +/*! + * \brief Retrieve groups by their ids loaded by LoadFrom() + * This is possible only when all meshes are fully loaded + */ +//================================================================================ + +void StdMeshers_ImportSource2D_i::UpdateAsMeshesRestored() +{ + std::vector smesh_groups; + for ( unsigned i = 0; i < _groupIDs.size(); ++i ) + { + std::istringstream is( _groupIDs[i].c_str() ); + SMESH::SMESH_GroupBase_var group = + StdMeshers_ObjRefUlils::LoadObjectFromStream( is ); + if ( SMESH_GroupBase_i* gp_i = SMESH::DownCast( group )) + smesh_groups.push_back( gp_i->GetSmeshGroup() ); + } + GetImpl()->RestoreGroups(smesh_groups); +} + +//============================================================================= +/*! + * StdMeshers_ImportSource2D_i::GetImpl + * + * Get implementation + */ +//============================================================================= + +::StdMeshers_ImportSource2D* StdMeshers_ImportSource2D_i::GetImpl() +{ + MESSAGE( "StdMeshers_ImportSource2D_i::GetImpl" ); + return ( ::StdMeshers_ImportSource2D* )myBaseImpl; +} + +//================================================================================ +/*! + * \brief Verify whether hypothesis supports given entity type + * \param type - dimension (see SMESH::Dimension enumeration) + * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise + * + * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration) + */ +//================================================================================ +CORBA::Boolean StdMeshers_ImportSource2D_i::IsDimSupported( SMESH::Dimension type ) +{ + return type == SMESH::DIM_2D; +} + diff --git a/src/StdMeshers_I/StdMeshers_ImportSource2D_i.hxx b/src/StdMeshers_I/StdMeshers_ImportSource2D_i.hxx new file mode 100644 index 000000000..7f2d71217 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_ImportSource2D_i.hxx @@ -0,0 +1,74 @@ +// 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 SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_ImportSource2D_i.hxx +// Module : SMESH +// +#ifndef _SMESH_ImportSource2D_I_HXX_ +#define _SMESH_ImportSource2D_I_HXX_ + +#include "SMESH_StdMeshers_I.hxx" + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_Hypothesis_i.hxx" +#include "StdMeshers_ImportSource.hxx" + +class SMESH_Gen; + +class STDMESHERS_I_EXPORT StdMeshers_ImportSource2D_i: + public virtual POA_StdMeshers::StdMeshers_ImportSource2D, + public virtual SMESH_Hypothesis_i +{ + public: + // Constructor + StdMeshers_ImportSource2D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_ImportSource2D_i(); + + void SetSourceFaces(const ::SMESH::ListOfGroups& groups); + SMESH::string_array* GetSourceFaces(); + void SetCopySourceMesh(::CORBA::Boolean toCopyMesh, ::CORBA::Boolean toCopyGroups); + void GetCopySourceMesh(::CORBA::Boolean& toCopyMesh, ::CORBA::Boolean& toCopyGroups); + + // Get implementation + ::StdMeshers_ImportSource2D* GetImpl(); + + // Verify whether hypothesis supports given entity type + CORBA::Boolean IsDimSupported( SMESH::Dimension type ); + + // Redefined Persistence + virtual char* SaveTo(); + virtual void LoadFrom( const char* theStream ); + virtual void UpdateAsMeshesRestored(); + + private: + SMESH::string_array_var _groupEntries; + std::vector< std::string > _groupIDs; +}; + +#endif + diff --git a/src/StdMeshers_I/StdMeshers_Import_1D2D_i.cxx b/src/StdMeshers_I/StdMeshers_Import_1D2D_i.cxx new file mode 100644 index 000000000..e2489e54d --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_Import_1D2D_i.cxx @@ -0,0 +1,67 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// +// 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 SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_Import_1D2D_i.cxx +// Module : SMESH +// +#include "StdMeshers_Import_1D2D_i.hxx" +#include "SMESH_Gen.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +using namespace std; + + +//============================================================================= +/*! + * StdMeshers_Import_1D2D_i::StdMeshers_Import_1D2D_i + */ +//============================================================================= + +StdMeshers_Import_1D2D_i::StdMeshers_Import_1D2D_i (PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + SMESH_Algo_i( thePOA ), + SMESH_2D_Algo_i( thePOA ) +{ + MESSAGE( "StdMeshers_Import_1D2D_i::StdMeshers_Import_1D2D_i" ); + myBaseImpl = new ::StdMeshers_Import_1D2D(theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); +} + +//----------------------------------------------------------------------------- + +StdMeshers_Import_1D2D_i::~StdMeshers_Import_1D2D_i() +{ + MESSAGE( "StdMeshers_Import_1D2D_i::~StdMeshers_Import_1D2D_i" ); +} + +//----------------------------------------------------------------------------- + +::StdMeshers_Import_1D2D* StdMeshers_Import_1D2D_i::GetImpl() +{ + MESSAGE( "StdMeshers_Import_1D2D_i::GetImpl" ); + return ( ::StdMeshers_Import_1D2D* )myBaseImpl; +} + diff --git a/src/StdMeshers_I/StdMeshers_Import_1D2D_i.hxx b/src/StdMeshers_I/StdMeshers_Import_1D2D_i.hxx new file mode 100644 index 000000000..8e569661c --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_Import_1D2D_i.hxx @@ -0,0 +1,53 @@ +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// +// 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 SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_Import_1D2D_i.hxx +// Module : SMESH +// +#ifndef _SMESH_Import_1D2D_I_HXX_ +#define _SMESH_Import_1D2D_I_HXX_ + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_2D_Algo_i.hxx" +#include "StdMeshers_Import_1D2D.hxx" + +class SMESH_Gen; + +class StdMeshers_Import_1D2D_i: + public virtual POA_StdMeshers::StdMeshers_Import_1D2D, + public virtual SMESH_2D_Algo_i +{ +public: + // Constructor + StdMeshers_Import_1D2D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + + // Destructor + virtual ~StdMeshers_Import_1D2D_i(); + + // Get implementation + ::StdMeshers_Import_1D2D* GetImpl(); +}; + + +#endif diff --git a/src/StdMeshers_I/StdMeshers_Import_1D_i.cxx b/src/StdMeshers_I/StdMeshers_Import_1D_i.cxx new file mode 100644 index 000000000..02b3e2951 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_Import_1D_i.cxx @@ -0,0 +1,85 @@ +// 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 SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_Import_1D_i.cxx +// Moved here from SMESH_Import_1D_i.cxx +// Author : Paul RASCLE, EDF +// Module : SMESH +// +#include "StdMeshers_Import_1D_i.hxx" +#include "SMESH_Gen.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +using namespace std; + +//============================================================================= +/*! + * StdMeshers_Import_1D_i::StdMeshers_Import_1D_i + * + * Constructor + */ +//============================================================================= + +StdMeshers_Import_1D_i::StdMeshers_Import_1D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + SMESH_Algo_i( thePOA ), + SMESH_1D_Algo_i( thePOA ) +{ + MESSAGE( "StdMeshers_Import_1D_i::StdMeshers_Import_1D_i" ); + myBaseImpl = new ::StdMeshers_Import_1D( theGenImpl->GetANewId(), + theStudyId, + theGenImpl ); +} + +//============================================================================= +/*! + * StdMeshers_Import_1D_i::~StdMeshers_Import_1D_i + * + * Destructor + */ +//============================================================================= + +StdMeshers_Import_1D_i::~StdMeshers_Import_1D_i() +{ + MESSAGE( "StdMeshers_Import_1D_i::~StdMeshers_Import_1D_i" ); +} + +//============================================================================= +/*! + * StdMeshers_Import_1D_i::GetImpl + * + * Get implementation + */ +//============================================================================= + +::StdMeshers_Import_1D* StdMeshers_Import_1D_i::GetImpl() +{ + MESSAGE( "StdMeshers_Import_1D_i::GetImpl" ); + return ( ::StdMeshers_Import_1D* )myBaseImpl; +} + diff --git a/src/StdMeshers_I/StdMeshers_Import_1D_i.hxx b/src/StdMeshers_I/StdMeshers_Import_1D_i.hxx new file mode 100644 index 000000000..d0e1d9752 --- /dev/null +++ b/src/StdMeshers_I/StdMeshers_Import_1D_i.hxx @@ -0,0 +1,54 @@ +// 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 SMESH_I : idl implementation based on 'SMESH' unit's calsses +// File : StdMeshers_Import_1D_i.hxx +// Module : SMESH +// +#ifndef _SMESH_Import_1D_I_HXX_ +#define _SMESH_Import_1D_I_HXX_ + +#include "SMESH_StdMeshers_I.hxx" + +#include +#include CORBA_SERVER_HEADER(SMESH_BasicHypothesis) + +#include "SMESH_1D_Algo_i.hxx" +#include "StdMeshers_Import_1D.hxx" + +class STDMESHERS_I_EXPORT StdMeshers_Import_1D_i: + public virtual POA_StdMeshers::StdMeshers_Import_1D, + public virtual SMESH_1D_Algo_i +{ + public: + // Constructor + StdMeshers_Import_1D_i( PortableServer::POA_ptr thePOA, + int theStudyId, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~StdMeshers_Import_1D_i(); + + // Get implementation + ::StdMeshers_Import_1D* GetImpl(); +}; + +#endif diff --git a/src/StdMeshers_I/StdMeshers_ProjectionSource1D_i.hxx b/src/StdMeshers_I/StdMeshers_ProjectionSource1D_i.hxx index d416a5787..fbd8b1898 100644 --- a/src/StdMeshers_I/StdMeshers_ProjectionSource1D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_ProjectionSource1D_i.hxx @@ -24,7 +24,6 @@ // File : StdMeshers_ProjectionSource1D_i.hxx // Author : Edward AGAPOV // Module : SMESH -// $Header$ // #ifndef _SMESH_ProjectionSource1D_I_HXX_ #define _SMESH_ProjectionSource1D_I_HXX_ diff --git a/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.cxx b/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.cxx index 612ccc9ee..85295c055 100644 --- a/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.cxx +++ b/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.cxx @@ -16,13 +16,11 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // - // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_QuadrangleParams_i.cxx // Author : Sergey KUUL, OCC // Module : SMESH -// $Header$ -// + #include "StdMeshers_QuadrangleParams_i.hxx" #include "SMESH_Gen_i.hxx" #include "SMESH_Gen.hxx" @@ -94,6 +92,21 @@ void StdMeshers_QuadrangleParams_i::SetTriaVertex(CORBA::Long vertID) << vertID << " )"; } +//============================================================================= +/*! + * StdMeshers_QuadrangleParams_i::GetTriaVertex + * + * Get base vertex for triangles + */ +//============================================================================= + +CORBA::Long StdMeshers_QuadrangleParams_i::GetTriaVertex() +{ + MESSAGE( "StdMeshers_QuadrangleParams_i::GetTriaVertex" ); + ASSERT( myBaseImpl ); + return this->GetImpl()->GetTriaVertex(); +} + //============================================================================= /*! * StdMeshers_QuadrangleParams_i::SetObjectEntry @@ -143,17 +156,65 @@ char* StdMeshers_QuadrangleParams_i::GetObjectEntry() //============================================================================= /*! - * StdMeshers_QuadrangleParams_i::GetTriaVertex + * StdMeshers_QuadrangleParams_i::SetQuadType * - * Get base vertex for triangles + * Set the type of quadrangulation */ //============================================================================= +void StdMeshers_QuadrangleParams_i::SetQuadType(StdMeshers::QuadType type) +{ + //static char* quadTypes[5] = {"StdMeshers.QUAD_STANDARD", + // "StdMeshers.QUAD_TRIANGLE_PREF", + // "StdMeshers.QUAD_QUADRANGLE_PREF", + // "StdMeshers.QUAD_QUADRANGLE_PREF_REVERSED", + // "StdMeshers.QUAD_REDUCED"}; -CORBA::Long StdMeshers_QuadrangleParams_i::GetTriaVertex() + MESSAGE("StdMeshers_QuadrangleParams_i::SetQuadType"); + ASSERT(myBaseImpl); + + if (int(type) >= int(StdMeshers::QUAD_NB_TYPES)) { + THROW_SALOME_CORBA_EXCEPTION("Bad type of quadrangulation", SALOME::BAD_PARAM); + } + + try { + this->GetImpl()->SetQuadType(StdMeshers_QuadType(int(type))); + } + catch (SALOME_Exception& S_ex) { + THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); + } + + // Update Python script + const char* quadType; + switch (type) { + case StdMeshers::QUAD_STANDARD: + quadType = "StdMeshers.QUAD_STANDARD"; break; + case StdMeshers::QUAD_TRIANGLE_PREF: + quadType = "StdMeshers.QUAD_TRIANGLE_PREF"; break; + case StdMeshers::QUAD_QUADRANGLE_PREF: + quadType = "StdMeshers.QUAD_QUADRANGLE_PREF"; break; + case StdMeshers::QUAD_QUADRANGLE_PREF_REVERSED: + quadType = "StdMeshers.QUAD_QUADRANGLE_PREF_REVERSED"; break; + case StdMeshers::QUAD_REDUCED: + quadType = "StdMeshers.QUAD_REDUCED"; break; + default: + quadType = "UNKNOWN"; + } + SMESH::TPythonDump() << _this() << ".SetQuadType( " << quadType << " )"; + //SMESH::TPythonDump() << _this() << ".SetQuadType( " << quadTypes[int(type)] << " )"; +} + +//============================================================================= +/*! + * StdMeshers_QuadrangleParams_i::GetQuadType + * + * Get the type of quadrangulation + */ +//============================================================================= +StdMeshers::QuadType StdMeshers_QuadrangleParams_i::GetQuadType() { - MESSAGE( "StdMeshers_QuadrangleParams_i::GetTriaVertex" ); - ASSERT( myBaseImpl ); - return this->GetImpl()->GetTriaVertex(); + MESSAGE("StdMeshers_QuadrangleParams_i::GetQuadType"); + ASSERT(myBaseImpl); + return StdMeshers::QuadType(int(this->GetImpl()->GetQuadType())); } //============================================================================= @@ -183,4 +244,3 @@ CORBA::Boolean StdMeshers_QuadrangleParams_i::IsDimSupported( SMESH::Dimension t { return type == SMESH::DIM_2D; } - diff --git a/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.hxx b/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.hxx index fa695107d..062af680d 100644 --- a/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.hxx +++ b/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.hxx @@ -16,13 +16,12 @@ // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // - -// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes // File : StdMeshers_QuadrangleParams_i.hxx // Author : Sergey KUUL, OCC // Module : SMESH // $Header$ -// + #ifndef _SMESH_QUADRANGLEPARAMS_I_HXX_ #define _SMESH_QUADRANGLEPARAMS_I_HXX_ @@ -43,9 +42,9 @@ class STDMESHERS_I_EXPORT StdMeshers_QuadrangleParams_i: { public: // Constructor - StdMeshers_QuadrangleParams_i( PortableServer::POA_ptr thePOA, + StdMeshers_QuadrangleParams_i (PortableServer::POA_ptr thePOA, int theStudyId, - ::SMESH_Gen* theGenImpl ); + ::SMESH_Gen* theGenImpl); // Destructor virtual ~StdMeshers_QuadrangleParams_i(); @@ -56,18 +55,24 @@ public: // Get length //CORBA::Double GetLength(CORBA::Boolean theIsStart); - //Set base vertex for triangles - void SetTriaVertex(CORBA::Long vertID); + // Set base vertex for triangles + void SetTriaVertex (CORBA::Long vertID); - //Get base vertex for triangles + // Get base vertex for triangles CORBA::Long GetTriaVertex(); - //Set the Entry of the Object - void SetObjectEntry(const char* theEntry); + // Set the Entry of the Object + void SetObjectEntry (const char* theEntry); - //Get Object Entry + // Get Object Entry char* GetObjectEntry(); + // Set the type of quadrangulation + void SetQuadType (StdMeshers::QuadType type); + + // Get the type of quadrangulation + StdMeshers::QuadType GetQuadType(); + // Get implementation ::StdMeshers_QuadrangleParams* GetImpl(); diff --git a/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.cxx b/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.cxx index 090e00ee9..b58d9cbd5 100644 --- a/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.cxx @@ -19,7 +19,6 @@ // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_RadialQuadrangle_1D2D_i.cxx -// Author : Paul RASCLE, EDF // Module : SMESH // #include "StdMeshers_RadialQuadrangle_1D2D_i.hxx" diff --git a/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.hxx b/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.hxx index 85a6e3ae0..1a9fb637c 100644 --- a/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_RadialQuadrangle_1D2D_i.hxx @@ -19,9 +19,7 @@ // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses // File : StdMeshers_RadialQuadrangle_1D2D_i.hxx -// Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #ifndef _SMESH_RadialQuadrangle_1D2D_I_HXX_ #define _SMESH_RadialQuadrangle_1D2D_I_HXX_ diff --git a/src/StdMeshers_I/StdMeshers_Regular_1D_i.cxx b/src/StdMeshers_I/StdMeshers_Regular_1D_i.cxx index 2b75cdc8a..d6fd3cf45 100644 --- a/src/StdMeshers_I/StdMeshers_Regular_1D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_Regular_1D_i.cxx @@ -25,7 +25,6 @@ // Moved here from SMESH_Regular_1D_i.cxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #include "StdMeshers_Regular_1D_i.hxx" #include "SMESH_Gen.hxx" diff --git a/src/StdMeshers_I/StdMeshers_Regular_1D_i.hxx b/src/StdMeshers_I/StdMeshers_Regular_1D_i.hxx index bfc463de5..02006c455 100644 --- a/src/StdMeshers_I/StdMeshers_Regular_1D_i.hxx +++ b/src/StdMeshers_I/StdMeshers_Regular_1D_i.hxx @@ -25,7 +25,6 @@ // Moved here from SMESH_Regular_1D_i.hxx // Author : Paul RASCLE, EDF // Module : SMESH -// $Header$ // #ifndef _SMESH_REGULAR_1D_I_HXX_ #define _SMESH_REGULAR_1D_I_HXX_ diff --git a/src/StdMeshers_I/StdMeshers_i.cxx b/src/StdMeshers_I/StdMeshers_i.cxx index f50fae594..a8f6a9824 100644 --- a/src/StdMeshers_I/StdMeshers_i.cxx +++ b/src/StdMeshers_I/StdMeshers_i.cxx @@ -56,6 +56,8 @@ #include "StdMeshers_SegmentLengthAroundVertex_i.hxx" #include "StdMeshers_MaxLength_i.hxx" #include "StdMeshers_QuadrangleParams_i.hxx" +#include "StdMeshers_ImportSource1D_i.hxx" +#include "StdMeshers_ImportSource2D_i.hxx" #include "StdMeshers_Regular_1D_i.hxx" #include "StdMeshers_MEFISTO_2D_i.hxx" @@ -67,6 +69,8 @@ #include "StdMeshers_CompositeSegment_1D_i.hxx" #include "StdMeshers_UseExisting_1D2D_i.hxx" #include "StdMeshers_RadialQuadrangle_1D2D_i.hxx" +#include "StdMeshers_Import_1D_i.hxx" +#include "StdMeshers_Import_1D2D_i.hxx" template class StdHypothesisCreator_i:public HypothesisCreator_i @@ -141,6 +145,10 @@ STDMESHERS_I_EXPORT aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "QuadrangleParams") == 0) aCreator = new StdHypothesisCreator_i; + else if (strcmp(aHypName, "ImportSource1D") == 0) + aCreator = new StdHypothesisCreator_i; + else if (strcmp(aHypName, "ImportSource2D") == 0) + aCreator = new StdHypothesisCreator_i; // Algorithms else if (strcmp(aHypName, "Regular_1D") == 0) @@ -171,6 +179,10 @@ STDMESHERS_I_EXPORT aCreator = new StdHypothesisCreator_i; else if (strcmp(aHypName, "RadialQuadrangle_1D2D") == 0) aCreator = new StdHypothesisCreator_i; + else if (strcmp(aHypName, "Import_1D") == 0) + aCreator = new StdHypothesisCreator_i; + else if (strcmp(aHypName, "Import_1D2D") == 0) + aCreator = new StdHypothesisCreator_i; else ; return aCreator;